Only adjust window layers from WindowLayerController

Various animation adjustment logic will directly set mAnimLayer
outside of WindowLayerController. If we end up setting this layer
very high, we can end up moving it above the special windows
collected in WindowLayersController.

Bug: 33702491
Bug: 35396882
Test: bit FrameworksServicesTests:com.android.server.wm.WindowTokenTests
Change-Id: I9850529ecd6f0067bc24421515b39b645885a3ec
This commit is contained in:
Robert Carr
2017-02-27 11:33:33 -08:00
parent b70ef8d79b
commit dee1b3f80c
10 changed files with 47 additions and 54 deletions

View File

@@ -248,8 +248,9 @@ public class AppWindowAnimator {
}
}
void updateLayers() {
thumbnailLayer = mAppToken.adjustAnimLayer(animLayerAdjustment);
private void updateLayers() {
mAppToken.getDisplayContent().assignWindowLayers(false /* relayoutNeeded */);
thumbnailLayer = mAppToken.getHighestAnimLayer();
}
private void stepThumbnailAnimation(long currentTime) {

View File

@@ -1408,6 +1408,11 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
return candidate;
}
@Override
int getAnimLayerAdjustment() {
return mAppAnimator.animLayerAdjustment;
}
@Override
void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);

View File

@@ -341,9 +341,6 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
};
private final Consumer<WindowState> mSetInputMethodAnimLayerAdjustment =
w -> w.adjustAnimLayer(mInputMethodAnimLayerAdjustment);
private final Consumer<WindowState> mScheduleToastTimeout = w -> {
final int lostFocusUid = mTmpWindow.mOwnerUid;
final Handler handler = mService.mH;
@@ -1281,8 +1278,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
void setInputMethodAnimLayerAdjustment(int adj) {
if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
mInputMethodAnimLayerAdjustment = adj;
mImeWindowsContainers.forAllWindows(mSetInputMethodAnimLayerAdjustment,
true /* traverseTopToBottom */);
assignWindowLayers(false /* relayoutNeeded */);
}
/**
@@ -1688,7 +1684,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
+ target + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
setInputMethodTarget(target, false, target.mAppToken != null
? target.mAppToken.mAppAnimator.animLayerAdjustment : 0);
? target.mAppToken.getAnimLayerAdjustment() : 0);
}
return target;

View File

@@ -547,6 +547,7 @@ class WallpaperController {
for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
token.updateWallpaperWindows(visible, mWallpaperAnimLayerAdjustment);
token.getDisplayContent().assignWindowLayers(false);
}
}
@@ -568,7 +569,7 @@ class WallpaperController {
// Only do this if we are not transferring between two wallpaper targets.
mWallpaperAnimLayerAdjustment =
(mPrevWallpaperTarget == null && mWallpaperTarget.mAppToken != null)
? mWallpaperTarget.mAppToken.mAppAnimator.animLayerAdjustment : 0;
? mWallpaperTarget.mAppToken.getAnimLayerAdjustment() : 0;
if (mWallpaperTarget.mWallpaperX >= 0) {
mLastWallpaperX = mWallpaperTarget.mWallpaperX;

View File

@@ -142,7 +142,6 @@ class WallpaperWindowToken extends WindowToken {
// First, make sure the client has the current visibility state.
wallpaper.dispatchWallpaperVisibility(visible);
wallpaper.adjustAnimLayer(animLayerAdj);
if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
+ wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);

View File

@@ -129,7 +129,7 @@ class WindowLayersController {
final WindowStateAnimator winAnimator = w.mWinAnimator;
Slog.v(TAG_WM, "Assign layer " + w + ": " + "mBase=" + w.mBaseLayer
+ " mLayer=" + w.mLayer + (w.mAppToken == null
? "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
? "" : " mAppLayer=" + w.mAppToken.getAnimLayerAdjustment())
+ " =mAnimLayer=" + winAnimator.mAnimLayer);
}, false /* traverseTopToBottom */);
}

View File

