Merge changes from topic "b/179251684" into sc-v2-dev

* changes:
  Make system bars appearence logic more generic (2/N)
  Make system bars appearence logic more generic (1/N)
This commit is contained in:
Jerry Chang
2021-06-17 04:37:26 +00:00
committed by Android (Google) Code Review
6 changed files with 136 additions and 212 deletions

View File

@@ -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.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 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_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR; import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
@@ -313,6 +314,7 @@ public class DisplayPolicy {
private WindowState mLastFocusedWindow; private WindowState mLastFocusedWindow;
private WindowState mSystemUiControllingWindow; private WindowState mSystemUiControllingWindow;
private WindowState mNavBarColorWindowCandidate;
private int mLastDisableFlags; private int mLastDisableFlags;
private int mLastAppearance; private int mLastAppearance;
@@ -346,8 +348,6 @@ public class DisplayPolicy {
private boolean mTopIsFullscreen; private boolean mTopIsFullscreen;
private boolean mForceStatusBar; private boolean mForceStatusBar;
private int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED; private int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED;
private boolean mForcingShowNavBar;
private int mForcingShowNavBarLayer;
private boolean mForceShowSystemBars; private boolean mForceShowSystemBars;
private boolean mShowingDream; private boolean mShowingDream;
@@ -1416,7 +1416,7 @@ public class DisplayPolicy {
/** /**
* @return true if the system bars are forced to stay visible * @return true if the system bars are forced to stay visible
*/ */
public boolean areSystemBarsForcedShownLw(WindowState windowState) { public boolean areSystemBarsForcedShownLw() {
return mForceShowSystemBars; return mForceShowSystemBars;
} }
@@ -1793,9 +1793,8 @@ public class DisplayPolicy {
mTopFullscreenOpaqueOrDimmingWindowState = null; mTopFullscreenOpaqueOrDimmingWindowState = null;
mTopDockedOpaqueWindowState = null; mTopDockedOpaqueWindowState = null;
mTopDockedOpaqueOrDimmingWindowState = null; mTopDockedOpaqueOrDimmingWindowState = null;
mNavBarColorWindowCandidate = null;
mForceStatusBar = false; mForceStatusBar = false;
mForcingShowNavBar = false;
mForcingShowNavBarLayer = -1;
mAllowLockscreenWhenOn = false; mAllowLockscreenWhenOn = false;
mShowingDream = false; mShowingDream = false;
@@ -1815,11 +1814,6 @@ public class DisplayPolicy {
if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi); if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi);
applyKeyguardPolicy(win, imeTarget); applyKeyguardPolicy(win, imeTarget);
final int fl = attrs.flags; 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 boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
&& attrs.type < FIRST_SYSTEM_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; final WindowState navBarWin = hasNavigationBar() ? mNavigationBar : null;
if (!mIsFreeformWindowOverlappingWithNavBar && win.inFreeformWindowingMode() if (isOverlappingWithNavBar(win, navBarWin)) {
&& isOverlappingWithNavBar(win, navBarWin)) { // Check if the freeform window overlaps with the navigation bar area.
mIsFreeformWindowOverlappingWithNavBar = true; 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 // 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; final WindowState win = winCandidate;
mSystemUiControllingWindow = win; mSystemUiControllingWindow = win;
mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
final boolean inSplitScreen = final boolean inSplitScreen =
mService.mRoot.getDefaultTaskDisplayArea().isSplitScreenModeActivated(); mService.mRoot.getDefaultTaskDisplayArea().isSplitScreenModeActivated();
if (inSplitScreen) { if (inSplitScreen) {
@@ -2647,15 +2652,12 @@ public class DisplayPolicy {
mTopDockedOpaqueOrDimmingWindowState); mTopDockedOpaqueOrDimmingWindowState);
final int disableFlags = win.getDisableFlags(); final int disableFlags = win.getDisableFlags();
final int opaqueAppearance = updateSystemBarsLw(win, disableFlags); final int opaqueAppearance = updateSystemBarsLw(win, disableFlags);
final WindowState navColorWin = chooseNavigationColorWindowLw( final WindowState navColorWin = chooseNavigationColorWindowLw(mNavBarColorWindowCandidate,
mTopFullscreenOpaqueWindowState, mTopFullscreenOpaqueOrDimmingWindowState,
mDisplayContent.mInputMethodWindow, mNavigationBarPosition); mDisplayContent.mInputMethodWindow, mNavigationBarPosition);
final boolean isNavbarColorManagedByIme = final boolean isNavbarColorManagedByIme =
navColorWin != null && navColorWin == mDisplayContent.mInputMethodWindow; navColorWin != null && navColorWin == mDisplayContent.mInputMethodWindow;
final int appearance = updateLightNavigationBarLw( final int appearance = updateLightNavigationBarLw(win.mAttrs.insetsFlags.appearance,
win.mAttrs.insetsFlags.appearance, mTopFullscreenOpaqueWindowState, navColorWin) | opaqueAppearance;
mTopFullscreenOpaqueOrDimmingWindowState,
mDisplayContent.mInputMethodWindow, navColorWin) | opaqueAppearance;
final int behavior = win.mAttrs.insetsFlags.behavior; final int behavior = win.mAttrs.insetsFlags.behavior;
final boolean isFullscreen = !win.getRequestedVisibility(ITYPE_STATUS_BAR) final boolean isFullscreen = !win.getRequestedVisibility(ITYPE_STATUS_BAR)
|| !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR); || !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR);
@@ -2714,8 +2716,7 @@ public class DisplayPolicy {
@VisibleForTesting @VisibleForTesting
@Nullable @Nullable
static WindowState chooseNavigationColorWindowLw(WindowState opaque, static WindowState chooseNavigationColorWindowLw(WindowState candidate, WindowState imeWindow,
WindowState opaqueOrDimming, WindowState imeWindow,
@NavigationBarPosition int navBarPosition) { @NavigationBarPosition int navBarPosition) {
// If the IME window is visible and FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set, then IME // If the IME window is visible and FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS is set, then IME
// window can be navigation color window. // window can be navigation color window.
@@ -2724,49 +2725,37 @@ public class DisplayPolicy {
&& navBarPosition == NAV_BAR_BOTTOM && navBarPosition == NAV_BAR_BOTTOM
&& (imeWindow.mAttrs.flags && (imeWindow.mAttrs.flags
& WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; & 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) { if (!imeWindowCanNavColorWindow) {
// No IME window is involved. Determine the result only with opaqueOrDimming. // No IME window is involved. Determine the result only with candidate window.
return opaqueOrDimming; return candidate;
} }
// The IME window and the dimming window are competing. Check if the dimming window can be if (candidate != null && candidate.isDimming()) {
// IME target or not. // The IME window and the dimming window are competing. Check if the dimming window can
if (LayoutParams.mayUseInputMethod(opaqueOrDimming.mAttrs.flags)) { // be IME target or not.
// The IME window is above the dimming window. if (LayoutParams.mayUseInputMethod(candidate.mAttrs.flags)) {
return imeWindow; // The IME window is above the dimming window.
} else { return imeWindow;
// The dimming window is above the IME window. } else {
return opaqueOrDimming; // The dimming window is above the IME window.
return candidate;
}
} }
return imeWindow;
} }
@VisibleForTesting @VisibleForTesting
int updateLightNavigationBarLw(int appearance, WindowState opaque, int updateLightNavigationBarLw(int appearance, WindowState navColorWin) {
WindowState opaqueOrDimming, WindowState imeWindow, WindowState navColorWin) {
if (navColorWin != null) { 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. // Respect the light flag.
appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS; appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
appearance |= navColorWin.mAttrs.insetsFlags.appearance appearance |= navColorWin.mAttrs.insetsFlags.appearance
& APPEARANCE_LIGHT_NAVIGATION_BARS; & 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)) { if (!isLightBarAllowed(navColorWin, ITYPE_NAVIGATION_BAR)) {
@@ -2776,19 +2765,22 @@ public class DisplayPolicy {
} }
private int updateSystemBarsLw(WindowState win, int disableFlags) { private int updateSystemBarsLw(WindowState win, int disableFlags) {
final boolean dockedRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea() final TaskDisplayArea defaultTaskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea();
.isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY); final boolean multiWindowTaskVisible =
final boolean resizing = mDisplayContent.getDockedDividerController().isResizing(); 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 // We need to force shows system bars when the multi-window or freeform root task is
// root task is focused but also when we are resizing for the transitions when docked // visible.
// root task visibility changes. mForceShowSystemBars = multiWindowTaskVisible || freeformRootTaskVisible;
mForceShowSystemBars = dockedRootTaskVisible || win.inFreeformWindowingMode() || resizing; mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
int appearance = APPEARANCE_OPAQUE_NAVIGATION_BARS | APPEARANCE_OPAQUE_STATUS_BARS; int appearance = APPEARANCE_OPAQUE_NAVIGATION_BARS | APPEARANCE_OPAQUE_STATUS_BARS;
appearance = configureStatusBarOpacity(appearance); appearance = configureStatusBarOpacity(appearance);
appearance = configureNavBarOpacity(appearance, dockedRootTaskVisible, resizing); appearance = configureNavBarOpacity(appearance, multiWindowTaskVisible,
freeformRootTaskVisible);
final boolean requestHideNavBar = !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR); final boolean requestHideNavBar = !win.getRequestedVisibility(ITYPE_NAVIGATION_BAR);
final long now = SystemClock.uptimeMillis(); 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 * @return the current visibility flags with the nav-bar opacity related flags toggled based
* on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}. * on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}.
*/ */
private int configureNavBarOpacity(int appearance, boolean dockedRootTaskVisible, private int configureNavBarOpacity(int appearance, boolean multiWindowTaskVisible,
boolean isDockedDividerResizing) { boolean freeformRootTaskVisible) {
final boolean freeformRootTaskVisible = mDisplayContent.getDefaultTaskDisplayArea() final boolean drawBackground = drawsBarBackground(mNavBarColorWindowCandidate);
.isRootTaskVisible(WINDOWING_MODE_FREEFORM);
final boolean fullscreenDrawsBackground =
drawsBarBackground(mTopFullscreenOpaqueWindowState);
final boolean dockedDrawsBackground =
drawsBarBackground(mTopDockedOpaqueWindowState);
if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) { if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) {
if (fullscreenDrawsBackground && dockedDrawsBackground) { if (drawBackground) {
appearance = clearNavBarOpaqueFlag(appearance); appearance = clearNavBarOpaqueFlag(appearance);
} else if (dockedRootTaskVisible) {
appearance = setNavBarOpaqueFlag(appearance);
} }
} else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
if (dockedRootTaskVisible || freeformRootTaskVisible || isDockedDividerResizing) { if (multiWindowTaskVisible || freeformRootTaskVisible) {
if (mIsFreeformWindowOverlappingWithNavBar) { if (mIsFreeformWindowOverlappingWithNavBar) {
appearance = clearNavBarOpaqueFlag(appearance); appearance = clearNavBarOpaqueFlag(appearance);
} else {
appearance = setNavBarOpaqueFlag(appearance);
} }
} else if (fullscreenDrawsBackground) { } else if (drawBackground) {
appearance = clearNavBarOpaqueFlag(appearance); appearance = clearNavBarOpaqueFlag(appearance);
} }
} else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) {
if (isDockedDividerResizing) { if (freeformRootTaskVisible) {
appearance = setNavBarOpaqueFlag(appearance);
} else if (freeformRootTaskVisible) {
appearance = clearNavBarOpaqueFlag(appearance); appearance = clearNavBarOpaqueFlag(appearance);
} else {
appearance = setNavBarOpaqueFlag(appearance);
} }
} }
if (!isFullyTransparentAllowed(mTopFullscreenOpaqueWindowState, TYPE_NAVIGATION_BAR) if (!isFullyTransparentAllowed(mNavBarColorWindowCandidate, TYPE_NAVIGATION_BAR)) {
|| !isFullyTransparentAllowed(mTopDockedOpaqueWindowState, TYPE_NAVIGATION_BAR)) {
appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS; appearance |= APPEARANCE_SEMI_TRANSPARENT_NAVIGATION_BARS;
} }
return appearance; return appearance;
} }
private int setNavBarOpaqueFlag(int appearance) {
return appearance | APPEARANCE_OPAQUE_NAVIGATION_BARS;
}
private int clearNavBarOpaqueFlag(int appearance) { private int clearNavBarOpaqueFlag(int appearance) {
return appearance & ~APPEARANCE_OPAQUE_NAVIGATION_BARS; return appearance & ~APPEARANCE_OPAQUE_NAVIGATION_BARS;
} }
@@ -3125,11 +3099,6 @@ public class DisplayPolicy {
pw.print(prefix); pw.print("mTopFullscreenOpaqueOrDimmingWindowState="); pw.print(prefix); pw.print("mTopFullscreenOpaqueOrDimmingWindowState=");
pw.println(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("mTopIsFullscreen="); pw.println(mTopIsFullscreen);
pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar); pw.print(prefix); pw.print("mForceStatusBar="); pw.print(mForceStatusBar);
pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn); pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn);

