From ff95d6e3e9a8119050cdb036371d062f16c0f30a Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Mon, 7 Jun 2021 11:02:19 +0000 Subject: [PATCH 1/2] Make system bars appearence logic more generic (1/N) Align force shown system bars conditions in DisplayPolicy and InsetsPolicy. Update docked task vibible condition to also consider multi-window task to cover new split screen implementations. Remove redundant resizing divider condition since the split-primary or multi-window task should always be visible when resizing divider bar. Bug: 179251684 Test: atest DisplayPolicyTests Test: atest InsetsPolicyTest Change-Id: I8077020ef0fdc62594affa98523b45dc96b28a50 --- .../com/android/server/wm/DisplayPolicy.java | 48 +++++++------------ .../com/android/server/wm/InsetsPolicy.java | 42 ++++------------ .../server/wm/WindowManagerService.java | 2 +- .../com/android/server/wm/WindowState.java | 2 +- .../android/server/wm/InsetsPolicyTest.java | 30 ++++++------ 5 files changed, 46 insertions(+), 78 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 7f7c095103e33..d1a34c296cf58 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; @@ -1390,7 +1391,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; } @@ -2488,8 +2489,6 @@ public class DisplayPolicy { final WindowState win = winCandidate; mSystemUiControllingWindow = win; - mDisplayContent.getInsetsPolicy().updateBarControlTarget(win); - final boolean inSplitScreen = mService.mRoot.getDefaultTaskDisplayArea().isSplitScreenModeActivated(); if (inSplitScreen) { @@ -2636,19 +2635,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(); @@ -2750,10 +2752,8 @@ 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); + private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible, + boolean freeformRootTaskVisible) { final boolean fullscreenDrawsBackground = drawsBarBackground(mTopFullscreenOpaqueWindowState); final boolean dockedDrawsBackground = @@ -2762,26 +2762,18 @@ 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 (dockedRootTaskVisible || freeformRootTaskVisible || isDockedDividerResizing) { + if (multiWindowTaskVisible || freeformRootTaskVisible) { 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 (isDockedDividerResizing) { - appearance = setNavBarOpaqueFlag(appearance); - } else if (freeformRootTaskVisible) { + if (freeformRootTaskVisible) { appearance = clearNavBarOpaqueFlag(appearance); - } else { - appearance = setNavBarOpaqueFlag(appearance); } } @@ -2793,10 +2785,6 @@ 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 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 339134486b0aa..2c0235e7c5f41 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 03762b3ee8bf2..069eca796a2aa 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(this); + displayContent.getDisplayPolicy().areSystemBarsForcedShownLw(); 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 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); } From ed389f0c00a8cf381478958dd4af7810967c5eb0 Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Mon, 7 Jun 2021 10:55:42 +0000 Subject: [PATCH 2/2] Make system bars appearence logic more generic (2/N) Simplify the logic of determining opaque and color of the navigation bar by caching the window that is overlapping with the navigation bar. Remove mForcingShowNavBar and mForcingShowNavBarLayer which are no longer needed. Bug: 179251684 Test: atest DisplayPolicyTests Change-Id: Id5015014aff8db833f42e153a2f62fd999eca536 --- .../com/android/server/wm/DisplayPolicy.java | 111 +++++++---------- .../android/server/wm/DisplayPolicyTests.java | 113 +++++++----------- 2 files changed, 90 insertions(+), 134 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index d1a34c296cf58..7f0ea9869f0d8 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -313,6 +313,7 @@ public class DisplayPolicy { private WindowState mLastFocusedWindow; private WindowState mSystemUiControllingWindow; + private WindowState mNavBarColorWindowCandidate; private int mLastDisableFlags; private int mLastAppearance; @@ -345,8 +346,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; @@ -1709,9 +1708,8 @@ public class DisplayPolicy { mTopFullscreenOpaqueOrDimmingWindowState = null; mTopDockedOpaqueWindowState = null; mTopDockedOpaqueOrDimmingWindowState = null; + mNavBarColorWindowCandidate = null; mForceStatusBar = false; - mForcingShowNavBar = false; - mForcingShowNavBarLayer = -1; mAllowLockscreenWhenOn = false; mShowingDream = false; @@ -1731,11 +1729,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; @@ -1806,11 +1799,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 @@ -2506,15 +2512,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); @@ -2573,8 +2576,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. @@ -2583,49 +2585,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)) { @@ -2754,13 +2744,10 @@ public class DisplayPolicy { */ private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible, boolean freeformRootTaskVisible) { - final boolean fullscreenDrawsBackground = - drawsBarBackground(mTopFullscreenOpaqueWindowState); - final boolean dockedDrawsBackground = - drawsBarBackground(mTopDockedOpaqueWindowState); + final boolean drawBackground = drawsBarBackground(mNavBarColorWindowCandidate); if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) { - if (fullscreenDrawsBackground && dockedDrawsBackground) { + if (drawBackground) { appearance = clearNavBarOpaqueFlag(appearance); } } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { @@ -2768,7 +2755,7 @@ public class DisplayPolicy { if (mIsFreeformWindowOverlappingWithNavBar) { appearance = clearNavBarOpaqueFlag(appearance); } - } else if (fullscreenDrawsBackground) { + } else if (drawBackground) { appearance = clearNavBarOpaqueFlag(appearance); } } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { @@ -2777,8 +2764,7 @@ public class DisplayPolicy { } } - if (!isFullyTransparentAllowed(mTopFullscreenOpaqueWindowState, TYPE_NAVIGATION_BAR) - || !isFullyTransparentAllowed(mTopDockedOpaqueWindowState, TYPE_NAVIGATION_BAR)) { + if (!isFullyTransparentAllowed(mNavBarColorWindowCandidate, TYPE_NAVIGATION_BAR)) { appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS; } @@ -2956,11 +2942,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/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index b793be74c033a..1cd52b425d898 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)