Loading core/java/android/view/IRecentsAnimationController.aidl +3 −1 Original line number Diff line number Diff line Loading @@ -41,9 +41,11 @@ interface IRecentsAnimationController { * with remote animation targets should be relinquished. If {@param moveHomeToTop} is true, then * the home activity should be moved to the top. Otherwise, the home activity is hidden and the * user is returned to the app. * @param sendUserLeaveHint If set to true, {@link Activity#onUserLeaving} will be sent to the * top resumed app, false otherwise. */ @UnsupportedAppUsage void finish(boolean moveHomeToTop); void finish(boolean moveHomeToTop, boolean sendUserLeaveHint); /** * Called by the handler to indicate that the recents animation input consumer should be Loading packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java +8 −2 Original line number Diff line number Diff line Loading @@ -77,9 +77,15 @@ public class RecentsAnimationControllerCompat { } } public void finish(boolean toHome) { /** * Finish the current recents animation. * @param toHome Going to home or back to the previous app. * @param sendUserLeaveHint determines whether userLeaveHint will be set true to the previous * app. */ public void finish(boolean toHome, boolean sendUserLeaveHint) { try { mAnimationController.finish(toHome); mAnimationController.finish(toHome, sendUserLeaveHint); } catch (RemoteException e) { Log.e(TAG, "Failed to finish recents animation", e); } Loading services/core/java/com/android/server/wm/BoundsAnimationController.java +74 −19 Original line number Diff line number Diff line Loading @@ -73,6 +73,13 @@ public class BoundsAnimationController { /** Schedule a PiP mode changed callback when this animation ends. */ public static final int SCHEDULE_PIP_MODE_CHANGED_ON_END = 2; public static final int BOUNDS = 0; public static final int FADE_IN = 1; @IntDef({BOUNDS, FADE_IN}) public @interface AnimationType {} private static final int FADE_IN_DURATION = 500; // Only accessed on UI thread. private ArrayMap<BoundsAnimationTarget, BoundsAnimator> mRunningAnimations = new ArrayMap<>(); Loading Loading @@ -115,6 +122,7 @@ public class BoundsAnimationController { private boolean mFinishAnimationAfterTransition = false; private final AnimationHandler mAnimationHandler; private Choreographer mChoreographer; private @AnimationType int mAnimationType; private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000; Loading @@ -140,6 +148,7 @@ public class BoundsAnimationController { implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { private final BoundsAnimationTarget mTarget; private final @AnimationType int mAnimationType; private final Rect mFrom = new Rect(); private final Rect mTo = new Rect(); private final Rect mTmpRect = new Rect(); Loading @@ -166,8 +175,8 @@ public class BoundsAnimationController { // Depending on whether we are animating from // a smaller to a larger size private final int mFrozenTaskWidth; private final int mFrozenTaskHeight; private int mFrozenTaskWidth; private int mFrozenTaskHeight; // Timeout callback to ensure we continue the animation if waiting for resuming or app // windows drawn fails Loading @@ -176,12 +185,13 @@ public class BoundsAnimationController { resume(); }; BoundsAnimator(BoundsAnimationTarget target, Rect from, Rect to, @SchedulePipModeChangedState int schedulePipModeChangedState, BoundsAnimator(BoundsAnimationTarget target, @AnimationType int animationType, Rect from, Rect to, @SchedulePipModeChangedState int schedulePipModeChangedState, @SchedulePipModeChangedState int prevShedulePipModeChangedState, boolean moveFromFullscreen, boolean moveToFullscreen, Rect frozenTask) { super(); mTarget = target; mAnimationType = animationType; mFrom.set(from); mTo.set(to); mSchedulePipModeChangedState = schedulePipModeChangedState; Loading @@ -195,6 +205,7 @@ public class BoundsAnimationController { // to their final size immediately so we can use scaling to make the window // larger. Likewise if we are going from bigger to smaller, we want to wait until // the end so we don't have to upscale from the smaller finished size. if (mAnimationType == BOUNDS) { if (animatingToLargerSize()) { mFrozenTaskWidth = mTo.width(); mFrozenTaskHeight = mTo.height(); Loading @@ -203,6 +214,7 @@ public class BoundsAnimationController { mFrozenTaskHeight = frozenTask.isEmpty() ? mFrom.height() : frozenTask.height(); } } } @Override public void onAnimationStart(Animator animation) { Loading @@ -222,8 +234,9 @@ public class BoundsAnimationController { // otherwise. boolean continueAnimation; if (mPrevSchedulePipModeChangedState == NO_PIP_MODE_CHANGED_CALLBACKS) { continueAnimation = mTarget.onAnimationStart(mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START, false /* forceUpdate */); continueAnimation = mTarget.onAnimationStart( mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START, false /* forceUpdate */, mAnimationType); // When starting an animation from fullscreen, pause here and wait for the // windows-drawn signal before we start the rest of the transition down into PiP. Loading @@ -238,7 +251,8 @@ public class BoundsAnimationController { // However, we still need to report to them that they are leaving PiP, so this will // force an update via a mode changed callback. continueAnimation = mTarget.onAnimationStart( true /* schedulePipModeChangedCallback */, true /* forceUpdate */); true /* schedulePipModeChangedCallback */, true /* forceUpdate */, mAnimationType); } else { // The animation is already running, but we should check that the TaskStack is still // valid before continuing with the animation Loading Loading @@ -285,6 +299,13 @@ public class BoundsAnimationController { @Override public void onAnimationUpdate(ValueAnimator animation) { final float value = (Float) animation.getAnimatedValue(); if (mAnimationType == FADE_IN) { if (!mTarget.setPinnedStackAlpha(value)) { cancelAndCallAnimationEnd(); } return; } final float remains = 1 - value; mTmpRect.left = (int) (mFrom.left * remains + mTo.left * value + 0.5f); mTmpRect.top = (int) (mFrom.top * remains + mTo.top * value + 0.5f); Loading Loading @@ -408,16 +429,29 @@ public class BoundsAnimationController { public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to, int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveFromFullscreen, boolean moveToFullscreen) { boolean moveFromFullscreen, boolean moveToFullscreen, @AnimationType int animationType) { animateBoundsImpl(target, from, to, animationDuration, schedulePipModeChangedState, moveFromFullscreen, moveToFullscreen); moveFromFullscreen, moveToFullscreen, animationType); } @VisibleForTesting BoundsAnimator animateBoundsImpl(final BoundsAnimationTarget target, Rect from, Rect to, int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveFromFullscreen, boolean moveToFullscreen) { boolean moveFromFullscreen, boolean moveToFullscreen, @AnimationType int animationType) { final BoundsAnimator existing = mRunningAnimations.get(target); // animateBoundsImpl gets called twice for each animation. The second time we get the final // to rect that respects the shelf, which is when we want to resize. Our signal for fade in // comes in from how to enter into pip, but we also need to use the to and from rect to // decide which animation we want to run finally. boolean shouldResize = false; if (isRunningFadeInAnimation(target)) { shouldResize = true; if (from.contains(to)) { animationType = FADE_IN; } } final boolean replacing = existing != null; @SchedulePipModeChangedState int prevSchedulePipModeChangedState = NO_PIP_MODE_CHANGED_CALLBACKS; Loading Loading @@ -477,18 +511,34 @@ public class BoundsAnimationController { // Since we are replacing, we skip both animation start and end callbacks existing.cancel(); } final BoundsAnimator animator = new BoundsAnimator(target, from, to, if (shouldResize) { target.setPinnedStackSize(to, null); } final BoundsAnimator animator = new BoundsAnimator(target, animationType, from, to, schedulePipModeChangedState, prevSchedulePipModeChangedState, moveFromFullscreen, moveToFullscreen, frozenTask); mRunningAnimations.put(target, animator); animator.setFloatValues(0f, 1f); animator.setDuration((animationDuration != -1 ? animationDuration : DEFAULT_TRANSITION_DURATION) * DEBUG_ANIMATION_SLOW_DOWN_FACTOR); animator.setDuration(animationType == FADE_IN ? FADE_IN_DURATION : (animationDuration != -1 ? animationDuration : DEFAULT_TRANSITION_DURATION) * DEBUG_ANIMATION_SLOW_DOWN_FACTOR); animator.setInterpolator(mFastOutSlowInInterpolator); animator.start(); return animator; } public void setAnimationType(@AnimationType int animationType) { mAnimationType = animationType; } /** return the current animation type. */ public @AnimationType int getAnimationType() { @AnimationType int animationType = mAnimationType; // Default to BOUNDS. mAnimationType = BOUNDS; return animationType; } public Handler getHandler() { return mHandler; } Loading @@ -498,6 +548,11 @@ public class BoundsAnimationController { mHandler.post(this::resume); } private boolean isRunningFadeInAnimation(final BoundsAnimationTarget target) { final BoundsAnimator existing = mRunningAnimations.get(target); return existing != null && existing.mAnimationType == FADE_IN && existing.isStarted(); } private void resume() { for (int i = 0; i < mRunningAnimations.size(); i++) { final BoundsAnimator b = mRunningAnimations.valueAt(i); Loading services/core/java/com/android/server/wm/BoundsAnimationTarget.java +5 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,8 @@ interface BoundsAnimationTarget { * callbacks * @return whether to continue the animation */ boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate); boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate, @BoundsAnimationController.AnimationType int animationType); /** * @return Whether the animation should be paused waiting for the windows to draw before Loading @@ -53,6 +54,9 @@ interface BoundsAnimationTarget { */ boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds); /** Sets the alpha of the animation target */ boolean setPinnedStackAlpha(float alpha); /** * Callback for the target to inform it that the animation has ended, so it can do some * necessary cleanup. Loading services/core/java/com/android/server/wm/RecentsAnimation.java +23 −5 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.view.WindowManager.TRANSIT_NONE; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.BoundsAnimationController.BOUNDS; import static com.android.server.wm.BoundsAnimationController.FADE_IN; import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP; Loading Loading @@ -201,7 +203,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } } private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) { private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode, boolean sendUserLeaveHint) { synchronized (mService.mGlobalLock) { if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller=" + mWindowManager.getRecentsAnimationController() Loading Loading @@ -246,7 +249,18 @@ class RecentsAnimation implements RecentsAnimationCallbacks, if (reorderMode == REORDER_MOVE_TO_TOP) { // Bring the target stack to the front mStackSupervisor.mNoAnimActivities.add(targetActivity); if (sendUserLeaveHint) { // Setting this allows the previous app to PiP. mStackSupervisor.mUserLeaving = true; targetStack.moveTaskToFrontLocked(targetActivity.getTaskRecord(), true /* noAnimation */, null /* activityOptions */, targetActivity.appTimeTracker, "RecentsAnimation.onAnimationFinished()"); } else { targetStack.moveToFront("RecentsAnimation.onAnimationFinished()"); } if (DEBUG) { final ActivityStack topStack = getTopNonAlwaysOnTopStack(); if (topStack != targetStack) { Loading Loading @@ -300,11 +314,11 @@ class RecentsAnimation implements RecentsAnimationCallbacks, @Override public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode, boolean runSychronously) { boolean runSychronously, boolean sendUserLeaveHint) { if (runSychronously) { finishAnimation(reorderMode); finishAnimation(reorderMode, sendUserLeaveHint); } else { mService.mH.post(() -> finishAnimation(reorderMode)); mService.mH.post(() -> finishAnimation(reorderMode, sendUserLeaveHint)); } } Loading @@ -317,6 +331,10 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } final RecentsAnimationController controller = mWindowManager.getRecentsAnimationController(); final DisplayContent dc = mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent; dc.mBoundsAnimationController.setAnimationType( controller.shouldCancelWithDeferredScreenshot() ? FADE_IN : BOUNDS); // Cancel running recents animation and screenshot previous task when the next // transition starts in below cases: Loading Loading
core/java/android/view/IRecentsAnimationController.aidl +3 −1 Original line number Diff line number Diff line Loading @@ -41,9 +41,11 @@ interface IRecentsAnimationController { * with remote animation targets should be relinquished. If {@param moveHomeToTop} is true, then * the home activity should be moved to the top. Otherwise, the home activity is hidden and the * user is returned to the app. * @param sendUserLeaveHint If set to true, {@link Activity#onUserLeaving} will be sent to the * top resumed app, false otherwise. */ @UnsupportedAppUsage void finish(boolean moveHomeToTop); void finish(boolean moveHomeToTop, boolean sendUserLeaveHint); /** * Called by the handler to indicate that the recents animation input consumer should be Loading
packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java +8 −2 Original line number Diff line number Diff line Loading @@ -77,9 +77,15 @@ public class RecentsAnimationControllerCompat { } } public void finish(boolean toHome) { /** * Finish the current recents animation. * @param toHome Going to home or back to the previous app. * @param sendUserLeaveHint determines whether userLeaveHint will be set true to the previous * app. */ public void finish(boolean toHome, boolean sendUserLeaveHint) { try { mAnimationController.finish(toHome); mAnimationController.finish(toHome, sendUserLeaveHint); } catch (RemoteException e) { Log.e(TAG, "Failed to finish recents animation", e); } Loading
services/core/java/com/android/server/wm/BoundsAnimationController.java +74 −19 Original line number Diff line number Diff line Loading @@ -73,6 +73,13 @@ public class BoundsAnimationController { /** Schedule a PiP mode changed callback when this animation ends. */ public static final int SCHEDULE_PIP_MODE_CHANGED_ON_END = 2; public static final int BOUNDS = 0; public static final int FADE_IN = 1; @IntDef({BOUNDS, FADE_IN}) public @interface AnimationType {} private static final int FADE_IN_DURATION = 500; // Only accessed on UI thread. private ArrayMap<BoundsAnimationTarget, BoundsAnimator> mRunningAnimations = new ArrayMap<>(); Loading Loading @@ -115,6 +122,7 @@ public class BoundsAnimationController { private boolean mFinishAnimationAfterTransition = false; private final AnimationHandler mAnimationHandler; private Choreographer mChoreographer; private @AnimationType int mAnimationType; private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000; Loading @@ -140,6 +148,7 @@ public class BoundsAnimationController { implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { private final BoundsAnimationTarget mTarget; private final @AnimationType int mAnimationType; private final Rect mFrom = new Rect(); private final Rect mTo = new Rect(); private final Rect mTmpRect = new Rect(); Loading @@ -166,8 +175,8 @@ public class BoundsAnimationController { // Depending on whether we are animating from // a smaller to a larger size private final int mFrozenTaskWidth; private final int mFrozenTaskHeight; private int mFrozenTaskWidth; private int mFrozenTaskHeight; // Timeout callback to ensure we continue the animation if waiting for resuming or app // windows drawn fails Loading @@ -176,12 +185,13 @@ public class BoundsAnimationController { resume(); }; BoundsAnimator(BoundsAnimationTarget target, Rect from, Rect to, @SchedulePipModeChangedState int schedulePipModeChangedState, BoundsAnimator(BoundsAnimationTarget target, @AnimationType int animationType, Rect from, Rect to, @SchedulePipModeChangedState int schedulePipModeChangedState, @SchedulePipModeChangedState int prevShedulePipModeChangedState, boolean moveFromFullscreen, boolean moveToFullscreen, Rect frozenTask) { super(); mTarget = target; mAnimationType = animationType; mFrom.set(from); mTo.set(to); mSchedulePipModeChangedState = schedulePipModeChangedState; Loading @@ -195,6 +205,7 @@ public class BoundsAnimationController { // to their final size immediately so we can use scaling to make the window // larger. Likewise if we are going from bigger to smaller, we want to wait until // the end so we don't have to upscale from the smaller finished size. if (mAnimationType == BOUNDS) { if (animatingToLargerSize()) { mFrozenTaskWidth = mTo.width(); mFrozenTaskHeight = mTo.height(); Loading @@ -203,6 +214,7 @@ public class BoundsAnimationController { mFrozenTaskHeight = frozenTask.isEmpty() ? mFrom.height() : frozenTask.height(); } } } @Override public void onAnimationStart(Animator animation) { Loading @@ -222,8 +234,9 @@ public class BoundsAnimationController { // otherwise. boolean continueAnimation; if (mPrevSchedulePipModeChangedState == NO_PIP_MODE_CHANGED_CALLBACKS) { continueAnimation = mTarget.onAnimationStart(mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START, false /* forceUpdate */); continueAnimation = mTarget.onAnimationStart( mSchedulePipModeChangedState == SCHEDULE_PIP_MODE_CHANGED_ON_START, false /* forceUpdate */, mAnimationType); // When starting an animation from fullscreen, pause here and wait for the // windows-drawn signal before we start the rest of the transition down into PiP. Loading @@ -238,7 +251,8 @@ public class BoundsAnimationController { // However, we still need to report to them that they are leaving PiP, so this will // force an update via a mode changed callback. continueAnimation = mTarget.onAnimationStart( true /* schedulePipModeChangedCallback */, true /* forceUpdate */); true /* schedulePipModeChangedCallback */, true /* forceUpdate */, mAnimationType); } else { // The animation is already running, but we should check that the TaskStack is still // valid before continuing with the animation Loading Loading @@ -285,6 +299,13 @@ public class BoundsAnimationController { @Override public void onAnimationUpdate(ValueAnimator animation) { final float value = (Float) animation.getAnimatedValue(); if (mAnimationType == FADE_IN) { if (!mTarget.setPinnedStackAlpha(value)) { cancelAndCallAnimationEnd(); } return; } final float remains = 1 - value; mTmpRect.left = (int) (mFrom.left * remains + mTo.left * value + 0.5f); mTmpRect.top = (int) (mFrom.top * remains + mTo.top * value + 0.5f); Loading Loading @@ -408,16 +429,29 @@ public class BoundsAnimationController { public void animateBounds(final BoundsAnimationTarget target, Rect from, Rect to, int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveFromFullscreen, boolean moveToFullscreen) { boolean moveFromFullscreen, boolean moveToFullscreen, @AnimationType int animationType) { animateBoundsImpl(target, from, to, animationDuration, schedulePipModeChangedState, moveFromFullscreen, moveToFullscreen); moveFromFullscreen, moveToFullscreen, animationType); } @VisibleForTesting BoundsAnimator animateBoundsImpl(final BoundsAnimationTarget target, Rect from, Rect to, int animationDuration, @SchedulePipModeChangedState int schedulePipModeChangedState, boolean moveFromFullscreen, boolean moveToFullscreen) { boolean moveFromFullscreen, boolean moveToFullscreen, @AnimationType int animationType) { final BoundsAnimator existing = mRunningAnimations.get(target); // animateBoundsImpl gets called twice for each animation. The second time we get the final // to rect that respects the shelf, which is when we want to resize. Our signal for fade in // comes in from how to enter into pip, but we also need to use the to and from rect to // decide which animation we want to run finally. boolean shouldResize = false; if (isRunningFadeInAnimation(target)) { shouldResize = true; if (from.contains(to)) { animationType = FADE_IN; } } final boolean replacing = existing != null; @SchedulePipModeChangedState int prevSchedulePipModeChangedState = NO_PIP_MODE_CHANGED_CALLBACKS; Loading Loading @@ -477,18 +511,34 @@ public class BoundsAnimationController { // Since we are replacing, we skip both animation start and end callbacks existing.cancel(); } final BoundsAnimator animator = new BoundsAnimator(target, from, to, if (shouldResize) { target.setPinnedStackSize(to, null); } final BoundsAnimator animator = new BoundsAnimator(target, animationType, from, to, schedulePipModeChangedState, prevSchedulePipModeChangedState, moveFromFullscreen, moveToFullscreen, frozenTask); mRunningAnimations.put(target, animator); animator.setFloatValues(0f, 1f); animator.setDuration((animationDuration != -1 ? animationDuration : DEFAULT_TRANSITION_DURATION) * DEBUG_ANIMATION_SLOW_DOWN_FACTOR); animator.setDuration(animationType == FADE_IN ? FADE_IN_DURATION : (animationDuration != -1 ? animationDuration : DEFAULT_TRANSITION_DURATION) * DEBUG_ANIMATION_SLOW_DOWN_FACTOR); animator.setInterpolator(mFastOutSlowInInterpolator); animator.start(); return animator; } public void setAnimationType(@AnimationType int animationType) { mAnimationType = animationType; } /** return the current animation type. */ public @AnimationType int getAnimationType() { @AnimationType int animationType = mAnimationType; // Default to BOUNDS. mAnimationType = BOUNDS; return animationType; } public Handler getHandler() { return mHandler; } Loading @@ -498,6 +548,11 @@ public class BoundsAnimationController { mHandler.post(this::resume); } private boolean isRunningFadeInAnimation(final BoundsAnimationTarget target) { final BoundsAnimator existing = mRunningAnimations.get(target); return existing != null && existing.mAnimationType == FADE_IN && existing.isStarted(); } private void resume() { for (int i = 0; i < mRunningAnimations.size(); i++) { final BoundsAnimator b = mRunningAnimations.valueAt(i); Loading
services/core/java/com/android/server/wm/BoundsAnimationTarget.java +5 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,8 @@ interface BoundsAnimationTarget { * callbacks * @return whether to continue the animation */ boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate); boolean onAnimationStart(boolean schedulePipModeChangedCallback, boolean forceUpdate, @BoundsAnimationController.AnimationType int animationType); /** * @return Whether the animation should be paused waiting for the windows to draw before Loading @@ -53,6 +54,9 @@ interface BoundsAnimationTarget { */ boolean setPinnedStackSize(Rect stackBounds, Rect taskBounds); /** Sets the alpha of the animation target */ boolean setPinnedStackAlpha(float alpha); /** * Callback for the target to inform it that the animation has ended, so it can do some * necessary cleanup. Loading
services/core/java/com/android/server/wm/RecentsAnimation.java +23 −5 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.view.WindowManager.TRANSIT_NONE; import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.BoundsAnimationController.BOUNDS; import static com.android.server.wm.BoundsAnimationController.FADE_IN; import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_TOP; Loading Loading @@ -201,7 +203,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } } private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) { private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode, boolean sendUserLeaveHint) { synchronized (mService.mGlobalLock) { if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller=" + mWindowManager.getRecentsAnimationController() Loading Loading @@ -246,7 +249,18 @@ class RecentsAnimation implements RecentsAnimationCallbacks, if (reorderMode == REORDER_MOVE_TO_TOP) { // Bring the target stack to the front mStackSupervisor.mNoAnimActivities.add(targetActivity); if (sendUserLeaveHint) { // Setting this allows the previous app to PiP. mStackSupervisor.mUserLeaving = true; targetStack.moveTaskToFrontLocked(targetActivity.getTaskRecord(), true /* noAnimation */, null /* activityOptions */, targetActivity.appTimeTracker, "RecentsAnimation.onAnimationFinished()"); } else { targetStack.moveToFront("RecentsAnimation.onAnimationFinished()"); } if (DEBUG) { final ActivityStack topStack = getTopNonAlwaysOnTopStack(); if (topStack != targetStack) { Loading Loading @@ -300,11 +314,11 @@ class RecentsAnimation implements RecentsAnimationCallbacks, @Override public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode, boolean runSychronously) { boolean runSychronously, boolean sendUserLeaveHint) { if (runSychronously) { finishAnimation(reorderMode); finishAnimation(reorderMode, sendUserLeaveHint); } else { mService.mH.post(() -> finishAnimation(reorderMode)); mService.mH.post(() -> finishAnimation(reorderMode, sendUserLeaveHint)); } } Loading @@ -317,6 +331,10 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } final RecentsAnimationController controller = mWindowManager.getRecentsAnimationController(); final DisplayContent dc = mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent; dc.mBoundsAnimationController.setAnimationType( controller.shouldCancelWithDeferredScreenshot() ? FADE_IN : BOUNDS); // Cancel running recents animation and screenshot previous task when the next // transition starts in below cases: Loading