Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 217844ec authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Allow IME windows to use light navigation bar

With this CL, a visible IME window that has
FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is officially allowed to use
SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR like a typical fullscreen
application window that has SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, as
long as FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set to the IME window and
there is no dimming window [1] is shown above the IME window layer.

Note that an example of not setting FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
for IME windows is a flotating IME, where IME window is completely
disjoint from the navigation bar region, like a typical floating
window.  In this scenario, the navigation bar background/button color
should be determined by the target application's flags.

 [1]: A window that has FLAG_DIM_BEHIND flag
 [2]: I4b10a19641bd3ce6c43e7629404b6f202d4186e8

Bug: 69111208
Fix: 69002467
Test: atest android.systemui.cts.LightBarTests
Test: atest com.android.server.policy.PhoneWindowManagerTest
Test: atest CtsInputMethodTestCases
Test: Manually tested with ThemedNavBarKeyboard sample [2]
Change-Id: I40d79f364059d13a7748f4935db17edebaf7ba2d
parent d0a66b21
Loading
Loading
Loading
Loading
+35 −7
Original line number Diff line number Diff line
@@ -7858,9 +7858,39 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    static WindowState chooseNavigationColorWindowLw(WindowState opaque,
            WindowState opaqueOrDimming, WindowState imeWindow,
            @NavigationBarPosition int navBarPosition) {
        if (imeWindow != null && imeWindow.isVisibleLw() && navBarPosition == NAV_BAR_BOTTOM) {
        // If the IME window is visible and FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set, then IME
        // window can be navigation color window.
        final boolean imeWindowCanNavColorWindow = imeWindow != null
                && imeWindow.isVisibleLw()
                && navBarPosition == NAV_BAR_BOTTOM
                && (PolicyControl.getWindowFlags(imeWindow, null)
                & 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 opaqueOrDimming.
            return opaqueOrDimming;
        }

        // The IME window and the dimming window are competing.  Check if the dimming window can be
        // IME target or not.
        if (LayoutParams.mayUseInputMethod(PolicyControl.getWindowFlags(opaqueOrDimming, null))) {
            // The IME window is above the dimming window.
            return imeWindow;
        } else {
            // The dimming window is above the IME window.
            return opaqueOrDimming;
        }
    }
@@ -7870,15 +7900,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            WindowState imeWindow, WindowState navColorWin) {

        if (navColorWin != null) {
            if (navColorWin == opaque) {
                // If the top fullscreen-or-dimming window is also the top fullscreen, respect
                // its light flag.
            if (navColorWin == imeWindow || navColorWin == opaque) {
                // Respect the light flag.
                vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
                vis |= PolicyControl.getSystemUiVisibility(navColorWin, null)
                        & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
            } else if ((navColorWin == opaqueOrDimming && navColorWin.isDimming())
                    || navColorWin == imeWindow) {
                // Otherwise if it's dimming or it's the IME window, clear the light flag.
            } else if (navColorWin == opaqueOrDimming && navColorWin.isDimming()) {
                // Clear the light flag for dimming window.
                vis &= ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
            }
        }
+10 −15
Original line number Diff line number Diff line
@@ -112,15 +112,13 @@ public class PhoneWindowManagerTest {
                null, null, visibleIme, NAV_BAR_BOTTOM));
        assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw(
                null, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM));
        // TODO(b/69002467): A dimming window that is shown above the IME window should win.
        assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw(
        assertEquals(dimmingNonImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
                null, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM));
        assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw(
                opaque, opaque, visibleIme, NAV_BAR_BOTTOM));
        assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw(
                opaque, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM));
        // TODO(b/69002467): A dimming window that is shown above the IME window should win.
        assertEquals(visibleIme, PhoneWindowManager.chooseNavigationColorWindowLw(
        assertEquals(dimmingNonImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
                opaque, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM));

        assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw(
@@ -131,15 +129,12 @@ public class PhoneWindowManagerTest {
                opaque, opaque, visibleIme, NAV_BAR_RIGHT));

        // Only IME windows that have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS should be navigation color
        // window, but it's not yet implemented.
        // TODO(b/69002467): Support this.
        assertEquals(imeNonDrawNavBar, PhoneWindowManager.chooseNavigationColorWindowLw(
        // window.
        assertEquals(opaque, PhoneWindowManager.chooseNavigationColorWindowLw(
                opaque, opaque, imeNonDrawNavBar, NAV_BAR_BOTTOM));
        // TODO(b/69002467): Support this.
        assertEquals(imeNonDrawNavBar, PhoneWindowManager.chooseNavigationColorWindowLw(
        assertEquals(dimmingImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
                opaque, dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
        // TODO(b/69002467): Support this.
        assertEquals(imeNonDrawNavBar, PhoneWindowManager.chooseNavigationColorWindowLw(
        assertEquals(dimmingNonImTarget, PhoneWindowManager.chooseNavigationColorWindowLw(
                opaque, dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
    }

@@ -194,9 +189,9 @@ public class PhoneWindowManagerTest {
                SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR, opaqueLightNavBar, opaqueLightNavBar,
                imeDrawDarkNavBar, imeDrawDarkNavBar));

        // Currently SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR in IME windows is ignored.
        // TODO(b/69002467): Support this.
        assertEquals(0, PhoneWindowManager.updateLightNavigationBarLw(
                0, opaqueDarkNavBar, opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar));
        // IME window should be able to use SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.
        assertEquals(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
                PhoneWindowManager.updateLightNavigationBarLw(0, opaqueDarkNavBar,
                        opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar));
    }
}