diff options
3 files changed, 34 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index ed1f221576d9..0363ea0e7512 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1573,7 +1573,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo // the heavy operations. This also benefits that the states of multiple activities // are handled together. r.linkFixedRotationTransform(prevRotatedLaunchingApp); - setFixedRotationLaunchingAppUnchecked(r, rotation); + if (r != mFixedRotationTransitionListener.mAnimatingRecents) { + // Only update the record for normal activity so the display orientation can be + // updated when the transition is done if it becomes the top. And the case of + // recents can be handled when the recents animation is finished. + setFixedRotationLaunchingAppUnchecked(r, rotation); + } return; } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 86aacf308068..1716dcd5ee16 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -531,7 +531,7 @@ class WindowToken extends WindowContainer<WindowState> { void applyFixedRotationTransform(DisplayInfo info, DisplayFrames displayFrames, Configuration config) { if (mFixedRotationTransformState != null) { - return; + cleanUpFixedRotationTransformState(true /* replacing */); } mFixedRotationTransformState = new FixedRotationTransformState(info, displayFrames, new Configuration(config), mDisplayContent.getRotation()); @@ -548,13 +548,13 @@ class WindowToken extends WindowContainer<WindowState> { * one. This takes the same effect as {@link #applyFixedRotationTransform}. */ void linkFixedRotationTransform(WindowToken other) { - if (mFixedRotationTransformState != null) { - return; - } final FixedRotationTransformState fixedRotationState = other.mFixedRotationTransformState; - if (fixedRotationState == null) { + if (fixedRotationState == null || mFixedRotationTransformState == fixedRotationState) { return; } + if (mFixedRotationTransformState != null) { + cleanUpFixedRotationTransformState(true /* replacing */); + } mFixedRotationTransformState = fixedRotationState; fixedRotationState.mAssociatedTokens.add(this); onConfigurationChanged(getParent().getConfiguration()); @@ -609,11 +609,17 @@ class WindowToken extends WindowContainer<WindowState> { // The state is cleared at the end, because it is used to indicate that other windows can // use seamless rotation when applying rotation to display. for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) { - state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState(); + state.mAssociatedTokens.get(i).cleanUpFixedRotationTransformState( + false /* replacing */); } } - private void cleanUpFixedRotationTransformState() { + private void cleanUpFixedRotationTransformState(boolean replacing) { + if (replacing && mFixedRotationTransformState.mAssociatedTokens.size() > 1) { + // The state is not only used by self. Make sure to leave the influence by others. + mFixedRotationTransformState.mAssociatedTokens.remove(this); + mFixedRotationTransformState.mRotatedContainers.remove(this); + } mFixedRotationTransformState = null; notifyFixedRotationTransform(false /* enabled */); } 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 23a097eb0c7c..0896db4b5532 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST; 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; @@ -139,6 +140,8 @@ public class WindowTokenTests extends WindowTestsBase { public void testFinishFixedRotationTransform() { final WindowToken appToken = mAppWindow.mToken; final WindowToken wallpaperToken = mWallpaperWindow.mToken; + final WindowToken testToken = + WindowTestUtils.createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent); final Configuration config = new Configuration(mDisplayContent.getConfiguration()); final int originalRotation = config.windowConfiguration.getRotation(); final int targetRotation = (originalRotation + 1) % 4; @@ -151,11 +154,20 @@ public class WindowTokenTests extends WindowTestsBase { assertEquals(targetRotation, appToken.getWindowConfiguration().getRotation()); assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation()); - // The display doesn't rotate, the transformation will be canceled. - mAppWindow.mToken.finishFixedRotationTransform(); + testToken.applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config); + // The wallpaperToken was linked to appToken, this should make it link to testToken. + wallpaperToken.linkFixedRotationTransform(testToken); - // The window tokens should restore to the original rotation. + // Assume the display doesn't rotate, the transformation will be canceled. + appToken.finishFixedRotationTransform(); + + // The appToken should restore to the original rotation. assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation()); + // The wallpaperToken is linked to testToken, it should keep the target rotation. + assertNotEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation()); + + testToken.finishFixedRotationTransform(); + // The rotation of wallpaperToken should be restored because its linked state is finished. assertEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation()); } |