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

Commit f612f5ed authored by Jerry Chang's avatar Jerry Chang Committed by Android (Google) Code Review
Browse files

Merge "Make system bars appearence logic more generic (2/N)" into sc-v2-dev

parents 6366de23 591d0f79
Loading
Loading
Loading
Loading
+81 −74
Original line number Diff line number Diff line
@@ -315,6 +315,13 @@ public class DisplayPolicy {

    private WindowState mSystemUiControllingWindow;

    // Candidate window to determine the color 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;

    private int mLastDisableFlags;
    private int mLastAppearance;
    private int mLastFullscreenAppearance;
@@ -347,8 +354,6 @@ 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;
@@ -1794,9 +1799,9 @@ public class DisplayPolicy {
        mTopFullscreenOpaqueOrDimmingWindowState = null;
        mTopDockedOpaqueWindowState = null;
        mTopDockedOpaqueOrDimmingWindowState = null;
        mNavBarColorWindowCandidate = null;
        mNavBarBackgroundWindow = null;
        mForceStatusBar = false;
        mForcingShowNavBar = false;
        mForcingShowNavBarLayer = -1;

        mAllowLockscreenWhenOn = false;
        mShowingDream = false;
@@ -1816,11 +1821,6 @@ 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;
@@ -1891,12 +1891,35 @@ public class DisplayPolicy {
            }
        }

        // Check if the freeform window overlaps with the navigation bar area.
        final WindowState navBarWin = hasNavigationBar() ? mNavigationBar : null;
        if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()
                && isOverlappingWithNavBar(win, navBarWin)) {
        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 (affectsSystemUi) {
                if ((appWindow && attached == null && attrs.isFullscreen())
                        || attrs.type == TYPE_VOICE_INTERACTION) {
                    if (mNavBarColorWindowCandidate == null) {
                        mNavBarColorWindowCandidate = win;
                    }
                    if (mNavBarBackgroundWindow == null) {
                        mNavBarBackgroundWindow = win;
                    }
                } else if (win.isDimming()) {
                    // For dimming window with it's host bounds overlapping with navigation bar, it
                    // can be used to determine navigation bar's color but not opacity.
                    if (mNavBarColorWindowCandidate == null) {
                        mNavBarColorWindowCandidate = win;
                    }
                }
            }
        }

        // Also keep track of any windows that are dimming but not necessarily fullscreen in the
        // docked root task.
@@ -2646,15 +2669,12 @@ public class DisplayPolicy {
                mTopDockedOpaqueOrDimmingWindowState);
        final int disableFlags = win.getDisableFlags();
        final int opaqueAppearance = updateSystemBarsLw(win, disableFlags);
        final WindowState navColorWin = chooseNavigationColorWindowLw(
                mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState,
        final WindowState navColorWin = chooseNavigationColorWindowLw(mNavBarColorWindowCandidate,
                mDisplayContent.mInputMethodWindow, mNavigationBarPosition);
        final boolean isNavbarColorManagedByIme =
                navColorWin != null && navColorWin == mDisplayContent.mInputMethodWindow;
        final int appearance = updateLightNavigationBarLw(
                win.mAttrs.insetsFlags.appearance, mTopFullscreenOpaqueWindowState,
                mTopFullscreenOpaqueOrDimmingWindowState,
                mDisplayContent.mInputMethodWindow, navColorWin) | opaqueAppearance;
        final int appearance = updateLightNavigationBarLw(win.mAttrs.insetsFlags.appearance,
                navColorWin) | opaqueAppearance;
        final int behavior = win.mAttrs.insetsFlags.behavior;
        final boolean isFullscreen = !win.getRequestedVisibility(ITYPE_STATUS_BAR)
                || !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR);
@@ -2713,8 +2733,7 @@ public class DisplayPolicy {

    @VisibleForTesting
    @Nullable
    static WindowState chooseNavigationColorWindowLw(WindowState opaque,
            WindowState opaqueOrDimming, WindowState imeWindow,
    static WindowState chooseNavigationColorWindowLw(WindowState candidate, 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.
@@ -2723,54 +2742,39 @@ 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 opaqueOrDimming.
            return opaqueOrDimming;
            // No IME window is involved. Determine the result only with candidate 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)) {
        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 opaqueOrDimming;
                return candidate;
            }
        }

        return imeWindow;
    }

    @VisibleForTesting
    int updateLightNavigationBarLw(int appearance, WindowState opaque,
            WindowState opaqueOrDimming, WindowState imeWindow, WindowState navColorWin) {
    int updateLightNavigationBarLw(int appearance, WindowState navColorWin) {
        if (navColorWin == null || navColorWin.isDimming()
                || !isLightBarAllowed(navColorWin, ITYPE_NAVIGATION_BAR)) {
            // Clear the light flag while not allowed.
            appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
            return appearance;
        }

        if (navColorWin != null) {
            if (navColorWin == imeWindow || navColorWin == opaque) {
                // Respect the light flag.
        // Respect the light flag of navigation color window.
        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)) {
            appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
        }
        return appearance;
    }

@@ -2911,13 +2915,10 @@ public class DisplayPolicy {
     */
    private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible,
            boolean freeformRootTaskVisible) {
        final boolean fullscreenDrawsBackground =
                drawsBarBackground(mTopFullscreenOpaqueWindowState);
        final boolean dockedDrawsBackground =
                drawsBarBackground(mTopDockedOpaqueWindowState);
        final boolean drawBackground = drawsBarBackground(mNavBarBackgroundWindow);

        if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) {
            if (fullscreenDrawsBackground && dockedDrawsBackground) {
            if (drawBackground) {
                appearance = clearNavBarOpaqueFlag(appearance);
            }
        } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
@@ -2925,7 +2926,7 @@ public class DisplayPolicy {
                if (mIsFreeformWindowOverlappingWithNavBar) {
                    appearance = clearNavBarOpaqueFlag(appearance);
                }
            } else if (fullscreenDrawsBackground) {
            } else if (drawBackground) {
                appearance = clearNavBarOpaqueFlag(appearance);
            }
        } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) {
@@ -2934,8 +2935,7 @@ public class DisplayPolicy {
            }
        }

        if (!isFullyTransparentAllowed(mTopFullscreenOpaqueWindowState, TYPE_NAVIGATION_BAR)
                || !isFullyTransparentAllowed(mTopDockedOpaqueWindowState, TYPE_NAVIGATION_BAR)) {
        if (!isFullyTransparentAllowed(mNavBarBackgroundWindow, TYPE_NAVIGATION_BAR)) {
            appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
        }

@@ -3113,10 +3113,13 @@ 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);
        if (mNavBarColorWindowCandidate != null) {
            pw.print(prefix); pw.print("mNavBarColorWindowCandidate=");
            pw.println(mNavBarColorWindowCandidate);
        }
        if (mNavBarBackgroundWindow != null) {
            pw.print(prefix); pw.print("mNavBarBackgroundWindow=");
            pw.println(mNavBarBackgroundWindow);
        }
        pw.print(prefix); pw.print("mTopIsFullscreen="); pw.println(mTopIsFullscreen);
        pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar);
