Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f5355954 authored by Tiger's avatar Tiger
Browse files

Introduce InsetsSource#FLAG_FORCE_CONSUMING

It controls whether the insets provided by the source should be forcibly
consumed.

We have mForceConsumeSystemBars to achieve the similar logic, however,
it cannot control individual types. And when it is changed, there is no
guarantee that the new value will be sent to the clients. This CL fixes
the issues.

After this CL, the legacy "alwaysConsumeSystemBars" will be redundant,
and there will be a follow-up CL to clean it up.

Fix: 277891341
Test: Launch immersive apps in kids space and make sure their content
      wouldn't be obscured by navigation bar.
Change-Id: I1c8b628660d7cde167f5bc832f8cc7568ab87d61
parent 52f45340
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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,
+9 −0
Original line number Diff line number Diff line
@@ -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();
    }

+18 −9
Original line number Diff line number Diff line
@@ -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;
+28 −23
Original line number Diff line number Diff line
@@ -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 */);
        }
+23 −20
Original line number Diff line number Diff line
@@ -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
        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);
                        && 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);
Loading