View File

@@ -18,8 +18,6 @@ package com.android.server.wm;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN; import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; 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_HIDE;
import static android.view.InsetsController.ANIMATION_TYPE_SHOW; import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_HIDDEN; import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_HIDDEN;
@@ -135,11 +133,8 @@ class InsetsPolicy {
abortTransient(); abortTransient();
} }
mFocusedWin = focusedWin; mFocusedWin = focusedWin;
boolean forceShowsSystemBarsForWindowingMode = forceShowsSystemBarsForWindowingMode(); InsetsControlTarget statusControlTarget = getStatusControlTarget(focusedWin);
InsetsControlTarget statusControlTarget = getStatusControlTarget(focusedWin, InsetsControlTarget navControlTarget = getNavControlTarget(focusedWin);
forceShowsSystemBarsForWindowingMode);
InsetsControlTarget navControlTarget = getNavControlTarget(focusedWin,
forceShowsSystemBarsForWindowingMode);
mStateController.onBarControlTargetChanged(statusControlTarget, mStateController.onBarControlTargetChanged(statusControlTarget,
getFakeControlTarget(focusedWin, statusControlTarget), getFakeControlTarget(focusedWin, statusControlTarget),
navControlTarget, navControlTarget,
@@ -304,8 +299,7 @@ class InsetsPolicy {
return realControlTarget == mDummyControlTarget ? focused : null; 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) { if (mShowingTransientTypes.indexOf(ITYPE_STATUS_BAR) != -1) {
return mDummyControlTarget; return mDummyControlTarget;
} }
@@ -319,10 +313,9 @@ class InsetsPolicy {
focusedWin.mAttrs.packageName); focusedWin.mAttrs.packageName);
return mDisplayContent.mRemoteInsetsControlTarget; return mDisplayContent.mRemoteInsetsControlTarget;
} }
if (forceShowsSystemBarsForWindowingMode) { if (mPolicy.areSystemBarsForcedShownLw()) {
// Status bar is forcibly shown for the windowing mode which is a steady state. // Status bar is forcibly shown, we don't want the client to control the status bar, and
// We don't want the client to control the status bar, and we will dispatch the real // we will dispatch the real visibility of status bar to the client.
// visibility of status bar to the client.
return null; return null;
} }
if (forceShowsStatusBarTransiently()) { if (forceShowsStatusBarTransiently()) {
@@ -350,8 +343,7 @@ class InsetsPolicy {
&& !win.inMultiWindowMode(); && !win.inMultiWindowMode();
} }
private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin, private @Nullable InsetsControlTarget getNavControlTarget(@Nullable WindowState focusedWin) {
boolean forceShowsSystemBarsForWindowingMode) {
final WindowState imeWin = mDisplayContent.mInputMethodWindow; final WindowState imeWin = mDisplayContent.mInputMethodWindow;
if (imeWin != null && imeWin.isVisible()) { if (imeWin != null && imeWin.isVisible()) {
// Force showing navigation bar while IME is visible. // Force showing navigation bar while IME is visible.
@@ -369,10 +361,9 @@ class InsetsPolicy {
focusedWin.mAttrs.packageName); focusedWin.mAttrs.packageName);
return mDisplayContent.mRemoteInsetsControlTarget; return mDisplayContent.mRemoteInsetsControlTarget;
} }
if (forceShowsSystemBarsForWindowingMode) { if (mPolicy.areSystemBarsForcedShownLw()) {
// Navigation bar is forcibly shown for the windowing mode which is a steady state. // Navigation bar is forcibly shown, we don't want the client to control the navigation
// We don't want the client to control the navigation bar, and we will dispatch the real // bar, and we will dispatch the real visibility of navigation bar to the client.
// visibility of navigation bar to the client.
return null; return null;
} }
if (forceShowsNavigationBarTransiently()) { if (forceShowsNavigationBarTransiently()) {
@@ -417,19 +408,6 @@ class InsetsPolicy {
&& (win.mAttrs.privateFlags & PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION) != 0; && (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 @VisibleForTesting
void startAnimation(boolean show, Runnable callback) { void startAnimation(boolean show, Runnable callback) {
int typesReady = 0; int typesReady = 0;

View File

@@ -2469,7 +2469,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (win.mActivityRecord != null) { if (win.mActivityRecord != null) {
win.mActivityRecord.updateReportedVisibilityLocked(); win.mActivityRecord.updateReportedVisibilityLocked();
} }
if (displayPolicy.areSystemBarsForcedShownLw(win)) { if (displayPolicy.areSystemBarsForcedShownLw()) {
result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS; result |= WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS;
} }
if (!win.isGoneForLayout()) { if (!win.isGoneForLayout()) {

View File

@@ -3892,7 +3892,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
final boolean forceRelayout = syncRedraw || reportOrientation || isDragResizeChanged(); final boolean forceRelayout = syncRedraw || reportOrientation || isDragResizeChanged();
final DisplayContent displayContent = getDisplayContent(); final DisplayContent displayContent = getDisplayContent();
final boolean alwaysConsumeSystemBars = final boolean alwaysConsumeSystemBars =
displayContent.getDisplayPolicy().areSystemBarsForcedShownLw(this); displayContent.getDisplayPolicy().areSystemBarsForcedShownLw();
final int displayId = displayContent.getDisplayId(); final int displayId = displayContent.getDisplayId();
markRedrawForSyncReported(); markRedrawForSyncReported();

View File

@@ -37,7 +37,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; 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_BOTTOM;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_RIGHT;
import static com.android.server.wm.utils.WmDisplayCutout.NO_CUTOUT; import static com.android.server.wm.utils.WmDisplayCutout.NO_CUTOUT;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@@ -107,8 +106,7 @@ public class DisplayPolicyTests extends WindowTestsBase {
@Test @Test
public void testChooseNavigationColorWindowLw() { public void testChooseNavigationColorWindowLw() {
final WindowState opaque = createOpaqueFullscreen(false); final WindowState candidate = createOpaqueFullscreen(false);
final WindowState dimmingImTarget = createDimmingDialogWindow(true); final WindowState dimmingImTarget = createDimmingDialogWindow(true);
final WindowState dimmingNonImTarget = createDimmingDialogWindow(false); final WindowState dimmingNonImTarget = createDimmingDialogWindow(false);
@@ -116,45 +114,51 @@ public class DisplayPolicyTests extends WindowTestsBase {
final WindowState invisibleIme = createInputMethodWindow(false, true, false); final WindowState invisibleIme = createInputMethodWindow(false, true, false);
final WindowState imeNonDrawNavBar = createInputMethodWindow(true, false, false); final WindowState imeNonDrawNavBar = createInputMethodWindow(true, false, false);
// If everything is null, return null // If everything is null, return null.
assertNull(null, DisplayPolicy.chooseNavigationColorWindowLw( assertNull(null, DisplayPolicy.chooseNavigationColorWindowLw(
null, null, null, NAV_BAR_BOTTOM)); null, null, NAV_BAR_BOTTOM));
assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( // If no IME windows, return candidate window.
opaque, opaque, null, NAV_BAR_BOTTOM)); assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
candidate, null, NAV_BAR_BOTTOM));
assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw( assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
opaque, dimmingImTarget, null, NAV_BAR_BOTTOM)); dimmingImTarget, null, NAV_BAR_BOTTOM));
assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
opaque, dimmingNonImTarget, null, NAV_BAR_BOTTOM)); dimmingNonImTarget, null, NAV_BAR_BOTTOM));
assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( // If IME is not visible, return candidate window.
null, null, visibleIme, NAV_BAR_BOTTOM)); assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw(
assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw( null, invisibleIme, NAV_BAR_BOTTOM));
null, dimmingImTarget, visibleIme, 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( assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
null, dimmingNonImTarget, visibleIme, NAV_BAR_BOTTOM)); dimmingNonImTarget, invisibleIme, 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));
assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( // If IME is visible, return candidate when the candidate window is not dimming.
opaque, opaque, invisibleIme, NAV_BAR_BOTTOM)); assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( null, visibleIme, NAV_BAR_BOTTOM));
opaque, opaque, invisibleIme, NAV_BAR_BOTTOM)); assertEquals(visibleIme, DisplayPolicy.chooseNavigationColorWindowLw(
assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( candidate, visibleIme, NAV_BAR_BOTTOM));
opaque, opaque, visibleIme, NAV_BAR_RIGHT));
// 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 // Only IME windows that have FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS should be navigation color
// window. // window.
assertEquals(opaque, DisplayPolicy.chooseNavigationColorWindowLw( assertEquals(null, DisplayPolicy.chooseNavigationColorWindowLw(
opaque, opaque, imeNonDrawNavBar, NAV_BAR_BOTTOM)); null, imeNonDrawNavBar, NAV_BAR_BOTTOM));
assertEquals(candidate, DisplayPolicy.chooseNavigationColorWindowLw(
candidate, imeNonDrawNavBar, NAV_BAR_BOTTOM));
assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw( assertEquals(dimmingImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
opaque, dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); dimmingImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw( assertEquals(dimmingNonImTarget, DisplayPolicy.chooseNavigationColorWindowLw(
opaque, dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM)); dimmingNonImTarget, imeNonDrawNavBar, NAV_BAR_BOTTOM));
} }
@UseTestDisplay(addWindows = { W_NAVIGATION_BAR }) @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. // If there is no window, APPEARANCE_LIGHT_NAVIGATION_BARS is not allowed.
assertEquals(0, assertEquals(0,
displayPolicy.updateLightNavigationBarLw( displayPolicy.updateLightNavigationBarLw(APPEARANCE_LIGHT_NAVIGATION_BARS, null));
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));
// Dimming window clears APPEARANCE_LIGHT_NAVIGATION_BARS. // Dimming window clears APPEARANCE_LIGHT_NAVIGATION_BARS.
assertEquals(0, displayPolicy.updateLightNavigationBarLw(0, dimming));
assertEquals(0, displayPolicy.updateLightNavigationBarLw( assertEquals(0, displayPolicy.updateLightNavigationBarLw(
0, opaqueDarkNavBar, dimming, null, dimming)); APPEARANCE_LIGHT_NAVIGATION_BARS, 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));
// 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( assertEquals(0, displayPolicy.updateLightNavigationBarLw(
APPEARANCE_LIGHT_NAVIGATION_BARS, null, null, imeDrawDarkNavBar, APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueDarkNavBar));
imeDrawDarkNavBar)); assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, displayPolicy.updateLightNavigationBarLw(
0, opaqueLightNavBar));
// Even if the top fullscreen has APPEARANCE_LIGHT_NAVIGATION_BARS, IME window wins. assertEquals(APPEARANCE_LIGHT_NAVIGATION_BARS, displayPolicy.updateLightNavigationBarLw(
assertEquals(0, displayPolicy.updateLightNavigationBarLw( APPEARANCE_LIGHT_NAVIGATION_BARS, opaqueLightNavBar));
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));
} }
@UseTestDisplay(addWindows = W_ACTIVITY) @UseTestDisplay(addWindows = W_ACTIVITY)

View File

@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; 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.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR;
@@ -80,7 +81,7 @@ public class InsetsPolicyTest extends WindowTestsBase {
} }
@Test @Test
public void testControlsForDispatch_dockedStackVisible() { public void testControlsForDispatch_dockedTaskVisible() {
addWindow(TYPE_STATUS_BAR, "statusBar"); addWindow(TYPE_STATUS_BAR, "statusBar");
addWindow(TYPE_NAVIGATION_BAR, "navBar"); addWindow(TYPE_NAVIGATION_BAR, "navBar");
@@ -93,7 +94,20 @@ public class InsetsPolicyTest extends WindowTestsBase {
} }
@Test @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_STATUS_BAR, "statusBar");
addWindow(TYPE_NAVIGATION_BAR, "navBar"); addWindow(TYPE_NAVIGATION_BAR, "navBar");
@@ -101,18 +115,6 @@ public class InsetsPolicyTest extends WindowTestsBase {
ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app"); ACTIVITY_TYPE_STANDARD, TYPE_APPLICATION, mDisplayContent, "app");
final InsetsSourceControl[] controls = addWindowAndGetControlsForDispatch(win); 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. // The app must not control any system bars.
assertNull(controls); assertNull(controls);
} }