Fixed bug where stack crop wasn't applied when it should
- Apply stack crop if window isn't animating when replacing window.
We were previously not applying the crop if replacing window regardless
of the animation state.
- Apply stack crop if the current docked window isn't animating.
We were previously not applying if any window in the system is animating.
- Also created setter/getter methods for WindowAnimator.mAnimating
to make debugging easier.
Bug: 25645069
Change-Id: I671549626e218358a7dea9e78bd0b2a1f1b3a51e
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 38bd71d..a96bd2c 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -67,7 +67,7 @@
private final WindowSurfacePlacer mWindowPlacerLocked;
/** Is any window animating? */
- boolean mAnimating;
+ private boolean mAnimating;
/** Is any app window animating? */
boolean mAppWindowAnimating;
@@ -168,7 +168,8 @@
appAnimator.wasAnimating = appAnimator.animating;
if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) {
appAnimator.animating = true;
- mAnimating = mAppWindowAnimating = true;
+ setAnimating(true);
+ mAppWindowAnimating = true;
} else if (appAnimator.wasAnimating) {
// stopped animating, do one more pass through the layout
setAppLayoutChanges(appAnimator,
@@ -186,7 +187,8 @@
final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator;
appAnimator.wasAnimating = appAnimator.animating;
if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) {
- mAnimating = mAppWindowAnimating = true;
+ setAnimating(true);
+ mAppWindowAnimating = true;
} else if (appAnimator.wasAnimating) {
// stopped animating, do one more pass through the layout
setAppLayoutChanges(appAnimator,
@@ -282,7 +284,7 @@
final boolean wasAnimating = winAnimator.mWasAnimating;
final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
winAnimator.mWasAnimating = nowAnimating;
- mAnimating |= nowAnimating;
+ orAnimating(nowAnimating);
if (DEBUG_WALLPAPER) {
Slog.v(TAG, win + ": wasAnimating=" + wasAnimating +
@@ -546,7 +548,7 @@
}
}
}
- mAnimating = true;
+ setAnimating(true);
}
// If this window's app token is running a detached wallpaper
@@ -617,7 +619,7 @@
// We can now show all of the drawn windows!
if (!mService.mOpeningApps.contains(wtoken)) {
- mAnimating |= appAnimator.showAllWindowsLocked();
+ orAnimating(appAnimator.showAllWindowsLocked());
}
}
}
@@ -636,7 +638,7 @@
mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE;
boolean wasAnimating = mAnimating;
- mAnimating = false;
+ setAnimating(false);
mAppWindowAnimating = false;
if (DEBUG_WINDOW_TRACE) {
Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
@@ -657,7 +659,7 @@
displayAnimator.mScreenRotationAnimation;
if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) {
- mAnimating = true;
+ setAnimating(true);
} else {
mBulkUpdateParams |= SET_UPDATE_ROTATION;
screenRotationAnimation.kill();
@@ -697,7 +699,7 @@
screenRotationAnimation.updateSurfacesInTransaction();
}
- mAnimating |= mService.getDisplayContentLocked(displayId).animateDimLayers();
+ orAnimating(mService.getDisplayContentLocked(displayId).animateDimLayers());
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mAccessibilityController != null
@@ -920,4 +922,16 @@
private class DisplayContentsAnimator {
ScreenRotationAnimation mScreenRotationAnimation = null;
}
+
+ boolean isAnimating() {
+ return mAnimating;
+ }
+
+ void setAnimating(boolean animating) {
+ mAnimating = animating;
+ }
+
+ void orAnimating(boolean animating) {
+ mAnimating |= animating;
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a22f821..89f0b83 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7683,7 +7683,7 @@
synchronized (mWindowMap) {
// Since we're holding both mWindowMap and mAnimator we don't need to
// hold mAnimator.mLayoutToAnim.
- if (mAnimator.mAnimating || mAnimationScheduled) {
+ if (mAnimator.isAnimating() || mAnimationScheduled) {
// If we are animating, don't do the gc now but
// delay a bit so we don't interrupt the animation.
sendEmptyMessageDelayed(H.FORCE_GC, 2000);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index decfb34..441a2ab 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1084,7 +1084,7 @@
} else if (w.mDecorFrame.isEmpty()) {
// Windows without policy decor aren't cropped.
w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
- } else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.mAnimating) {
+ } else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.isAnimating()) {
// If we're animating, the wallpaper crop should only be updated at the end of the
// animation.
mTmpClipRect.set(w.mSystemDecorRect);
@@ -1124,12 +1124,8 @@
// The clip rect was generated assuming (0,0) as the window origin,
// so we need to translate to match the actual surface coordinates.
clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
- // We don't want to clip to stack bounds windows that are currently doing entrance
- // animation for docked window, otherwise the animating window will be suddenly cut off.
- if (!(mAnimator.mAnimating && w.inDockedWorkspace())) {
- adjustCropToStackBounds(w, clipRect, isFreeformResizing);
- }
+ adjustCropToStackBounds(w, clipRect, isFreeformResizing);
w.transformFromScreenToSurfaceSpace(clipRect);
@@ -1142,31 +1138,40 @@
private void adjustCropToStackBounds(WindowState w, Rect clipRect, boolean isFreeformResizing) {
final AppWindowToken appToken = w.mAppToken;
final Task task = w.getTask();
- // We don't apply the the stack bounds to the window that is being replaced, because it was
- // living in a different stack. If we suddenly crop it to the new stack bounds, it might
- // get cut off. We don't want it to happen, so we let it ignore the stack bounds until it
- // gets removed. The window that will replace it will abide them.
- if (task != null && appToken.mCropWindowsToStack && !appToken.mWillReplaceWindow) {
- TaskStack stack = task.mStack;
- stack.getDimBounds(mTmpStackBounds);
- // When we resize we use the big surface approach, which means we can't trust the
- // window frame bounds anymore. Instead, the window will be placed at 0, 0, but to avoid
- // hardcoding it, we use surface coordinates.
- final int frameX = isFreeformResizing ? (int) mSurfaceController.getX() :
- w.mFrame.left + mWin.mXOffset - w.getAttrs().surfaceInsets.left;
- final int frameY = isFreeformResizing ? (int) mSurfaceController.getY() :
- w.mFrame.top + mWin.mYOffset - w.getAttrs().surfaceInsets.top;
- // We need to do some acrobatics with surface position, because their clip region is
- // relative to the inside of the surface, but the stack bounds aren't.
- clipRect.left = Math.max(0,
- Math.max(mTmpStackBounds.left, frameX + clipRect.left) - frameX);
- clipRect.top = Math.max(0,
- Math.max(mTmpStackBounds.top, frameY + clipRect.top) - frameY);
- clipRect.right = Math.max(0,
- Math.min(mTmpStackBounds.right, frameX + clipRect.right) - frameX);
- clipRect.bottom = Math.max(0,
- Math.min(mTmpStackBounds.bottom, frameY + clipRect.bottom) - frameY);
+ if (task == null || !appToken.mCropWindowsToStack) {
+ return;
}
+
+ // We don't apply the stack bounds crop if:
+ // 1. The window is currently animating docked mode, otherwise the animating window will be
+ // suddenly cut off.
+ // 2. The window that is being replaced during animation, because it was living in a
+ // different stack. If we suddenly crop it to the new stack bounds, it might get cut off.
+ // We don't want it to happen, so we let it ignore the stack bounds until it gets removed.
+ // The window that will replace it will abide them.
+ if (isAnimating() && (appToken.mWillReplaceWindow || w.inDockedWorkspace())) {
+ return;
+ }
+
+ final TaskStack stack = task.mStack;
+ stack.getDimBounds(mTmpStackBounds);
+ // When we resize we use the big surface approach, which means we can't trust the
+ // window frame bounds anymore. Instead, the window will be placed at 0, 0, but to avoid
+ // hardcoding it, we use surface coordinates.
+ final int frameX = isFreeformResizing ? (int) mSurfaceController.getX() :
+ w.mFrame.left + mWin.mXOffset - w.getAttrs().surfaceInsets.left;
+ final int frameY = isFreeformResizing ? (int) mSurfaceController.getY() :
+ w.mFrame.top + mWin.mYOffset - w.getAttrs().surfaceInsets.top;
+ // We need to do some acrobatics with surface position, because their clip region is
+ // relative to the inside of the surface, but the stack bounds aren't.
+ clipRect.left = Math.max(0,
+ Math.max(mTmpStackBounds.left, frameX + clipRect.left) - frameX);
+ clipRect.top = Math.max(0,
+ Math.max(mTmpStackBounds.top, frameY + clipRect.top) - frameY);
+ clipRect.right = Math.max(0,
+ Math.min(mTmpStackBounds.right, frameX + clipRect.right) - frameX);
+ clipRect.bottom = Math.max(0,
+ Math.min(mTmpStackBounds.bottom, frameY + clipRect.bottom) - frameY);
}
void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 3b57634..ae96658 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -542,11 +542,8 @@
mService.scheduleAnimationLocked();
- if (DEBUG_WINDOW_TRACE) {
- Slog.e(TAG,
- "performSurfacePlacementInner exit: animating="
- + mService.mAnimator.mAnimating);
- }
+ if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
+ "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
}
private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
@@ -1184,7 +1181,7 @@
">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
SurfaceControl.openTransaction();
try {
- mService.mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+ mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
} finally {
SurfaceControl.closeTransaction();
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
@@ -1467,7 +1464,7 @@
appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
}
mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
- mService.mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+ mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
}
}
}