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
This commit is contained in:
Riddle Hsu
2020-05-27 23:15:39 +08:00
parent edcb2c38f4
commit 0c1b0d1af3
3 changed files with 29 additions and 9 deletions

View File

@@ -1152,15 +1152,12 @@ class WindowContainer<E extends 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);
}
}

View File

@@ -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);

View File

@@ -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);