diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index e3035daf0fd34..31fe39027fb0d 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -702,6 +702,14 @@ public class ActivityManager { public static boolean windowsAreScaleable(int stackId) { return stackId == PINNED_STACK_ID; } + + /** + * Returns true if windows in this stack should be given move animations + * by default. + */ + public static boolean hasMovementAnimations(int stackId) { + return stackId != PINNED_STACK_ID; + } } /** diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java index 51c40456c66a5..5bfece4144460 100644 --- a/services/core/java/com/android/server/wm/BoundsAnimationController.java +++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java @@ -156,12 +156,10 @@ public class BoundsAnimationController { + mTmpRect + " from=" + mFrom + " mTo=" + mTo + " value=" + value + " remains=" + remains); - if (remains != 0) { - mTmpTaskBounds.set(mTmpRect.left, mTmpRect.top, - mTmpRect.left + mFrozenTaskWidth, mTmpRect.top + mFrozenTaskHeight); - } + mTmpTaskBounds.set(mTmpRect.left, mTmpRect.top, + mTmpRect.left + mFrozenTaskWidth, mTmpRect.top + mFrozenTaskHeight); - if (!mTarget.setPinnedStackSize(mTmpRect, remains != 0 ? mTmpTaskBounds : null)) { + if (!mTarget.setPinnedStackSize(mTmpRect, mTmpTaskBounds)) { // Whoops, the target doesn't feel like animating anymore. Let's immediately finish // any further animation. animation.cancel(); @@ -205,11 +203,12 @@ public class BoundsAnimationController { return; } + finishAnimation(); + + mTarget.setPinnedStackSize(mTo, null); if (mMoveToFullScreen && !mWillReplace) { mTarget.moveToFullscreen(); } - - finishAnimation(); } @Override diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index eb8c1dc1d7a21..f51fd8aaf7eb5 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -130,12 +130,6 @@ public class TaskStack implements DimLayer.DimLayerUser, // certain logic we would otherwise apply while resizing, // while resizing in the bounds animating mode. private boolean mBoundsAnimating = false; - // By default, movement animations are applied to all - // window movement. If this is true, animations will not - // be applied within this stack. This is useful for example - // if the windows are moving as the result of a stack animation, - // in which case a second window animation would cause jitter. - private boolean mFreezeMovementAnimations = false; // Temporary storage for the new bounds that should be used after the configuration change. // Will be cleared once the client retrieves the new bounds via getBoundsForNewConfiguration(). @@ -1361,7 +1355,6 @@ public class TaskStack implements DimLayer.DimLayerUser, @Override // AnimatesBounds public void onAnimationStart() { synchronized (mService.mWindowMap) { - mFreezeMovementAnimations = true; mBoundsAnimating = true; } } @@ -1369,7 +1362,6 @@ public class TaskStack implements DimLayer.DimLayerUser, @Override // AnimatesBounds public void onAnimationEnd() { synchronized (mService.mWindowMap) { - mFreezeMovementAnimations = false; mBoundsAnimating = false; mService.requestTraversal(); } @@ -1396,8 +1388,8 @@ public class TaskStack implements DimLayer.DimLayerUser, getDisplayContent().getContentRect(bounds); } - public boolean getFreezeMovementAnimations() { - return mFreezeMovementAnimations; + public boolean hasMovementAnimations() { + return StackId.hasMovementAnimations(mStackId); } public boolean getForceScaleToCrop() { diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index d9367222602f3..54c421406ebcb 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -229,6 +229,8 @@ class WindowStateAnimator { long mDeferTransactionUntilFrame = -1; long mDeferTransactionTime = -1; + boolean mForceScaleUntilResize; + private final Rect mTmpSize = new Rect(); WindowStateAnimator(final WindowState win) { @@ -1416,8 +1418,13 @@ class WindowStateAnimator { float extraHScale = (float) 1.0; float extraVScale = (float) 1.0; + mSurfaceResized = mSurfaceController.setSizeInTransaction( + mTmpSize.width(), mTmpSize.height(), recoveringMemory); + mForceScaleUntilResize = mForceScaleUntilResize && !mSurfaceResized; + + calculateSurfaceWindowCrop(mTmpClipRect, mTmpFinalClipRect); - if (task != null && task.mStack.getForceScaleToCrop()) { + if ((task != null && task.mStack.getForceScaleToCrop()) || mForceScaleUntilResize) { int hInsets = w.getAttrs().surfaceInsets.left + w.getAttrs().surfaceInsets.right; int vInsets = w.getAttrs().surfaceInsets.top + w.getAttrs().surfaceInsets.bottom; // We want to calculate the scaling based on the content area, not based on @@ -1447,6 +1454,14 @@ class WindowStateAnimator { // past where the system would have cropped us mTmpClipRect.set(0, 0, mTmpSize.width(), mTmpSize.height()); mTmpFinalClipRect.setEmpty(); + + // Various surfaces in the scaled stack may resize at different times. + // We need to ensure for each surface, that we disable transformation matrix + // scaling in the same transaction which we resize the surface in. + // As we are in SCALING_MODE_SCALE_TO_WINDOW, SurfaceFlinger will + // then take over the scaling until the new buffer arrives, and things + // will be seamless. + mForceScaleUntilResize = true; } else { mSurfaceController.setPositionInTransaction(mTmpSize.left, mTmpSize.top, recoveringMemory); @@ -1458,8 +1473,6 @@ class WindowStateAnimator { mDtDx * w.mVScale * extraVScale, mDsDy * w.mHScale * extraHScale, mDtDy * w.mVScale * extraVScale, recoveringMemory); - mSurfaceResized = mSurfaceController.setSizeInTransaction( - mTmpSize.width(), mTmpSize.height(), recoveringMemory); if (mSurfaceResized) { mReportSurfaceResized = true; diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 7e9993db4cb4c..308b24dd8dd68 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -719,7 +719,7 @@ class WindowSurfacePlacer { || task.mStack.isAdjustedForIme()); if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0 && !w.isDragResizing() && !adjustedForMinimizedDockOrIme - && (task == null || !w.getTask().mStack.getFreezeMovementAnimations()) + && (task == null || w.getTask().mStack.hasMovementAnimations()) && !w.mWinAnimator.mLastHidden) { winAnimator.setMoveAnimation(left, top); } @@ -731,7 +731,9 @@ class WindowSurfacePlacer { } try { - w.mClient.moved(left, top); + if (task == null || task.mStack.getBoundsAnimating()) { + w.mClient.moved(left, top); + } } catch (RemoteException e) { } w.mMovedByResize = false;