Loading services/core/java/com/android/server/wm/DisplayPolicy.java +9 −6 Original line number Diff line number Diff line Loading @@ -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()); } /** Loading services/core/java/com/android/server/wm/InsetsPolicy.java +16 −18 Original line number Diff line number Diff line Loading @@ -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(); } Loading Loading @@ -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); } /** Loading @@ -248,7 +234,6 @@ class InsetsPolicy { if (abortTypes.size() > 0) { mPolicy.getStatusBarManagerInternal().abortTransient(mDisplayContent.getDisplayId(), abortTypes.toArray()); updateBarControlTarget(mFocusedWin); } } } Loading Loading @@ -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; } Loading Loading @@ -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) { Loading services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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") Loading Loading
services/core/java/com/android/server/wm/DisplayPolicy.java +9 −6 Original line number Diff line number Diff line Loading @@ -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()); } /** Loading
services/core/java/com/android/server/wm/InsetsPolicy.java +16 −18 Original line number Diff line number Diff line Loading @@ -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(); } Loading Loading @@ -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); } /** Loading @@ -248,7 +234,6 @@ class InsetsPolicy { if (abortTypes.size() > 0) { mPolicy.getStatusBarManagerInternal().abortTransient(mDisplayContent.getDisplayId(), abortTypes.toArray()); updateBarControlTarget(mFocusedWin); } } } Loading Loading @@ -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; } Loading Loading @@ -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) { Loading
services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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") Loading