Merge "Introduce InsetsSource#FLAG_FORCE_CONSUMING" into udc-qpr-dev

This commit is contained in:
Tiger Huang
2023-06-29 06:16:39 +00:00
committed by Android (Google) Code Review
12 changed files with 181 additions and 92 deletions

View File

@@ -797,7 +797,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
} }
WindowInsets insets = state.calculateInsets(mFrame, mState /* ignoringVisibilityState*/, WindowInsets insets = state.calculateInsets(mFrame, mState /* ignoringVisibilityState*/,
mLastInsets.isRound(), mLastInsets.shouldAlwaysConsumeSystemBars(), mLastInsets.isRound(), false /* alwaysConsumeSystemBars */,
mLastLegacySoftInputMode, mLastLegacyWindowFlags, mLastLegacySystemUiFlags, mLastLegacySoftInputMode, mLastLegacyWindowFlags, mLastLegacySystemUiFlags,
mWindowType, mLastWindowingMode, null /* idSideMap */); mWindowType, mLastWindowingMode, null /* idSideMap */);
mHost.dispatchWindowInsetsAnimationProgress(insets, mHost.dispatchWindowInsetsAnimationProgress(insets,

View File

@@ -68,10 +68,16 @@ public class InsetsSource implements Parcelable {
*/ */
public static final int FLAG_INSETS_ROUNDED_CORNER = 1 << 1; 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) @Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, prefix = "FLAG_", value = { @IntDef(flag = true, prefix = "FLAG_", value = {
FLAG_SUPPRESS_SCRIM, FLAG_SUPPRESS_SCRIM,
FLAG_INSETS_ROUNDED_CORNER, FLAG_INSETS_ROUNDED_CORNER,
FLAG_FORCE_CONSUMING,
}) })
public @interface Flags {} public @interface Flags {}
@@ -328,6 +334,9 @@ public class InsetsSource implements Parcelable {
if ((flags & FLAG_INSETS_ROUNDED_CORNER) != 0) { if ((flags & FLAG_INSETS_ROUNDED_CORNER) != 0) {
joiner.add("INSETS_ROUNDED_CORNER"); joiner.add("INSETS_ROUNDED_CORNER");
} }
if ((flags & FLAG_FORCE_CONSUMING) != 0) {
joiner.add("FORCE_CONSUMING");
}
return joiner.toString(); return joiner.toString();
} }

View File

