From e3d243d3e7740bd856e2ba5ce53802c39b3cc341 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Tue, 25 Apr 2023 12:28:05 +0000 Subject: Update config according to insets of status bar Previously, only cutout and navbar are included, so only the change of decor frame may trigger config change. But screenWidthDp and screenHeightDp are calculated according to config (stable) frame, which includes the insets from status bar. So this change makes the display configuration consistent with the latest state of the display decor insets. Fix: 259693044 Test: DisplayPolicyTests#testUpdateDisplayConfigurationByDecor Change-Id: Idaa7280ed23076b3282c987a249259e0c38b6630 --- services/core/java/com/android/server/wm/DisplayPolicy.java | 8 +++++++- .../java/com/android/server/wm/WindowManagerService.java | 4 ++-- services/core/java/com/android/server/wm/WindowState.java | 8 ++++---- .../src/com/android/server/wm/ActivityRecordTests.java | 2 +- .../src/com/android/server/wm/DisplayPolicyTests.java | 13 +++++++++++-- .../wmtests/src/com/android/server/wm/WindowTestsBase.java | 11 +++++++++++ 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 747819e93ff2..ce4362853b23 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1882,6 +1882,12 @@ public class DisplayPolicy { static final int DECOR_TYPES = Type.displayCutout() | Type.navigationBars(); + /** + * The types that may affect display configuration. This excludes cutout because it is + * known from display info. + */ + static final int CONFIG_TYPES = Type.statusBars() | Type.navigationBars(); + private final DisplayContent mDisplayContent; private final Info[] mInfoForRotation = new Info[4]; final Info mTmpInfo = new Info(); @@ -1921,7 +1927,7 @@ public class DisplayPolicy { final DecorInsets.Info newInfo = mDecorInsets.mTmpInfo; newInfo.update(mDisplayContent, rotation, dw, dh); final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh); - if (newInfo.mNonDecorFrame.equals(currentInfo.mNonDecorFrame)) { + if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)) { return false; } mDecorInsets.invalidate(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 40b8274d4e51..6cb6d9d7bcea 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1831,7 +1831,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean needToSendNewConfiguration = win.isVisibleRequestedOrAdding() && displayContent.updateOrientation(); - if (win.providesNonDecorInsets()) { + if (win.providesDisplayDecorInsets()) { needToSendNewConfiguration |= displayPolicy.updateDecorInsetsInfo(); } if (needToSendNewConfiguration) { @@ -2274,7 +2274,7 @@ public class WindowManagerService extends IWindowManager.Stub & WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED) != 0) { win.mLayoutNeeded = true; } - if (layoutChanged && win.providesNonDecorInsets()) { + if (layoutChanged && win.providesDisplayDecorInsets()) { configChanged = displayPolicy.updateDecorInsetsInfo(); } if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0 diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 2920652674d3..6f07b7719be0 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1834,13 +1834,13 @@ class WindowState extends WindowContainer implements WindowManagerP return (mPolicyVisibility & POLICY_VISIBILITY_ALL) == POLICY_VISIBILITY_ALL; } - boolean providesNonDecorInsets() { + boolean providesDisplayDecorInsets() { if (mInsetsSourceProviders == null) { return false; } for (int i = mInsetsSourceProviders.size() - 1; i >= 0; i--) { final InsetsSource source = mInsetsSourceProviders.valueAt(i).getSource(); - if (source.getType() == WindowInsets.Type.navigationBars()) { + if ((source.getType() & DisplayPolicy.DecorInsets.CONFIG_TYPES) != 0) { return true; } } @@ -2507,13 +2507,13 @@ class WindowState extends WindowContainer implements WindowManagerP } // Check if window provides non decor insets before clearing its provided insets. - final boolean windowProvidesNonDecorInsets = providesNonDecorInsets(); + final boolean windowProvidesDisplayDecorInsets = providesDisplayDecorInsets(); removeImmediately(); // Removing a visible window may affect the display orientation so just update it if // needed. Also recompute configuration if it provides screen decor insets. boolean needToSendNewConfiguration = wasVisible && displayContent.updateOrientation(); - if (windowProvidesNonDecorInsets) { + if (windowProvidesDisplayDecorInsets) { needToSendNewConfiguration |= displayContent.getDisplayPolicy().updateDecorInsetsInfo(); } 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 0033e3e368c6..97d7dbf43a39 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -3124,7 +3124,7 @@ public class ActivityRecordTests extends WindowTestsBase { .setSystemDecorations(true).build(); // Add a decor insets provider window. final WindowState navbar = createNavBarWithProvidedInsets(squareDisplay); - assertTrue(navbar.providesNonDecorInsets() + assertTrue(navbar.providesDisplayDecorInsets() && squareDisplay.getDisplayPolicy().updateDecorInsetsInfo()); squareDisplay.sendNewConfiguration(); final Task task = new TaskBuilder(mSupervisor).setDisplay(squareDisplay).build(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index c8fdee06f3e4..353a8ecaf13d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -45,6 +45,8 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -298,20 +300,27 @@ public class DisplayPolicyTests extends WindowTestsBase { @Test public void testUpdateDisplayConfigurationByDecor() { + doReturn(NO_CUTOUT).when(mDisplayContent).calculateDisplayCutoutForRotation(anyInt()); final WindowState navbar = createNavBarWithProvidedInsets(mDisplayContent); final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy(); final DisplayInfo di = mDisplayContent.getDisplayInfo(); final int prevScreenHeightDp = mDisplayContent.getConfiguration().screenHeightDp; - assertTrue(navbar.providesNonDecorInsets() && displayPolicy.updateDecorInsetsInfo()); + assertTrue(navbar.providesDisplayDecorInsets() && displayPolicy.updateDecorInsetsInfo()); assertEquals(NAV_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation, di.logicalWidth, di.logicalHeight).mConfigInsets.bottom); mDisplayContent.sendNewConfiguration(); assertNotEquals(prevScreenHeightDp, mDisplayContent.getConfiguration().screenHeightDp); - assertFalse(navbar.providesNonDecorInsets() && displayPolicy.updateDecorInsetsInfo()); + assertFalse(navbar.providesDisplayDecorInsets() && displayPolicy.updateDecorInsetsInfo()); navbar.removeIfPossible(); assertEquals(0, displayPolicy.getDecorInsetsInfo(di.rotation, di.logicalWidth, di.logicalHeight).mNonDecorInsets.bottom); + + final WindowState statusBar = createStatusBarWithProvidedInsets(mDisplayContent); + assertTrue(statusBar.providesDisplayDecorInsets() + && displayPolicy.updateDecorInsetsInfo()); + assertEquals(STATUS_BAR_HEIGHT, displayPolicy.getDecorInsetsInfo(di.rotation, + di.logicalWidth, di.logicalHeight).mConfigInsets.top); } @SetupWindows(addWindows = { W_NAVIGATION_BAR, W_INPUT_METHOD }) diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 07244a4f2478..a63807d23a14 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -471,6 +471,17 @@ class WindowTestsBase extends SystemServiceTestsBase { return navbar; } + WindowState createStatusBarWithProvidedInsets(DisplayContent dc) { + final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, dc, "statusBar"); + final Binder owner = new Binder(); + statusBar.mAttrs.providedInsets = new InsetsFrameProvider[] { + new InsetsFrameProvider(owner, 0, WindowInsets.Type.statusBars()) + .setInsetsSize(Insets.of(0, STATUS_BAR_HEIGHT, 0, 0)) + }; + dc.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs); + return statusBar; + } + WindowState createAppWindow(Task task, int type, String name) { final ActivityRecord activity = createNonAttachedActivityRecord(task.getDisplayContent()); task.addChild(activity, 0); -- cgit v1.2.3-59-g8ed1b