Fix screenlayout calculation with overridden screenW/Hdp

Split-screen adjust-for-ime overrides screenW/Hdp in order
to prevent the app-configuration from changing. However, the
logic in Task#computeConfigResourceOverrides was ignoring
the overrides and blindly using the display's non-decor
bounds. This means that on loong screens, the app will
flip into/out-of long layout when adjusting (non-adjusted
task has no screenSizeDp overrides so it goes through logic
which crops mTmpNonDecorBounds).

Fix this by honoring the screenW/Hdp overrides when
calculating screenLayout.

Bug: 163848060
Test: On long screen (eg 21:9 aspect), open ime in second
      split. Also added regression unit-test.
Change-Id: I0fcec4f035e466fafedc31be5925c0b04a6580f7
This commit is contained in:
Evan Rosky
2020-08-18 13:52:04 -07:00
parent dcca9929b1
commit ea5f48562f
3 changed files with 36 additions and 3 deletions

View File

@@ -2788,8 +2788,16 @@ class Task extends WindowContainer<WindowContainer> {
// For calculating screen layout, we need to use the non-decor inset screen area for the
// calculation for compatibility reasons, i.e. screen area without system bars that
// could never go away in Honeycomb.
final int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
int compatScreenWidthDp = (int) (mTmpNonDecorBounds.width() / density);
int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density);
// Use overrides if provided. If both overrides are provided, mTmpNonDecorBounds is
// undefined so it can't be used.
if (inOutConfig.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
compatScreenWidthDp = inOutConfig.screenWidthDp;
}
if (inOutConfig.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
compatScreenHeightDp = inOutConfig.screenHeightDp;
}
// Reducing the screen layout starting from its parent config.
inOutConfig.screenLayout = computeScreenLayoutOverride(parentConfig.screenLayout,
compatScreenWidthDp, compatScreenHeightDp);

View File

@@ -544,7 +544,7 @@ public class ActivityRecordTests extends WindowTestsBase {
mActivity = new ActivityBuilder(mAtm)
.setTask(mTask)
.setLaunchTaskBehind(true)
.setConfigChanges(CONFIG_ORIENTATION)
.setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT)
.build();
mActivity.setState(Task.ActivityState.STOPPED, "Testing");

View File

@@ -431,6 +431,31 @@ public class TaskRecordTests extends WindowTestsBase {
assertEquals(Configuration.ORIENTATION_LANDSCAPE, inOutConfig.orientation);
}
@Test
public void testComputeConfigResourceLayoutOverrides() {
final Rect fullScreenBounds = new Rect(0, 0, 1000, 2500);
TestDisplayContent display = new TestDisplayContent.Builder(
mAtm, fullScreenBounds.width(), fullScreenBounds.height()).build();
final Task task = new TaskBuilder(mSupervisor).setDisplay(display).build();
final Configuration inOutConfig = new Configuration();
final Configuration parentConfig = new Configuration();
final Rect nonLongBounds = new Rect(0, 0, 1000, 1250);
parentConfig.windowConfiguration.setBounds(fullScreenBounds);
parentConfig.windowConfiguration.setAppBounds(fullScreenBounds);
parentConfig.densityDpi = 400;
parentConfig.screenHeightDp = (fullScreenBounds.bottom * 160) / parentConfig.densityDpi;
parentConfig.screenWidthDp = (fullScreenBounds.right * 160) / parentConfig.densityDpi;
parentConfig.windowConfiguration.setRotation(ROTATION_0);
// Set BOTH screenW/H to an override value
inOutConfig.screenWidthDp = nonLongBounds.width() * 160 / parentConfig.densityDpi;
inOutConfig.screenHeightDp = nonLongBounds.height() * 160 / parentConfig.densityDpi;
task.computeConfigResourceOverrides(inOutConfig, parentConfig);
// screenLayout should honor override when both screenW/H are set.
assertTrue((inOutConfig.screenLayout & Configuration.SCREENLAYOUT_LONG_NO) != 0);
}
@Test
public void testComputeNestedConfigResourceOverrides() {
final Task task = new TaskBuilder(mSupervisor).build();