From f6d661df9e23437b207f65333c5dfcf2f795f5ae Mon Sep 17 00:00:00 2001 From: Tiger Date: Mon, 22 May 2023 19:09:19 +0800 Subject: [PATCH] Take IME into account when deciding nav bar background window IME can also be the navigation bar background window. If it is visible and it is at the same side of navigation bar, it will draw the navigation bar background. Fix: 274666717 Test: atest DisplayPolicyTests Change-Id: I777d1b15107ed35d5b6ba5ea915271a6eda6d664 --- .../com/android/server/wm/DisplayPolicy.java | 59 +++++++++++++------ .../android/server/wm/DisplayPolicyTests.java | 38 ++++++++++++ 2 files changed, 80 insertions(+), 17 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 77e70a25d497f..90e15eaf9bfdd 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 @@ -1387,7 +1387,7 @@ public class DisplayPolicy { mBottomGestureHost = null; mTopFullscreenOpaqueWindowState = null; mNavBarColorWindowCandidate = null; - mNavBarBackgroundWindow = null; + mNavBarBackgroundWindowCandidate = null; mStatusBarAppearanceRegionList.clear(); mLetterboxDetails.clear(); mStatusBarBackgroundWindows.clear(); @@ -1514,8 +1514,8 @@ public class DisplayPolicy { mNavBarColorWindowCandidate = win; addSystemBarColorApp(win); } - if (mNavBarBackgroundWindow == null) { - mNavBarBackgroundWindow = win; + if (mNavBarBackgroundWindowCandidate == null) { + mNavBarBackgroundWindowCandidate = win; } } @@ -1539,12 +1539,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; + } } } @@ -2465,7 +2472,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; } @@ -2505,7 +2512,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) { @@ -2525,7 +2536,7 @@ public class DisplayPolicy { } } - if (!isFullyTransparentAllowed(mNavBarBackgroundWindow, Type.navigationBars())) { + if (!isFullyTransparentAllowed(navBackgroundWin, Type.navigationBars())) { appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS; } @@ -2536,6 +2547,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; @@ -2708,9 +2733,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() {