diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index d1a34c296cf58..7f7c095103e33 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -20,7 +20,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 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_SECONDARY; import static android.content.res.Configuration.UI_MODE_TYPE_CAR; @@ -1391,7 +1390,7 @@ public class DisplayPolicy { /** * @return true if the system bars are forced to stay visible */ - public boolean areSystemBarsForcedShownLw() { + public boolean areSystemBarsForcedShownLw(WindowState windowState) { return mForceShowSystemBars; } @@ -2489,6 +2488,8 @@ public class DisplayPolicy { final WindowState win = winCandidate; mSystemUiControllingWindow = win; + mDisplayContent.getInsetsPolicy().updateBarControlTarget(win); + final boolean inSplitScreen = mService.mRoot.getDefaultTaskDisplayArea().isSplitScreenModeActivated(); if (inSplitScreen) { @@ -2635,22 +2636,19 @@ public class DisplayPolicy { } private int updateSystemBarsLw(WindowState win, int disableFlags) { - final TaskDisplayArea defaultTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea(); - final boolean multiWindowTaskVisible = - defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) - || defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_MULTI_WINDOW); - final boolean freeformRootTaskVisible = - defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_FREEFORM); + final boolean dockedRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea() + .isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); + final boolean resizing = mDisplayContent.getDockedDividerController().isResizing(); - // We need to force shows system bars when the multi-window or freeform root task is - // visible. - mForceShowSystemBars = multiWindowTaskVisible || freeformRootTaskVisible; - mDisplayContent.getInsetsPolicy().updateBarControlTarget(win); + // We need to force system bars when the docked root task is visible, when the freeform + // root task is focused but also when we are resizing for the transitions when docked + // root task visibility changes. + mForceShowSystemBars = dockedRootTaskVisible || win.inFreeformWindowingMode() || resizing; int appearance = APPEARANCE_OPAQUE_NAVIGATION_BARS | APPEARANCE_OPAQUE_STATUS_BARS; + appearance = configureStatusBarOpacity(appearance); - appearance = configureNavBarOpacity(appearance, multiWindowTaskVisible, - freeformRootTaskVisible); + appearance = configureNavBarOpacity(appearance, dockedRootTaskVisible, resizing); final boolean requestHideNavBar = !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR); final long now = SystemClock.uptimeMillis(); @@ -2752,8 +2750,10 @@ public class DisplayPolicy { * @return the current visibility flags with the nav-bar opacity related flags toggled based * on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}. */ - private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible, - boolean freeformRootTaskVisible) { + private int configureNavBarOpacity(int appearance, boolean dockedRootTaskVisible, + boolean isDockedDividerResizing) { + final boolean freeformRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea() + .isRootTaskVisible(WINDOWING_MODE_FREEFORM); final boolean fullscreenDrawsBackground = drawsBarBackground(mTopFullscreenOpaqueWindowState); final boolean dockedDrawsBackground = @@ -2762,18 +2762,26 @@ public class DisplayPolicy { if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) { if (fullscreenDrawsBackground && dockedDrawsBackground) { appearance = clearNavBarOpaqueFlag(appearance); + } else if (dockedRootTaskVisible) { + appearance = setNavBarOpaqueFlag(appearance); } } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { - if (multiWindowTaskVisible || freeformRootTaskVisible) { + if (dockedRootTaskVisible || freeformRootTaskVisible || isDockedDividerResizing) { if (mIsFreeformWindowOverlappingWithNavBar) { appearance = clearNavBarOpaqueFlag(appearance); + } else { + appearance = setNavBarOpaqueFlag(appearance); } } else if (fullscreenDrawsBackground) { appearance = clearNavBarOpaqueFlag(appearance); } } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { - if (freeformRootTaskVisible) { + if (isDockedDividerResizing) { + appearance = setNavBarOpaqueFlag(appearance); + } else if (freeformRootTaskVisible) { appearance = clearNavBarOpaqueFlag(appearance); + } else { + appearance = setNavBarOpaqueFlag(appearance); } } @@ -2785,6 +2793,10 @@ public class DisplayPolicy { return appearance; } + private int setNavBarOpaqueFlag(int appearance) { + return appearance | APPEARANCE_OPAQUE_NAVIGATION_BARS; + } + private int clearNavBarOpaqueFlag(int appearance) { return appearance & ~APPEARANCE_OPAQUE_NAVIGATION_BARS; } diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 6d1b373428296..f2f192686ad55 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -18,6 +18,8 @@ package com.android.server.wm; import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN; 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_SHOW; import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_HIDDEN; @@ -133,8 +135,11 @@ class InsetsPolicy { abortTransient(); } mFocusedWin = focusedWin; - InsetsControlTarget statusControlTarget = getStatusControlTarget(focusedWin); - InsetsControlTarget navControlTarget = getNavControlTarget(focusedWin); + boolean forceShowsSystemBarsForWindowingMode = forceShowsSystemBarsForWindowingMode(); + InsetsControlTarget statusControlTarget = getStatusControlTarget(focusedWin, + forceShowsSystemBarsForWindowingMode); + InsetsControlTarget navControlTarget = getNavControlTarget(focusedWin, + forceShowsSystemBarsForWindowingMode); mStateController.onBarControlTargetChanged(statusControlTarget, getFakeControlTarget(focusedWin, statusControlTarget), navControlTarget, @@ -299,7 +304,8 @@ class InsetsPolicy { 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) { return mDummyControlTarget; } @@ -313,9 +319,10 @@ class InsetsPolicy { focusedWin.mAttrs.packageName); return mDisplayContent.mRemoteInsetsControlTarget; } - if (mPolicy.areSystemBarsForcedShownLw()) { - // Status bar is forcibly shown, we don't want the client to control the status bar, and - // we will dispatch the real visibility of status bar to the client. + if (forceShowsSystemBarsForWindowingMode) { + // Status bar is forcibly shown for the windowing mode which is a steady state. + // We don't want the client to control the status bar, and we will dispatch the real + // visibility of status bar to the client. return null; } if (forceShowsStatusBarTransiently()) { @@ -343,7 +350,8 @@ class InsetsPolicy { && !win.inMultiWindowMode(); } - private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin) { + private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin, + boolean forceShowsSystemBarsForWindowingMode) { final WindowState imeWin = mDisplayContent.mInputMethodWindow; if (imeWin != null && imeWin.isVisible()) { // Force showing navigation bar while IME is visible. @@ -361,9 +369,10 @@ class InsetsPolicy { focusedWin.mAttrs.packageName); return mDisplayContent.mRemoteInsetsControlTarget; } - if (mPolicy.areSystemBarsForcedShownLw()) { - // Navigation bar is forcibly shown, we don't want the client to control the navigation - // bar, and we will dispatch the real visibility of navigation bar to the client. + if (forceShowsSystemBarsForWindowingMode) { + // Navigation bar is forcibly shown for the windowing mode which is a steady state. + // We don't want the client to control the navigation bar, and we will dispatch the real + // visibility of navigation bar to the client. return null; } if (forceShowsNavigationBarTransiently()) { @@ -408,6 +417,19 @@ class InsetsPolicy { && (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 void startAnimation(boolean show, Runnable callback) { int typesReady = 0; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 2c0235e7c5f41..339134486b0aa 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2469,7 +2469,7 @@ public class WindowManagerService extends IWindowManager.Stub if (win.mActivityRecord != null) { win.mActivityRecord.updateReportedVisibilityLocked(); } - if (displayPolicy.areSystemBarsForcedShownLw()) { + if (displayPolicy.areSystemBarsForcedShownLw(win)) { result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS; } if (!win.isGoneForLayout()) { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 069eca796a2aa..03762b3ee8bf2 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3861,7 +3861,7 @@ class WindowState extends WindowContainer implements WindowManagerP final boolean forceRelayout = syncRedraw || reportOrientation || isDragResizeChanged(); final DisplayContent displayContent = getDisplayContent(); final boolean alwaysConsumeSystemBars = - displayContent.getDisplayPolicy().areSystemBarsForcedShownLw(); + displayContent.getDisplayPolicy().areSystemBarsForcedShownLw(this); final int displayId = displayContent.getDisplayId(); markRedrawForSyncReported(); 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 5b04c91d5a633..bf3ed692dc8ef 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -18,7 +18,6 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; 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.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; @@ -81,7 +80,7 @@ public class InsetsPolicyTest extends WindowTestsBase { } @Test - public void testControlsForDispatch_dockedTaskVisible() { + public void testControlsForDispatch_dockedStackVisible() { addWindow(TYPE_STATUS_BAR, "statusBar"); addWindow(TYPE_NAVIGATION_BAR, "navBar"); @@ -94,20 +93,7 @@ public class InsetsPolicyTest extends WindowTestsBase { } @Test - public void testControlsForDispatch_multiWindowTaskVisible() { - addWindow(TYPE_STATUS_BAR, "statusBar"); - addWindow(TYPE_NAVIGATION_BAR, "navBar"); - - final WindowState win = createWindow(null, WINDOWING_MODE_MULTI_WINDOW, - ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app"); - final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win); - - // The app must not control any system bars. - assertNull(controls); - } - - @Test - public void testControlsForDispatch_freeformTaskVisible() { + public void testControlsForDispatch_freeformStackVisible() { addWindow(TYPE_STATUS_BAR, "statusBar"); addWindow(TYPE_NAVIGATION_BAR, "navBar"); @@ -115,6 +101,18 @@ public class InsetsPolicyTest extends WindowTestsBase { ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app"); final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win); + // The app must not control any bars. + assertNull(controls); + } + + @Test + public void testControlsForDispatch_dockedDividerControllerResizing() { + addWindow(TYPE_STATUS_BAR, "statusBar"); + addWindow(TYPE_NAVIGATION_BAR, "navBar"); + mDisplayContent.getDockedDividerController().setResizing(true); + + final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); + // The app must not control any system bars. assertNull(controls); }