diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index a3ed224073e19..2d4e93dc957da 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -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.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; @@ -313,6 +314,7 @@ public class DisplayPolicy { private WindowState mLastFocusedWindow; private WindowState mSystemUiControllingWindow; + private WindowState mNavBarColorWindowCandidate; private int mLastDisableFlags; private int mLastAppearance; @@ -346,8 +348,6 @@ public class DisplayPolicy { private boolean mTopIsFullscreen; private boolean mForceStatusBar; private int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED; - private boolean mForcingShowNavBar; - private int mForcingShowNavBarLayer; private boolean mForceShowSystemBars; private boolean mShowingDream; @@ -1416,7 +1416,7 @@ public class DisplayPolicy { /** * @return true if the system bars are forced to stay visible */ - public boolean areSystemBarsForcedShownLw(WindowState windowState) { + public boolean areSystemBarsForcedShownLw() { return mForceShowSystemBars; } @@ -1793,9 +1793,8 @@ public class DisplayPolicy { mTopFullscreenOpaqueOrDimmingWindowState = null; mTopDockedOpaqueWindowState = null; mTopDockedOpaqueOrDimmingWindowState = null; + mNavBarColorWindowCandidate = null; mForceStatusBar = false; - mForcingShowNavBar = false; - mForcingShowNavBarLayer = -1; mAllowLockscreenWhenOn = false; mShowingDream = false; @@ -1815,11 +1814,6 @@ public class DisplayPolicy { if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi); applyKeyguardPolicy(win, imeTarget); final int fl = attrs.flags; - if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi - && attrs.type == TYPE_INPUT_METHOD) { - mForcingShowNavBar = true; - mForcingShowNavBarLayer = win.getSurfaceLayer(); - } boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW && attrs.type < FIRST_SYSTEM_WINDOW; @@ -1890,11 +1884,24 @@ public class DisplayPolicy { } } - // Check if the freeform window overlaps with the navigation bar area. final WindowState navBarWin = hasNavigationBar() ? mNavigationBar : null; - if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode() - && isOverlappingWithNavBar(win, navBarWin)) { - mIsFreeformWindowOverlappingWithNavBar = true; + if (isOverlappingWithNavBar(win, navBarWin)) { + // Check if the freeform window overlaps with the navigation bar area. + if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode()) { + mIsFreeformWindowOverlappingWithNavBar = true; + } + // Cache app window that overlaps with the navigation bar area to determine opacity and + // appearance of the navigation bar. We only need to cache one window because there + // should be only one overlapping window if it's not in gesture navigation mode; if it's + // in gesture navigation mode, the navigation bar will be NAV_BAR_FORCE_TRANSPARENT and + // its appearance won't be decided by overlapping windows. + if (mNavBarColorWindowCandidate == null && affectsSystemUi) { + if ((appWindow && attached == null && attrs.isFullscreen()) + || attrs.type == TYPE_VOICE_INTERACTION + || win.isDimming()) { + mNavBarColorWindowCandidate = win; + } + } } // Also keep track of any windows that are dimming but not necessarily fullscreen in the @@ -2628,8 +2635,6 @@ public class DisplayPolicy { final WindowState win = winCandidate; mSystemUiControllingWindow = win; - mDisplayContent.getInsetsPolicy().updateBarControlTarget(win); - final boolean inSplitScreen = mService.mRoot.getDefaultTaskDisplayArea().isSplitScreenModeActivated(); if (inSplitScreen) { @@ -2647,15 +2652,12 @@ public class DisplayPolicy { mTopDockedOpaqueOrDimmingWindowState); final int disableFlags = win.getDisableFlags(); final int opaqueAppearance = updateSystemBarsLw(win, disableFlags); - final WindowState navColorWin = chooseNavigationColorWindowLw( - mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState, + final WindowState navColorWin = chooseNavigationColorWindowLw(mNavBarColorWindowCandidate, mDisplayContent.mInputMethodWindow, mNavigationBarPosition); final boolean isNavbarColorManagedByIme = navColorWin != null && navColorWin == mDisplayContent.mInputMethodWindow; - final int appearance = updateLightNavigationBarLw( - win.mAttrs.insetsFlags.appearance, mTopFullscreenOpaqueWindowState, - mTopFullscreenOpaqueOrDimmingWindowState, - mDisplayContent.mInputMethodWindow, navColorWin) | opaqueAppearance; + final int appearance = updateLightNavigationBarLw(win.mAttrs.insetsFlags.appearance, + navColorWin) | opaqueAppearance; final int behavior = win.mAttrs.insetsFlags.behavior; final boolean isFullscreen = !win.getRequestedVisibility(ITYPE_STATUS_BAR) || !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR); @@ -2714,8 +2716,7 @@ public class DisplayPolicy { @VisibleForTesting @Nullable - static WindowState chooseNavigationColorWindowLw(WindowState opaque, - WindowState opaqueOrDimming, WindowState imeWindow, + static WindowState chooseNavigationColorWindowLw(WindowState candidate, WindowState imeWindow, @NavigationBarPosition int navBarPosition) { // If the IME window is visible and FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set, then IME // window can be navigation color window. @@ -2724,49 +2725,37 @@ public class DisplayPolicy { && navBarPosition == NAV_BAR_BOTTOM && (imeWindow.mAttrs.flags & WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; - - if (opaque != null && opaqueOrDimming == opaque) { - // If the top fullscreen-or-dimming window is also the top fullscreen, respect it - // unless IME window is also eligible, since currently the IME window is always show - // above the opaque fullscreen app window, regardless of the IME target window. - // TODO(b/31559891): Maybe we need to revisit this condition once b/31559891 is fixed. - return imeWindowCanNavColorWindow ? imeWindow : opaque; - } - - if (opaqueOrDimming == null || !opaqueOrDimming.isDimming()) { - // No dimming window is involved. Determine the result only with the IME window. - return imeWindowCanNavColorWindow ? imeWindow : null; - } - if (!imeWindowCanNavColorWindow) { - // No IME window is involved. Determine the result only with opaqueOrDimming. - return opaqueOrDimming; + // No IME window is involved. Determine the result only with candidate window. + return candidate; } - // The IME window and the dimming window are competing. Check if the dimming window can be - // IME target or not. - if (LayoutParams.mayUseInputMethod(opaqueOrDimming.mAttrs.flags)) { - // The IME window is above the dimming window. - return imeWindow; - } else { - // The dimming window is above the IME window. - return opaqueOrDimming; + if (candidate != null && candidate.isDimming()) { + // The IME window and the dimming window are competing. Check if the dimming window can + // be IME target or not. + if (LayoutParams.mayUseInputMethod(candidate.mAttrs.flags)) { + // The IME window is above the dimming window. + return imeWindow; + } else { + // The dimming window is above the IME window. + return candidate; + } } + + return imeWindow; } @VisibleForTesting - int updateLightNavigationBarLw(int appearance, WindowState opaque, - WindowState opaqueOrDimming, WindowState imeWindow, WindowState navColorWin) { - + int updateLightNavigationBarLw(int appearance, WindowState navColorWin) { if (navColorWin != null) { - if (navColorWin == imeWindow || navColorWin == opaque) { + if (navColorWin.isDimming()) { + // Clear the light flag for dimming window. + appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; + } else { // Respect the light flag. appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; appearance |= navColorWin.mAttrs.insetsFlags.appearance & APPEARANCE_LIGHT_NAVIGATION_BARS; - } else if (navColorWin == opaqueOrDimming && navColorWin.isDimming()) { - // Clear the light flag for dimming window. - appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; } } if (!isLightBarAllowed(navColorWin, ITYPE_NAVIGATION_BAR)) { @@ -2776,19 +2765,22 @@ public class DisplayPolicy { } private int updateSystemBarsLw(WindowState win, int disableFlags) { - final boolean dockedRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea() - .isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); - final boolean resizing = mDisplayContent.getDockedDividerController().isResizing(); + 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); - // 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; + // We need to force shows 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; - appearance = configureStatusBarOpacity(appearance); - appearance = configureNavBarOpacity(appearance, dockedRootTaskVisible, resizing); + appearance = configureNavBarOpacity(appearance, multiWindowTaskVisible, + freeformRootTaskVisible); final boolean requestHideNavBar = !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR); final long now = SystemClock.uptimeMillis(); @@ -2907,53 +2899,35 @@ 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 dockedRootTaskVisible, - boolean isDockedDividerResizing) { - final boolean freeformRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea() - .isRootTaskVisible(WINDOWING_MODE_FREEFORM); - final boolean fullscreenDrawsBackground = - drawsBarBackground(mTopFullscreenOpaqueWindowState); - final boolean dockedDrawsBackground = - drawsBarBackground(mTopDockedOpaqueWindowState); + private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible, + boolean freeformRootTaskVisible) { + final boolean drawBackground = drawsBarBackground(mNavBarColorWindowCandidate); if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) { - if (fullscreenDrawsBackground && dockedDrawsBackground) { + if (drawBackground) { appearance = clearNavBarOpaqueFlag(appearance); - } else if (dockedRootTaskVisible) { - appearance = setNavBarOpaqueFlag(appearance); } } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { - if (dockedRootTaskVisible || freeformRootTaskVisible || isDockedDividerResizing) { + if (multiWindowTaskVisible || freeformRootTaskVisible) { if (mIsFreeformWindowOverlappingWithNavBar) { appearance = clearNavBarOpaqueFlag(appearance); - } else { - appearance = setNavBarOpaqueFlag(appearance); } - } else if (fullscreenDrawsBackground) { + } else if (drawBackground) { appearance = clearNavBarOpaqueFlag(appearance); } } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { - if (isDockedDividerResizing) { - appearance = setNavBarOpaqueFlag(appearance); - } else if (freeformRootTaskVisible) { + if (freeformRootTaskVisible) { appearance = clearNavBarOpaqueFlag(appearance); - } else { - appearance = setNavBarOpaqueFlag(appearance); } } - if (!isFullyTransparentAllowed(mTopFullscreenOpaqueWindowState, TYPE_NAVIGATION_BAR) - || !isFullyTransparentAllowed(mTopDockedOpaqueWindowState, TYPE_NAVIGATION_BAR)) { + if (!isFullyTransparentAllowed(mNavBarColorWindowCandidate, TYPE_NAVIGATION_BAR)) { appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS; } return appearance; } - private int setNavBarOpaqueFlag(int appearance) { - return appearance | APPEARANCE_OPAQUE_NAVIGATION_BARS; - } - private int clearNavBarOpaqueFlag(int appearance) { return appearance & ~APPEARANCE_OPAQUE_NAVIGATION_BARS; } @@ -3125,11 +3099,6 @@ public class DisplayPolicy { pw.print(prefix); pw.print("mTopFullscreenOpaqueOrDimmingWindowState="); pw.println(mTopFullscreenOpaqueOrDimmingWindowState); } - if (mForcingShowNavBar) { - pw.print(prefix); pw.print("mForcingShowNavBar="); pw.println(mForcingShowNavBar); - pw.print(prefix); pw.print("mForcingShowNavBarLayer="); - pw.println(mForcingShowNavBarLayer); - } pw.print(prefix); pw.print("mTopIsFullscreen="); pw.println(mTopIsFullscreen); pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn); diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index f2f192686ad55..6d1b373428296 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -18,8 +18,6 @@ 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; @@ -135,11 +133,8 @@ class InsetsPolicy { abortTransient(); } mFocusedWin = focusedWin; - boolean forceShowsSystemBarsForWindowingMode = forceShowsSystemBarsForWindowingMode(); - InsetsControlTarget statusControlTarget = getStatusControlTarget(focusedWin, - forceShowsSystemBarsForWindowingMode); - InsetsControlTarget navControlTarget = getNavControlTarget(focusedWin, - forceShowsSystemBarsForWindowingMode); + InsetsControlTarget statusControlTarget = getStatusControlTarget(focusedWin); + InsetsControlTarget navControlTarget = getNavControlTarget(focusedWin); mStateController.onBarControlTargetChanged(statusControlTarget, getFakeControlTarget(focusedWin, statusControlTarget), navControlTarget, @@ -304,8 +299,7 @@ class InsetsPolicy { return realControlTarget == mDummyControlTarget ? focused : null; } - private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin, - boolean forceShowsSystemBarsForWindowingMode) { + private @Nullable InsetsControlTarget getStatusControlTarget(@Nullable WindowState focusedWin) { if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) { return mDummyControlTarget; } @@ -319,10 +313,9 @@ class InsetsPolicy { focusedWin.mAttrs.packageName); return mDisplayContent.mRemoteInsetsControlTarget; } - 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. + 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. return null; } if (forceShowsStatusBarTransiently()) { @@ -350,8 +343,7 @@ class InsetsPolicy { && !win.inMultiWindowMode(); } - private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin, - boolean forceShowsSystemBarsForWindowingMode) { + private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin) { final WindowState imeWin = mDisplayContent.mInputMethodWindow; if (imeWin != null && imeWin.isVisible()) { // Force showing navigation bar while IME is visible. @@ -369,10 +361,9 @@ class InsetsPolicy { focusedWin.mAttrs.packageName); return mDisplayContent.mRemoteInsetsControlTarget; } - 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. + 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. return null; } if (forceShowsNavigationBarTransiently()) { @@ -417,19 +408,6 @@ 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 a748b45ab07c1..3a5bf581da1a7 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(win)) { + if (displayPolicy.areSystemBarsForcedShownLw()) { 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 43879a01720ba..0a259ee174f9f 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -3892,7 +3892,7 @@ class WindowState extends WindowContainer implements WindowManagerP final boolean forceRelayout = syncRedraw || reportOrientation || isDragResizeChanged(); final DisplayContent displayContent = getDisplayContent(); final boolean alwaysConsumeSystemBars = - displayContent.getDisplayPolicy().areSystemBarsForcedShownLw(this); + displayContent.getDisplayPolicy().areSystemBarsForcedShownLw(); final int displayId = displayContent.getDisplayId(); markRedrawForSyncReported(); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index 3f13394874dc9..b99808887aaba 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -37,7 +37,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_BOTTOM; -import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT; import static com.android.server.wm.utils.WmDisplayCutout.NO_CUTOUT; import static org.junit.Assert.assertEquals; @@ -107,8 +106,7 @@ public class DisplayPolicyTests extends WindowTestsBase { @Test public void testChooseNavigationColorWindowLw() { - final WindowState opaque = createOpaqueFullscreen(false); - + final WindowState candidate = createOpaqueFullscreen(false); final WindowState dimmingImTarget = createDimmingDialogWindow(true); final WindowState dimmingNonImTarget = createDimmingDialogWindow(false); @@ -116,45 +114,51 @@ public class DisplayPolicyTests extends WindowTestsBase { final WindowState invisibleIme = createInputMethodWindow(false, true, false); final WindowState imeNonDrawNavBar = createInputMethodWindow(true, false, false); - // If everything is null, return null + // If everything is null, return null. assertNull(null, DisplayPolicy.chooseNavigationColorWindowLw( - null, null, null, NAV_BAR_BOTTOM)); + null, null, NAV_BAR_BOTTOM)); - assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, opaque, null, NAV_BAR_BOTTOM)); + // If no IME windows, return candidate window. + assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw( + candidate, null, NAV_BAR_BOTTOM)); assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, dimmingImTarget, null, NAV_BAR_BOTTOM)); + dimmingImTarget, null, NAV_BAR_BOTTOM)); assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, dimmingNonImTarget, null, NAV_BAR_BOTTOM)); + dimmingNonImTarget, null, NAV_BAR_BOTTOM)); - assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( - null, null, visibleIme, NAV_BAR_BOTTOM)); - assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( - null, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM)); + // If IME is not visible, return candidate window. + assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw( + null, invisibleIme, NAV_BAR_BOTTOM)); + assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw( + candidate, invisibleIme, NAV_BAR_BOTTOM)); + assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw( + dimmingImTarget, invisibleIme, NAV_BAR_BOTTOM)); assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - null, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM)); - assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, opaque, visibleIme, NAV_BAR_BOTTOM)); - assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, dimmingImTarget, visibleIme, NAV_BAR_BOTTOM)); - assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM)); + dimmingNonImTarget, invisibleIme, NAV_BAR_BOTTOM)); - assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, opaque, invisibleIme, NAV_BAR_BOTTOM)); - assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, opaque, invisibleIme, NAV_BAR_BOTTOM)); - assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, opaque, visibleIme, NAV_BAR_RIGHT)); + // If IME is visible, return candidate when the candidate window is not dimming. + assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( + null, visibleIme, NAV_BAR_BOTTOM)); + assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( + candidate, visibleIme, NAV_BAR_BOTTOM)); + + // If IME is visible and the candidate window is dimming, checks whether the dimming window + // can be IME tartget or not. + assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( + dimmingImTarget, visibleIme, NAV_BAR_BOTTOM)); + assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( + dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM)); // Only IME windows that have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS should be navigation color // window. - assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, opaque, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw( + null, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw( + candidate, imeNonDrawNavBar, NAV_BAR_BOTTOM)); assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( - opaque, dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); + dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); } @UseTestDisplay(addWindows = { W_NAVIGATION_BAR }) @@ -182,50 +186,21 @@ public class DisplayPolicyTests extends WindowTestsBase { // If there is no window, APPEARANCE_LIGHT_NAVIGATION_BARS is not allowed. assertEquals(0, - displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, null, null, - null, null)); - - // Opaque top fullscreen window overrides APPEARANCE_LIGHT_NAVIGATION_BARS flag. - assertEquals(0, displayPolicy.updateLightNavigationBarLw( - 0, opaqueDarkNavBar, opaqueDarkNavBar, null, opaqueDarkNavBar)); - assertEquals(0, displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueDarkNavBar, opaqueDarkNavBar, null, - opaqueDarkNavBar)); - assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, - displayPolicy.updateLightNavigationBarLw(0, opaqueLightNavBar, - opaqueLightNavBar, null, opaqueLightNavBar)); - assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, - displayPolicy.updateLightNavigationBarLw(APPEARANCE_LIGHT_NAVIGATION_BARS, - opaqueLightNavBar, opaqueLightNavBar, null, opaqueLightNavBar)); + displayPolicy.updateLightNavigationBarLw(APPEARANCE_LIGHT_NAVIGATION_BARS, null)); // Dimming window clears APPEARANCE_LIGHT_NAVIGATION_BARS. + assertEquals(0, displayPolicy.updateLightNavigationBarLw(0, dimming)); assertEquals(0, displayPolicy.updateLightNavigationBarLw( - 0, opaqueDarkNavBar, dimming, null, dimming)); - assertEquals(0, displayPolicy.updateLightNavigationBarLw( - 0, opaqueLightNavBar, dimming, null, dimming)); - assertEquals(0, displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueDarkNavBar, dimming, null, dimming)); - assertEquals(0, displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueLightNavBar, dimming, null, dimming)); - assertEquals(0, displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueLightNavBar, dimming, imeDrawLightNavBar, - dimming)); + APPEARANCE_LIGHT_NAVIGATION_BARS, dimming)); - // IME window clears APPEARANCE_LIGHT_NAVIGATION_BARS + // Control window overrides APPEARANCE_LIGHT_NAVIGATION_BARS flag. + assertEquals(0, displayPolicy.updateLightNavigationBarLw(0, opaqueDarkNavBar)); assertEquals(0, displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, null, null, imeDrawDarkNavBar, - imeDrawDarkNavBar)); - - // Even if the top fullscreen has APPEARANCE_LIGHT_NAVIGATION_BARS, IME window wins. - assertEquals(0, displayPolicy.updateLightNavigationBarLw( - APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueLightNavBar, opaqueLightNavBar, - imeDrawDarkNavBar, imeDrawDarkNavBar)); - - // IME window should be able to use APPEARANCE_LIGHT_NAVIGATION_BARS. - assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, - displayPolicy.updateLightNavigationBarLw(0, opaqueDarkNavBar, - opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar)); + APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueDarkNavBar)); + assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, displayPolicy.updateLightNavigationBarLw( + 0, opaqueLightNavBar)); + assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, displayPolicy.updateLightNavigationBarLw( + APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueLightNavBar)); } @UseTestDisplay(addWindows = W_ACTIVITY) 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 bf3ed692dc8ef..5b04c91d5a633 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -18,6 +18,7 @@ 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; @@ -80,7 +81,7 @@ public class InsetsPolicyTest extends WindowTestsBase { } @Test - public void testControlsForDispatch_dockedStackVisible() { + public void testControlsForDispatch_dockedTaskVisible() { addWindow(TYPE_STATUS_BAR, "statusBar"); addWindow(TYPE_NAVIGATION_BAR, "navBar"); @@ -93,7 +94,20 @@ public class InsetsPolicyTest extends WindowTestsBase { } @Test - public void testControlsForDispatch_freeformStackVisible() { + 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() { addWindow(TYPE_STATUS_BAR, "statusBar"); addWindow(TYPE_NAVIGATION_BAR, "navBar"); @@ -101,18 +115,6 @@ 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); }