@@ -16,6 +16,7 @@
package android.view; package android.view;
import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER; import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
import static android.view.InsetsStateProto.DISPLAY_CUTOUT; import static android.view.InsetsStateProto.DISPLAY_CUTOUT;
import static android.view.InsetsStateProto.DISPLAY_FRAME; import static android.view.InsetsStateProto.DISPLAY_FRAME;
@@ -144,12 +145,18 @@ public class InsetsState implements Parcelable {
boolean[] typeVisibilityMap = new boolean[Type.SIZE]; boolean[] typeVisibilityMap = new boolean[Type.SIZE];
final Rect relativeFrame = new Rect(frame); final Rect relativeFrame = new Rect(frame);
final Rect relativeFrameMax = new Rect(frame); final Rect relativeFrameMax = new Rect(frame);
@InsetsType int forceConsumingTypes = 0;
@InsetsType int suppressScrimTypes = 0; @InsetsType int suppressScrimTypes = 0;
for (int i = mSources.size() - 1; i >= 0; i--) { for (int i = mSources.size() - 1; i >= 0; i--) {
final InsetsSource source = mSources.valueAt(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) { if ((source.getFlags() & InsetsSource.FLAG_SUPPRESS_SCRIM) != 0) {
suppressScrimTypes |= source.getType(); suppressScrimTypes |= type;
} }
processSource(source, relativeFrame, false /* ignoreVisibility */, typeInsetsMap, 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 // IME won't be reported in max insets as the size depends on the EditorInfo of the IME
// target. // target.
if (source.getType() != WindowInsets.Type.ime()) { if (type != WindowInsets.Type.ime()) {
InsetsSource ignoringVisibilitySource = ignoringVisibilityState != null InsetsSource ignoringVisibilitySource = ignoringVisibilityState != null
? ignoringVisibilityState.peekSource(source.getId()) ? ignoringVisibilityState.peekSource(source.getId())
: source; : source;
@@ -178,13 +185,13 @@ public class InsetsState implements Parcelable {
if ((legacyWindowFlags & FLAG_FULLSCREEN) != 0) { if ((legacyWindowFlags & FLAG_FULLSCREEN) != 0) {
compatInsetsTypes &= ~statusBars(); compatInsetsTypes &= ~statusBars();
} }
if (clearsCompatInsets(windowType, legacyWindowFlags, windowingMode) if (clearsCompatInsets(windowType, legacyWindowFlags, windowingMode)) {
&& !alwaysConsumeSystemBars) { // Clear all types but forceConsumingTypes.
compatInsetsTypes = 0; compatInsetsTypes &= forceConsumingTypes;
} }
return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound, return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound,
alwaysConsumeSystemBars, suppressScrimTypes, calculateRelativeCutout(frame), forceConsumingTypes, suppressScrimTypes, calculateRelativeCutout(frame),
calculateRelativeRoundedCorners(frame), calculateRelativeRoundedCorners(frame),
calculateRelativePrivacyIndicatorBounds(frame), calculateRelativePrivacyIndicatorBounds(frame),
calculateRelativeDisplayShape(frame), calculateRelativeDisplayShape(frame),
@@ -290,9 +297,8 @@ public class InsetsState implements Parcelable {
public Insets calculateVisibleInsets(Rect frame, int windowType, int windowingMode, public Insets calculateVisibleInsets(Rect frame, int windowType, int windowingMode,
@SoftInputModeFlags int softInputMode, int windowFlags) { @SoftInputModeFlags int softInputMode, int windowFlags) {
if (clearsCompatInsets(windowType, windowFlags, windowingMode)) { final boolean clearsCompatInsets = clearsCompatInsets(
return Insets.NONE; windowType, windowFlags, windowingMode);
}
final int softInputAdjustMode = softInputMode & SOFT_INPUT_MASK_ADJUST; final int softInputAdjustMode = softInputMode & SOFT_INPUT_MASK_ADJUST;
final int visibleInsetsTypes = softInputAdjustMode != SOFT_INPUT_ADJUST_NOTHING final int visibleInsetsTypes = softInputAdjustMode != SOFT_INPUT_ADJUST_NOTHING
? systemBars() | ime() ? systemBars() | ime()
@@ -303,6 +309,9 @@ public class InsetsState implements Parcelable {
if ((source.getType() & visibleInsetsTypes) == 0) { if ((source.getType() & visibleInsetsTypes) == 0) {
continue; continue;
} }
if (clearsCompatInsets && !source.hasFlags(FLAG_FORCE_CONSUMING)) {
continue;
}
insets = Insets.max(source.calculateVisibleInsets(frame), insets); insets = Insets.max(source.calculateVisibleInsets(frame), insets);
} }
return insets; return insets;

View File

@@ -84,13 +84,7 @@ public final class WindowInsets {
@Nullable private final PrivacyIndicatorBounds mPrivacyIndicatorBounds; @Nullable private final PrivacyIndicatorBounds mPrivacyIndicatorBounds;
@Nullable private final DisplayShape mDisplayShape; @Nullable private final DisplayShape mDisplayShape;
/** private final @InsetsType int mForceConsumingTypes;
* 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 mSuppressScrimTypes; private final @InsetsType int mSuppressScrimTypes;
private final boolean mSystemWindowInsetsConsumed; private final boolean mSystemWindowInsetsConsumed;
private final boolean mStableInsetsConsumed; private final boolean mStableInsetsConsumed;
@@ -117,7 +111,7 @@ public final class WindowInsets {
static { static {
CONSUMED = new WindowInsets(createCompatTypeMap(null), createCompatTypeMap(null), 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); null, null, null, systemBars(), false);
} }
@@ -137,7 +131,8 @@ public final class WindowInsets {
@Nullable Insets[] typeMaxInsetsMap, @Nullable Insets[] typeMaxInsetsMap,
boolean[] typeVisibilityMap, boolean[] typeVisibilityMap,
boolean isRound, boolean isRound,
boolean alwaysConsumeSystemBars, @InsetsType int suppressScrimTypes, @InsetsType int forceConsumingTypes,
@InsetsType int suppressScrimTypes,
DisplayCutout displayCutout, DisplayCutout displayCutout,
RoundedCorners roundedCorners, RoundedCorners roundedCorners,
PrivacyIndicatorBounds privacyIndicatorBounds, PrivacyIndicatorBounds privacyIndicatorBounds,
@@ -155,7 +150,7 @@ public final class WindowInsets {
mTypeVisibilityMap = typeVisibilityMap; mTypeVisibilityMap = typeVisibilityMap;
mIsRound = isRound; mIsRound = isRound;
mAlwaysConsumeSystemBars = alwaysConsumeSystemBars; mForceConsumingTypes = forceConsumingTypes;
mSuppressScrimTypes = suppressScrimTypes; mSuppressScrimTypes = suppressScrimTypes;
mCompatInsetsTypes = compatInsetsTypes; mCompatInsetsTypes = compatInsetsTypes;
mCompatIgnoreVisibility = compatIgnoreVisibility; mCompatIgnoreVisibility = compatIgnoreVisibility;
@@ -178,7 +173,7 @@ public final class WindowInsets {
this(src.mSystemWindowInsetsConsumed ? null : src.mTypeInsetsMap, this(src.mSystemWindowInsetsConsumed ? null : src.mTypeInsetsMap,
src.mStableInsetsConsumed ? null : src.mTypeMaxInsetsMap, src.mStableInsetsConsumed ? null : src.mTypeMaxInsetsMap,
src.mTypeVisibilityMap, src.mIsRound, src.mTypeVisibilityMap, src.mIsRound,
src.mAlwaysConsumeSystemBars, src.mSuppressScrimTypes, src.mForceConsumingTypes, src.mSuppressScrimTypes,
displayCutoutCopyConstructorArgument(src), displayCutoutCopyConstructorArgument(src),
src.mRoundedCorners, src.mRoundedCorners,
src.mPrivacyIndicatorBounds, src.mPrivacyIndicatorBounds,
@@ -235,7 +230,7 @@ public final class WindowInsets {
/** @hide */ /** @hide */
@UnsupportedAppUsage @UnsupportedAppUsage
public WindowInsets(Rect systemWindowInsets) { 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 */); null, null, null, null, systemBars(), false /* compatIgnoreVisibility */);
} }
@@ -556,7 +551,7 @@ public final class WindowInsets {
return new WindowInsets(mSystemWindowInsetsConsumed ? null : mTypeInsetsMap, return new WindowInsets(mSystemWindowInsetsConsumed ? null : mTypeInsetsMap,
mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mStableInsetsConsumed ? null : mTypeMaxInsetsMap,
mTypeVisibilityMap, mTypeVisibilityMap,
mIsRound, mAlwaysConsumeSystemBars, mSuppressScrimTypes, mIsRound, mForceConsumingTypes, mSuppressScrimTypes,
null /* displayCutout */, mRoundedCorners, mPrivacyIndicatorBounds, mDisplayShape, null /* displayCutout */, mRoundedCorners, mPrivacyIndicatorBounds, mDisplayShape,
mCompatInsetsTypes, mCompatIgnoreVisibility); mCompatInsetsTypes, mCompatIgnoreVisibility);
} }
@@ -607,7 +602,7 @@ public final class WindowInsets {
public WindowInsets consumeSystemWindowInsets() { public WindowInsets consumeSystemWindowInsets() {
return new WindowInsets(null, null, return new WindowInsets(null, null,
mTypeVisibilityMap, mTypeVisibilityMap,
mIsRound, mAlwaysConsumeSystemBars, mSuppressScrimTypes, mIsRound, mForceConsumingTypes, mSuppressScrimTypes,
// If the system window insets types contain displayCutout, we should also consume // If the system window insets types contain displayCutout, we should also consume
// it. // it.
(mCompatInsetsTypes & displayCutout()) != 0 (mCompatInsetsTypes & displayCutout()) != 0
@@ -895,8 +890,8 @@ public final class WindowInsets {
/** /**
* @hide * @hide
*/ */
public boolean shouldAlwaysConsumeSystemBars() { public @InsetsType int getForceConsumingTypes() {
return mAlwaysConsumeSystemBars; return mForceConsumingTypes;
} }
/** /**
@@ -930,6 +925,8 @@ public final class WindowInsets {
result.append("\n "); result.append("\n ");
result.append(mDisplayShape != null ? "displayShape=" + mDisplayShape : ""); result.append(mDisplayShape != null ? "displayShape=" + mDisplayShape : "");
result.append("\n "); result.append("\n ");
result.append("forceConsumingTypes=" + Type.toString(mForceConsumingTypes));
result.append("\n ");
result.append("suppressScrimTypes=" + Type.toString(mSuppressScrimTypes)); result.append("suppressScrimTypes=" + Type.toString(mSuppressScrimTypes));
result.append("\n "); result.append("\n ");
result.append("compatInsetsTypes=" + Type.toString(mCompatInsetsTypes)); result.append("compatInsetsTypes=" + Type.toString(mCompatInsetsTypes));
@@ -1027,7 +1024,7 @@ public final class WindowInsets {
? null ? null
: insetInsets(mTypeMaxInsetsMap, left, top, right, bottom), : insetInsets(mTypeMaxInsetsMap, left, top, right, bottom),
mTypeVisibilityMap, mTypeVisibilityMap,
mIsRound, mAlwaysConsumeSystemBars, mSuppressScrimTypes, mIsRound, mForceConsumingTypes, mSuppressScrimTypes,
mDisplayCutoutConsumed mDisplayCutoutConsumed
? null ? null
: mDisplayCutout == null : mDisplayCutout == null
@@ -1050,7 +1047,7 @@ public final class WindowInsets {
WindowInsets that = (WindowInsets) o; WindowInsets that = (WindowInsets) o;
return mIsRound == that.mIsRound return mIsRound == that.mIsRound
&& mAlwaysConsumeSystemBars == that.mAlwaysConsumeSystemBars && mForceConsumingTypes == that.mForceConsumingTypes
&& mSuppressScrimTypes == that.mSuppressScrimTypes && mSuppressScrimTypes == that.mSuppressScrimTypes
&& mSystemWindowInsetsConsumed == that.mSystemWindowInsetsConsumed && mSystemWindowInsetsConsumed == that.mSystemWindowInsetsConsumed
&& mStableInsetsConsumed == that.mStableInsetsConsumed && mStableInsetsConsumed == that.mStableInsetsConsumed
@@ -1068,7 +1065,7 @@ public final class WindowInsets {
public int hashCode() { public int hashCode() {
return Objects.hash(Arrays.hashCode(mTypeInsetsMap), Arrays.hashCode(mTypeMaxInsetsMap), return Objects.hash(Arrays.hashCode(mTypeInsetsMap), Arrays.hashCode(mTypeMaxInsetsMap),
Arrays.hashCode(mTypeVisibilityMap), mIsRound, mDisplayCutout, mRoundedCorners, Arrays.hashCode(mTypeVisibilityMap), mIsRound, mDisplayCutout, mRoundedCorners,
mAlwaysConsumeSystemBars, mSuppressScrimTypes, mSystemWindowInsetsConsumed, mForceConsumingTypes, mSuppressScrimTypes, mSystemWindowInsetsConsumed,
mStableInsetsConsumed, mDisplayCutoutConsumed, mPrivacyIndicatorBounds, mStableInsetsConsumed, mDisplayCutoutConsumed, mPrivacyIndicatorBounds,
mDisplayShape); mDisplayShape);
} }
@@ -1134,7 +1131,7 @@ public final class WindowInsets {
private DisplayShape mDisplayShape = DisplayShape.NONE; private DisplayShape mDisplayShape = DisplayShape.NONE;
private boolean mIsRound; private boolean mIsRound;
private boolean mAlwaysConsumeSystemBars; private @InsetsType int mForceConsumingTypes;
private @InsetsType int mSuppressScrimTypes; private @InsetsType int mSuppressScrimTypes;
private PrivacyIndicatorBounds mPrivacyIndicatorBounds = new PrivacyIndicatorBounds(); private PrivacyIndicatorBounds mPrivacyIndicatorBounds = new PrivacyIndicatorBounds();
@@ -1162,7 +1159,7 @@ public final class WindowInsets {
mDisplayCutout = displayCutoutCopyConstructorArgument(insets); mDisplayCutout = displayCutoutCopyConstructorArgument(insets);
mRoundedCorners = insets.mRoundedCorners; mRoundedCorners = insets.mRoundedCorners;
mIsRound = insets.mIsRound; mIsRound = insets.mIsRound;
mAlwaysConsumeSystemBars = insets.mAlwaysConsumeSystemBars; mForceConsumingTypes = insets.mForceConsumingTypes;
mSuppressScrimTypes = insets.mSuppressScrimTypes; mSuppressScrimTypes = insets.mSuppressScrimTypes;
mPrivacyIndicatorBounds = insets.mPrivacyIndicatorBounds; mPrivacyIndicatorBounds = insets.mPrivacyIndicatorBounds;
mDisplayShape = insets.mDisplayShape; mDisplayShape = insets.mDisplayShape;
@@ -1433,7 +1430,15 @@ public final class WindowInsets {
/** @hide */ /** @hide */
@NonNull @NonNull
public Builder setAlwaysConsumeSystemBars(boolean alwaysConsumeSystemBars) { 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; return this;
} }
@@ -1453,7 +1458,7 @@ public final class WindowInsets {
public WindowInsets build() { public WindowInsets build() {
return new WindowInsets(mSystemInsetsConsumed ? null : mTypeInsetsMap, return new WindowInsets(mSystemInsetsConsumed ? null : mTypeInsetsMap,
mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap, mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap,
mIsRound, mAlwaysConsumeSystemBars, mSuppressScrimTypes, mDisplayCutout, mIsRound, mForceConsumingTypes, mSuppressScrimTypes, mDisplayCutout,
mRoundedCorners, mPrivacyIndicatorBounds, mDisplayShape, systemBars(), mRoundedCorners, mPrivacyIndicatorBounds, mDisplayShape, systemBars(),
false /* compatIgnoreVisibility */); false /* compatIgnoreVisibility */);
} }

View File

@@ -232,7 +232,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
private boolean mLastHasRightStableInset = false; private boolean mLastHasRightStableInset = false;
private boolean mLastHasLeftStableInset = false; private boolean mLastHasLeftStableInset = false;
private int mLastWindowFlags = 0; private int mLastWindowFlags = 0;
private boolean mLastShouldAlwaysConsumeSystemBars = false; private @InsetsType int mLastForceConsumingTypes = 0;
private @InsetsType int mLastSuppressScrimTypes = 0; private @InsetsType int mLastSuppressScrimTypes = 0;
private int mRootScrollY = 0; private int mRootScrollY = 0;
@@ -1111,19 +1111,19 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
: controller.getSystemBarsAppearance(); : controller.getSystemBarsAppearance();
if (insets != null) { if (insets != null) {
mLastShouldAlwaysConsumeSystemBars = insets.shouldAlwaysConsumeSystemBars(); mLastForceConsumingTypes = insets.getForceConsumingTypes();
final boolean clearsCompatInsets = @InsetsType int compatInsetsTypes =
clearsCompatInsets(attrs.type, attrs.flags, WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout();
getResources().getConfiguration().windowConfiguration if (clearsCompatInsets(attrs.type, attrs.flags,
.getWindowingMode()) getResources().getConfiguration().windowConfiguration.getWindowingMode())) {
&& !mLastShouldAlwaysConsumeSystemBars; compatInsetsTypes &= mLastForceConsumingTypes;
}
final Insets stableBarInsets = insets.getInsetsIgnoringVisibility( final Insets stableBarInsets = insets.getInsetsIgnoringVisibility(
WindowInsets.Type.systemBars()); WindowInsets.Type.systemBars());
final Insets systemInsets = clearsCompatInsets final Insets systemInsets = compatInsetsTypes == 0
? Insets.NONE ? Insets.NONE
: Insets.min(insets.getInsets(WindowInsets.Type.systemBars() : Insets.min(insets.getInsets(compatInsetsTypes), stableBarInsets);
| WindowInsets.Type.displayCutout()), stableBarInsets);
mLastTopInset = systemInsets.top; mLastTopInset = systemInsets.top;
mLastBottomInset = systemInsets.bottom; mLastBottomInset = systemInsets.bottom;
mLastRightInset = systemInsets.right; mLastRightInset = systemInsets.right;
@@ -1208,7 +1208,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
&& (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0 && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
&& decorFitsSystemWindows && decorFitsSystemWindows
&& !hideNavigation) && !hideNavigation)
|| (mLastShouldAlwaysConsumeSystemBars && hideNavigation); || ((mLastForceConsumingTypes & WindowInsets.Type.navigationBars()) != 0
&& hideNavigation);
boolean consumingNavBar = boolean consumingNavBar =
((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 ((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 boolean fullscreen = (sysUiVisibility & SYSTEM_UI_FLAG_FULLSCREEN) != 0
|| (attrs.flags & FLAG_FULLSCREEN) != 0 || (attrs.flags & FLAG_FULLSCREEN) != 0
|| (requestedVisibleTypes & WindowInsets.Type.statusBars()) == 0; || (requestedVisibleTypes & WindowInsets.Type.statusBars()) == 0;
boolean consumingStatusBar = (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0 boolean consumingStatusBar =
((sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0
&& decorFitsSystemWindows && decorFitsSystemWindows
&& (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0 && (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0
&& (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0 && (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0
&& mForceWindowDrawsBarBackgrounds && mForceWindowDrawsBarBackgrounds
&& mLastTopInset != 0 && mLastTopInset != 0)
|| (mLastShouldAlwaysConsumeSystemBars && fullscreen); || ((mLastForceConsumingTypes & WindowInsets.Type.statusBars()) != 0
&& fullscreen);
int consumedTop = consumingStatusBar ? mLastTopInset : 0; int consumedTop = consumingStatusBar ? mLastTopInset : 0;
int consumedRight = consumingNavBar ? mLastRightInset : 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, private void updateColorViewInt(final ColorViewState state, int color, int dividerColor,
int size, boolean verticalBar, boolean seascape, int sideMargin, boolean animate, int size, boolean verticalBar, boolean seascape, int sideMargin, boolean animate,
boolean force, @InsetsType int requestedVisibleTypes) { boolean force, @InsetsType int requestedVisibleTypes) {
final @InsetsType int type = state.attributes.insetsType;
state.present = state.attributes.isPresent( state.present = state.attributes.isPresent(
(requestedVisibleTypes & state.attributes.insetsType) != 0 (requestedVisibleTypes & type) != 0 || (mLastForceConsumingTypes & type) != 0,
|| mLastShouldAlwaysConsumeSystemBars,
mWindow.getAttributes().flags, force); mWindow.getAttributes().flags, force);
boolean show = state.attributes.isVisible(state.present, color, boolean show = state.attributes.isVisible(state.present, color,
mWindow.getAttributes().flags, force); mWindow.getAttributes().flags, force);

View File

@@ -40,14 +40,14 @@ public class WindowInsetsTest {
@Test @Test
public void systemWindowInsets_afterConsuming_isConsumed() { public void systemWindowInsets_afterConsuming_isConsumed() {
assertTrue(new WindowInsets(WindowInsets.createCompatTypeMap(new Rect(1, 2, 3, 4)), null, 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) WindowInsets.Type.systemBars(), false)
.consumeSystemWindowInsets().isConsumed()); .consumeSystemWindowInsets().isConsumed());
} }
@Test @Test
public void multiNullConstructor_isConsumed() { 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()); WindowInsets.Type.systemBars(), false).isConsumed());
} }
@@ -63,7 +63,7 @@ public class WindowInsetsTest {
boolean[] visible = new boolean[SIZE]; boolean[] visible = new boolean[SIZE];
WindowInsets.assignCompatInsets(maxInsets, new Rect(0, 10, 0, 0)); WindowInsets.assignCompatInsets(maxInsets, new Rect(0, 10, 0, 0));
WindowInsets.assignCompatInsets(insets, new Rect(0, 0, 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(), 0, null, null, null, DisplayShape.NONE, systemBars(),
true /* compatIgnoreVisibility */); true /* compatIgnoreVisibility */);
assertEquals(Insets.of(0, 10, 0, 0), windowInsets.getSystemWindowInsets()); assertEquals(Insets.of(0, 10, 0, 0), windowInsets.getSystemWindowInsets());

View File

@@ -169,7 +169,7 @@ public class ActionBarOverlayLayoutTest {
private WindowInsets insetsWith(Insets content, DisplayCutout cutout) { private WindowInsets insetsWith(Insets content, DisplayCutout cutout) {
return new WindowInsets(WindowInsets.createCompatTypeMap(content.toRect()), null, null, 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) { private ViewGroup createViewGroupWithId(int id) {

View File

@@ -3701,6 +3701,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mInputMonitor.dump(pw, " "); mInputMonitor.dump(pw, " ");
pw.println(); pw.println();
mInsetsStateController.dump(prefix, pw); mInsetsStateController.dump(prefix, pw);
mInsetsPolicy.dump(prefix, pw);
mDwpcHelper.dump(prefix, pw); mDwpcHelper.dump(prefix, pw);
pw.println(); pw.println();
} }

View File

@@ -327,8 +327,6 @@ public class DisplayPolicy {
private WindowState mTopFullscreenOpaqueWindowState; private WindowState mTopFullscreenOpaqueWindowState;
private boolean mTopIsFullscreen; private boolean mTopIsFullscreen;
private int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED; 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 * 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 ANIMATION_STYLEABLE;
} }
/** // TODO (b/277891341): Remove this and related usages. This has been replaced by
* @return true if the system bars are forced to be consumed // InsetsSource#FLAG_FORCE_CONSUMING.
*/
public boolean areSystemBarsForcedConsumedLw() { public boolean areSystemBarsForcedConsumedLw() {
return mForceConsumeSystemBars; return false;
}
/**
* @return true if the system bars are forced to stay visible
*/
public boolean areSystemBarsForcedShownLw() {
return mForceShowSystemBars;
} }
/** /**
@@ -1694,7 +1684,8 @@ public class DisplayPolicy {
* @return Whether the top fullscreen app hides the given type of system bar. * @return Whether the top fullscreen app hides the given type of system bar.
*/ */
boolean topAppHidesSystemBar(@InsetsType int type) { boolean topAppHidesSystemBar(@InsetsType int type) {
if (mTopFullscreenOpaqueWindowState == null || mForceShowSystemBars) { if (mTopFullscreenOpaqueWindowState == null
|| getInsetsPolicy().areTypesForciblyShowing(type)) {
return false; return false;
} }
return !mTopFullscreenOpaqueWindowState.isRequestedVisible(type); return !mTopFullscreenOpaqueWindowState.isRequestedVisible(type);
@@ -2371,14 +2362,7 @@ public class DisplayPolicy {
final boolean freeformRootTaskVisible = final boolean freeformRootTaskVisible =
defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_FREEFORM); defaultTaskDisplayArea.isRootTaskVisible(WINDOWING_MODE_FREEFORM);
// We need to force showing system bars when adjacent tasks or freeform roots visible. getInsetsPolicy().updateSystemBars(win, adjacentTasksVisible, freeformRootTaskVisible);
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);
final boolean topAppHidesStatusBar = topAppHidesSystemBar(Type.statusBars()); final boolean topAppHidesStatusBar = topAppHidesSystemBar(Type.statusBars());
if (getStatusBar() != null) { if (getStatusBar() != null) {

View File

@@ -64,6 +64,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.DisplayThread; import com.android.server.DisplayThread;
import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.statusbar.StatusBarManagerInternal;
import java.io.PrintWriter;
/** /**
* Policy that implements who gets control over the windows generating insets. * 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 mStatusBar = new BarWindow(StatusBarManager.WINDOW_STATUS_BAR);
private final BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR); private final BarWindow mNavBar = new BarWindow(StatusBarManager.WINDOW_NAVIGATION_BAR);
private @InsetsType int mShowingTransientTypes; private @InsetsType int mShowingTransientTypes;
private @InsetsType int mForcedShowingTypes;
private boolean mAnimatingShown; private boolean mAnimatingShown;
private final boolean mHideNavBarForKeyboard; private final boolean mHideNavBarForKeyboard;
@@ -127,7 +130,6 @@ class InsetsPolicy {
mHideNavBarForKeyboard = r.getBoolean(R.bool.config_hideNavBarForKeyboard); mHideNavBarForKeyboard = r.getBoolean(R.bool.config_hideNavBarForKeyboard);
} }
/** Updates the target which can control system bars. */ /** Updates the target which can control system bars. */
void updateBarControlTarget(@Nullable WindowState focusedWin) { void updateBarControlTarget(@Nullable WindowState focusedWin) {
if (mFocusedWin != focusedWin) { if (mFocusedWin != focusedWin) {
@@ -514,7 +516,7 @@ class InsetsPolicy {
component, focusedWin.getRequestedVisibleTypes()); component, focusedWin.getRequestedVisibleTypes());
return mDisplayContent.mRemoteInsetsControlTarget; 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 // 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. // we will dispatch the real visibility of status bar to the client.
return null; return null;
@@ -567,13 +569,6 @@ class InsetsPolicy {
return focusedWin; 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)) { if (remoteInsetsControllerControlsSystemBars(focusedWin)) {
ComponentName component = focusedWin.mActivityRecord != null ComponentName component = focusedWin.mActivityRecord != null
? focusedWin.mActivityRecord.mActivityComponent : null; ? focusedWin.mActivityRecord.mActivityComponent : null;
@@ -581,7 +576,7 @@ class InsetsPolicy {
component, focusedWin.getRequestedVisibleTypes()); component, focusedWin.getRequestedVisibleTypes());
return mDisplayContent.mRemoteInsetsControlTarget; 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 // 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. // bar, and we will dispatch the real visibility of navigation bar to the client.
return null; return null;
@@ -603,7 +598,32 @@ class InsetsPolicy {
return focusedWin; 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 return mPolicy.isForceShowNavigationBarEnabled() && win != null
&& win.getActivityType() == ACTIVITY_TYPE_STANDARD; && win.getActivityType() == ACTIVITY_TYPE_STANDARD;
} }
@@ -696,6 +716,21 @@ class InsetsPolicy {
wereRevealedFromSwipeOnSystemBar); 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 class BarWindow {
private final int mId; private final int mId;

View File

@@ -40,6 +40,7 @@ import android.graphics.Rect;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream;
import android.view.InsetsSource; import android.view.InsetsSource;
import android.view.InsetsSource.Flags;
import android.view.InsetsSourceControl; import android.view.InsetsSourceControl;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction; import android.view.SurfaceControl.Transaction;
@@ -81,6 +82,8 @@ class InsetsSourceProvider {
private final Rect mSourceFrame = new Rect(); private final Rect mSourceFrame = new Rect();
private final Rect mLastSourceFrame = new Rect(); private final Rect mLastSourceFrame = new Rect();
private @NonNull Insets mInsetsHint = Insets.NONE; private @NonNull Insets mInsetsHint = Insets.NONE;
private @Flags int mFlagsFromFrameProvider;
private @Flags int mFlagsFromServer;
private final Consumer<Transaction> mSetLeashPositionConsumer = t -> { private final Consumer<Transaction> mSetLeashPositionConsumer = t -> {
if (mControl != null) { 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 * The source frame can affect the layout of other windows, so this should be called once the
* window container gets laid out. * window container gets laid out.
@@ -217,11 +230,11 @@ class InsetsSourceProvider {
mSourceFrame.set(frame); mSourceFrame.set(frame);
if (mFrameProvider != null) { if (mFrameProvider != null) {
final int flags = mFrameProvider.apply( mFlagsFromFrameProvider = mFrameProvider.apply(
mWindowContainer.getDisplayContent().mDisplayFrames, mWindowContainer.getDisplayContent().mDisplayFrames,
mWindowContainer, mWindowContainer,
mSourceFrame); mSourceFrame);
mSource.setFlags(flags); mSource.setFlags(mFlagsFromFrameProvider | mFlagsFromServer);
} }
updateSourceFrameForServerVisibility(); updateSourceFrameForServerVisibility();

View File

@@ -17,6 +17,7 @@
package com.android.server.wm; package com.android.server.wm;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; 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.InsetsSource.ID_IME;
import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime; import static android.view.WindowInsets.Type.ime;
@@ -85,6 +86,8 @@ class InsetsStateController {
} }
}; };
private @InsetsType int mForcedConsumingTypes;
InsetsStateController(DisplayContent displayContent) { InsetsStateController(DisplayContent displayContent) {
mDisplayContent = displayContent; mDisplayContent = displayContent;
} }
@@ -122,6 +125,11 @@ class InsetsStateController {
provider = id == ID_IME provider = id == ID_IME
? new ImeInsetsSourceProvider(source, this, mDisplayContent) ? new ImeInsetsSourceProvider(source, this, mDisplayContent)
: new InsetsSourceProvider(source, this, mDisplayContent); : new InsetsSourceProvider(source, this, mDisplayContent);
provider.setFlags(
(mForcedConsumingTypes & type) != 0
? FLAG_FORCE_CONSUMING
: 0,
FLAG_FORCE_CONSUMING);
mProviders.put(id, provider); mProviders.put(id, provider);
return 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. * Called when a layout pass has occurred.
*/ */
@@ -391,6 +417,10 @@ class InsetsStateController {
for (int i = mProviders.size() - 1; i >= 0; i--) { for (int i = mProviders.size() - 1; i >= 0; i--) {
mProviders.valueAt(i).dump(pw, prefix + " "); mProviders.valueAt(i).dump(pw, prefix + " ");
} }
if (mForcedConsumingTypes != 0) {
pw.println(prefix + "mForcedConsumingTypes="
+ WindowInsets.Type.toString(mForcedConsumingTypes));
}
} }
void dumpDebug(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) { void dumpDebug(ProtoOutputStream proto, @WindowTraceLogLevel int logLevel) {