diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index df35402e7320a..35e891ce8bbe5 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -271,13 +271,13 @@ public class DisplayPolicy { private WindowState mSystemUiControllingWindow; // Candidate window to determine the color of navigation bar. The window needs to be top - // fullscreen-app windows or dim layers that are intersecting with the window frame of status - // bar. + // fullscreen-app windows or dim layers that are intersecting with the window frame of + // navigation bar. private WindowState mNavBarColorWindowCandidate; - // The window to determine opacity and background of translucent navigation bar. The window - // needs to be opaque. - private WindowState mNavBarBackgroundWindow; + // Candidate window to determine opacity and background of translucent navigation bar. + // The window frame must intersect the frame of navigation bar. + private WindowState mNavBarBackgroundWindowCandidate; /** * A collection of {@link AppearanceRegion} to indicate that which region of status bar applies @@ -1383,7 +1383,7 @@ public class DisplayPolicy { mBottomGestureHost = null; mTopFullscreenOpaqueWindowState = null; mNavBarColorWindowCandidate = null; - mNavBarBackgroundWindow = null; + mNavBarBackgroundWindowCandidate = null; mStatusBarAppearanceRegionList.clear(); mLetterboxDetails.clear(); mStatusBarBackgroundWindows.clear(); @@ -1510,8 +1510,8 @@ public class DisplayPolicy { mNavBarColorWindowCandidate = win; addSystemBarColorApp(win); } - if (mNavBarBackgroundWindow == null) { - mNavBarBackgroundWindow = win; + if (mNavBarBackgroundWindowCandidate == null) { + mNavBarBackgroundWindowCandidate = win; } } @@ -1535,12 +1535,19 @@ public class DisplayPolicy { } if (isOverlappingWithNavBar(win) && mNavBarColorWindowCandidate == null) { mNavBarColorWindowCandidate = win; + addSystemBarColorApp(win); } - } else if (appWindow && attached == null && mNavBarColorWindowCandidate == null + } else if (appWindow && attached == null + && (mNavBarColorWindowCandidate == null || mNavBarBackgroundWindowCandidate == null) && win.getFrame().contains( getBarContentFrameForWindow(win, Type.navigationBars()))) { - mNavBarColorWindowCandidate = win; - addSystemBarColorApp(win); + if (mNavBarColorWindowCandidate == null) { + mNavBarColorWindowCandidate = win; + addSystemBarColorApp(win); + } + if (mNavBarBackgroundWindowCandidate == null) { + mNavBarBackgroundWindowCandidate = win; + } } } @@ -2461,7 +2468,7 @@ public class DisplayPolicy { return win.isFullyTransparentBarAllowed(getBarContentFrameForWindow(win, type)); } - private boolean drawsBarBackground(WindowState win) { + private static boolean drawsBarBackground(WindowState win) { if (win == null) { return true; } @@ -2501,7 +2508,11 @@ public class DisplayPolicy { */ private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible, boolean freeformRootTaskVisible) { - final boolean drawBackground = drawsBarBackground(mNavBarBackgroundWindow); + final WindowState navBackgroundWin = chooseNavigationBackgroundWindow( + mNavBarBackgroundWindowCandidate, + mDisplayContent.mInputMethodWindow, + mNavigationBarPosition); + final boolean drawBackground = navBackgroundWin != null; if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) { if (drawBackground) { @@ -2521,7 +2532,7 @@ public class DisplayPolicy { } } - if (!isFullyTransparentAllowed(mNavBarBackgroundWindow, Type.navigationBars())) { + if (!isFullyTransparentAllowed(navBackgroundWin, Type.navigationBars())) { appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS; } @@ -2532,6 +2543,20 @@ public class DisplayPolicy { return appearance & ~APPEARANCE_OPAQUE_NAVIGATION_BARS; } + @VisibleForTesting + @Nullable + static WindowState chooseNavigationBackgroundWindow(WindowState candidate, + WindowState imeWindow, @NavigationBarPosition int navBarPosition) { + if (imeWindow != null && imeWindow.isVisible() && navBarPosition == NAV_BAR_BOTTOM + && drawsBarBackground(imeWindow)) { + return imeWindow; + } + if (drawsBarBackground(candidate)) { + return candidate; + } + return null; + } + private boolean isImmersiveMode(WindowState win) { if (win == null) { return false; @@ -2704,9 +2729,9 @@ public class DisplayPolicy { pw.print(prefix); pw.print("mNavBarColorWindowCandidate="); pw.println(mNavBarColorWindowCandidate); } - if (mNavBarBackgroundWindow != null) { - pw.print(prefix); pw.print("mNavBarBackgroundWindow="); - pw.println(mNavBarBackgroundWindow); + if (mNavBarBackgroundWindowCandidate != null) { + pw.print(prefix); pw.print("mNavBarBackgroundWindowCandidate="); + pw.println(mNavBarBackgroundWindowCandidate); } if (mLastStatusBarAppearanceRegions != null) { pw.print(prefix); pw.println("mLastStatusBarAppearanceRegions="); 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 5ec36048234bf..a422c6893de58 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -178,6 +178,44 @@ public class DisplayPolicyTests extends WindowTestsBase { dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); } + @Test + public void testChooseNavigationBackgroundWindow() { + final WindowState drawBarWin = createOpaqueFullscreen(false); + final WindowState nonDrawBarWin = createDimmingDialogWindow(true); + + final WindowState visibleIme = createInputMethodWindow(true, true, false); + final WindowState invisibleIme = createInputMethodWindow(false, true, false); + final WindowState nonDrawBarIme = createInputMethodWindow(true, false, false); + + assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow( + drawBarWin, null, NAV_BAR_BOTTOM)); + assertNull(DisplayPolicy.chooseNavigationBackgroundWindow( + null, null, NAV_BAR_BOTTOM)); + assertNull(DisplayPolicy.chooseNavigationBackgroundWindow( + nonDrawBarWin, null, NAV_BAR_BOTTOM)); + + assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow( + drawBarWin, visibleIme, NAV_BAR_BOTTOM)); + assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow( + null, visibleIme, NAV_BAR_BOTTOM)); + assertEquals(visibleIme, DisplayPolicy.chooseNavigationBackgroundWindow( + nonDrawBarWin, visibleIme, NAV_BAR_BOTTOM)); + + assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow( + drawBarWin, invisibleIme, NAV_BAR_BOTTOM)); + assertNull(DisplayPolicy.chooseNavigationBackgroundWindow( + null, invisibleIme, NAV_BAR_BOTTOM)); + assertNull(DisplayPolicy.chooseNavigationBackgroundWindow( + nonDrawBarWin, invisibleIme, NAV_BAR_BOTTOM)); + + assertEquals(drawBarWin, DisplayPolicy.chooseNavigationBackgroundWindow( + drawBarWin, nonDrawBarIme, NAV_BAR_BOTTOM)); + assertNull(DisplayPolicy.chooseNavigationBackgroundWindow( + null, nonDrawBarIme, NAV_BAR_BOTTOM)); + assertNull(DisplayPolicy.chooseNavigationBackgroundWindow( + nonDrawBarWin, nonDrawBarIme, NAV_BAR_BOTTOM)); + } + @SetupWindows(addWindows = W_NAVIGATION_BAR) @Test public void testUpdateLightNavigationBarLw() {