From f9aa2a966eefb464775287aa4966c82641fac5f1 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Tue, 26 Apr 2016 14:22:19 -0700 Subject: [PATCH] Delay pinned animation finish during app transition. Sometimes in the case of pinned animation, we end up with multiple animations on screen. For example when transitioning pip->fullscreen, we are typically closing recents, and replacing it with a task behind. We need to delay swapping ourselves to the fullscreen stack until this app transition has finished, otherwise we will be in the fullscreen stack with the transitioning app, but not transitioning ourselves and thus assigned a lower Z-order. Bug: 28333917 Bug: 27793381 Bug: 28332969 Change-Id: Ie18cc04ceeabd94093017f79676253e1189f5249 --- .../server/wm/BoundsAnimationController.java | 42 ++++++++++++++++++- .../server/wm/WindowManagerService.java | 5 ++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java index debb382578174..220a6de1d8888 100644 --- a/services/core/java/com/android/server/wm/BoundsAnimationController.java +++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java @@ -24,10 +24,12 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.animation.Animator; import android.animation.ValueAnimator; import android.graphics.Rect; +import android.os.IBinder; import android.os.Debug; import android.util.ArrayMap; import android.util.Slog; import android.view.animation.LinearInterpolator; +import android.view.WindowManagerInternal; /** * Enables animating bounds of objects. @@ -49,6 +51,32 @@ public class BoundsAnimationController { // Only accessed on UI thread. private ArrayMap mRunningAnimations = new ArrayMap<>(); + private final WindowManagerInternal.AppTransitionListener mAppTransitionNotifier + = new WindowManagerInternal.AppTransitionListener() { + public void onAppTransitionCancelledLocked() { + animationFinished(); + } + public void onAppTransitionFinishedLocked(IBinder token) { + animationFinished(); + } + private void animationFinished() { + if (mFinishAnimationAfterTransition) { + for (int i = 0; i < mRunningAnimations.size(); i++) { + BoundsAnimator b = mRunningAnimations.valueAt(i); + b.onAnimationEnd(null); + } + } + } + }; + + private final AppTransition mAppTransition; + private boolean mFinishAnimationAfterTransition = false; + + BoundsAnimationController(AppTransition transition) { + mAppTransition = transition; + mAppTransition.registerListenerLocked(mAppTransitionNotifier); + } + private final class BoundsAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { private final AnimateBoundsUser mTarget; @@ -129,6 +157,7 @@ public class BoundsAnimationController { public void onAnimationStart(Animator animation) { if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget + " mReplacement=" + mReplacement); + mFinishAnimationAfterTransition = false; // Ensure that we have prepared the target for animation before // we trigger any size changes, so it can swap surfaces // in to appropriate modes, or do as it wishes otherwise. @@ -150,10 +179,21 @@ public class BoundsAnimationController { if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget + " mMoveToFullScreen=" + mMoveToFullScreen + " mWillReplace=" + mWillReplace); - finishAnimation(); + // There could be another animation running. For example in the + // move to fullscreen case, recents will also be closing while the + // previous task will be taking its place in the fullscreen stack. + // we have to ensure this is completed before we finish the animation + // and take our place in the fullscreen stack. + if (mAppTransition.isRunning() && !mFinishAnimationAfterTransition) { + mFinishAnimationAfterTransition = true; + return; + } + if (mMoveToFullScreen && !mWillReplace) { mTarget.moveToFullscreen(); } + + finishAnimation(); } @Override diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index cf415ff4e6474..f803256d5ea98 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -715,8 +715,7 @@ public class WindowManagerService extends IWindowManager.Stub final WindowAnimator mAnimator; - private final BoundsAnimationController mBoundsAnimationController = - new BoundsAnimationController(); + private final BoundsAnimationController mBoundsAnimationController; SparseArray mTaskIdToTask = new SparseArray<>(); @@ -974,6 +973,8 @@ public class WindowManagerService extends IWindowManager.Stub mAppTransition = new AppTransition(context, this); mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier); + mBoundsAnimationController = new BoundsAnimationController(mAppTransition); + mActivityManager = ActivityManagerNative.getDefault(); mAmInternal = LocalServices.getService(ActivityManagerInternal.class); mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);