Merge "Adjust smallestScreenWidthDp for letterbox" into tm-qpr-dev am: ac2768ae43

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19416406

Change-Id: I6712a5164c94cd16a437b785fee16309d9b2915b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Mariia Sandrikova
2023-01-06 14:19:41 +00:00
committed by Automerger Merge Worker
3 changed files with 108 additions and 10 deletions

View File

@@ -7938,6 +7938,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// The smallest screen width is the short side of screen bounds. Because the bounds // The smallest screen width is the short side of screen bounds. Because the bounds
// and density won't be changed, smallestScreenWidthDp is also fixed. // and density won't be changed, smallestScreenWidthDp is also fixed.
overrideConfig.smallestScreenWidthDp = fullConfig.smallestScreenWidthDp; overrideConfig.smallestScreenWidthDp = fullConfig.smallestScreenWidthDp;
// TODO(b/264276741): Check whether the runtime orietnation request is fixed rather than
// the manifest orientation which may be obsolete.
if (info.isFixedOrientation()) { if (info.isFixedOrientation()) {
// lock rotation too. When in size-compat, onConfigurationChanged will watch for and // lock rotation too. When in size-compat, onConfigurationChanged will watch for and
// apply runtime rotation changes. // apply runtime rotation changes.
@@ -8051,8 +8053,24 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
updateResolvedBoundsPosition(newParentConfiguration); updateResolvedBoundsPosition(newParentConfiguration);
} }
if (mVisibleRequested) { boolean isIgnoreOrientationRequest = mDisplayContent != null
updateCompatDisplayInsets(); && mDisplayContent.getIgnoreOrientationRequest();
if (mCompatDisplayInsets == null // for size compat mode set in updateCompatDisplayInsets
// Fixed orientation letterboxing is possible on both large screen devices
// with ignoreOrientationRequest enabled and on phones in split screen even with
// ignoreOrientationRequest disabled.
&& (mLetterboxBoundsForFixedOrientationAndAspectRatio != null
// Limiting check for aspect ratio letterboxing to devices with enabled
// ignoreOrientationRequest. This avoids affecting phones where apps may
// not expect the change of smallestScreenWidthDp after rotation which is
// possible with this logic. Not having smallestScreenWidthDp completely
// accurate on phones shouldn't make the big difference and is expected
// to be already well-tested by apps.
|| (isIgnoreOrientationRequest && mIsAspectRatioApplied))) {
// TODO(b/264034555): Use mDisplayContent to calculate smallestScreenWidthDp from all
// rotations and only re-calculate if parent bounds have non-orientation size change.
resolvedConfig.smallestScreenWidthDp =
Math.min(resolvedConfig.screenWidthDp, resolvedConfig.screenHeightDp);
} }
// Assign configuration sequence number into hierarchy because there is a different way than // Assign configuration sequence number into hierarchy because there is a different way than
@@ -8440,7 +8458,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Calculate app bounds using fixed orientation bounds because they will be needed later // Calculate app bounds using fixed orientation bounds because they will be needed later
// for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}. // for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}.
getTaskFragment().computeConfigResourceOverrides(getResolvedOverrideConfiguration(), getTaskFragment().computeConfigResourceOverrides(getResolvedOverrideConfiguration(),
newParentConfig); newParentConfig, mCompatDisplayInsets);
mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds); mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds);
} }
@@ -9119,6 +9137,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mLastReportedDisplayId = newDisplayId; mLastReportedDisplayId = newDisplayId;
} }
// Calling from here rather than from onConfigurationChanged because it's possible that
// onConfigurationChanged was called before mVisibleRequested became true and
// mCompatDisplayInsets may not be called again when mVisibleRequested changes. And we
// don't want to save mCompatDisplayInsets in onConfigurationChanged without visibility
// check to avoid remembering obsolete configuration which can lead to unnecessary
// size-compat mode.
if (mVisibleRequested) {
// Calling from here rather than resolveOverrideConfiguration to ensure that this is
// called after full config is updated in ConfigurationContainer#onConfigurationChanged.
updateCompatDisplayInsets();
}
// Short circuit: if the two full configurations are equal (the common case), then there is // Short circuit: if the two full configurations are equal (the common case), then there is
// nothing to do. We test the full configuration instead of the global and merged override // nothing to do. We test the full configuration instead of the global and merged override
// configurations because there are cases (like moving a task to the root pinned task) where // configurations because there are cases (like moving a task to the root pinned task) where
@@ -9127,12 +9157,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) { if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display " ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display "
+ "unchanged in %s", this); + "unchanged in %s", this);
// It's possible that resolveOverrideConfiguration was called before mVisibleRequested
// became true and mCompatDisplayInsets may not have been created so ensure
// that mCompatDisplayInsets is created here.
if (mVisibleRequested) {
updateCompatDisplayInsets();
}
return true; return true;
} }

