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

Commit d0bc05ea authored by Jerry Chang's avatar Jerry Chang
Browse files

Make system bars appearence logic more generic (1/N)

Align force shown system bars conditions in DisplayPolicy and
InsetsPolicy. Update docked task vibible condition to also consider
multi-window task to cover new split screen implementations. Remove
redundant resizing divider condition since the split-primary or
multi-window task should always be visible when resizing divider bar.

Bug: 179251684
Test: atest DisplayPolicyTests
Test: atest InsetsPolicyTest
Change-Id: I8d413a506336253c5604f3ac88d39bb9585b34a3
parent ca897dc3
Loading
Loading
Loading
Loading
+19 −31
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
@@ -1416,7 +1417,7 @@ public class DisplayPolicy {
    /**
    /**
     * @return true if the system bars are forced to stay visible
     * @return true if the system bars are forced to stay visible
     */
     */
    public boolean areSystemBarsForcedShownLw(WindowState windowState) {
    public boolean areSystemBarsForcedShownLw() {
        return mForceShowSystemBars;
        return mForceShowSystemBars;
    }
    }


@@ -2628,8 +2629,6 @@ public class DisplayPolicy {
        final WindowState win = winCandidate;
        final WindowState win = winCandidate;
        mSystemUiControllingWindow = win;
        mSystemUiControllingWindow = win;


        mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);

        final boolean inSplitScreen =
        final boolean inSplitScreen =
                mService.mRoot.getDefaultTaskDisplayArea().isSplitScreenModeActivated();
                mService.mRoot.getDefaultTaskDisplayArea().isSplitScreenModeActivated();
        if (inSplitScreen) {
        if (inSplitScreen) {
@@ -2776,19 +2775,22 @@ public class DisplayPolicy {
    }
    }


    private int updateSystemBarsLw(WindowState win, int disableFlags) {
    private int updateSystemBarsLw(WindowState win, int disableFlags) {
        final boolean dockedRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea()
        final TaskDisplayArea defaultTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
                .isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
        final boolean multiWindowTaskVisible =
        final boolean resizing = mDisplayContent.getDockedDividerController().isResizing();
                defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)

                        || defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_MULTI_WINDOW);
        // We need to force system bars when the docked root task is visible, when the freeform
        final boolean freeformRootTaskVisible =
        // root task is focused but also when we are resizing for the transitions when docked
                defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_FREEFORM);
        // root task visibility changes.

        mForceShowSystemBars = dockedRootTaskVisible || win.inFreeformWindowingMode() || resizing;
        // We need to force showing system bars when the multi-window or freeform root task is
        // visible.
        mForceShowSystemBars = multiWindowTaskVisible || freeformRootTaskVisible;
        mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);


        int appearance = APPEARANCE_OPAQUE_NAVIGATION_BARS | APPEARANCE_OPAQUE_STATUS_BARS;
        int appearance = APPEARANCE_OPAQUE_NAVIGATION_BARS | APPEARANCE_OPAQUE_STATUS_BARS;

        appearance = configureStatusBarOpacity(appearance);
        appearance = configureStatusBarOpacity(appearance);
        appearance = configureNavBarOpacity(appearance, dockedRootTaskVisible, resizing);
        appearance = configureNavBarOpacity(appearance, multiWindowTaskVisible,
                freeformRootTaskVisible);


        final boolean requestHideNavBar = !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR);
        final boolean requestHideNavBar = !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR);
        final long now = SystemClock.uptimeMillis();
        final long now = SystemClock.uptimeMillis();
