Loading services/core/java/com/android/server/wm/DisplayRotation.java +4 −1 Original line number Diff line number Diff line Loading @@ -442,7 +442,9 @@ public class DisplayRotation { return false; } if (mDisplayContent.mFixedRotationTransitionListener final RecentsAnimationController recentsAnimController = mService.getRecentsAnimationController(); if (recentsAnimController != null && mDisplayContent.mFixedRotationTransitionListener .isTopFixedOrientationRecentsAnimating() // If screen is off or the device is going to sleep, then still allow to update. && mService.mPolicy.okToAnimate(false /* ignoreScreenOn */)) { Loading @@ -450,6 +452,7 @@ public class DisplayRotation { // In order to ignore its requested orientation to avoid a sensor led rotation (e.g // user rotating the device while the recents animation is running), we ignore // rotation update while the animation is running. recentsAnimController.setCheckRotationAfterCleanup(); return false; } } Loading services/core/java/com/android/server/wm/RecentsAnimationController.java +23 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ public class RecentsAnimationController implements DeathRecipient { private final int mDisplayId; private boolean mWillFinishToHome = false; private final Runnable mFailsafeRunnable = this::onFailsafe; private Runnable mCheckRotationAfterCleanup; // The recents component app token that is shown behind the visibile tasks private ActivityRecord mTargetActivityRecord; Loading Loading @@ -920,6 +921,24 @@ public class RecentsAnimationController implements DeathRecipient { mCancelDeferredWithScreenshot = screenshot; } /** * If the display rotation change is ignored while recents animation is running, make sure that * the pending rotation change will be applied after the animation finishes. */ void setCheckRotationAfterCleanup() { if (mCheckRotationAfterCleanup != null) return; mCheckRotationAfterCleanup = () -> { synchronized (mService.mGlobalLock) { if (mDisplayContent.getDisplayRotation() .updateRotationAndSendNewConfigIfChanged()) { if (mTargetActivityRecord != null) { mTargetActivityRecord.finishFixedRotationTransform(); } } } }; } /** * @return Whether we should defer the cancel from a root task order change until the next app * transition. Loading Loading @@ -1007,6 +1026,10 @@ public class RecentsAnimationController implements DeathRecipient { if (mStatusBar != null) { mStatusBar.onRecentsAnimationStateChanged(false /* running */); } if (mCheckRotationAfterCleanup != null) { mService.mH.post(mCheckRotationAfterCleanup); mCheckRotationAfterCleanup = null; } } void scheduleFailsafe() { Loading services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -1562,6 +1562,7 @@ public class DisplayContentTests extends WindowTestsBase { final ActivityRecord activity = createActivityRecord(mDisplayContent); final ActivityRecord recentsActivity = createActivityRecord(mDisplayContent); recentsActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); doReturn(mock(RecentsAnimationController.class)).when(mWm).getRecentsAnimationController(); // Do not rotate if the recents animation is animating on top. mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(recentsActivity); Loading Loading @@ -2513,7 +2514,7 @@ public class DisplayContentTests extends WindowTestsBase { assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop))); } private static int getRotatedOrientation(DisplayContent dc) { static int getRotatedOrientation(DisplayContent dc) { return dc.mBaseDisplayWidth > dc.mBaseDisplayHeight ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE; Loading services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +17 −1 Original line number Diff line number Diff line Loading @@ -41,8 +41,8 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; Loading Loading @@ -438,6 +438,22 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertTrue(activity.hasFixedRotationTransform()); } @Test public void testCheckRotationAfterCleanup() { mWm.setRecentsAnimationController(mController); spyOn(mDisplayContent.mFixedRotationTransitionListener); doReturn(true).when(mDisplayContent.mFixedRotationTransitionListener) .isTopFixedOrientationRecentsAnimating(); // Rotation update is skipped while the recents animation is running. assertFalse(mDisplayContent.getDisplayRotation().updateOrientation(DisplayContentTests .getRotatedOrientation(mDefaultDisplay), false /* forceUpdate */)); final int prevRotation = mDisplayContent.getRotation(); mWm.cleanupRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); waitHandlerIdle(mWm.mH); // The display should be updated to the changed orientation after the animation is finished. assertNotEquals(mDisplayContent.getRotation(), prevRotation); } @Test public void testWallpaperHasFixedRotationApplied() { unblockDisplayRotation(mDefaultDisplay); Loading Loading
services/core/java/com/android/server/wm/DisplayRotation.java +4 −1 Original line number Diff line number Diff line Loading @@ -442,7 +442,9 @@ public class DisplayRotation { return false; } if (mDisplayContent.mFixedRotationTransitionListener final RecentsAnimationController recentsAnimController = mService.getRecentsAnimationController(); if (recentsAnimController != null && mDisplayContent.mFixedRotationTransitionListener .isTopFixedOrientationRecentsAnimating() // If screen is off or the device is going to sleep, then still allow to update. && mService.mPolicy.okToAnimate(false /* ignoreScreenOn */)) { Loading @@ -450,6 +452,7 @@ public class DisplayRotation { // In order to ignore its requested orientation to avoid a sensor led rotation (e.g // user rotating the device while the recents animation is running), we ignore // rotation update while the animation is running. recentsAnimController.setCheckRotationAfterCleanup(); return false; } } Loading
services/core/java/com/android/server/wm/RecentsAnimationController.java +23 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ public class RecentsAnimationController implements DeathRecipient { private final int mDisplayId; private boolean mWillFinishToHome = false; private final Runnable mFailsafeRunnable = this::onFailsafe; private Runnable mCheckRotationAfterCleanup; // The recents component app token that is shown behind the visibile tasks private ActivityRecord mTargetActivityRecord; Loading Loading @@ -920,6 +921,24 @@ public class RecentsAnimationController implements DeathRecipient { mCancelDeferredWithScreenshot = screenshot; } /** * If the display rotation change is ignored while recents animation is running, make sure that * the pending rotation change will be applied after the animation finishes. */ void setCheckRotationAfterCleanup() { if (mCheckRotationAfterCleanup != null) return; mCheckRotationAfterCleanup = () -> { synchronized (mService.mGlobalLock) { if (mDisplayContent.getDisplayRotation() .updateRotationAndSendNewConfigIfChanged()) { if (mTargetActivityRecord != null) { mTargetActivityRecord.finishFixedRotationTransform(); } } } }; } /** * @return Whether we should defer the cancel from a root task order change until the next app * transition. Loading Loading @@ -1007,6 +1026,10 @@ public class RecentsAnimationController implements DeathRecipient { if (mStatusBar != null) { mStatusBar.onRecentsAnimationStateChanged(false /* running */); } if (mCheckRotationAfterCleanup != null) { mService.mH.post(mCheckRotationAfterCleanup); mCheckRotationAfterCleanup = null; } } void scheduleFailsafe() { Loading
services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +2 −1 Original line number Diff line number Diff line Loading @@ -1562,6 +1562,7 @@ public class DisplayContentTests extends WindowTestsBase { final ActivityRecord activity = createActivityRecord(mDisplayContent); final ActivityRecord recentsActivity = createActivityRecord(mDisplayContent); recentsActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); doReturn(mock(RecentsAnimationController.class)).when(mWm).getRecentsAnimationController(); // Do not rotate if the recents animation is animating on top. mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(recentsActivity); Loading Loading @@ -2513,7 +2514,7 @@ public class DisplayContentTests extends WindowTestsBase { assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop))); } private static int getRotatedOrientation(DisplayContent dc) { static int getRotatedOrientation(DisplayContent dc) { return dc.mBaseDisplayWidth > dc.mBaseDisplayHeight ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE; Loading
services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +17 −1 Original line number Diff line number Diff line Loading @@ -41,8 +41,8 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; Loading Loading @@ -438,6 +438,22 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertTrue(activity.hasFixedRotationTransform()); } @Test public void testCheckRotationAfterCleanup() { mWm.setRecentsAnimationController(mController); spyOn(mDisplayContent.mFixedRotationTransitionListener); doReturn(true).when(mDisplayContent.mFixedRotationTransitionListener) .isTopFixedOrientationRecentsAnimating(); // Rotation update is skipped while the recents animation is running. assertFalse(mDisplayContent.getDisplayRotation().updateOrientation(DisplayContentTests .getRotatedOrientation(mDefaultDisplay), false /* forceUpdate */)); final int prevRotation = mDisplayContent.getRotation(); mWm.cleanupRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION); waitHandlerIdle(mWm.mH); // The display should be updated to the changed orientation after the animation is finished. assertNotEquals(mDisplayContent.getRotation(), prevRotation); } @Test public void testWallpaperHasFixedRotationApplied() { unblockDisplayRotation(mDefaultDisplay); Loading