From 25a9738e05b3d35a56f9ad6d81bc1377cb528628 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 17 Jun 2021 19:25:17 +0000 Subject: [PATCH] Revert "Make system bars appearence logic more generic (2/N)" Revert submission 14880637-b/179251684 Reason for revert: Broke android.view.inputmethod.cts.NavigationBarColorTest#testDimmingWindow Reverted Changes: Id5015014a:Make system bars appearence logic more generic (2/... I8077020ef:Make system bars appearence logic more generic (1/... The root cause is expected to be discussed at Bug 191383345. Bug: 179251684 Bug: 191383345 Fix: 191335315 Test: Manually verified on aosp_coral-userdebug as follows 1. Have an IME that uses SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR 2. Show a dialog with FLAG_DIM_BEHIND above the IME 3. Make sure that navbar icons are optimized for dark background Change-Id: Id53dfc45551e7975c534d9fa3210db76634c22fb --- .../com/android/server/wm/DisplayPolicy.java | 111 ++++++++++-------- .../android/server/wm/DisplayPolicyTests.java | 109 ++++++++++------- 2 files changed, 132 insertions(+), 88 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 7f0ea9869f0d8..d1a34c296cf58 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -313,7 +313,6 @@ public class DisplayPolicy { private WindowState mLastFocusedWindow; private WindowState mSystemUiControllingWindow; - private WindowState mNavBarColorWindowCandidate; private int mLastDisableFlags; private int mLastAppearance; @@ -346,6 +345,8 @@ public class DisplayPolicy { private boolean mTopIsFullscreen; private boolean mForceStatusBar; private int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED; + private boolean mForcingShowNavBar; + private int mForcingShowNavBarLayer; private boolean mForceShowSystemBars; private boolean mShowingDream; @@ -1708,8 +1709,9 @@ public class DisplayPolicy { mTopFullscreenOpaqueOrDimmingWindowState = null; mTopDockedOpaqueWindowState = null; mTopDockedOpaqueOrDimmingWindowState = null; - mNavBarColorWindowCandidate = null; mForceStatusBar = false; + mForcingShowNavBar = false; + mForcingShowNavBarLayer = -1; mAllowLockscreenWhenOn = false; mShowingDream = false; @@ -1729,6 +1731,11 @@ public class DisplayPolicy { if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi); applyKeyguardPolicy(win, imeTarget); final int fl = attrs.flags; + if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi + && attrs.type == TYPE_INPUT_METHOD) { + mForcingShowNavBar = true; + mForcingShowNavBarLayer = win.getSurfaceLayer(); + } boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW && attrs.type < FIRST_SYSTEM_WINDOW; @@ -1799,24 +1806,11 @@ public class DisplayPolicy { } } + // Check if the freeform window overlaps with the navigation bar area. final WindowState navBarWin = hasNavigationBar() ? mNavigationBar : null; - if (isOverlappingWithNavBar(win, navBarWin)) { - // Check if the freeform window overlaps with the navigation bar area. - if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()) { - mIsFreeformWindowOverlappingWithNavBar = true; - } - // Cache app window that overlaps with the navigation bar area to determine opacity and - // appearance of the navigation bar. We only need to cache one window because there - // should be only one overlapping window if it's not in gesture navigation mode; if it's - // in gesture navigation mode, the navigation bar will be NAV_BAR_FORCE_TRANSPARENT and - // its appearance won't be decided by overlapping windows. - if (mNavBarColorWindowCandidate == null && affectsSystemUi) { - if ((appWindow && attached == null && attrs.isFullscreen()) - || attrs.type == TYPE_VOICE_INTERACTION - || win.isDimming()) { - mNavBarColorWindowCandidate = win; - } - } + if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode() + && isOverlappingWithNavBar(win, navBarWin)) { + mIsFreeformWindowOverlappingWithNavBar = true; } // Also keep track of any windows that are dimming but not necessarily fullscreen in the @@ -2512,12 +2506,15 @@ public class DisplayPolicy { mTopDockedOpaqueOrDimmingWindowState); final int disableFlags = win.getDisableFlags(); final int opaqueAppearance = updateSystemBarsLw(win, disableFlags); - final WindowState navColorWin = chooseNavigationColorWindowLw(mNavBarColorWindowCandidate, + final WindowState navColorWin = chooseNavigationColorWindowLw( + mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState, mDisplayContent.mInputMethodWindow, mNavigationBarPosition); final boolean isNavbarColorManagedByIme = navColorWin != null && navColorWin == mDisplayContent.mInputMethodWindow; - final int appearance = updateLightNavigationBarLw(win.mAttrs.insetsFlags.appearance, - navColorWin) | opaqueAppearance; + final int appearance = updateLightNavigationBarLw( + win.mAttrs.insetsFlags.appearance, mTopFullscreenOpaqueWindowState, + mTopFullscreenOpaqueOrDimmingWindowState, + mDisplayContent.mInputMethodWindow, navColorWin) | opaqueAppearance; final int behavior = win.mAttrs.insetsFlags.behavior; final boolean isFullscreen = !win.getRequestedVisibility(ITYPE_STATUS_BAR) || !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR); @@ -2576,7 +2573,8 @@ public class DisplayPolicy { @VisibleForTesting @Nullable - static WindowState chooseNavigationColorWindowLw(WindowState candidate, WindowState imeWindow, + static WindowState chooseNavigationColorWindowLw(WindowState opaque, + WindowState opaqueOrDimming, WindowState imeWindow, @NavigationBarPosition int navBarPosition) { // If the IME window is visible and FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set, then IME // window can be navigation color window. @@ -2585,37 +2583,49 @@ public class DisplayPolicy { && navBarPosition == NAV_BAR_BOTTOM && (imeWindow.mAttrs.flags & WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; + + if (opaque != null && opaqueOrDimming == opaque) { + // If the top fullscreen-or-dimming window is also the top fullscreen, respect it + // unless IME window is also eligible, since currently the IME window is always show + // above the opaque fullscreen app window, regardless of the IME target window. + // TODO(b/31559891): Maybe we need to revisit this condition once b/31559891 is fixed. + return imeWindowCanNavColorWindow ? imeWindow : opaque; + } + + if (opaqueOrDimming == null || !opaqueOrDimming.isDimming()) { + // No dimming window is involved. Determine the result only with the IME window. + return imeWindowCanNavColorWindow ? imeWindow : null; + } + if (!imeWindowCanNavColorWindow) { - // No IME window is involved. Determine the result only with candidate window. - return candidate; + // No IME window is involved. Determine the result only with opaqueOrDimming. + return opaqueOrDimming; } - if (candidate != null && candidate.isDimming()) { - // The IME window and the dimming window are competing. Check if the dimming window can - // be IME target or not. - if (LayoutParams.mayUseInputMethod(candidate.mAttrs.flags)) { - // The IME window is above the dimming window. - return imeWindow; - } else { - // The dimming window is above the IME window. - return candidate; - } + // The IME window and the dimming window are competing. Check if the dimming window can be + // IME target or not. + if (LayoutParams.mayUseInputMethod(opaqueOrDimming.mAttrs.flags)) { + // The IME window is above the dimming window. + return imeWindow; + } else { + // The dimming window is above the IME window. + return opaqueOrDimming; } - - return imeWindow; } @VisibleForTesting - int updateLightNavigationBarLw(int appearance, WindowState navColorWin) { + int updateLightNavigationBarLw(int appearance, WindowState opaque, + WindowState opaqueOrDimming, WindowState imeWindow, WindowState navColorWin) { + if (navColorWin != null) { - if (navColorWin.isDimming()) { - // Clear the light flag for dimming window. - appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; - } else { + if (navColorWin == imeWindow || navColorWin == opaque) { // Respect the light flag. appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; appearance |= navColorWin.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_NAVIGATION_BARS; + } else if (navColorWin == opaqueOrDimming && navColorWin.isDimming()) { + // Clear the light flag for dimming window. + appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; } } if (!isLightBarAllowed(navColorWin, ITYPE_NAVIGATION_BAR)) { @@ -2744,10 +2754,13 @@ public class DisplayPolicy { */ private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible, boolean freeformRootTaskVisible) { - final boolean drawBackground = drawsBarBackground(mNavBarColorWindowCandidate); + final boolean fullscreenDrawsBackground = + drawsBarBackground(mTopFullscreenOpaqueWindowState); + final boolean dockedDrawsBackground = + drawsBarBackground(mTopDockedOpaqueWindowState); if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) { - if (drawBackground) { + if (fullscreenDrawsBackground && dockedDrawsBackground) { appearance = clearNavBarOpaqueFlag(appearance); } } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { @@ -2755,7 +2768,7 @@ public class DisplayPolicy { if (mIsFreeformWindowOverlappingWithNavBar) { appearance = clearNavBarOpaqueFlag(appearance); } - } else if (drawBackground) { + } else if (fullscreenDrawsBackground) { appearance = clearNavBarOpaqueFlag(appearance); } } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { @@ -2764,7 +2777,8 @@ public class DisplayPolicy { } } - if (!isFullyTransparentAllowed(mNavBarColorWindowCandidate, TYPE_NAVIGATION_BAR)) { + if (!isFullyTransparentAllowed(mTopFullscreenOpaqueWindowState, TYPE_NAVIGATION_BAR) + || !isFullyTransparentAllowed(mTopDockedOpaqueWindowState, TYPE_NAVIGATION_BAR)) { appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS; } @@ -2942,6 +2956,11 @@ public class DisplayPolicy { pw.print(prefix); pw.print("mTopFullscreenOpaqueOrDimmingWindowState="); pw.println(mTopFullscreenOpaqueOrDimmingWindowState); } + if (mForcingShowNavBar) { + pw.print(prefix); pw.print("mForcingShowNavBar="); pw.println(mForcingShowNavBar); + pw.print(prefix); pw.print("mForcingShowNavBarLayer="); + pw.println(mForcingShowNavBarLayer); + } pw.print(prefix); pw.print("mTopIsFullscreen="); pw.println(mTopIsFullscreen); pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn); 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 1cd52b425d898..b793be74c033a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -37,6 +37,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM; +import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT; import static com.android.server.wm.utils.WmDisplayCutout.NO_CUTOUT; import static org.junit.Assert.assertEquals; @@ -106,7 +107,8 @@ public class DisplayPolicyTests extends WindowTestsBase { @Test public void testChooseNavigationColorWindowLw() { - final WindowState candidate = createOpaqueFullscreen(false); + final WindowState opaque = createOpaqueFullscreen(false); + final WindowState dimmingImTarget = createDimmingDialogWindow(true); final WindowState dimmingNonImTarget = createDimmingDialogWindow(false); @@ -114,51 +116,45 @@ public class DisplayPolicyTests extends WindowTestsBase { final WindowState invisibleIme = createInputMethodWindow(false, true, false); final WindowState imeNonDrawNavBar = createInputMethodWindow(true, false, false); - // If everything is null, return null. + // If everything is null, return null assertNull(null, DisplayPolicy.chooseNavigationColorWindowLw( - null, null, NAV_BAR_BOTTOM)); + null, null, null, NAV_BAR_BOTTOM)); - // If no IME windows, return candidate window. - assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw( - candidate, null, NAV_BAR_BOTTOM)); + assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( + opaque, opaque, null, NAV_BAR_BOTTOM)); assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - dimmingImTarget, null, NAV_BAR_BOTTOM)); + opaque, dimmingImTarget, null, NAV_BAR_BOTTOM)); assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - dimmingNonImTarget, null, NAV_BAR_BOTTOM)); + opaque, dimmingNonImTarget, null, NAV_BAR_BOTTOM)); - // If IME is not visible, return candidate window. - assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw( - null, invisibleIme, NAV_BAR_BOTTOM)); - assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw( - candidate, invisibleIme, NAV_BAR_BOTTOM)); - assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - dimmingImTarget, invisibleIme, NAV_BAR_BOTTOM)); + assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( + null, null, visibleIme, NAV_BAR_BOTTOM)); + assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( + null, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM)); assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - dimmingNonImTarget, invisibleIme, NAV_BAR_BOTTOM)); - - // If IME is visible, return candidate when the candidate window is not dimming. + null, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM)); assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( - null, visibleIme, NAV_BAR_BOTTOM)); + opaque, opaque, visibleIme, NAV_BAR_BOTTOM)); assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( - candidate, visibleIme, NAV_BAR_BOTTOM)); - - // If IME is visible and the candidate window is dimming, checks whether the dimming window - // can be IME tartget or not. - assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( - dimmingImTarget, visibleIme, NAV_BAR_BOTTOM)); + opaque, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM)); assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM)); + opaque, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM)); + + assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( + opaque, opaque, invisibleIme, NAV_BAR_BOTTOM)); + assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( + opaque, opaque, invisibleIme, NAV_BAR_BOTTOM)); + assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( + opaque, opaque, visibleIme, NAV_BAR_RIGHT)); // Only IME windows that have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS should be navigation color // window. - assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw( - null, imeNonDrawNavBar, NAV_BAR_BOTTOM)); - assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw( - candidate, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( + opaque, opaque, imeNonDrawNavBar, NAV_BAR_BOTTOM)); assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + opaque, dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + opaque, dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); } @UseTestDisplay(addWindows = { W_NAVIGATION_BAR }) @@ -186,21 +182,50 @@ public class DisplayPolicyTests extends WindowTestsBase { // If there is no window, APPEARANCE_LIGHT_NAVIGATION_BARS is not allowed. assertEquals(0, - displayPolicy.updateLightNavigationBarLw(APPEARANCE_LIGHT_NAVIGATION_BARS, null)); + displayPolicy.updateLightNavigationBarLw( + APPEARANCE_LIGHT_NAVIGATION_BARS, null, null, + null, null)); + + // Opaque top fullscreen window overrides APPEARANCE_LIGHT_NAVIGATION_BARS flag. + assertEquals(0, displayPolicy.updateLightNavigationBarLw( + 0, opaqueDarkNavBar, opaqueDarkNavBar, null, opaqueDarkNavBar)); + assertEquals(0, displayPolicy.updateLightNavigationBarLw( + APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueDarkNavBar, opaqueDarkNavBar, null, + opaqueDarkNavBar)); + assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, + displayPolicy.updateLightNavigationBarLw(0, opaqueLightNavBar, + opaqueLightNavBar, null, opaqueLightNavBar)); + assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, + displayPolicy.updateLightNavigationBarLw(APPEARANCE_LIGHT_NAVIGATION_BARS, + opaqueLightNavBar, opaqueLightNavBar, null, opaqueLightNavBar)); // Dimming window clears APPEARANCE_LIGHT_NAVIGATION_BARS. - assertEquals(0, displayPolicy.updateLightNavigationBarLw(0, dimming)); assertEquals(0, displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, dimming)); + 0, opaqueDarkNavBar, dimming, null, dimming)); + assertEquals(0, displayPolicy.updateLightNavigationBarLw( + 0, opaqueLightNavBar, dimming, null, dimming)); + assertEquals(0, displayPolicy.updateLightNavigationBarLw( + APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueDarkNavBar, dimming, null, dimming)); + assertEquals(0, displayPolicy.updateLightNavigationBarLw( + APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueLightNavBar, dimming, null, dimming)); + assertEquals(0, displayPolicy.updateLightNavigationBarLw( + APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueLightNavBar, dimming, imeDrawLightNavBar, + dimming)); - // Control window overrides APPEARANCE_LIGHT_NAVIGATION_BARS flag. - assertEquals(0, displayPolicy.updateLightNavigationBarLw(0, opaqueDarkNavBar)); + // IME window clears APPEARANCE_LIGHT_NAVIGATION_BARS assertEquals(0, displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueDarkNavBar)); - assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, displayPolicy.updateLightNavigationBarLw( - 0, opaqueLightNavBar)); - assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueLightNavBar)); + APPEARANCE_LIGHT_NAVIGATION_BARS, null, null, imeDrawDarkNavBar, + imeDrawDarkNavBar)); + + // Even if the top fullscreen has APPEARANCE_LIGHT_NAVIGATION_BARS, IME window wins. + assertEquals(0, displayPolicy.updateLightNavigationBarLw( + APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueLightNavBar, opaqueLightNavBar, + imeDrawDarkNavBar, imeDrawDarkNavBar)); + + // IME window should be able to use APPEARANCE_LIGHT_NAVIGATION_BARS. + assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, + displayPolicy.updateLightNavigationBarLw(0, opaqueDarkNavBar, + opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar)); } @UseTestDisplay(addWindows = W_ACTIVITY)