From 0c1b0d1af3279be1d41435edc1330acea3f67cb8 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 27 May 2020 23:15:39 +0800 Subject: [PATCH] Do not set orientation to requested configuration This restores the original behavior that non-top fullscreen windowing mode activity with fixed orientation can inherit the orientation from parent. And non-fullscreen windowing mode still resolves orientation individually as before. Assume an activity uses fixed portrait orientation, and starts another activity in different process with fixed landscape orientation. Without this change, the process of background activity will receive config with portrait orientation but screenWidthDp > screenHeightDp because only the requested orientation is overridden and other fields are from parent configuration. Currently there is a preload mechanism to make recents (home) activity update to latest configuration in background to speed up next start. The inconsistent configuration will cause preload to be triggered unexpectedly. Then the UI may show in wrong state or even slow down the gesture navigation by the unnecessary configuration change. Note a legacy behavior that if the top is a non-occluding activity, the activities visible behind will show in the same orientation even fixed orientation is requested. Bug: 156891776 Test: atest AppWindowTokenTests#testRespectTopFullscreenOrientation Change-Id: I4ea394ccd18054410e8e15df8edbe782c26d9ccd --- .../android/server/wm/WindowContainer.java | 11 ++++------ .../server/wm/AppWindowTokenTests.java | 22 +++++++++++++++++++ .../android/server/wm/SizeCompatTests.java | 5 +++-- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index a1fbb597533f0..69a191741569a 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -1152,15 +1152,12 @@ class WindowContainer extends ConfigurationContainer< } mOrientation = orientation; - final int configOrientation = getRequestedConfigurationOrientation(); - if (getRequestedOverrideConfiguration().orientation != configOrientation) { - mTmpConfig.setTo(getRequestedOverrideConfiguration()); - mTmpConfig.orientation = configOrientation; - onRequestedOverrideConfigurationChanged(mTmpConfig); - } - final WindowContainer parent = getParent(); if (parent != null) { + if (getConfiguration().orientation != getRequestedConfigurationOrientation()) { + // Resolve the requested orientation. + onConfigurationChanged(parent.getConfiguration()); + } onDescendantOrientationChanged(freezeDisplayToken, requestingContainer); } } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java index 36d4888fa56e8..02de408343c52 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -294,6 +295,27 @@ public class AppWindowTokenTests extends WindowTestsBase { mWm.mDisplayFrozen = false; } + @Test + public void testRespectTopFullscreenOrientation() { + final Configuration displayConfig = mActivity.mDisplayContent.getConfiguration(); + final Configuration activityConfig = mActivity.getConfiguration(); + mActivity.setOrientation(SCREEN_ORIENTATION_PORTRAIT); + + assertEquals(Configuration.ORIENTATION_PORTRAIT, displayConfig.orientation); + assertEquals(Configuration.ORIENTATION_PORTRAIT, activityConfig.orientation); + + final ActivityRecord topActivity = WindowTestUtils.createTestActivityRecord(mStack); + topActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); + + assertEquals(Configuration.ORIENTATION_LANDSCAPE, displayConfig.orientation); + // Although the activity requested portrait, it is not the top activity that determines + // the display orientation. So it should be able to inherit the orientation from parent. + // Otherwise its configuration will be inconsistent that its orientation is portrait but + // other screen configurations are in landscape, e.g. screenWidthDp, screenHeightDp, and + // window configuration. + assertEquals(Configuration.ORIENTATION_LANDSCAPE, activityConfig.orientation); + } + @Test public void testReportOrientationChange() { mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE); diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 68bc58493f13f..665cf83cd33c6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -145,7 +145,8 @@ public class SizeCompatTests extends ActivityTestsBase { final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds(); // The parent configuration doesn't change since the first resolved configuration, so the - // activity should fit in the parent naturally. (size=583x700). + // activity should fit in the parent naturally (size=583x700, appBounds=[9, 100 - 592, 800], + // horizontal offset = round((600 - 583) / 2) = 9)). assertFitted(); final int offsetX = (int) ((1f + displayBounds.width() - appBounds.width()) / 2); // The bounds must be horizontal centered. @@ -160,7 +161,7 @@ public class SizeCompatTests extends ActivityTestsBase { assertFitted(); // After the orientation of activity is changed, even display is not rotated, the aspect - // ratio should be the same (appBounds=[9, 100 - 592, 800], x-offset=round((600-583)/2)=9). + // ratio should be the same (bounds=[0, 0 - 600, 600], appBounds=[0, 100 - 600, 600]). assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */); // The notch is still on top. assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight);