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

Commit f310e540 authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Handle rotation while recents animation is running" into sc-dev

parents c46c9e64 6a930e06
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -5492,6 +5492,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    boolean updateDisplayOverrideConfigurationLocked() {
        // Preemptively cancel the running recents animation -- SysUI can't currently handle this
        // case properly since the signals it receives all happen post-change
        final RecentsAnimationController recentsAnimationController =
                mWmService.getRecentsAnimationController();
        if (recentsAnimationController != null) {
            recentsAnimationController.cancelAnimationForDisplayChange();
        }

        Configuration values = new Configuration();
        computeScreenConfiguration(values);

+10 −0
Original line number Diff line number Diff line
@@ -480,6 +480,16 @@ public class DisplayRotation {
            return false;
        }

        // Preemptively cancel the running recents animation -- SysUI can't currently handle this
        // case properly since the signals it receives all happen post-change. We do this earlier
        // in the rotation flow, since DisplayContent.updateDisplayOverrideConfigurationLocked seems
        // to happen too late.
        final RecentsAnimationController recentsAnimationController =
                mService.getRecentsAnimationController();
        if (recentsAnimationController != null) {
            recentsAnimationController.cancelAnimationForDisplayChange();
        }

        final Transition t = (useShellTransitions
                && !mService.mAtmService.getTransitionController().isCollecting())
                ? mService.mAtmService.getTransitionController().createTransition(TRANSIT_CHANGE)
+41 −10
Original line number Diff line number Diff line
@@ -221,7 +221,7 @@ public class RecentsAnimationController implements DeathRecipient {
                            final ArraySet<Task> tasks = Sets.newArraySet(task);
                            snapshotController.snapshotTasks(tasks);
                            snapshotController.addSkipClosingAppSnapshotTasks(tasks);
                            return snapshotController.getSnapshot(taskId, 0 /* userId */,
                            return snapshotController.getSnapshot(taskId, task.mUserId,
                                    false /* restoreFromDisk */, false /* isLowResolution */);
                        }
                    }
@@ -353,18 +353,23 @@ public class RecentsAnimationController implements DeathRecipient {

        @Override
        public void cleanupScreenshot() {
            final long token = Binder.clearCallingIdentity();
            try {
                synchronized (mService.mGlobalLock) {
                    if (mRecentScreenshotAnimator != null) {
                        mRecentScreenshotAnimator.cancelAnimation();
                        mRecentScreenshotAnimator = null;
                    }
                }
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }

        @Override
        public void setWillFinishToHome(boolean willFinishToHome) {
            synchronized (mService.getWindowManagerLock()) {
                mWillFinishToHome = willFinishToHome;
                RecentsAnimationController.this.setWillFinishToHome(willFinishToHome);
            }
        }

@@ -513,7 +518,6 @@ public class RecentsAnimationController implements DeathRecipient {
                || config.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
    }


    @VisibleForTesting
    AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) {
        return addAnimation(task, isRecentTaskInvisible, false /* hidden */,
@@ -816,6 +820,18 @@ public class RecentsAnimationController implements DeathRecipient {
        cancelAnimation(REORDER_KEEP_IN_PLACE, screenshot, "rootTaskOrderChanged");
    }

    /**
     * If there is a recents animation running, we need to cancel the animation and snapshot the
     * tasks before the change (to ensure they are captured at the right configuration)
     */
    public void cancelAnimationForDisplayChange() {
        if (mCanceled) {
            return;
        }
        cancelAnimation(mWillFinishToHome ? REORDER_MOVE_TO_TOP : REORDER_MOVE_TO_ORIGINAL_POSITION,
                true /* screenshot */, "cancelAnimationForDisplayChange");
    }

    private void cancelAnimation(@ReorderMode int reorderMode, boolean screenshot, String reason) {
        ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS, "cancelAnimation(): reason=%s", reason);
        synchronized (mService.getWindowManagerLock()) {
@@ -826,7 +842,7 @@ public class RecentsAnimationController implements DeathRecipient {
            mService.mH.removeCallbacks(mFailsafeRunnable);
            mCanceled = true;

            if (screenshot) {
            if (screenshot && !mPendingAnimations.isEmpty()) {
                // Screen shot previous task when next task starts transition and notify the runner.
                // We will actually finish the animation once the runner calls cleanUpScreenshot().
                final Task task = mPendingAnimations.get(0).mTask;
@@ -853,6 +869,11 @@ public class RecentsAnimationController implements DeathRecipient {
        }
    }

    @VisibleForTesting
    void setWillFinishToHome(boolean willFinishToHome) {
        mWillFinishToHome = willFinishToHome;
    }

    /**
     * Cancel recents animation when the next app transition starts.
     * <p>
@@ -905,7 +926,8 @@ public class RecentsAnimationController implements DeathRecipient {
            return null;
        }

        final TaskScreenshotAnimatable animatable = new TaskScreenshotAnimatable(mService.mSurfaceControlFactory, task,
        final TaskScreenshotAnimatable animatable = new TaskScreenshotAnimatable(
                mService.mSurfaceControlFactory, task,
                new SurfaceControl.ScreenshotHardwareBuffer(taskSnapshot.getHardwareBuffer(),
                        taskSnapshot.getColorSpace(), false /* containsSecureLayers */));
        mRecentScreenshotAnimator = new SurfaceAnimator(
@@ -1006,7 +1028,16 @@ public class RecentsAnimationController implements DeathRecipient {

    @Override
    public void binderDied() {
        if (!mCanceled) {
            cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
        } else {
            synchronized (mService.getWindowManagerLock()) {
                if (mRecentScreenshotAnimator != null) {
                    mRecentScreenshotAnimator.cancelAnimation();
                    mRecentScreenshotAnimator = null;
                }
            }
        }

        synchronized (mService.getWindowManagerLock()) {
            // Clear associated input consumers on runner death
+30 −0
Original line number Diff line number Diff line
@@ -655,6 +655,36 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
        assertFalse(win1.mHasSurface);
    }

    @Test
    public void testCancelForRotation_ReorderToTop() throws Exception {
        mWm.setRecentsAnimationController(mController);
        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
        final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
        activity.addWindow(win1);

        mController.addAnimation(activity.getTask(), false /* isRecentTaskInvisible */);
        mController.setWillFinishToHome(true);
        mController.cancelAnimationForDisplayChange();

        verify(mMockRunner).onAnimationCanceled(any());
        verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_TOP, false);
    }

    @Test
    public void testCancelForRotation_ReorderToOriginalPosition() throws Exception {
        mWm.setRecentsAnimationController(mController);
        final ActivityRecord activity = createActivityRecord(mDefaultDisplay);
        final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, activity, "win1");
        activity.addWindow(win1);

        mController.addAnimation(activity.getTask(), false /* isRecentTaskInvisible */);
        mController.setWillFinishToHome(false);
        mController.cancelAnimationForDisplayChange();

        verify(mMockRunner).onAnimationCanceled(any());
        verify(mAnimationCallbacks).onAnimationFinished(REORDER_MOVE_TO_ORIGINAL_POSITION, false);
    }

    private ActivityRecord createHomeActivity() {
        final ActivityRecord homeActivity = new ActivityBuilder(mWm.mAtmService)
                .setParentTask(mRootHomeTask)