From 658f85c5c42bf2819683e786b24e6edc98065599 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Tue, 29 Sep 2020 13:30:15 -0700 Subject: [PATCH] DO NOT MERGE Update the stable display frame for flexible insets When using layoutStatusBar or layoutNavigationBar, the stable display frame is modified to take the system bars into account. However when we use flexible inset mapping, the stable display frame is not modified and causes issues in getLayoutHint() and potentially affects how dialogs are laid out. This change ensures that even system bars that use flexible inset mapping modifies the stable display frame as well. Bug: 168846852 Test: manual, atest DialogFrameTests WindowInsetsControllerTests InsetsStateTest InsetsStateControllerTest Change-Id: Ie89298eb98cf8c6bc9ada5494c544a3150b3b2de --- .../com/android/server/wm/DisplayPolicy.java | 42 +++++++++++++++++ .../server/wm/DisplayPolicyLayoutTests.java | 46 +++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index c691a0e220ed7..515d1f58d3ef7 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -2659,6 +2659,14 @@ public class DisplayPolicy { } win.computeFrame(displayFrames); + + // When system bars are added to the Android device through {@link #layoutStatusBar} and + // {@link #layoutNavigationBar}, the displayFrames are adjusted to take the system bars into + // account. The call below adjusts the display frames for system bars which use flexible + // insets mapping instead of {@link #layoutStatusbar} and {@link #layoutNavigationBar}. Note + // that this call is a no-op if not using flexible insets mapping. + adjustDisplayFramesForFlexibleInsets(win, displayFrames); + // Dock windows carve out the bottom of the screen, so normal windows // can't appear underneath them. if (type == TYPE_INPUT_METHOD && win.isVisibleLw() @@ -2671,6 +2679,40 @@ public class DisplayPolicy { } } + private void adjustDisplayFramesForFlexibleInsets(WindowState win, + DisplayFrames displayFrames) { + if (win == mStatusBarAlt) { + adjustDisplayFramesForWindow(win, mStatusBarAltPosition, displayFrames); + } else if (win == mNavigationBarAlt) { + adjustDisplayFramesForWindow(win, mNavigationBarAltPosition, displayFrames); + } else if (win == mClimateBarAlt) { + adjustDisplayFramesForWindow(win, mClimateBarAltPosition, displayFrames); + } else if (win == mExtraNavBarAlt) { + adjustDisplayFramesForWindow(win, mExtraNavBarAltPosition, displayFrames); + } + } + + private static void adjustDisplayFramesForWindow(WindowState win, + @WindowManagerPolicy.AltBarPosition int position, DisplayFrames displayFrames) { + final Rect frame = win.getFrameLw(); + + // Note: This doesn't take into account display cutouts. + switch (position) { + case ALT_BAR_TOP: + displayFrames.mStable.top = frame.bottom; + break; + case ALT_BAR_BOTTOM: + displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = frame.top; + break; + case ALT_BAR_LEFT: + displayFrames.mStable.left = displayFrames.mStableFullscreen.left = frame.right; + break; + case ALT_BAR_RIGHT: + displayFrames.mStable.right = displayFrames.mStableFullscreen.right = frame.left; + break; + } + } + private void layoutWallpaper(DisplayFrames displayFrames, Rect pf, Rect df, Rect cf) { // The wallpaper has Real Ultimate Power df.set(displayFrames.mUnrestricted); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index cb9b49abfe2b7..58d4104bf2b07 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -45,6 +45,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; +import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; import static android.view.WindowManagerPolicyConstants.ALT_BAR_BOTTOM; import static android.view.WindowManagerPolicyConstants.ALT_BAR_LEFT; @@ -752,6 +753,51 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0); } + @Test + public void layoutWindowLw_withFlexibleSystemBars_adjustStableFrame() { + mDisplayPolicy.removeWindowLw(mStatusBarWindow); + mDisplayPolicy.removeWindowLw(mNavBarWindow); + + WindowState statusWin = spy(createWindow(null, TYPE_STATUS_BAR_ADDITIONAL, + "StatusBarAdditional")); + doNothing().when(statusWin).computeFrameLw(); + statusWin.mAttrs.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR}; + statusWin.mAttrs.gravity = Gravity.TOP; + statusWin.mAttrs.height = STATUS_BAR_HEIGHT; + statusWin.mAttrs.width = MATCH_PARENT; + statusWin.getFrameLw().set(0, 0, DISPLAY_WIDTH, STATUS_BAR_HEIGHT); + addWindow(statusWin); + + WindowState navWin = spy(createWindow(null, TYPE_NAVIGATION_BAR_PANEL, + "NavigationBarPanel")); + doNothing().when(navWin).computeFrameLw(); + navWin.mAttrs.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR}; + navWin.mAttrs.gravity = Gravity.BOTTOM; + navWin.mAttrs.height = NAV_BAR_HEIGHT; + navWin.mAttrs.width = MATCH_PARENT; + navWin.getFrameLw().set(0, DISPLAY_HEIGHT - NAV_BAR_HEIGHT, DISPLAY_WIDTH, DISPLAY_HEIGHT); + addWindow(navWin); + + WindowState climateWin = spy(createWindow(null, TYPE_NAVIGATION_BAR_PANEL, + "ClimatePanel")); + doNothing().when(climateWin).computeFrameLw(); + climateWin.mAttrs.providesInsetsTypes = new int[]{ITYPE_CLIMATE_BAR}; + climateWin.mAttrs.gravity = Gravity.LEFT; + climateWin.mAttrs.height = MATCH_PARENT; + climateWin.mAttrs.width = 20; + climateWin.getFrameLw().set(0, 0, 20, DISPLAY_HEIGHT); + addWindow(climateWin); + + mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mDisplayPolicy.layoutWindowLw(statusWin, null, mFrames); + mDisplayPolicy.layoutWindowLw(navWin, null, mFrames); + mDisplayPolicy.layoutWindowLw(climateWin, null, mFrames); + + assertThat(mFrames.mStable, + is(new Rect(20, STATUS_BAR_HEIGHT, DISPLAY_WIDTH, + DISPLAY_HEIGHT - NAV_BAR_HEIGHT))); + } + @Test public void layoutHint_appWindow() { mWindow.mAttrs.flags =