@@ -2907,10 +2909,8 @@ public class DisplayPolicy {
     * @return the current visibility flags with the nav-bar opacity related flags toggled based
     * @return the current visibility flags with the nav-bar opacity related flags toggled based
     *         on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}.
     *         on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}.
     */
     */
    private int configureNavBarOpacity(int appearance, boolean dockedRootTaskVisible,
    private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible,
            boolean isDockedDividerResizing) {
            boolean freeformRootTaskVisible) {
        final boolean freeformRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea()
                .isRootTaskVisible(WINDOWING_MODE_FREEFORM);
        final boolean fullscreenDrawsBackground =
        final boolean fullscreenDrawsBackground =
                drawsBarBackground(mTopFullscreenOpaqueWindowState);
                drawsBarBackground(mTopFullscreenOpaqueWindowState);
        final boolean dockedDrawsBackground =
        final boolean dockedDrawsBackground =
@@ -2919,26 +2919,18 @@ public class DisplayPolicy {
        if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) {
        if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) {
            if (fullscreenDrawsBackground && dockedDrawsBackground) {
            if (fullscreenDrawsBackground && dockedDrawsBackground) {
                appearance = clearNavBarOpaqueFlag(appearance);
                appearance = clearNavBarOpaqueFlag(appearance);
            } else if (dockedRootTaskVisible) {
                appearance = setNavBarOpaqueFlag(appearance);
            }
            }
        } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
        } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
            if (dockedRootTaskVisible || freeformRootTaskVisible || isDockedDividerResizing) {
            if (multiWindowTaskVisible || freeformRootTaskVisible) {
                if (mIsFreeformWindowOverlappingWithNavBar) {
                if (mIsFreeformWindowOverlappingWithNavBar) {
                    appearance = clearNavBarOpaqueFlag(appearance);
                    appearance = clearNavBarOpaqueFlag(appearance);
                } else {
                    appearance = setNavBarOpaqueFlag(appearance);
                }
                }
            } else if (fullscreenDrawsBackground) {
            } else if (fullscreenDrawsBackground) {
                appearance = clearNavBarOpaqueFlag(appearance);
                appearance = clearNavBarOpaqueFlag(appearance);
            }
            }
        } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) {
        } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) {
            if (isDockedDividerResizing) {
            if (freeformRootTaskVisible) {
                appearance = setNavBarOpaqueFlag(appearance);
            } else if (freeformRootTaskVisible) {
                appearance = clearNavBarOpaqueFlag(appearance);
                appearance = clearNavBarOpaqueFlag(appearance);
            } else {
                appearance = setNavBarOpaqueFlag(appearance);
            }
            }
        }
        }


@@ -2950,10 +2942,6 @@ public class DisplayPolicy {
        return appearance;
        return appearance;
    }
    }


    private int setNavBarOpaqueFlag(int appearance) {
        return appearance | APPEARANCE_OPAQUE_NAVIGATION_BARS;
    }

    private int clearNavBarOpaqueFlag(int appearance) {
    private int clearNavBarOpaqueFlag(int appearance) {
        return appearance & ~APPEARANCE_OPAQUE_NAVIGATION_BARS;
        return appearance & ~APPEARANCE_OPAQUE_NAVIGATION_BARS;
    }
    }
+10 −32
Original line number Original line Diff line number Diff line
@@ -18,8 +18,6 @@ package com.android.server.wm;


import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.view.InsetsController.ANIMATION_TYPE_HIDE;
import static android.view.InsetsController.ANIMATION_TYPE_HIDE;
import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_HIDDEN;
import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_HIDDEN;
@@ -135,11 +133,8 @@ class InsetsPolicy {
            abortTransient();
            abortTransient();
        }
        }
        mFocusedWin = focusedWin;
        mFocusedWin = focusedWin;
        boolean forceShowsSystemBarsForWindowingMode = forceShowsSystemBarsForWindowingMode();
        InsetsControlTarget statusControlTarget = getStatusControlTarget(focusedWin);
        InsetsControlTarget statusControlTarget = getStatusControlTarget(focusedWin,
        InsetsControlTarget navControlTarget = getNavControlTarget(focusedWin);
                forceShowsSystemBarsForWindowingMode);
        InsetsControlTarget navControlTarget = getNavControlTarget(focusedWin,
                forceShowsSystemBarsForWindowingMode);
        mStateController.onBarControlTargetChanged(statusControlTarget,
        mStateController.onBarControlTargetChanged(statusControlTarget,
                getFakeControlTarget(focusedWin, statusControlTarget),
                getFakeControlTarget(focusedWin, statusControlTarget),
                navControlTarget,
                navControlTarget,
@@ -304,8 +299,7 @@ class InsetsPolicy {
        return realControlTarget == mDummyControlTarget ? focused : null;
        return realControlTarget == mDummyControlTarget ? focused : null;
    }
    }


    private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin,
    private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin) {
            boolean forceShowsSystemBarsForWindowingMode) {
        if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
        if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
            return mDummyControlTarget;
            return mDummyControlTarget;
        }
        }
