diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c41029b206515..5b2ccf43833da 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -498,6 +498,9 @@ class DisplayContent extends WindowContainer mWinAddedSinceNullFocus = new ArrayList<>(); @@ -928,6 +931,7 @@ class DisplayContent extends WindowContainer applyRotation(oldRotation, newRotation)); mFixedRotationLaunchingApp = null; } @@ -5494,6 +5494,34 @@ class DisplayContent extends WindowContainer { * rotated by the given rotated display info, frames and insets. */ private static class FixedRotationTransformState { - final WindowToken mOwner; final DisplayInfo mDisplayInfo; final DisplayFrames mDisplayFrames; final InsetsState mInsetsState; @@ -133,10 +132,9 @@ class WindowToken extends WindowContainer { final ArrayList> mRotatedContainers = new ArrayList<>(3); boolean mIsTransforming = true; - FixedRotationTransformState(WindowToken owner, DisplayInfo rotatedDisplayInfo, + FixedRotationTransformState(DisplayInfo rotatedDisplayInfo, DisplayFrames rotatedDisplayFrames, InsetsState rotatedInsetsState, Configuration rotatedConfig, int currentRotation) { - mOwner = owner; mDisplayInfo = rotatedDisplayInfo; mDisplayFrames = rotatedDisplayFrames; mInsetsState = rotatedInsetsState; @@ -482,6 +480,14 @@ class WindowToken extends WindowContainer { return mFixedRotationTransformState != null; } + /** Returns {@code true} if the given token shares the same transform. */ + boolean hasFixedRotationTransform(WindowToken token) { + if (mFixedRotationTransformState == null || token == null) { + return false; + } + return this == token || mFixedRotationTransformState == token.mFixedRotationTransformState; + } + boolean isFinishingFixedRotationTransform() { return mFixedRotationTransformState != null && !mFixedRotationTransformState.mIsTransforming; @@ -520,15 +526,14 @@ class WindowToken extends WindowContainer { final InsetsState insetsState = new InsetsState(); mDisplayContent.getDisplayPolicy().simulateLayoutDisplay(displayFrames, insetsState, mDisplayContent.getConfiguration().uiMode); - mFixedRotationTransformState = new FixedRotationTransformState(this, info, displayFrames, + mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames, insetsState, new Configuration(config), mDisplayContent.getRotation()); onConfigurationChanged(getParent().getConfiguration()); } /** * Reuses the {@link FixedRotationTransformState} (if any) from the other WindowToken to this - * one. This takes the same effect as {@link #applyFixedRotationTransform}, but the linked state - * can only be cleared by the state owner. + * one. This takes the same effect as {@link #applyFixedRotationTransform}. */ void linkFixedRotationTransform(WindowToken other) { if (mFixedRotationTransformState != null) { @@ -543,28 +548,15 @@ class WindowToken extends WindowContainer { onConfigurationChanged(getParent().getConfiguration()); } - /** - * Finishes the transform and continue updating the orientation change of display. Only the - * state owner can finish the transform state. - */ void finishFixedRotationTransform() { - if (mFixedRotationTransformState == null || mFixedRotationTransformState.mOwner != this) { - return; - } - final boolean changed = - mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp(this); - // If it is not the launching app or the display is not rotated, make sure the transform is - // cleared and the configuration is restored from parent. - if (!changed) { - clearFixedRotationTransform(null /* applyDisplayRotation */); - } + finishFixedRotationTransform(null /* applyDisplayRotation */); } /** - * Clears the transform and apply display rotation if the action is given. If the display will + * Finishes the transform and apply display rotation if the action is given. If the display will * not rotate, the transformed containers are restored to their original states. */ - void clearFixedRotationTransform(Runnable applyDisplayRotation) { + void finishFixedRotationTransform(Runnable applyDisplayRotation) { final FixedRotationTransformState state = mFixedRotationTransformState; if (state == null) { return; diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index e02ea813cdd7b..cba89d0aea2d2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -790,9 +790,7 @@ public class DisplayContentTests extends WindowTestsBase { final DisplayContent dc = createNewDisplay(); dc.getDisplayRotation().setFixedToUserRotation( IWindowManager.FIXED_TO_USER_ROTATION_DISABLED); - final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE - ? SCREEN_ORIENTATION_PORTRAIT - : SCREEN_ORIENTATION_LANDSCAPE; + final int newOrientation = getRotatedOrientation(dc); final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer) @@ -812,9 +810,7 @@ public class DisplayContentTests extends WindowTestsBase { final DisplayContent dc = createNewDisplay(); dc.getDisplayRotation().setFixedToUserRotation( IWindowManager.FIXED_TO_USER_ROTATION_ENABLED); - final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE - ? SCREEN_ORIENTATION_PORTRAIT - : SCREEN_ORIENTATION_LANDSCAPE; + final int newOrientation = getRotatedOrientation(dc); final ActivityStack stack = new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootWindowContainer) @@ -1083,7 +1079,8 @@ public class DisplayContentTests extends WindowTestsBase { mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */); mDisplayContent.mOpeningApps.add(app); - app.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); + final int newOrientation = getRotatedOrientation(mDisplayContent); + app.setRequestedOrientation(newOrientation); assertTrue(app.isFixedRotationTransforming()); assertTrue(mDisplayContent.getDisplayRotation().shouldRotateSeamlessly( @@ -1124,12 +1121,25 @@ public class DisplayContentTests extends WindowTestsBase { mWallpaperWindow.mToken.onAnimationLeashCreated(t, null /* leash */); verify(t, never()).setPosition(any(), eq(0), eq(0)); + // Launch another activity before the transition is finished. + final ActivityRecord app2 = new ActivityTestsBase.StackBuilder(mWm.mRoot) + .setDisplay(mDisplayContent).build().getTopMostActivity(); + mDisplayContent.prepareAppTransition(WindowManager.TRANSIT_ACTIVITY_OPEN, + false /* alwaysKeepCurrent */); + mDisplayContent.mOpeningApps.add(app2); + app2.setRequestedOrientation(newOrientation); + + // The activity should share the same transform state as the existing one. + assertTrue(app.hasFixedRotationTransform(app2)); + + // The display should be rotated after the launch is finished. mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(app.token); // The animation in old rotation should be cancelled. assertFalse(closingApp.isAnimating()); - // The display should be rotated after the launch is finished. + // The fixed rotation should be cleared and the new rotation is applied to display. assertFalse(app.hasFixedRotationTransform()); + assertFalse(app2.hasFixedRotationTransform()); assertEquals(config90.orientation, mDisplayContent.getConfiguration().orientation); } @@ -1292,6 +1302,12 @@ public class DisplayContentTests extends WindowTestsBase { assertThat("topToBottom", actualWindows, is(reverseList(expectedWindowsBottomToTop))); } + private static int getRotatedOrientation(DisplayContent dc) { + return dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE + ? SCREEN_ORIENTATION_PORTRAIT + : SCREEN_ORIENTATION_LANDSCAPE; + } + private static List reverseList(List list) { final ArrayList result = new ArrayList<>(list); Collections.reverse(result); diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java index f19550ced0bf7..409889b660b76 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java @@ -401,10 +401,6 @@ public class RecentsAnimationControllerTest extends WindowTestsBase { assertEquals(Configuration.ORIENTATION_PORTRAIT, wallpapers.get(0).getConfiguration().orientation); - // Wallpaper's transform state is controlled by home, so the invocation should be no-op. - wallpaperWindowToken.finishFixedRotationTransform(); - assertTrue(wallpaperWindowToken.hasFixedRotationTransform()); - // Wallpaper's transform state should be cleared with home. homeActivity.finishFixedRotationTransform(); assertFalse(wallpaperWindowToken.hasFixedRotationTransform()); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java index 535d53eeef719..23a097eb0c7ce 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -136,7 +136,7 @@ public class WindowTokenTests extends WindowTestsBase { } @Test - public void testClearFixedRotationTransform() { + public void testFinishFixedRotationTransform() { final WindowToken appToken = mAppWindow.mToken; final WindowToken wallpaperToken = mWallpaperWindow.mToken; final Configuration config = new Configuration(mDisplayContent.getConfiguration()); @@ -152,7 +152,7 @@ public class WindowTokenTests extends WindowTestsBase { assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation()); // The display doesn't rotate, the transformation will be canceled. - mAppWindow.mToken.clearFixedRotationTransform(null /* applyDisplayRotation */); + mAppWindow.mToken.finishFixedRotationTransform(); // The window tokens should restore to the original rotation. assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation());