diff options
6 files changed, 52 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 0da178b2bcd0..7f32b09f1d92 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -2004,6 +2004,9 @@ public class DisplayPolicy { */ final Rect mConfigFrame = new Rect(); + /** The count of insets sources when calculating this info. */ + int mLastInsetsSourceCount; + private boolean mNeedUpdate = true; void update(DisplayContent dc, int rotation, int w, int h) { @@ -2025,6 +2028,7 @@ public class DisplayPolicy { mNonDecorFrame.inset(mNonDecorInsets); mConfigFrame.set(displayFrame); mConfigFrame.inset(mConfigInsets); + mLastInsetsSourceCount = dc.getDisplayPolicy().mInsetsSourceWindowsExceptIme.size(); mNeedUpdate = false; } @@ -2033,6 +2037,7 @@ public class DisplayPolicy { mConfigInsets.set(other.mConfigInsets); mNonDecorFrame.set(other.mNonDecorFrame); mConfigFrame.set(other.mConfigFrame); + mLastInsetsSourceCount = other.mLastInsetsSourceCount; mNeedUpdate = false; } @@ -2048,6 +2053,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(); @@ -2087,7 +2098,20 @@ 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)) { + // Even if the config frame is not changed in current rotation, it may change the + // insets in other rotations if the source count is changed. + if (newInfo.mLastInsetsSourceCount != currentInfo.mLastInsetsSourceCount) { + for (int i = mDecorInsets.mInfoForRotation.length - 1; i >= 0; i--) { + if (i != rotation) { + final boolean flipSize = (i + rotation) % 2 == 1; + final int w = flipSize ? dh : dw; + final int h = flipSize ? dw : dh; + mDecorInsets.mInfoForRotation[i].update(mDisplayContent, i, w, h); + } + } + mDecorInsets.mInfoForRotation[rotation].set(newInfo); + } 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 78ed43658dd5..706989069e4b 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1885,7 +1885,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean needToSendNewConfiguration = win.isVisibleRequestedOrAdding() && displayContent.updateOrientation(); - if (win.providesNonDecorInsets()) { + if (win.providesDisplayDecorInsets()) { needToSendNewConfiguration |= displayPolicy.updateDecorInsetsInfo(); } if (needToSendNewConfiguration) { @@ -2358,7 +2358,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 0169387c483d..b9d43d9eb220 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -1897,13 +1897,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP return (mPolicyVisibility & POLICY_VISIBILITY_ALL) == POLICY_VISIBILITY_ALL; } - boolean providesNonDecorInsets() { + boolean providesDisplayDecorInsets() { if (mProvidedInsetsSources == null) { return false; } for (int i = mProvidedInsetsSources.size() - 1; i >= 0; i--) { final int type = mProvidedInsetsSources.keyAt(i); - if ((InsetsState.toPublicType(type) & WindowInsets.Type.navigationBars()) != 0) { + if ((InsetsState.toPublicType(type) & DisplayPolicy.DecorInsets.CONFIG_TYPES) != 0) { return true; } } @@ -2631,13 +2631,13 @@ class WindowState extends WindowContainer<WindowState> 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 c91822279e7c..04c020285832 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -3117,7 +3117,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 ac8dd465adbe..5da3c36fbef8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -48,6 +48,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -301,20 +302,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); } @UseTestDisplay(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 57e7afd9f85a..d762651f511e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -438,6 +438,16 @@ class WindowTestsBase extends SystemServiceTestsBase { return navbar; } + WindowState createStatusBarWithProvidedInsets(DisplayContent dc) { + final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, dc, "statusBar"); + statusBar.mAttrs.width = WindowManager.LayoutParams.MATCH_PARENT; + statusBar.mAttrs.height = STATUS_BAR_HEIGHT; + statusBar.mAttrs.gravity = Gravity.TOP; + statusBar.mAttrs.setFitInsetsTypes(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); |