From c7294607fc0debc54e92abac18bec2601a21ce27 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Fri, 13 May 2016 11:32:05 -0700 Subject: [PATCH] Fixes for ending PiP animation. During the PiP animation, we have two basic requirements: 1. We need to scale windows to the pinned stack bounds. 2. We need to halt resize and movement notifications to the client. As we end the animation, we need to disable these states at differing times. First we need to deliver a final resize and movement notification to the client for it's new position. However, Surfaces may not immediately resize (in particular in the case of child windows, it may be some time!), furthermore Surfaces may resize at different times so we need to persist scaling on a Surface by Surface basis after reenabling resize notifications. Bug: 28559097 Change-Id: I6d52a3e213e08a34f4c0eea892b2a84cd4c20e18 --- core/java/android/app/ActivityManager.java | 8 ++++++++ .../server/wm/BoundsAnimationController.java | 13 ++++++------- .../java/com/android/server/wm/TaskStack.java | 12 ++---------- .../server/wm/WindowStateAnimator.java | 19 ++++++++++++++++--- .../server/wm/WindowSurfacePlacer.java | 6 ++++-- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 8a92b5477caf0..1381ddb64ba84 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 f7fc00535cb2d..c92d325f45a98 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;