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

Commit 2bbb08bc authored by Tiger Huang's avatar Tiger Huang Committed by Android (Google) Code Review
Browse files

Merge "Let top-fullscreen-app window keep controlling status bar" into rvc-dev

parents 8032fd3d 8949be4a
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -2756,19 +2756,22 @@ public class DisplayPolicy {
     * @return Whether the top app should hide the statusbar based on the top fullscreen opaque
     *         window.
     */
    private boolean topAppHidesStatusBar() {
    boolean topAppHidesStatusBar() {
        if (mTopFullscreenOpaqueWindowState == null || mForceShowSystemBars) {
            return false;
        }
        final int fl = PolicyControl.getWindowFlags(null,
                mTopFullscreenOpaqueWindowState.getAttrs());
        final LayoutParams attrs = mTopFullscreenOpaqueWindowState.getAttrs();
        final int fl = PolicyControl.getWindowFlags(null, attrs);
        final int sysui = PolicyControl.getSystemUiVisibility(null, attrs);
        final InsetsSource request = mTopFullscreenOpaqueWindowState.getRequestedInsetsState()
                .peekSource(ITYPE_STATUS_BAR);
        if (WindowManagerDebugConfig.DEBUG) {
            Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw());
            Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
                    + " lp.flags=0x" + Integer.toHexString(fl));
            Slog.d(TAG, "attr: " + attrs + " request: " + request);
        }
        return (fl & LayoutParams.FLAG_FULLSCREEN) != 0
                || (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
                || (sysui & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0
                || (request != null && !request.isVisible());
    }

    /**
+16 −18
Original line number Diff line number Diff line
@@ -117,13 +117,8 @@ class InsetsPolicy {
        if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
            return;
        }
        mStatusBar.setVisible(focusedWin == null
                || focusedWin != getStatusControlTarget(focusedWin)
                || focusedWin.getRequestedInsetsState().getSource(ITYPE_STATUS_BAR).isVisible());
        mNavBar.setVisible(focusedWin == null
                || focusedWin != getNavControlTarget(focusedWin)
                || focusedWin.getRequestedInsetsState().getSource(ITYPE_NAVIGATION_BAR)
                        .isVisible());
        mStatusBar.updateVisibility(getStatusControlTarget(focusedWin), ITYPE_STATUS_BAR);
        mNavBar.updateVisibility(getNavControlTarget(focusedWin), ITYPE_NAVIGATION_BAR);
        mPolicy.updateHideNavInputEventReceiver();
    }

@@ -215,16 +210,7 @@ class InsetsPolicy {
    void onInsetsModified(WindowState windowState, InsetsState state) {
        mStateController.onInsetsModified(windowState, state);
        checkAbortTransient(windowState, state);
        if (ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL) {
            return;
        }
        if (windowState == getStatusControlTarget(mFocusedWin)) {
            mStatusBar.setVisible(state.getSource(ITYPE_STATUS_BAR).isVisible());
        }
        if (windowState == getNavControlTarget(mFocusedWin)) {
            mNavBar.setVisible(state.getSource(ITYPE_NAVIGATION_BAR).isVisible());
        }
        mPolicy.updateHideNavInputEventReceiver();
        updateBarControlTarget(mFocusedWin);
    }

    /**
@@ -248,7 +234,6 @@ class InsetsPolicy {
            if (abortTypes.size() > 0) {
                mPolicy.getStatusBarManagerInternal().abortTransient(mDisplayContent.getDisplayId(),
                        abortTypes.toArray());
                updateBarControlTarget(mFocusedWin);
            }
        }
    }
@@ -289,6 +274,11 @@ class InsetsPolicy {
            // fake control to the client, so that it can re-show the bar during this scenario.
            return mDummyControlTarget;
        }
        if (mPolicy.topAppHidesStatusBar()) {
            // Non-fullscreen focused window should not break the state that the top-fullscreen-app
            // window hides status bar.
            return mPolicy.getTopFullscreenOpaqueWindow();
        }
        return focusedWin;
    }

@@ -378,6 +368,14 @@ class InsetsPolicy {
            mId = id;
        }

        private void updateVisibility(InsetsControlTarget controlTarget,
                @InternalInsetsType int type) {
            final WindowState controllingWin =
                    controlTarget instanceof WindowState ? (WindowState) controlTarget : null;
            setVisible(controllingWin == null
                    || controllingWin.getRequestedInsetsState().getSource(type).isVisible());
        }

        private void setVisible(boolean visible) {
            final int state = visible ? WINDOW_STATE_SHOWING : WINDOW_STATE_HIDDEN;
            if (mState != state) {
+42 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
@@ -182,6 +183,47 @@ public class InsetsPolicyTest extends WindowTestsBase {
        assertNull(controls);
    }

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

        // Add a fullscreen (MATCH_PARENT x MATCH_PARENT) app window which hides status bar.
        final WindowState fullscreenApp = addWindow(TYPE_APPLICATION, "fullscreenApp");
        final InsetsState requestedState = new InsetsState();
        requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false);
        fullscreenApp.updateRequestedInsetsState(requestedState);

        // Add a non-fullscreen dialog window.
        final WindowState dialog = addWindow(TYPE_APPLICATION, "dialog");
        dialog.mAttrs.width = WRAP_CONTENT;
        dialog.mAttrs.height = WRAP_CONTENT;

        // Let fullscreenApp be mTopFullscreenOpaqueWindowState.
        final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
        displayPolicy.beginPostLayoutPolicyLw();
        displayPolicy.applyPostLayoutPolicyLw(dialog, dialog.mAttrs, fullscreenApp, null);
        displayPolicy.applyPostLayoutPolicyLw(fullscreenApp, fullscreenApp.mAttrs, null, null);
        displayPolicy.finishPostLayoutPolicyLw();
        mDisplayContent.getInsetsPolicy().updateBarControlTarget(dialog);

        assertEquals(fullscreenApp, displayPolicy.getTopFullscreenOpaqueWindow());

        // dialog is the focused window, but it can only control navigation bar.
        final InsetsSourceControl[] dialogControls =
                mDisplayContent.getInsetsStateController().getControlsForDispatch(dialog);
        assertNotNull(dialogControls);
        assertEquals(1, dialogControls.length);
        assertEquals(ITYPE_NAVIGATION_BAR, dialogControls[0].getType());

        // fullscreenApp is hiding status bar, and it can keep controlling status bar.
        final InsetsSourceControl[] fullscreenAppControls =
                mDisplayContent.getInsetsStateController().getControlsForDispatch(fullscreenApp);
        assertNotNull(fullscreenAppControls);
        assertEquals(1, fullscreenAppControls.length);
        assertEquals(ITYPE_STATUS_BAR, fullscreenAppControls[0].getType());
    }

    @Test
    public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() {
        addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")