@@ -1923,16 +1923,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mIsImWindow && mService.mInputMethodTarget != null) {
final AppWindowToken appToken = mService.mInputMethodTarget.mAppToken;
if (appToken != null) {
return appToken.mAppAnimator.animLayerAdjustment;
return appToken.getAnimLayerAdjustment();
}
}
if (mAppToken != null) {
return mAppToken.mAppAnimator.animLayerAdjustment;
}
// Nothing is animating, so there is no animation adjustment.
return 0;
return mToken.getAnimLayerAdjustment();
}
int getSpecialWindowAnimLayerAdjustment() {
@@ -3860,20 +3855,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return highest;
}
int adjustAnimLayer(int adj) {
int highestAnimLayer = mWinAnimator.mAnimLayer = mLayer + adj;
if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG_WM,
"adjustAnimLayer win=" + this + " anim layer: " + mWinAnimator.mAnimLayer);
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState childWindow = mChildren.get(i);
childWindow.adjustAnimLayer(adj);
if (childWindow.mWinAnimator.mAnimLayer > highestAnimLayer) {
highestAnimLayer = childWindow.mWinAnimator.mAnimLayer;
}
}
return highestAnimLayer;
}
@Override
boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
if (mChildren.isEmpty()) {

View File

@@ -151,21 +151,6 @@ class WindowToken extends WindowContainer<WindowState> {
}
}
int adjustAnimLayer(int adj) {
int highestAnimLayer = -1;
for (int j = mChildren.size() - 1; j >= 0; j--) {
final WindowState w = mChildren.get(j);
final int winHighestAnimLayer = w.adjustAnimLayer(adj);
if (winHighestAnimLayer > highestAnimLayer) {
highestAnimLayer = winHighestAnimLayer;
}
if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
mDisplayContent.setInputMethodAnimLayerAdjustment(adj);
}
}
return highestAnimLayer;
}
/**
* Returns true if the new window is considered greater than the existing window in terms of
* z-order.
@@ -197,6 +182,11 @@ class WindowToken extends WindowContainer<WindowState> {
return mChildren.isEmpty();
}
// Used by AppWindowToken.
int getAnimLayerAdjustment() {
return 0;
}
WindowState getReplacingWindow() {
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState win = mChildren.get(i);

View File

@@ -280,6 +280,7 @@ class WindowTestsBase {
/* Used so we can gain access to some protected members of the {@link WindowToken} class */
static class TestWindowToken extends WindowToken {
int adj = 0;
TestWindowToken(int type, DisplayContent dc) {
this(type, dc, false /* persistOnEmpty */);
@@ -297,6 +298,11 @@ class WindowTestsBase {
boolean hasWindow(WindowState w) {
return mChildren.contains(w);
}
@Override
int getAnimLayerAdjustment() {
return adj;
}
}
/** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */

View File

@@ -102,14 +102,28 @@ public class WindowTokenTests extends WindowTestsBase {
final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
final int adj = 50;
final int window2StartLayer = window2.mLayer = 100;
final int window3StartLayer = window3.mLayer = 200;
final int highestLayer = token.adjustAnimLayer(adj);
window2.mLayer = 100;
window3.mLayer = 200;
assertEquals(adj, window1.mWinAnimator.mAnimLayer);
assertEquals(adj, window11.mWinAnimator.mAnimLayer);
assertEquals(adj, window12.mWinAnimator.mAnimLayer);
// We assign layers once, to get the base values computed by
// the controller.
sLayersController.assignWindowLayers(sDisplayContent);
final int window1StartLayer = window1.mWinAnimator.mAnimLayer;
final int window11StartLayer = window11.mWinAnimator.mAnimLayer;
final int window12StartLayer = window12.mWinAnimator.mAnimLayer;
final int window2StartLayer = window2.mWinAnimator.mAnimLayer;
final int window3StartLayer = window3.mWinAnimator.mAnimLayer;
// Then we set an adjustment, and assign them again, they should
// be offset.
int adj = token.adj = 50;
sLayersController.assignWindowLayers(sDisplayContent);
final int highestLayer = token.getHighestAnimLayer();
assertEquals(window1StartLayer + adj, window1.mWinAnimator.mAnimLayer);
assertEquals(window11StartLayer + adj, window11.mWinAnimator.mAnimLayer);
assertEquals(window12StartLayer + adj, window12.mWinAnimator.mAnimLayer);
assertEquals(window2StartLayer + adj, window2.mWinAnimator.mAnimLayer);
assertEquals(window3StartLayer + adj, window3.mWinAnimator.mAnimLayer);
assertEquals(window3StartLayer + adj, highestLayer);