From 522029a9f9852572985ba6c44be338949abdb036 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Fri, 10 Apr 2020 21:21:24 +0800 Subject: [PATCH] Restore config of associated window when clearing fixed rotation If wallpaper is visible and its target window has fixed rotation transform, wallpaper token will be associated to share the same transform. So if the target window cancels the transform, the associated window, i.e. wallpaper should also be restored to the original configuration. Fixes: 153420536 Fixes: 153201558 Test: atest WindowTokenTests#testClearFixedRotationTransform Change-Id: I75fe8bfadf3b681f2dc33df9c6599a9bbc5769ea --- .../com/android/server/wm/WindowToken.java | 21 +++++++++++++--- .../android/server/wm/WindowTokenTests.java | 25 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 5976b48db7644..e34b81654c720 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -554,13 +554,12 @@ class WindowToken extends WindowContainer { // cleared and the configuration is restored from parent. if (!changed) { clearFixedRotationTransform(null /* applyDisplayRotation */); - onConfigurationChanged(getParent().getConfiguration()); } } /** - * Clears the transform and apply display rotation if the action is given. The caller needs to - * refresh the configuration of this container after this method call. + * Clears 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) { final FixedRotationTransformState state = mFixedRotationTransformState; @@ -574,6 +573,12 @@ class WindowToken extends WindowContainer { state.mIsTransforming = false; if (applyDisplayRotation != null) { applyDisplayRotation.run(); + } else { + // The display will not rotate to the rotation of this container, let's cancel them. + for (int i = state.mAssociatedTokens.size() - 1; i >= 0; i--) { + state.mAssociatedTokens.get(i).cancelFixedRotationTransform(); + } + cancelFixedRotationTransform(); } // 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. @@ -583,6 +588,16 @@ class WindowToken extends WindowContainer { mFixedRotationTransformState = null; } + /** Restores the changes that applies to this container. */ + private void cancelFixedRotationTransform() { + final WindowContainer parent = getParent(); + if (parent == null) { + // The window may be detached or detaching. + return; + } + onConfigurationChanged(parent.getConfiguration()); + } + @Override void resolveOverrideConfiguration(Configuration newParentConfig) { super.resolveOverrideConfiguration(newParentConfig); 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 76479cb95b09b..535d53eeef719 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java @@ -29,6 +29,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; +import android.content.res.Configuration; import android.os.IBinder; import android.platform.test.annotations.Presubmit; @@ -134,6 +135,30 @@ public class WindowTokenTests extends WindowTestsBase { assertEquals(0, token.getWindowsCount()); } + @Test + public void testClearFixedRotationTransform() { + final WindowToken appToken = mAppWindow.mToken; + final WindowToken wallpaperToken = mWallpaperWindow.mToken; + final Configuration config = new Configuration(mDisplayContent.getConfiguration()); + final int originalRotation = config.windowConfiguration.getRotation(); + final int targetRotation = (originalRotation + 1) % 4; + + config.windowConfiguration.setRotation(targetRotation); + appToken.applyFixedRotationTransform(mDisplayInfo, mDisplayContent.mDisplayFrames, config); + wallpaperToken.linkFixedRotationTransform(appToken); + + // The window tokens should apply the rotation by the transformation. + assertEquals(targetRotation, appToken.getWindowConfiguration().getRotation()); + assertEquals(targetRotation, wallpaperToken.getWindowConfiguration().getRotation()); + + // The display doesn't rotate, the transformation will be canceled. + mAppWindow.mToken.clearFixedRotationTransform(null /* applyDisplayRotation */); + + // The window tokens should restore to the original rotation. + assertEquals(originalRotation, appToken.getWindowConfiguration().getRotation()); + assertEquals(originalRotation, wallpaperToken.getWindowConfiguration().getRotation()); + } + /** * Test that {@link WindowToken} constructor parameters is set with expectation. */