Loading services/core/java/com/android/server/wm/DisplayContent.java +8 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/core/java/com/android/server/wm/DisplayRotation.java +10 −0 Original line number Diff line number Diff line Loading @@ -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) Loading services/core/java/com/android/server/wm/RecentsAnimationController.java +41 −10 Original line number Diff line number Diff line Loading @@ -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 */); } } Loading Loading @@ -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); } } Loading Loading @@ -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 */, Loading Loading @@ -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()) { Loading @@ -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; Loading @@ -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> Loading Loading @@ -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( Loading Loading @@ -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 Loading services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +30 −0 Original line number Diff line number Diff line Loading @@ -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) Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +8 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/core/java/com/android/server/wm/DisplayRotation.java +10 −0 Original line number Diff line number Diff line Loading @@ -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) Loading
services/core/java/com/android/server/wm/RecentsAnimationController.java +41 −10 Original line number Diff line number Diff line Loading @@ -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 */); } } Loading Loading @@ -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); } } Loading Loading @@ -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 */, Loading Loading @@ -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()) { Loading @@ -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; Loading @@ -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> Loading Loading @@ -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( Loading Loading @@ -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 Loading
services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +30 −0 Original line number Diff line number Diff line Loading @@ -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) Loading