@@ -3198,13 +3201,17 @@ public class DisplayPolicy {
    }

    @VisibleForTesting
    static boolean isOverlappingWithNavBar(WindowState targetWindow, WindowState navBarWindow) {
    static boolean isOverlappingWithNavBar(@NonNull WindowState targetWindow,
            WindowState navBarWindow) {
        if (navBarWindow == null || !navBarWindow.isVisible()
                || targetWindow.mActivityRecord == null || !targetWindow.isVisible()) {
            return false;
        }

        return Rect.intersects(targetWindow.getFrame(), navBarWindow.getFrame());
        // When the window is dimming means it's requesting dim layer to its host container, so
        // checking whether it's overlapping with navigation bar by its container's bounds.
        return Rect.intersects(targetWindow.isDimming()
                ? targetWindow.getBounds() : targetWindow.getFrame(), navBarWindow.getFrame());
    }

    /**
+42 −67
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ 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;
@@ -107,8 +106,7 @@ public class DisplayPolicyTests extends WindowTestsBase {

    @Test
    public void testChooseNavigationColorWindowLw() {
        final WindowState opaque = createOpaqueFullscreen(false);

        final WindowState candidate = createOpaqueFullscreen(false);
        final WindowState dimmingImTarget = createDimmingDialogWindow(true);
        final WindowState dimmingNonImTarget = createDimmingDialogWindow(false);

@@ -116,45 +114,51 @@ 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, null, NAV_BAR_BOTTOM));
                null, null, NAV_BAR_BOTTOM));

        assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw(
                opaque, opaque, null, NAV_BAR_BOTTOM));
        // If no IME windows, return candidate window.
        assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
                candidate, null, NAV_BAR_BOTTOM));
        assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                opaque, dimmingImTarget, null, NAV_BAR_BOTTOM));
                dimmingImTarget, null, NAV_BAR_BOTTOM));
        assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                opaque, dimmingNonImTarget, null, NAV_BAR_BOTTOM));
                dimmingNonImTarget, null, NAV_BAR_BOTTOM));

        assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
                null, null, visibleIme, NAV_BAR_BOTTOM));
        assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
                null, dimmingImTarget, visibleIme, 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(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                null, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM));
                dimmingNonImTarget, invisibleIme, NAV_BAR_BOTTOM));

        // If IME is visible, return candidate when the candidate window is not dimming.
        assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
                opaque, opaque, visibleIme, NAV_BAR_BOTTOM));
                null, visibleIme, NAV_BAR_BOTTOM));
        assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
                opaque, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM));
        assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                opaque, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM));
                candidate, 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));
        // 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));
        assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM));

        // Only IME windows that have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS should be navigation color
        // window.
        assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw(
                opaque, opaque, imeNonDrawNavBar, NAV_BAR_BOTTOM));
        assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw(
                null, imeNonDrawNavBar, NAV_BAR_BOTTOM));
        assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
                candidate, imeNonDrawNavBar, NAV_BAR_BOTTOM));
        assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                opaque, dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
                dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
        assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
                opaque, dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
                dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
    }

    @UseTestDisplay(addWindows = { W_NAVIGATION_BAR })
@@ -182,50 +186,21 @@ 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, 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));
                displayPolicy.updateLightNavigationBarLw(APPEARANCE_LIGHT_NAVIGATION_BARS, null));

        // Dimming window clears APPEARANCE_LIGHT_NAVIGATION_BARS.
        assertEquals(0, displayPolicy.updateLightNavigationBarLw(0, dimming));
        assertEquals(0, displayPolicy.updateLightNavigationBarLw(
                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));

        // IME window clears APPEARANCE_LIGHT_NAVIGATION_BARS
        assertEquals(0, displayPolicy.updateLightNavigationBarLw(
                APPEARANCE_LIGHT_NAVIGATION_BARS, null, null, imeDrawDarkNavBar,
                imeDrawDarkNavBar));
                APPEARANCE_LIGHT_NAVIGATION_BARS, dimming));

        // Even if the top fullscreen has APPEARANCE_LIGHT_NAVIGATION_BARS, IME window wins.
        // Control window overrides APPEARANCE_LIGHT_NAVIGATION_BARS flag.
        assertEquals(0, displayPolicy.updateLightNavigationBarLw(0, opaqueDarkNavBar));
        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));
                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));
    }

    @UseTestDisplay(addWindows = W_ACTIVITY)