Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbcf2ca2 authored by Winson Chung's avatar Winson Chung
Browse files

Fix a couple more issues with canceling the recents animation w/ screenshots

- There are a couple scenarios that were exposed in further testing of
  cancelling the recents animation with screenshots:
1) ensure that we force-cancel the recents animation (ie. continue
   cancel when deferred) if the process dies, the failsafe occurs
   or starting a new animation.  Previous the failsafe was not
   continuing since it was already canceled
2) Add a failsafe when deferring cancelling. This is a catch-all for
   cases where launcher fails to return promptly, the system won't
   be stuck in a pending state waiting for the cleanup
3) Always finish the animation when requested by the runner even if
   there is a deferred cancel. Launcher was assuming that this was
   the case, but we were actually skipping the finish (which also
   causes the controller on the launcher side to be cleared) which
   prevents the cleanupScreenshot() from happening.

Bug: 192564669
Test: atest RecentsAnimationControllerTest

Change-Id: I8952a0c404bb17056c03f2bc8e78f51fc5bd0a1e
parent 4162c032
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -239,8 +239,10 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
            // Fetch all the surface controls and pass them to the client to get the animation
            // started. Cancel any existing recents animation running synchronously (do not hold the
            // WM lock)
            mWindowManager.cancelRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION,
                    "startRecentsActivity");
            if (mWindowManager.getRecentsAnimationController() != null) {
                mWindowManager.getRecentsAnimationController().forceCancelAnimation(
                        REORDER_MOVE_TO_ORIGINAL_POSITION, "startRecentsActivity");
            }
            mWindowManager.initializeRecentsAnimation(mTargetActivityType, recentsAnimationRunner,
                    this, mDefaultTaskDisplayArea.getDisplayId(),
                    mTaskSupervisor.mRecentTasks.getRecentTaskIds(), targetActivity);
+20 −19
Original line number Diff line number Diff line
@@ -122,9 +122,7 @@ public class RecentsAnimationController implements DeathRecipient {
            new ArrayList<>();
    private final int mDisplayId;
    private boolean mWillFinishToHome = false;
    private final Runnable mFailsafeRunnable = () -> cancelAnimation(
            mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_MOVE_TO_ORIGINAL_POSITION,
            "failSafeRunnable");
    private final Runnable mFailsafeRunnable = this::onFailsafe;

    // The recents component app token that is shown behind the visibile tasks
    private ActivityRecord mTargetActivityRecord;
@@ -262,9 +260,6 @@ public class RecentsAnimationController implements DeathRecipient {
            final long token = Binder.clearCallingIdentity();
            try {
                synchronized (mService.getWindowManagerLock()) {
                    if (mCanceled) {
                        return;
                    }
                    // Remove all new task targets.
                    for (int i = mPendingNewTaskTargets.size() - 1; i >= 0; i--) {
                        removeTaskInternal(mPendingNewTaskTargets.get(i));
@@ -807,6 +802,14 @@ public class RecentsAnimationController implements DeathRecipient {
                }, mPendingWallpaperAnimations);
    }

    void forceCancelAnimation(@ReorderMode int reorderMode, String reason) {
        if (!mCanceled) {
            cancelAnimation(reorderMode, reason);
        } else {
            continueDeferredCancelAnimation();
        }
    }

    void cancelAnimation(@ReorderMode int reorderMode, String reason) {
        cancelAnimation(reorderMode, false /*screenshot */, reason);
    }
@@ -821,9 +824,6 @@ public class RecentsAnimationController implements DeathRecipient {
     * finish the animation.
     */
    public void cancelAnimationForHomeStart() {
        if (mCanceled) {
            return;
        }
        final int reorderMode = mTargetActivityType == ACTIVITY_TYPE_HOME && mWillFinishToHome
                ? REORDER_MOVE_TO_TOP
                : REORDER_KEEP_IN_PLACE;
@@ -836,9 +836,6 @@ public class RecentsAnimationController implements DeathRecipient {
     * how to finish the animation.
     */
    public void cancelAnimationForDisplayChange() {
        if (mCanceled) {
            return;
        }
        cancelAnimation(mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_MOVE_TO_ORIGINAL_POSITION,
                true /* screenshot */, "cancelAnimationForDisplayChange");
    }
@@ -868,6 +865,8 @@ public class RecentsAnimationController implements DeathRecipient {
                if (taskSnapshot != null) {
                    // Defer until the runner calls back to cleanupScreenshot()
                    adapter.setSnapshotOverlay(taskSnapshot);
                    // Schedule a new failsafe for if the runner doesn't clean up the screenshot
                    scheduleFailsafe();
                } else {
                    // Do a normal cancel since we couldn't screenshot
                    mCallbacks.onAnimationFinished(reorderMode, false /* sendUserLeaveHint */);
@@ -1014,6 +1013,12 @@ public class RecentsAnimationController implements DeathRecipient {
        mService.mH.postDelayed(mFailsafeRunnable, FAILSAFE_DELAY);
    }

    void onFailsafe() {
        forceCancelAnimation(
                mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_MOVE_TO_ORIGINAL_POSITION,
                "onFailsafe");
    }

    private void linkToDeathOfRunner() throws RemoteException {
        if (!mLinkedToDeathOfRunner) {
            mRunner.asBinder().linkToDeath(this, 0);
@@ -1030,13 +1035,7 @@ public class RecentsAnimationController implements DeathRecipient {

    @Override
    public void binderDied() {
        if (!mCanceled) {
            cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
        } else {
            // If we are already canceled but with a screenshot, and are waiting for the
            // cleanupScreenshot() callback, then force-finish the animation now
            continueDeferredCancelAnimation();
        }
        forceCancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");

        synchronized (mService.getWindowManagerLock()) {
            // Clear associated input consumers on runner death
@@ -1358,5 +1357,7 @@ public class RecentsAnimationController implements DeathRecipient {
                + mCancelOnNextTransitionStart);
        pw.print(innerPrefix); pw.println("mCancelDeferredWithScreenshot="
                + mCancelDeferredWithScreenshot);
        pw.print(innerPrefix); pw.println("mPendingCancelWithScreenshotReorderMode="
                + mPendingCancelWithScreenshotReorderMode);
    }
}