View File

@@ -2138,7 +2138,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
final Rect parentBounds = parentConfig.windowConfiguration.getBounds(); final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
final Rect resolvedBounds = inOutConfig.windowConfiguration.getBounds(); final Rect resolvedBounds = inOutConfig.windowConfiguration.getBounds();
if (resolvedBounds == null || resolvedBounds.isEmpty()) { if (resolvedBounds.isEmpty()) {
mTmpFullBounds.set(parentBounds); mTmpFullBounds.set(parentBounds);
insideParentBounds = true; insideParentBounds = true;
} else { } else {
@@ -2227,6 +2227,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
: overrideScreenHeightDp; : overrideScreenHeightDp;
} }
// TODO(b/238331848): Consider simplifying logic that computes smallestScreenWidthDp.
if (inOutConfig.smallestScreenWidthDp if (inOutConfig.smallestScreenWidthDp
== Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
// When entering to or exiting from Pip, the PipTaskOrganizer will set the // When entering to or exiting from Pip, the PipTaskOrganizer will set the

View File

@@ -1616,6 +1616,79 @@ public class SizeCompatTests extends WindowTestsBase {
assertEquals(displayBounds.height() / defaultAspectRatio, activityBounds.width(), 0.5); assertEquals(displayBounds.height() / defaultAspectRatio, activityBounds.width(), 0.5);
} }
@Test
public void testComputeConfigResourceOverrides_unresizableApp() {
// Set up a display in landscape and ignoring orientation request.
setUpDisplaySizeWithApp(2800, 1400);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
final Rect activityBounds = new Rect(mActivity.getBounds());
int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp;
int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp;
// App should launch in fixed orientation letterbox.
// Activity bounds should be 700x1400 with the ratio as the display.
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFitted();
assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
assertTrue(originalScreenWidthDp < originalScreenHeighthDp);
// Rotate display to portrait.
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
// After we rotate, the activity should go in the size-compat mode and report the same
// configuration values.
assertScaled();
assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
assertEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
assertEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
// Restart activity
mActivity.restartProcessIfVisible();
// Now configuration should be updated
assertFitted();
assertNotEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
assertNotEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
assertEquals(mActivity.getConfiguration().screenWidthDp,
mActivity.getConfiguration().smallestScreenWidthDp);
}
@Test
public void testComputeConfigResourceOverrides_resizableFixedOrientationActivity() {
// Set up a display in landscape and ignoring orientation request.
setUpDisplaySizeWithApp(2800, 1400);
mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
// Portrait fixed app without max aspect.
prepareLimitedBounds(mActivity, SCREEN_ORIENTATION_PORTRAIT, false /* isUnresizable */);
final Rect activityBounds = new Rect(mActivity.getBounds());
int originalScreenWidthDp = mActivity.getConfiguration().screenWidthDp;
int originalScreenHeighthDp = mActivity.getConfiguration().screenHeightDp;
// App should launch in fixed orientation letterbox.
// Activity bounds should be 700x1400 with the ratio as the display.
assertTrue(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
assertFitted();
assertEquals(originalScreenWidthDp, mActivity.getConfiguration().smallestScreenWidthDp);
assertTrue(originalScreenWidthDp < originalScreenHeighthDp);
// Rotate display to portrait.
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
// Now configuration should be updated
assertFitted();
assertNotEquals(originalScreenWidthDp, mActivity.getConfiguration().screenWidthDp);
assertNotEquals(originalScreenHeighthDp, mActivity.getConfiguration().screenHeightDp);
assertEquals(mActivity.getConfiguration().screenWidthDp,
mActivity.getConfiguration().smallestScreenWidthDp);
}
@Test @Test
public void testSplitAspectRatioForUnresizablePortraitApps() { public void testSplitAspectRatioForUnresizablePortraitApps() {
// Set up a display in landscape and ignoring orientation request. // Set up a display in landscape and ignoring orientation request.