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*/,
mLastInsets.isRound(), mLastInsets.shouldAlwaysConsumeSystemBars(),
mLastInsets.isRound(), false /* alwaysConsumeSystemBars */,
mLastLegacySoftInputMode, mLastLegacyWindowFlags, mLastLegacySystemUiFlags,
mWindowType, mLastWindowingMode, null /* idSideMap */);
mHost.dispatchWindowInsetsAnimationProgress(insets,

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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 */);
}

View File

@@ -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);

View File

@@ -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());

View File

@@ -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) {

View File

@@ -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();
}

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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();

View File

@@ -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) {