Use full bounds if fixed aspect ratio does not apply

If a non-resizable activity can fill the non-decor space,
its bounds should not exclude decor bounds because the
activity and decor can show as a continuous area. otherwise
unexpected letterbox may be created and IME cannot attach
to it due to the activity doesn't match parent's bounds.

Fix: 152197007
Test: SizeCompatTests#testAspectRatioMatchParentBoundsAndImeAttachable

Change-Id: I61d2c99702fb8642a3bf5728949489b6b98eb508
This commit is contained in:
Riddle Hsu
2020-04-09 01:57:36 +08:00
parent 9c50a64e91
commit 89e8206393
3 changed files with 30 additions and 4 deletions

View File

@@ -6484,11 +6484,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final Rect containingBounds = mTmpBounds;
mCompatDisplayInsets.getContainerBounds(containingAppBounds, containingBounds, rotation,
orientation, orientationRequested, canChangeOrientation);
resolvedBounds.set(containingAppBounds);
resolvedBounds.set(containingBounds);
// The size of floating task is fixed (only swap), so the aspect ratio is already correct.
if (!mCompatDisplayInsets.mIsFloating) {
applyAspectRatio(resolvedBounds, containingAppBounds, containingBounds);
}
// If the bounds are restricted by fixed aspect ratio, the resolved bounds should be put in
// the container app bounds. Otherwise the entire container bounds are available.
final boolean fillContainer = resolvedBounds.equals(containingBounds);
if (!fillContainer) {
// The horizontal position should not cover insets.
resolvedBounds.left = containingAppBounds.left;
}
// Use resolvedBounds to compute other override configurations such as appBounds. The bounds
// are calculated in compat container space. The actual position on screen will be applied
@@ -6557,7 +6564,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final int offsetX = getHorizontalCenterOffset(
(int) viewportW, (int) (contentW * mSizeCompatScale));
// Above coordinates are in "@" space, now place "*" and "#" to screen space.
final int screenPosX = parentAppBounds.left + offsetX;
final int screenPosX = (fillContainer ? parentBounds.left : parentAppBounds.left) + offsetX;
final int screenPosY = parentBounds.top;
if (screenPosX != 0 || screenPosY != 0) {
if (mSizeCompatBounds != null) {
@@ -7654,8 +7661,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// Ensure the app bounds won't overlap with insets.
Task.intersectWithInsetsIfFits(outAppBounds, outBounds, mNonDecorInsets[rotation]);
}
// The horizontal position is centered and it should not cover insets.
outBounds.left = outAppBounds.left;
}
}

View File

@@ -242,6 +242,26 @@ public class SizeCompatTests extends ActivityTestsBase {
assertFalse(mActivity.mDisplayContent.isImeAttachedToApp());
}
@Test
public void testAspectRatioMatchParentBoundsAndImeAttachable() {
setUpApp(new TestDisplayContent.Builder(mService, 1000, 2000)
.setSystemDecorations(true).build());
prepareUnresizable(2f /* maxAspect */, SCREEN_ORIENTATION_UNSPECIFIED);
assertFitted();
rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
mActivity.mDisplayContent.mInputMethodTarget = addWindowToActivity(mActivity);
// Because the aspect ratio of display doesn't exceed the max aspect ratio of activity.
// The activity should still fill its parent container and IME can attach to the activity.
assertTrue(mActivity.matchParentBounds());
assertTrue(mActivity.mDisplayContent.isImeAttachedToApp());
final Rect letterboxInnerBounds = new Rect();
mActivity.getLetterboxInnerBounds(letterboxInnerBounds);
// The activity should not have letterbox.
assertTrue(letterboxInnerBounds.isEmpty());
}
@Test
public void testMoveToDifferentOrientDisplay() {
setUpDisplaySizeWithApp(1000, 2500);

View File

@@ -137,6 +137,7 @@ class TestDisplayContent extends DisplayContent {
spyOn(displayPolicy);
if (mSystemDecorations) {
doReturn(true).when(newDisplay).supportsSystemDecorations();
doReturn(true).when(displayPolicy).hasNavigationBar();
} else {
doReturn(false).when(displayPolicy).hasNavigationBar();
doReturn(false).when(displayPolicy).hasStatusBar();