diff options
| author | 2020-05-22 20:35:28 +0000 | |
|---|---|---|
| committer | 2020-05-22 20:35:28 +0000 | |
| commit | 2bbb08bc42f3226efac6d097a021b644311a9365 (patch) | |
| tree | 95ba46131d3361a200b1eb56bf0bb7d27c279abc | |
| parent | 8032fd3d0c48ae9414c1e2b60f97e95bbec28caa (diff) | |
| parent | 8949be4a6c4c5648ba2b837139558190587a1956 (diff) | |
Merge "Let top-fullscreen-app window keep controlling status bar" into rvc-dev
3 files changed, 67 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 2f18a0d7e531..e244b5551d19 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -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()); } /** diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index d02be88ef0d4..035f2015fe91 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -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) { diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index 2444c24b5e4a..c794e1a3b328 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -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; @@ -183,6 +184,47 @@ public class InsetsPolicyTest extends WindowTestsBase { } @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") .getControllableInsetProvider().getSource().setVisible(false); |