summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/InsetsController.java2
-rw-r--r--core/java/android/view/InsetsSource.java9
-rw-r--r--core/java/android/view/InsetsState.java27
-rw-r--r--core/java/android/view/WindowInsets.java51
-rw-r--r--core/java/com/android/internal/policy/DecorView.java43
-rw-r--r--core/tests/coretests/src/android/view/WindowInsetsTest.java6
-rw-r--r--core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java1
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java28
-rw-r--r--services/core/java/com/android/server/wm/InsetsPolicy.java57
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java17
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java30
12 files changed, 181 insertions, 92 deletions
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 5019b85ca503..0abad6c76c2e 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -797,7 +797,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
}
WindowInsets insets = state.calculateInsets(mFrame, mState /* ignoringVisibilityState*/,
- mLastInsets.isRound(), mLastInsets.shouldAlwaysConsumeSystemBars(),
+ mLastInsets.isRound(), false /* alwaysConsumeSystemBars */,
mLastLegacySoftInputMode, mLastLegacyWindowFlags, mLastLegacySystemUiFlags,
mWindowType, mLastWindowingMode, null /* idSideMap */);
mHost.dispatchWindowInsetsAnimationProgress(insets,
diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java
index e10184976abe..64411866f020 100644
--- a/core/java/android/view/InsetsSource.java
+++ b/core/java/android/view/InsetsSource.java
@@ -68,10 +68,16 @@ public class InsetsSource implements Parcelable {
*/
public static final int FLAG_INSETS_ROUNDED_CORNER = 1 << 1;
+ /**
+ * Controls whether the insets provided by this source should be forcibly consumed.
+ */
+ public static final int FLAG_FORCE_CONSUMING = 1 << 2;
+
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = "FLAG_", value = {
FLAG_SUPPRESS_SCRIM,
FLAG_INSETS_ROUNDED_CORNER,
+ FLAG_FORCE_CONSUMING,
})
public @interface Flags {}
@@ -328,6 +334,9 @@ public class InsetsSource implements Parcelable {
if ((flags & FLAG_INSETS_ROUNDED_CORNER) != 0) {
joiner.add("INSETS_ROUNDED_CORNER");
}
+ if ((flags & FLAG_FORCE_CONSUMING) != 0) {
+ joiner.add("FORCE_CONSUMING");
+ }
return joiner.toString();
}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index dceae90822b8..c13b9ab0abd1 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
import static android.view.InsetsStateProto.DISPLAY_CUTOUT;
import static android.view.InsetsStateProto.DISPLAY_FRAME;
@@ -144,12 +145,18 @@ public class InsetsState implements Parcelable {
boolean[] typeVisibilityMap = new boolean[Type.SIZE];
final Rect relativeFrame = new Rect(frame);
final Rect relativeFrameMax = new Rect(frame);
+ @InsetsType int forceConsumingTypes = 0;
@InsetsType int suppressScrimTypes = 0;
for (int i = mSources.size() - 1; i >= 0; i--) {
final InsetsSource source = mSources.valueAt(i);
+ final @InsetsType int type = source.getType();
+
+ if ((source.getFlags() & InsetsSource.FLAG_FORCE_CONSUMING) != 0) {
+ forceConsumingTypes |= type;
+ }
if ((source.getFlags() & InsetsSource.FLAG_SUPPRESS_SCRIM) != 0) {
- suppressScrimTypes |= source.getType();
+ suppressScrimTypes |= type;
}
processSource(source, relativeFrame, false /* ignoreVisibility */, typeInsetsMap,
@@ -157,7 +164,7 @@ public class InsetsState implements Parcelable {
// IME won't be reported in max insets as the size depends on the EditorInfo of the IME
// target.
- if (source.getType() != WindowInsets.Type.ime()) {
+ if (type != WindowInsets.Type.ime()) {
InsetsSource ignoringVisibilitySource = ignoringVisibilityState != null
? ignoringVisibilityState.peekSource(source.getId())
: source;
@@ -178,13 +185,13 @@ public class InsetsState implements Parcelable {
if ((legacyWindowFlags & FLAG_FULLSCREEN) != 0) {
compatInsetsTypes &= ~statusBars();
}
- if (clearsCompatInsets(windowType, legacyWindowFlags, windowingMode)
- && !alwaysConsumeSystemBars) {
- compatInsetsTypes = 0;
+ if (clearsCompatInsets(windowType, legacyWindowFlags, windowingMode)) {
+ // Clear all types but forceConsumingTypes.
+ compatInsetsTypes &= forceConsumingTypes;
}
return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound,
- alwaysConsumeSystemBars, suppressScrimTypes, calculateRelativeCutout(frame),
+ forceConsumingTypes, suppressScrimTypes, calculateRelativeCutout(frame),
calculateRelativeRoundedCorners(frame),
calculateRelativePrivacyIndicatorBounds(frame),
calculateRelativeDisplayShape(frame),
@@ -290,9 +297,8 @@ public class InsetsState implements Parcelable {
public Insets calculateVisibleInsets(Rect frame, int windowType, int windowingMode,
@SoftInputModeFlags int softInputMode, int windowFlags) {
- if (clearsCompatInsets(windowType, windowFlags, windowingMode)) {
- return Insets.NONE;
- }
+ final boolean clearsCompatInsets = clearsCompatInsets(
+ windowType, windowFlags, windowingMode);
final int softInputAdjustMode = softInputMode & SOFT_INPUT_MASK_ADJUST;
final int visibleInsetsTypes = softInputAdjustMode != SOFT_INPUT_ADJUST_NOTHING
? systemBars() | ime()
@@ -303,6 +309,9 @@ public class InsetsState implements Parcelable {
if ((source.getType() & visibleInsetsTypes) == 0) {
continue;
}
+ if (clearsCompatInsets && !source.hasFlags(FLAG_FORCE_CONSUMING)) {
+ continue;
+ }
insets = Insets.max(source.calculateVisibleInsets(frame), insets);
}
return insets;
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 4acaea849586..57a41619ff8d 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -84,13 +84,7 @@ public final class WindowInsets {
@Nullable private final PrivacyIndicatorBounds mPrivacyIndicatorBounds;
@Nullable private final DisplayShape mDisplayShape;
- /**
- * In multi-window we force show the navigation bar. Because we don't want that the surface size
- * changes in this mode, we instead have a flag whether the navigation bar size should always
- * be consumed, so the app is treated like there is no virtual navigation bar at all.
- */
- private final boolean mAlwaysConsumeSystemBars;
-
+ private final @InsetsType int mForceConsumingTypes;
private final @InsetsType int mSuppressScrimTypes;
private final boolean mSystemWindowInsetsConsumed;
private final boolean mStableInsetsConsumed;
@@ -117,7 +111,7 @@ public final class WindowInsets {
static {
CONSUMED = new WindowInsets(createCompatTypeMap(null), createCompatTypeMap(null),
- createCompatVisibilityMap(createCompatTypeMap(null)), false, false, 0, null,
+ createCompatVisibilityMap(createCompatTypeMap(null)), false, 0, 0, null,
null, null, null, systemBars(), false);
}
@@ -137,7 +131,8 @@ public final class WindowInsets {
@Nullable Insets[] typeMaxInsetsMap,
boolean[] typeVisibilityMap,
boolean isRound,
- boolean alwaysConsumeSystemBars, @InsetsType int suppressScrimTypes,
+ @InsetsType int forceConsumingTypes,
+ @InsetsType int suppressScrimTypes,
DisplayCutout displayCutout,
RoundedCorners roundedCorners,
PrivacyIndicatorBounds privacyIndicatorBounds,
@@ -155,7 +150,7 @@ public final class WindowInsets {
mTypeVisibilityMap = typeVisibilityMap;
mIsRound = isRound;
- mAlwaysConsumeSystemBars = alwaysConsumeSystemBars;
+ mForceConsumingTypes = forceConsumingTypes;
mSuppressScrimTypes = suppressScrimTypes;
mCompatInsetsTypes = compatInsetsTypes;
mCompatIgnoreVisibility = compatIgnoreVisibility;
@@ -178,7 +173,7 @@ public final class WindowInsets {
this(src.mSystemWindowInsetsConsumed ? null : src.mTypeInsetsMap,
src.mStableInsetsConsumed ? null : src.mTypeMaxInsetsMap,
src.mTypeVisibilityMap, src.mIsRound,
- src.mAlwaysConsumeSystemBars, src.mSuppressScrimTypes,
+ src.mForceConsumingTypes, src.mSuppressScrimTypes,
displayCutoutCopyConstructorArgument(src),
src.mRoundedCorners,
src.mPrivacyIndicatorBounds,
@@ -235,7 +230,7 @@ public final class WindowInsets {
/** @hide */
@UnsupportedAppUsage
public WindowInsets(Rect systemWindowInsets) {
- this(createCompatTypeMap(systemWindowInsets), null, new boolean[SIZE], false, false, 0,
+ this(createCompatTypeMap(systemWindowInsets), null, new boolean[SIZE], false, 0, 0,
null, null, null, null, systemBars(), false /* compatIgnoreVisibility */);
}
@@ -556,7 +551,7 @@ public final class WindowInsets {
return new WindowInsets(mSystemWindowInsetsConsumed ? null : mTypeInsetsMap,
mStableInsetsConsumed ? null : mTypeMaxInsetsMap,
mTypeVisibilityMap,
- mIsRound, mAlwaysConsumeSystemBars, mSuppressScrimTypes,
+ mIsRound, mForceConsumingTypes, mSuppressScrimTypes,
null /* displayCutout */, mRoundedCorners, mPrivacyIndicatorBounds, mDisplayShape,
mCompatInsetsTypes, mCompatIgnoreVisibility);
}
@@ -607,7 +602,7 @@ public final class WindowInsets {
public WindowInsets consumeSystemWindowInsets() {
return new WindowInsets(null, null,
mTypeVisibilityMap,
- mIsRound, mAlwaysConsumeSystemBars, mSuppressScrimTypes,
+ mIsRound, mForceConsumingTypes, mSuppressScrimTypes,
// If the system window insets types contain displayCutout, we should also consume
// it.
(mCompatInsetsTypes & displayCutout()) != 0
@@ -895,8 +890,8 @@ public final class WindowInsets {
/**
* @hide
*/
- public boolean shouldAlwaysConsumeSystemBars() {
- return mAlwaysConsumeSystemBars;
+ public @InsetsType int getForceConsumingTypes() {
+ return mForceConsumingTypes;
}
/**
@@ -930,6 +925,8 @@ public final class WindowInsets {
result.append("\n ");
result.append(mDisplayShape != null ? "displayShape=" + mDisplayShape : "");
result.append("\n ");
+ result.append("forceConsumingTypes=" + Type.toString(mForceConsumingTypes));
+ result.append("\n ");
result.append("suppressScrimTypes=" + Type.toString(mSuppressScrimTypes));
result.append("\n ");
result.append("compatInsetsTypes=" + Type.toString(mCompatInsetsTypes));
@@ -1027,7 +1024,7 @@ public final class WindowInsets {
? null
: insetInsets(mTypeMaxInsetsMap, left, top, right, bottom),
mTypeVisibilityMap,
- mIsRound, mAlwaysConsumeSystemBars, mSuppressScrimTypes,
+ mIsRound, mForceConsumingTypes, mSuppressScrimTypes,
mDisplayCutoutConsumed
? null
: mDisplayCutout == null
@@ -1050,7 +1047,7 @@ public final class WindowInsets {
WindowInsets that = (WindowInsets) o;
return mIsRound == that.mIsRound
- && mAlwaysConsumeSystemBars == that.mAlwaysConsumeSystemBars
+ && mForceConsumingTypes == that.mForceConsumingTypes
&& mSuppressScrimTypes == that.mSuppressScrimTypes
&& mSystemWindowInsetsConsumed == that.mSystemWindowInsetsConsumed
&& mStableInsetsConsumed == that.mStableInsetsConsumed
@@ -1068,7 +1065,7 @@ public final class WindowInsets {
public int hashCode() {
return Objects.hash(Arrays.hashCode(mTypeInsetsMap), Arrays.hashCode(mTypeMaxInsetsMap),
Arrays.hashCode(mTypeVisibilityMap), mIsRound, mDisplayCutout, mRoundedCorners,
- mAlwaysConsumeSystemBars, mSuppressScrimTypes, mSystemWindowInsetsConsumed,
+ mForceConsumingTypes, mSuppressScrimTypes, mSystemWindowInsetsConsumed,
mStableInsetsConsumed, mDisplayCutoutConsumed, mPrivacyIndicatorBounds,
mDisplayShape);
}
@@ -1134,7 +1131,7 @@ public final class WindowInsets {
private DisplayShape mDisplayShape = DisplayShape.NONE;
private boolean mIsRound;
- private boolean mAlwaysConsumeSystemBars;
+ private @InsetsType int mForceConsumingTypes;
private @InsetsType int mSuppressScrimTypes;
private PrivacyIndicatorBounds mPrivacyIndicatorBounds = new PrivacyIndicatorBounds();
@@ -1162,7 +1159,7 @@ public final class WindowInsets {
mDisplayCutout = displayCutoutCopyConstructorArgument(insets);
mRoundedCorners = insets.mRoundedCorners;
mIsRound = insets.mIsRound;
- mAlwaysConsumeSystemBars = insets.mAlwaysConsumeSystemBars;
+ mForceConsumingTypes = insets.mForceConsumingTypes;
mSuppressScrimTypes = insets.mSuppressScrimTypes;
mPrivacyIndicatorBounds = insets.mPrivacyIndicatorBounds;
mDisplayShape = insets.mDisplayShape;
@@ -1433,7 +1430,15 @@ public final class WindowInsets {
/** @hide */
@NonNull
public Builder setAlwaysConsumeSystemBars(boolean alwaysConsumeSystemBars) {
- mAlwaysConsumeSystemBars = alwaysConsumeSystemBars;
+ // TODO (b/277891341): Remove this and related usages. This has been replaced by
+ // #setForceConsumingTypes.
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setForceConsumingTypes(@InsetsType int forceConsumingTypes) {
+ mForceConsumingTypes = forceConsumingTypes;
return this;
}
@@ -1453,7 +1458,7 @@ public final class WindowInsets {
public WindowInsets build() {
return new WindowInsets(mSystemInsetsConsumed ? null : mTypeInsetsMap,
mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap,
- mIsRound, mAlwaysConsumeSystemBars, mSuppressScrimTypes, mDisplayCutout,
+ mIsRound, mForceConsumingTypes, mSuppressScrimTypes, mDisplayCutout,
mRoundedCorners, mPrivacyIndicatorBounds, mDisplayShape, systemBars(),
false /* compatIgnoreVisibility */);
}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index af1fdd79169a..bb868018bc95 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -232,7 +232,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
private boolean mLastHasRightStableInset = false;
private boolean mLastHasLeftStableInset = false;
private int mLastWindowFlags = 0;
- private boolean mLastShouldAlwaysConsumeSystemBars = false;
+ private @InsetsType int mLastForceConsumingTypes = 0;
private @InsetsType int mLastSuppressScrimTypes = 0;
private int mRootScrollY = 0;
@@ -1111,19 +1111,19 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
: controller.getSystemBarsAppearance();
if (insets != null) {
- mLastShouldAlwaysConsumeSystemBars = insets.shouldAlwaysConsumeSystemBars();
+ mLastForceConsumingTypes = insets.getForceConsumingTypes();
- final boolean clearsCompatInsets =
- clearsCompatInsets(attrs.type, attrs.flags,
- getResources().getConfiguration().windowConfiguration
- .getWindowingMode())
- && !mLastShouldAlwaysConsumeSystemBars;
+ @InsetsType int compatInsetsTypes =
+ WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout();
+ if (clearsCompatInsets(attrs.type, attrs.flags,
+ getResources().getConfiguration().windowConfiguration.getWindowingMode())) {
+ compatInsetsTypes &= mLastForceConsumingTypes;
+ }
final Insets stableBarInsets = insets.getInsetsIgnoringVisibility(
WindowInsets.Type.systemBars());
- final Insets systemInsets = clearsCompatInsets
+ final Insets systemInsets = compatInsetsTypes == 0
? Insets.NONE
- : Insets.min(insets.getInsets(WindowInsets.Type.systemBars()
- | WindowInsets.Type.displayCutout()), stableBarInsets);
+ : Insets.min(insets.getInsets(compatInsetsTypes), stableBarInsets);
mLastTopInset = systemInsets.top;
mLastBottomInset = systemInsets.bottom;
mLastRightInset = systemInsets.right;
@@ -1208,7 +1208,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
&& (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
&& decorFitsSystemWindows
&& !hideNavigation)
- || (mLastShouldAlwaysConsumeSystemBars && hideNavigation);
+ || ((mLastForceConsumingTypes & WindowInsets.Type.navigationBars()) != 0
+ && hideNavigation);
boolean consumingNavBar =
((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
@@ -1224,13 +1225,15 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
boolean fullscreen = (sysUiVisibility & SYSTEM_UI_FLAG_FULLSCREEN) != 0
|| (attrs.flags & FLAG_FULLSCREEN) != 0
|| (requestedVisibleTypes & WindowInsets.Type.statusBars()) == 0;
- boolean consumingStatusBar = (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0
- && decorFitsSystemWindows
- && (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0
- && (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0
- && mForceWindowDrawsBarBackgrounds
- && mLastTopInset != 0
- || (mLastShouldAlwaysConsumeSystemBars && fullscreen);
+ boolean consumingStatusBar =
+ ((sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0
+ && decorFitsSystemWindows
+ && (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0
+ && (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0
+ && mForceWindowDrawsBarBackgrounds
+ && mLastTopInset != 0)
+ || ((mLastForceConsumingTypes & WindowInsets.Type.statusBars()) != 0
+ && fullscreen);
int consumedTop = consumingStatusBar ? mLastTopInset : 0;
int consumedRight = consumingNavBar ? mLastRightInset : 0;
@@ -1434,9 +1437,9 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
private void updateColorViewInt(final ColorViewState state, int color, int dividerColor,
int size, boolean verticalBar, boolean seascape, int sideMargin, boolean animate,
boolean force, @InsetsType int requestedVisibleTypes) {
+ final @InsetsType int type = state.attributes.insetsType;
state.present = state.attributes.isPresent(
- (requestedVisibleTypes & state.attributes.insetsType) != 0
- || mLastShouldAlwaysConsumeSystemBars,
+ (requestedVisibleTypes & type) != 0 || (mLastForceConsumingTypes & type) != 0,
mWindow.getAttributes().flags, force);
boolean show = state.attributes.isVisible(state.present, color,
mWindow.getAttributes().flags, force);
diff --git a/core/tests/coretests/src/android/view/WindowInsetsTest.java b/core/tests/coretests/src/android/view/WindowInsetsTest.java
index b4ba23c92a22..69abf5f3204f 100644
--- a/core/tests/coretests/src/android/view/WindowInsetsTest.java
+++ b/core/tests/coretests/src/android/view/WindowInsetsTest.java
@@ -40,14 +40,14 @@ public class WindowInsetsTest {
@Test
public void systemWindowInsets_afterConsuming_isConsumed() {
assertTrue(new WindowInsets(WindowInsets.createCompatTypeMap(new Rect(1, 2, 3, 4)), null,
- null, false, false, 0, null, null, null, null,
+ null, false, 0, 0, null, null, null, null,
WindowInsets.Type.systemBars(), false)
.consumeSystemWindowInsets().isConsumed());
}
@Test
public void multiNullConstructor_isConsumed() {
- assertTrue(new WindowInsets(null, null, null, false, false, 0, null, null, null, null,
+ assertTrue(new WindowInsets(null, null, null, false, 0, 0, null, null, null, null,
WindowInsets.Type.systemBars(), false).isConsumed());
}
@@ -63,7 +63,7 @@ public class WindowInsetsTest {
boolean[] visible = new boolean[SIZE];
WindowInsets.assignCompatInsets(maxInsets, new Rect(0, 10, 0, 0));
WindowInsets.assignCompatInsets(insets, new Rect(0, 0, 0, 0));
- WindowInsets windowInsets = new WindowInsets(insets, maxInsets, visible, false, false,
+ WindowInsets windowInsets = new WindowInsets(insets, maxInsets, visible, false, 0,
0, null, null, null, DisplayShape.NONE, systemBars(),
true /* compatIgnoreVisibility */);
assertEquals(Insets.of(0, 10, 0, 0), windowInsets.getSystemWindowInsets());
diff --git a/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java b/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
index a1a4265cd0a5..84dd2740e8b7 100644
--- a/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
@@ -169,7 +169,7 @@ public class ActionBarOverlayLayoutTest {
private WindowInsets insetsWith(Insets content, DisplayCutout cutout) {
return new WindowInsets(WindowInsets.createCompatTypeMap(content.toRect()), null, null,
- false, false, 0, cutout, null, null, null, WindowInsets.Type.systemBars(), false);
+ false, 0, 0, cutout, null, null, null, WindowInsets.Type.systemBars(), false);
}
private ViewGroup createViewGroupWithId(int id) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 12b5f5f774de..bfd2a10a8882 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3701,6 +3701,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mInputMonitor.dump(pw, " ");
pw.println();
mInsetsStateController.dump(prefix, pw);
+ mInsetsPolicy.dump(prefix, pw);
mDwpcHelper.dump(prefix, pw);
pw.println();
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index a02fd11ba832..2717a6a8ab04 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -327,8 +327,6 @@ public class DisplayPolicy {
private WindowState mTopFullscreenOpaqueWindowState;
private boolean mTopIsFullscreen;
private int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED;
- private boolean mForceConsumeSystemBars;
- private boolean mForceShowSystemBars;
/**
* Windows that provides gesture insets. If multiple windows provide gesture insets at the same
@@ -1286,18 +1284,10 @@ public class DisplayPolicy {
return ANIMATION_STYLEABLE;
}
- /**
- * @return true if the system bars are forced to be consumed
- */
+ // TODO (b/277891341): Remove this and related usages. This has been replaced by
+ // InsetsSource#FLAG_FORCE_CONSUMING.
public boolean areSystemBarsForcedConsumedLw() {
- return mForceConsumeSystemBars;
- }
-
- /**
- * @return true if the system bars are forced to stay visible
- */
- public boolean areSystemBarsForcedShownLw() {
- return mForceShowSystemBars;
+ return false;
}
/**
@@ -1694,7 +1684,8 @@ public class DisplayPolicy {
* @return Whether the top fullscreen app hides the given type of system bar.
*/
boolean topAppHidesSystemBar(@InsetsType int type) {
- if (mTopFullscreenOpaqueWindowState == null || mForceShowSystemBars) {
+ if (mTopFullscreenOpaqueWindowState == null
+ || getInsetsPolicy().areTypesForciblyShowing(type)) {
return false;
}
return !mTopFullscreenOpaqueWindowState.isRequestedVisible(type);
@@ -2371,14 +2362,7 @@ public class DisplayPolicy {
final boolean freeformRootTaskVisible =
defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_FREEFORM);
- // We need to force showing system bars when adjacent tasks or freeform roots visible.
- mForceShowSystemBars = adjacentTasksVisible || freeformRootTaskVisible;
- // We need to force the consumption of the system bars if they are force shown or if they
- // are controlled by a remote insets controller.
- mForceConsumeSystemBars = mForceShowSystemBars
- || getInsetsPolicy().remoteInsetsControllerControlsSystemBars(win)
- || getInsetsPolicy().forcesShowingNavigationBars(win);
- mDisplayContent.getInsetsPolicy().updateBarControlTarget(win);
+ getInsetsPolicy().updateSystemBars(win, adjacentTasksVisible, freeformRootTaskVisible);
final boolean topAppHidesStatusBar = topAppHidesSystemBar(Type.statusBars());
if (getStatusBar() != null) {
diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java
index 798dc85ec11b..4620266c981e 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -64,6 +64,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.DisplayThread;
import com.android.server.statusbar.StatusBarManagerInternal;
+import java.io.PrintWriter;
+
/**
* Policy that implements who gets control over the windows generating insets.
*/
@@ -114,6 +116,7 @@ class InsetsPolicy {
private final BarWindow mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR);
private final BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR);
private @InsetsType int mShowingTransientTypes;
+ private @InsetsType int mForcedShowingTypes;
private boolean mAnimatingShown;
private final boolean mHideNavBarForKeyboard;
@@ -127,7 +130,6 @@ class InsetsPolicy {
mHideNavBarForKeyboard = r.getBoolean(R.bool.config_hideNavBarForKeyboard);
}
-
/** Updates the target which can control system bars. */
void updateBarControlTarget(@Nullable WindowState focusedWin) {
if (mFocusedWin != focusedWin) {
@@ -514,7 +516,7 @@ class InsetsPolicy {
component, focusedWin.getRequestedVisibleTypes());
return mDisplayContent.mRemoteInsetsControlTarget;
}
- if (mPolicy.areSystemBarsForcedShownLw()) {
+ if (areTypesForciblyShowing(Type.statusBars())) {
// 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;
@@ -567,13 +569,6 @@ class InsetsPolicy {
return focusedWin;
}
}
- if (forcesShowingNavigationBars(focusedWin)) {
- // When "force show navigation bar" is enabled, it means both force visible is true, and
- // we are in 3-button navigation. In this mode, the navigation bar is forcibly shown
- // when activity type is ACTIVITY_TYPE_STANDARD which means Launcher or Recent could
- // still control the navigation bar in this mode.
- return null;
- }
if (remoteInsetsControllerControlsSystemBars(focusedWin)) {
ComponentName component = focusedWin.mActivityRecord != null
? focusedWin.mActivityRecord.mActivityComponent : null;
@@ -581,7 +576,7 @@ class InsetsPolicy {
component, focusedWin.getRequestedVisibleTypes());
return mDisplayContent.mRemoteInsetsControlTarget;
}
- if (mPolicy.areSystemBarsForcedShownLw()) {
+ if (areTypesForciblyShowing(Type.navigationBars())) {
// 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;
@@ -603,7 +598,32 @@ class InsetsPolicy {
return focusedWin;
}
- boolean forcesShowingNavigationBars(WindowState win) {
+ boolean areTypesForciblyShowing(@InsetsType int types) {
+ return (mForcedShowingTypes & types) == types;
+ }
+
+ void updateSystemBars(WindowState win, boolean inSplitScreenMode, boolean inFreeformMode) {
+ mForcedShowingTypes = (inSplitScreenMode || inFreeformMode)
+ ? (Type.statusBars() | Type.navigationBars())
+ : forceShowingNavigationBars(win)
+ ? Type.navigationBars()
+ : 0;
+
+ // The client app won't be able to control these types of system bars. Here makes the client
+ // forcibly consume these types to prevent the app content from getting obscured.
+ mStateController.setForcedConsumingTypes(
+ mForcedShowingTypes | (remoteInsetsControllerControlsSystemBars(win)
+ ? (Type.statusBars() | Type.navigationBars())
+ : 0));
+
+ updateBarControlTarget(win);
+ }
+
+ private boolean forceShowingNavigationBars(WindowState win) {
+ // When "force show navigation bar" is enabled, it means both force visible is true, and
+ // we are in 3-button navigation. In this mode, the navigation bar is forcibly shown
+ // when activity type is ACTIVITY_TYPE_STANDARD which means Launcher or Recent could
+ // still control the navigation bar in this mode.
return mPolicy.isForceShowNavigationBarEnabled() && win != null
&& win.getActivityType() == ACTIVITY_TYPE_STANDARD;
}
@@ -696,6 +716,21 @@ class InsetsPolicy {
wereRevealedFromSwipeOnSystemBar);
}
+ void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "InsetsPolicy");
+ prefix = prefix + " ";
+ pw.println(prefix + "status: " + StatusBarManager.windowStateToString(mStatusBar.mState));
+ pw.println(prefix + "nav: " + StatusBarManager.windowStateToString(mNavBar.mState));
+ if (mShowingTransientTypes != 0) {
+ pw.println(prefix + "mShowingTransientTypes="
+ + WindowInsets.Type.toString(mShowingTransientTypes));
+ }
+ if (mForcedShowingTypes != 0) {
+ pw.println(prefix + "mForcedShowingTypes="
+ + WindowInsets.Type.toString(mForcedShowingTypes));
+ }
+ }
+
private class BarWindow {
private final int mId;
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index e1c865bb85be..2b8312c3ea60 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -40,6 +40,7 @@ import android.graphics.Rect;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsSource;
+import android.view.InsetsSource.Flags;
import android.view.InsetsSourceControl;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -81,6 +82,8 @@ class InsetsSourceProvider {
private final Rect mSourceFrame = new Rect();
private final Rect mLastSourceFrame = new Rect();
private @NonNull Insets mInsetsHint = Insets.NONE;
+ private @Flags int mFlagsFromFrameProvider;
+ private @Flags int mFlagsFromServer;
private final Consumer<Transaction> mSetLeashPositionConsumer = t -> {
if (mControl != null) {
@@ -189,6 +192,16 @@ class InsetsSourceProvider {
}
}
+ boolean setFlags(@Flags int flags, @Flags int mask) {
+ mFlagsFromServer = (mFlagsFromServer & ~mask) | (flags & mask);
+ final @Flags int mergedFlags = mFlagsFromFrameProvider | mFlagsFromServer;
+ if (mSource.getFlags() != mergedFlags) {
+ mSource.setFlags(mergedFlags);
+ return true;
+ }
+ return false;
+ }
+
/**
* The source frame can affect the layout of other windows, so this should be called once the
* window container gets laid out.
@@ -217,11 +230,11 @@ class InsetsSourceProvider {
mSourceFrame.set(frame);
if (mFrameProvider != null) {
- final int flags = mFrameProvider.apply(
+ mFlagsFromFrameProvider = mFrameProvider.apply(
mWindowContainer.getDisplayContent().mDisplayFrames,
mWindowContainer,
mSourceFrame);
- mSource.setFlags(flags);
+ mSource.setFlags(mFlagsFromFrameProvider | mFlagsFromServer);
}
updateSourceFrameForServerVisibility();
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index addb5219c663..081ebe0e7cbd 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
import static android.view.InsetsSource.ID_IME;
import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime;
@@ -85,6 +86,8 @@ class InsetsStateController {
}
};
+ private @InsetsType int mForcedConsumingTypes;
+
InsetsStateController(DisplayContent displayContent) {
mDisplayContent = displayContent;
}
@@ -122,6 +125,11 @@ class InsetsStateController {
provider = id == ID_IME
? new ImeInsetsSourceProvider(source, this, mDisplayContent)
: new InsetsSourceProvider(source, this, mDisplayContent);
+ provider.setFlags(
+ (mForcedConsumingTypes & type) != 0
+ ? FLAG_FORCE_CONSUMING
+ : 0,
+ FLAG_FORCE_CONSUMING);
mProviders.put(id, provider);
return provider;
}
@@ -137,6 +145,24 @@ class InsetsStateController {
}
}
+ void setForcedConsumingTypes(@InsetsType int types) {
+ if (mForcedConsumingTypes != types) {
+ mForcedConsumingTypes = types;
+ boolean changed = false;
+ for (int i = mProviders.size() - 1; i >= 0; i--) {
+ final InsetsSourceProvider provider = mProviders.valueAt(i);
+ changed |= provider.setFlags(
+ (types & provider.getSource().getType()) != 0
+ ? FLAG_FORCE_CONSUMING
+ : 0,
+ FLAG_FORCE_CONSUMING);
+ }
+ if (changed) {
+ notifyInsetsChanged();
+ }
+ }
+ }
+
/**
* Called when a layout pass has occurred.
*/
@@ -391,6 +417,10 @@ class InsetsStateController {
for (int i = mProviders.size() - 1; i >= 0; i--) {
mProviders.valueAt(i).dump(pw, prefix + " ");
}
+ if (mForcedConsumingTypes != 0) {
+ pw.println(prefix + "mForcedConsumingTypes="
+ + WindowInsets.Type.toString(mForcedConsumingTypes));
+ }
}
void dumpDebug(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) {