@@ -319,10 +313,9 @@ class InsetsPolicy {
                    focusedWin.mAttrs.packageName);
                    focusedWin.mAttrs.packageName);
            return mDisplayContent.mRemoteInsetsControlTarget;
            return mDisplayContent.mRemoteInsetsControlTarget;
        }
        }
        if (forceShowsSystemBarsForWindowingMode) {
        if (mPolicy.areSystemBarsForcedShownLw()) {
            // Status bar is forcibly shown for the windowing mode which is a steady state.
            // Status bar is forcibly shown. We don't want the client to control the status bar, and
            // We don't want the client to control the status bar, and we will dispatch the real
            // we will dispatch the real visibility of status bar to the client.
            // visibility of status bar to the client.
            return null;
            return null;
        }
        }
        if (forceShowsStatusBarTransiently()) {
        if (forceShowsStatusBarTransiently()) {
@@ -350,8 +343,7 @@ class InsetsPolicy {
                && !win.inMultiWindowMode();
                && !win.inMultiWindowMode();
    }
    }


    private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin,
    private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin) {
            boolean forceShowsSystemBarsForWindowingMode) {
        final WindowState imeWin = mDisplayContent.mInputMethodWindow;
        final WindowState imeWin = mDisplayContent.mInputMethodWindow;
        if (imeWin != null && imeWin.isVisible()) {
        if (imeWin != null && imeWin.isVisible()) {
            // Force showing navigation bar while IME is visible.
            // Force showing navigation bar while IME is visible.
@@ -369,10 +361,9 @@ class InsetsPolicy {
                    focusedWin.mAttrs.packageName);
                    focusedWin.mAttrs.packageName);
            return mDisplayContent.mRemoteInsetsControlTarget;
            return mDisplayContent.mRemoteInsetsControlTarget;
        }
        }
        if (forceShowsSystemBarsForWindowingMode) {
        if (mPolicy.areSystemBarsForcedShownLw()) {
            // Navigation bar is forcibly shown for the windowing mode which is a steady state.
            // Navigation bar is forcibly shown. We don't want the client to control the navigation
            // We don't want the client to control the navigation bar, and we will dispatch the real
            // bar, and we will dispatch the real visibility of navigation bar to the client.
            // visibility of navigation bar to the client.
            return null;
            return null;
        }
        }
        if (forceShowsNavigationBarTransiently()) {
        if (forceShowsNavigationBarTransiently()) {
@@ -417,19 +408,6 @@ class InsetsPolicy {
                && (win.mAttrs.privateFlags & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0;
                && (win.mAttrs.privateFlags & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0;
    }
    }


    private boolean forceShowsSystemBarsForWindowingMode() {
        final boolean isDockedRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea()
                .isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
        final boolean isFreeformRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea()
                .isRootTaskVisible(WINDOWING_MODE_FREEFORM);
        final boolean isResizing = mDisplayContent.getDockedDividerController().isResizing();

        // We need to force system bars when the docked root task is visible, when the freeform
        // root task is visible but also when we are resizing for the transitions when docked
        // root task visibility changes.
        return isDockedRootTaskVisible || isFreeformRootTaskVisible || isResizing;
    }

    @VisibleForTesting
    @VisibleForTesting
    void startAnimation(boolean show, Runnable callback) {
    void startAnimation(boolean show, Runnable callback) {
        int typesReady = 0;
        int typesReady = 0;
+1 −1
Original line number Original line Diff line number Diff line
@@ -2483,7 +2483,7 @@ public class WindowManagerService extends IWindowManager.Stub
            if (win.mActivityRecord != null) {
            if (win.mActivityRecord != null) {
                win.mActivityRecord.updateReportedVisibilityLocked();
                win.mActivityRecord.updateReportedVisibilityLocked();
            }
            }
            if (displayPolicy.areSystemBarsForcedShownLw(win)) {
            if (displayPolicy.areSystemBarsForcedShownLw()) {
                result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
                result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
            }
            }
            if (!win.isGoneForLayout()) {
            if (!win.isGoneForLayout()) {
+1 −1
Original line number Original line Diff line number Diff line
@@ -3893,7 +3893,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        final boolean forceRelayout = syncRedraw || reportOrientation || isDragResizeChanged();
        final boolean forceRelayout = syncRedraw || reportOrientation || isDragResizeChanged();
        final DisplayContent displayContent = getDisplayContent();
        final DisplayContent displayContent = getDisplayContent();
        final boolean alwaysConsumeSystemBars =
        final boolean alwaysConsumeSystemBars =
                displayContent.getDisplayPolicy().areSystemBarsForcedShownLw(this);
                displayContent.getDisplayPolicy().areSystemBarsForcedShownLw();
        final int displayId = displayContent.getDisplayId();
        final int displayId = displayContent.getDisplayId();


        markRedrawForSyncReported();
        markRedrawForSyncReported();
+9 −7
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.wm;


import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
@@ -80,7 +81,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
    }
    }


    @Test
    @Test
    public void testControlsForDispatch_dockedStackVisible() {
    public void testControlsForDispatch_dockedTaskVisible() {
        addWindow(TYPE_STATUS_BAR, "statusBar");
        addWindow(TYPE_STATUS_BAR, "statusBar");
        addWindow(TYPE_NAVIGATION_BAR, "navBar");
        addWindow(TYPE_NAVIGATION_BAR, "navBar");


@@ -93,25 +94,26 @@ public class InsetsPolicyTest extends WindowTestsBase {
    }
    }


    @Test
    @Test
    public void testControlsForDispatch_freeformStackVisible() {
    public void testControlsForDispatch_multiWindowTaskVisible() {
        addWindow(TYPE_STATUS_BAR, "statusBar");
        addWindow(TYPE_STATUS_BAR, "statusBar");
        addWindow(TYPE_NAVIGATION_BAR, "navBar");
        addWindow(TYPE_NAVIGATION_BAR, "navBar");


        final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM,
        final WindowState win = createWindow(null, WINDOWING_MODE_MULTI_WINDOW,
                ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
                ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
        final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win);
        final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win);


        // The app must not control any bars.
        // The app must not control any system bars.
        assertNull(controls);
        assertNull(controls);
    }
    }


    @Test
    @Test
    public void testControlsForDispatch_dockedDividerControllerResizing() {
    public void testControlsForDispatch_freeformTaskVisible() {
        addWindow(TYPE_STATUS_BAR, "statusBar");
        addWindow(TYPE_STATUS_BAR, "statusBar");
        addWindow(TYPE_NAVIGATION_BAR, "navBar");
        addWindow(TYPE_NAVIGATION_BAR, "navBar");
        mDisplayContent.getDockedDividerController().setResizing(true);


        final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch();
        final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM,
                ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
        final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win);


        // The app must not control any system bars.
        // The app must not control any system bars.
        assertNull(controls);
        assertNull(controls);