From 6212e2a6d0e54e4e179383db1f64ff0cdcccdd27 Mon Sep 17 00:00:00 2001 From: Evan Rosky Date: Tue, 18 Aug 2020 13:52:04 -0700 Subject: [PATCH] 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 Merged-In: I0fcec4f035e466fafedc31be5925c0b04a6580f7 --- .../core/java/com/android/server/wm/Task.java | 12 +++++++-- .../server/wm/ActivityRecordTests.java | 2 +- .../android/server/wm/TaskRecordTests.java | 25 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 6785127d59535..efcb6dc9ada19 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -2371,8 +2371,16 @@ class Task extends 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); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 6ab0697206e35..bb85c8aa1977e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -536,7 +536,7 @@ public class ActivityRecordTests extends ActivityTestsBase { mActivity = new ActivityBuilder(mService) .setTask(mTask) .setLaunchTaskBehind(true) - .setConfigChanges(CONFIG_ORIENTATION) + .setConfigChanges(CONFIG_ORIENTATION | CONFIG_SCREEN_LAYOUT) .build(); mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing"); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java index fb24d868e9709..ddaa586fae8ae 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java @@ -402,6 +402,31 @@ public class TaskRecordTests extends ActivityTestsBase { assertEquals(Configuration.ORIENTATION_LANDSCAPE, inOutConfig.orientation); } + @Test + public void testComputeConfigResourceLayoutOverrides() { + final Rect fullScreenBounds = new Rect(0, 0, 1000, 2500); + TestDisplayContent display = new TestDisplayContent.Builder( + mService, 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();