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

Commit e2ee483b authored by Jorge Gil's avatar Jorge Gil
Browse files

Add WindowInsets#getBoundingRects APIs

Adds:
1) getBoundingRects(): to obtain the rectangles within Insets that are
partially or fully obscuring the window
2) getFrame(): to query the size of the window during WindowInsets
updates
3) WCT#addInsetsSource w/boundingRects param: for sources (e.g. WM
Shell's caption bar) to specify the bounding rects.

Bug: 316387515
Flag: ACONFIG android.view.flags.customizable_window_headers DEVELOPMENT
Test: atest InsetsSourceTest WindowInsetsTest InsetsStateTest
WindowDecorationTests WindowOrganizerTests

Change-Id: If044d67e0614b9ca336169487b54b04004394066
parent 3feb8b66
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -53609,8 +53609,11 @@ package android.view {
    method @Deprecated @NonNull public android.view.WindowInsets consumeDisplayCutout();
    method @Deprecated @NonNull public android.view.WindowInsets consumeDisplayCutout();
    method @Deprecated @NonNull public android.view.WindowInsets consumeStableInsets();
    method @Deprecated @NonNull public android.view.WindowInsets consumeStableInsets();
    method @Deprecated @NonNull public android.view.WindowInsets consumeSystemWindowInsets();
    method @Deprecated @NonNull public android.view.WindowInsets consumeSystemWindowInsets();
    method @FlaggedApi("android.view.flags.customizable_window_headers") @NonNull public java.util.List<android.graphics.Rect> getBoundingRects(int);
    method @FlaggedApi("android.view.flags.customizable_window_headers") @NonNull public java.util.List<android.graphics.Rect> getBoundingRectsIgnoringVisibility(int);
    method @Nullable public android.view.DisplayCutout getDisplayCutout();
    method @Nullable public android.view.DisplayCutout getDisplayCutout();
    method @Nullable public android.view.DisplayShape getDisplayShape();
    method @Nullable public android.view.DisplayShape getDisplayShape();
    method @FlaggedApi("android.view.flags.customizable_window_headers") @NonNull public android.util.Size getFrame();
    method @NonNull public android.graphics.Insets getInsets(int);
    method @NonNull public android.graphics.Insets getInsets(int);
    method @NonNull public android.graphics.Insets getInsetsIgnoringVisibility(int);
    method @NonNull public android.graphics.Insets getInsetsIgnoringVisibility(int);
    method @Deprecated @NonNull public android.graphics.Insets getMandatorySystemGestureInsets();
    method @Deprecated @NonNull public android.graphics.Insets getMandatorySystemGestureInsets();
@@ -53645,8 +53648,11 @@ package android.view {
    ctor public WindowInsets.Builder();
    ctor public WindowInsets.Builder();
    ctor public WindowInsets.Builder(@NonNull android.view.WindowInsets);
    ctor public WindowInsets.Builder(@NonNull android.view.WindowInsets);
    method @NonNull public android.view.WindowInsets build();
    method @NonNull public android.view.WindowInsets build();
    method @FlaggedApi("android.view.flags.customizable_window_headers") @NonNull public android.view.WindowInsets.Builder setBoundingRects(int, @NonNull java.util.List<android.graphics.Rect>);
    method @FlaggedApi("android.view.flags.customizable_window_headers") @NonNull public android.view.WindowInsets.Builder setBoundingRectsIgnoringVisibility(int, @NonNull java.util.List<android.graphics.Rect>);
    method @NonNull public android.view.WindowInsets.Builder setDisplayCutout(@Nullable android.view.DisplayCutout);
    method @NonNull public android.view.WindowInsets.Builder setDisplayCutout(@Nullable android.view.DisplayCutout);
    method @NonNull public android.view.WindowInsets.Builder setDisplayShape(@NonNull android.view.DisplayShape);
    method @NonNull public android.view.WindowInsets.Builder setDisplayShape(@NonNull android.view.DisplayShape);
    method @FlaggedApi("android.view.flags.customizable_window_headers") @NonNull public android.view.WindowInsets.Builder setFrame(int, int);
    method @NonNull public android.view.WindowInsets.Builder setInsets(int, @NonNull android.graphics.Insets);
    method @NonNull public android.view.WindowInsets.Builder setInsets(int, @NonNull android.graphics.Insets);
    method @NonNull public android.view.WindowInsets.Builder setInsetsIgnoringVisibility(int, @NonNull android.graphics.Insets) throws java.lang.IllegalArgumentException;
    method @NonNull public android.view.WindowInsets.Builder setInsetsIgnoringVisibility(int, @NonNull android.graphics.Insets) throws java.lang.IllegalArgumentException;
    method @Deprecated @NonNull public android.view.WindowInsets.Builder setMandatorySystemGestureInsets(@NonNull android.graphics.Insets);
    method @Deprecated @NonNull public android.view.WindowInsets.Builder setMandatorySystemGestureInsets(@NonNull android.graphics.Insets);
+31 −2
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package android.view;


import android.annotation.IntRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.IBinder;
@@ -109,6 +110,12 @@ public class InsetsFrameProvider implements Parcelable {
     */
     */
    private Insets mMinimalInsetsSizeInDisplayCutoutSafe = null;
    private Insets mMinimalInsetsSizeInDisplayCutoutSafe = null;


    /**
     * Indicates the bounding rectangles within the provided insets frame, in relative coordinates
     * to the source frame.
     */
    private Rect[] mBoundingRects = null;

    /**
    /**
     * Creates an InsetsFrameProvider which describes what frame an insets source should have.
     * Creates an InsetsFrameProvider which describes what frame an insets source should have.
     *
     *
@@ -205,6 +212,22 @@ public class InsetsFrameProvider implements Parcelable {
        return mMinimalInsetsSizeInDisplayCutoutSafe;
        return mMinimalInsetsSizeInDisplayCutoutSafe;
    }
    }


    /**
     * Sets the bounding rectangles within and relative to the source frame.
     */
    public InsetsFrameProvider setBoundingRects(@Nullable Rect[] boundingRects) {
        mBoundingRects = boundingRects == null ? null : boundingRects.clone();
        return this;
    }

    /**
     * Returns the arbitrary bounding rects, or null if none were set.
     */
    @Nullable
    public Rect[] getBoundingRects() {
        return mBoundingRects;
    }

    @Override
    @Override
    public int describeContents() {
    public int describeContents() {
        return 0;
        return 0;
@@ -231,6 +254,9 @@ public class InsetsFrameProvider implements Parcelable {
            sb.append(", mMinimalInsetsSizeInDisplayCutoutSafe=")
            sb.append(", mMinimalInsetsSizeInDisplayCutoutSafe=")
                    .append(mMinimalInsetsSizeInDisplayCutoutSafe);
                    .append(mMinimalInsetsSizeInDisplayCutoutSafe);
        }
        }
        if (mBoundingRects != null) {
            sb.append(", mBoundingRects=").append(Arrays.toString(mBoundingRects));
        }
        sb.append("}");
        sb.append("}");
        return sb.toString();
        return sb.toString();
    }
    }
@@ -257,6 +283,7 @@ public class InsetsFrameProvider implements Parcelable {
        mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR);
        mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR);
        mArbitraryRectangle = in.readTypedObject(Rect.CREATOR);
        mArbitraryRectangle = in.readTypedObject(Rect.CREATOR);
        mMinimalInsetsSizeInDisplayCutoutSafe = in.readTypedObject(Insets.CREATOR);
        mMinimalInsetsSizeInDisplayCutoutSafe = in.readTypedObject(Insets.CREATOR);
        mBoundingRects = in.createTypedArray(Rect.CREATOR);
    }
    }


    @Override
    @Override
@@ -268,6 +295,7 @@ public class InsetsFrameProvider implements Parcelable {
        out.writeTypedArray(mInsetsSizeOverrides, flags);
        out.writeTypedArray(mInsetsSizeOverrides, flags);
        out.writeTypedObject(mArbitraryRectangle, flags);
        out.writeTypedObject(mArbitraryRectangle, flags);
        out.writeTypedObject(mMinimalInsetsSizeInDisplayCutoutSafe, flags);
        out.writeTypedObject(mMinimalInsetsSizeInDisplayCutoutSafe, flags);
        out.writeTypedArray(mBoundingRects, flags);
    }
    }


    public boolean idEquals(InsetsFrameProvider o) {
    public boolean idEquals(InsetsFrameProvider o) {
@@ -288,14 +316,15 @@ public class InsetsFrameProvider implements Parcelable {
                && Arrays.equals(mInsetsSizeOverrides, other.mInsetsSizeOverrides)
                && Arrays.equals(mInsetsSizeOverrides, other.mInsetsSizeOverrides)
                && Objects.equals(mArbitraryRectangle, other.mArbitraryRectangle)
                && Objects.equals(mArbitraryRectangle, other.mArbitraryRectangle)
                && Objects.equals(mMinimalInsetsSizeInDisplayCutoutSafe,
                && Objects.equals(mMinimalInsetsSizeInDisplayCutoutSafe,
                        other.mMinimalInsetsSizeInDisplayCutoutSafe);
                        other.mMinimalInsetsSizeInDisplayCutoutSafe)
                && Arrays.equals(mBoundingRects, other.mBoundingRects);
    }
    }


    @Override
    @Override
    public int hashCode() {
    public int hashCode() {
        return Objects.hash(mId, mSource, mFlags, mInsetsSize,
        return Objects.hash(mId, mSource, mFlags, mInsetsSize,
                Arrays.hashCode(mInsetsSizeOverrides), mArbitraryRectangle,
                Arrays.hashCode(mInsetsSizeOverrides), mArbitraryRectangle,
                mMinimalInsetsSizeInDisplayCutoutSafe);
                mMinimalInsetsSizeInDisplayCutoutSafe, Arrays.hashCode(mBoundingRects));
    }
    }


    public static final @NonNull Parcelable.Creator<InsetsFrameProvider> CREATOR =
    public static final @NonNull Parcelable.Creator<InsetsFrameProvider> CREATOR =
+116 −2
Original line number Original line Diff line number Diff line
@@ -38,6 +38,8 @@ import android.view.WindowInsets.Type.InsetsType;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Objects;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.StringJoiner;


@@ -105,6 +107,12 @@ public class InsetsSource implements Parcelable {
    })
    })
    public @interface Flags {}
    public @interface Flags {}


    /**
     * Used when there are no bounding rects to describe an inset, which is only possible when the
     * insets itself is {@link Insets#NONE}.
     */
    private static final Rect[] NO_BOUNDING_RECTS = new Rect[0];

    private @Flags int mFlags;
    private @Flags int mFlags;


    /**
    /**
@@ -117,6 +125,7 @@ public class InsetsSource implements Parcelable {
    /** Frame of the source in screen coordinate space */
    /** Frame of the source in screen coordinate space */
    private final Rect mFrame;
    private final Rect mFrame;
    private @Nullable Rect mVisibleFrame;
    private @Nullable Rect mVisibleFrame;
    private @Nullable Rect[] mBoundingRects;


    private boolean mVisible;
    private boolean mVisible;


@@ -127,6 +136,7 @@ public class InsetsSource implements Parcelable {
    private @InternalInsetsSide int mSideHint = SIDE_NONE;
    private @InternalInsetsSide int mSideHint = SIDE_NONE;


    private final Rect mTmpFrame = new Rect();
    private final Rect mTmpFrame = new Rect();
    private final Rect mTmpBoundingRect = new Rect();


    public InsetsSource(int id, @InsetsType int type) {
    public InsetsSource(int id, @InsetsType int type) {
        mId = id;
        mId = id;
@@ -145,6 +155,9 @@ public class InsetsSource implements Parcelable {
                : null;
                : null;
        mFlags = other.mFlags;
        mFlags = other.mFlags;
        mSideHint = other.mSideHint;
        mSideHint = other.mSideHint;
        mBoundingRects = other.mBoundingRects != null
                ? other.mBoundingRects.clone()
                : null;
    }
    }


    public void set(InsetsSource other) {
    public void set(InsetsSource other) {
@@ -155,6 +168,9 @@ public class InsetsSource implements Parcelable {
                : null;
                : null;
        mFlags = other.mFlags;
        mFlags = other.mFlags;
        mSideHint = other.mSideHint;
        mSideHint = other.mSideHint;
        mBoundingRects = other.mBoundingRects != null
                ? other.mBoundingRects.clone()
                : null;
    }
    }


    public InsetsSource setFrame(int left, int top, int right, int bottom) {
    public InsetsSource setFrame(int left, int top, int right, int bottom) {
@@ -199,6 +215,15 @@ public class InsetsSource implements Parcelable {
        return this;
        return this;
    }
    }


    /**
     * Set the bounding rectangles of this source. They are expected to be relative to the source
     * frame.
     */
    public InsetsSource setBoundingRects(@Nullable Rect[] rects) {
        mBoundingRects = rects != null ? rects.clone() : null;
        return this;
    }

    public int getId() {
    public int getId() {
        return mId;
        return mId;
    }
    }
@@ -227,6 +252,13 @@ public class InsetsSource implements Parcelable {
        return (mFlags & flags) == flags;
        return (mFlags & flags) == flags;
    }
    }


    /**
     * Returns the bounding rectangles of this source.
     */
    public @Nullable Rect[] getBoundingRects() {
        return mBoundingRects;
    }

    /**
    /**
     * Calculates the insets this source will cause to a client window.
     * Calculates the insets this source will cause to a client window.
     *
     *
@@ -312,6 +344,82 @@ public class InsetsSource implements Parcelable {
        return Insets.NONE;
        return Insets.NONE;
    }
    }


    /**
     * Calculates the bounding rects the source will cause to a client window.
     */
    public @NonNull Rect[] calculateBoundingRects(Rect relativeFrame, boolean ignoreVisibility) {
        if (!ignoreVisibility && !mVisible) {
            return NO_BOUNDING_RECTS;
        }

        final Rect frame = getFrame();
        if (mBoundingRects == null) {
            // No bounding rects set, make a single bounding rect that covers the intersection of
            // the |frame| and the |relativeFrame|.
            return mTmpBoundingRect.setIntersect(frame, relativeFrame)
                    ? new Rect[]{ new Rect(mTmpBoundingRect) }
                    : NO_BOUNDING_RECTS;

        }

        // Special treatment for captionBar inset type. During drag-resizing, the |frame| and
        // |boundingRects| may not get updated as quickly as |relativeFrame|, so just assume the
        // |frame| will always be either at the top or bottom of |relativeFrame|. This means some
        // calculations to make |boundingRects| relative to |relativeFrame| can be skipped or
        // simplified.
        // TODO(b/254128050): remove special treatment.
        if (getType() == WindowInsets.Type.captionBar()) {
            final ArrayList<Rect> validBoundingRects = new ArrayList<>();
            for (final Rect boundingRect : mBoundingRects) {
                // Assume that the caption |frame| and |relativeFrame| perfectly align at the top
                // or bottom, meaning that the provided |boundingRect|, which is relative to the
                // |frame| either is already relative to |relativeFrame| (for top captionBar()), or
                // just needs to be made relative to |relativeFrame| for bottom bars.
                final int frameHeight = frame.height();
                mTmpBoundingRect.set(boundingRect);
                if (getId() == ID_IME_CAPTION_BAR) {
                    mTmpBoundingRect.offset(0, relativeFrame.height() - frameHeight);
                }
                validBoundingRects.add(new Rect(mTmpBoundingRect));
            }
            return validBoundingRects.toArray(new Rect[validBoundingRects.size()]);
        }

        // Regular treatment for non-captionBar inset types.
        final ArrayList<Rect> validBoundingRects = new ArrayList<>();
        for (final Rect boundingRect : mBoundingRects) {
            // |boundingRect| was provided relative to |frame|. Make it absolute to be in the same
            // coordinate system as |frame|.
            final Rect absBoundingRect = new Rect(
                    boundingRect.left + frame.left,
                    boundingRect.top + frame.top,
                    boundingRect.right + frame.left,
                    boundingRect.bottom + frame.top
            );
            // Now find the intersection of that |absBoundingRect| with |relativeFrame|. In other
            // words, whichever part of the bounding rect is inside the window frame.
            if (!mTmpBoundingRect.setIntersect(absBoundingRect, relativeFrame)) {
                // It's possible for this to be empty if the frame and bounding rects were larger
                // than the |relativeFrame|, such as when a system window is wider than the app
                // window width. Just ignore that rect since it will have no effect on the
                // window insets.
                continue;
            }
            // At this point, |mTmpBoundingRect| is a valid bounding rect located fully inside the
            // window, convert it to be relative to the window so that apps don't need to know the
            // location of the window to understand bounding rects.
            validBoundingRects.add(new Rect(
                    mTmpBoundingRect.left - relativeFrame.left,
                    mTmpBoundingRect.top - relativeFrame.top,
                    mTmpBoundingRect.right - relativeFrame.left,
                    mTmpBoundingRect.bottom - relativeFrame.top));
        }
        if (validBoundingRects.isEmpty()) {
            return NO_BOUNDING_RECTS;
        }
        return validBoundingRects.toArray(new Rect[validBoundingRects.size()]);
    }

    /**
    /**
     * Outputs the intersection of two rectangles. The shared edges will also be counted in the
     * Outputs the intersection of two rectangles. The shared edges will also be counted in the
     * intersection.
     * intersection.
@@ -467,6 +575,7 @@ public class InsetsSource implements Parcelable {
        pw.print(" visible="); pw.print(mVisible);
        pw.print(" visible="); pw.print(mVisible);
        pw.print(" flags="); pw.print(flagsToString(mFlags));
        pw.print(" flags="); pw.print(flagsToString(mFlags));
        pw.print(" sideHint="); pw.print(sideToString(mSideHint));
        pw.print(" sideHint="); pw.print(sideToString(mSideHint));
        pw.print(" boundingRects="); pw.print(Arrays.toString(mBoundingRects));
        pw.println();
        pw.println();
    }
    }


@@ -492,12 +601,14 @@ public class InsetsSource implements Parcelable {
        if (mSideHint != that.mSideHint) return false;
        if (mSideHint != that.mSideHint) return false;
        if (excludeInvisibleImeFrames && !mVisible && mType == WindowInsets.Type.ime()) return true;
        if (excludeInvisibleImeFrames && !mVisible && mType == WindowInsets.Type.ime()) return true;
        if (!Objects.equals(mVisibleFrame, that.mVisibleFrame)) return false;
        if (!Objects.equals(mVisibleFrame, that.mVisibleFrame)) return false;
        return mFrame.equals(that.mFrame);
        if (!mFrame.equals(that.mFrame)) return false;
        return Arrays.equals(mBoundingRects, that.mBoundingRects);
    }
    }


    @Override
    @Override
    public int hashCode() {
    public int hashCode() {
        return Objects.hash(mId, mType, mFrame, mVisibleFrame, mVisible, mFlags, mSideHint);
        return Objects.hash(mId, mType, mFrame, mVisibleFrame, mVisible, mFlags, mSideHint,
                Arrays.hashCode(mBoundingRects));
    }
    }


    public InsetsSource(Parcel in) {
    public InsetsSource(Parcel in) {
@@ -512,6 +623,7 @@ public class InsetsSource implements Parcelable {
        mVisible = in.readBoolean();
        mVisible = in.readBoolean();
        mFlags = in.readInt();
        mFlags = in.readInt();
        mSideHint = in.readInt();
        mSideHint = in.readInt();
        mBoundingRects = in.createTypedArray(Rect.CREATOR);
    }
    }


    @Override
    @Override
@@ -533,6 +645,7 @@ public class InsetsSource implements Parcelable {
        dest.writeBoolean(mVisible);
        dest.writeBoolean(mVisible);
        dest.writeInt(mFlags);
        dest.writeInt(mFlags);
        dest.writeInt(mSideHint);
        dest.writeInt(mSideHint);
        dest.writeTypedArray(mBoundingRects, flags);
    }
    }


    @Override
    @Override
@@ -543,6 +656,7 @@ public class InsetsSource implements Parcelable {
                + " mVisible=" + mVisible
                + " mVisible=" + mVisible
                + " mFlags=" + flagsToString(mFlags)
                + " mFlags=" + flagsToString(mFlags)
                + " mSideHint=" + sideToString(mSideHint)
                + " mSideHint=" + sideToString(mSideHint)
                + " mBoundingRects=" + Arrays.toString(mBoundingRects)
                + "}";
                + "}";
    }
    }


+31 −10
Original line number Original line Diff line number Diff line
@@ -128,6 +128,8 @@ public class InsetsState implements Parcelable {
        final Rect relativeFrameMax = new Rect(frame);
        final Rect relativeFrameMax = new Rect(frame);
        @InsetsType int forceConsumingTypes = 0;
        @InsetsType int forceConsumingTypes = 0;
        @InsetsType int suppressScrimTypes = 0;
        @InsetsType int suppressScrimTypes = 0;
        final Rect[][] typeBoundingRectsMap = new Rect[Type.SIZE][];
        final Rect[][] typeMaxBoundingRectsMap = new Rect[Type.SIZE][];
        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();
            final @InsetsType int type = source.getType();
@@ -141,7 +143,7 @@ public class InsetsState implements Parcelable {
            }
            }


            processSource(source, relativeFrame, false /* ignoreVisibility */, typeInsetsMap,
            processSource(source, relativeFrame, false /* ignoreVisibility */, typeInsetsMap,
                    idSideMap, typeVisibilityMap);
                    idSideMap, typeVisibilityMap, typeBoundingRectsMap);


            // 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.
@@ -154,7 +156,7 @@ public class InsetsState implements Parcelable {
                }
                }
                processSource(ignoringVisibilitySource, relativeFrameMax,
                processSource(ignoringVisibilitySource, relativeFrameMax,
                        true /* ignoreVisibility */, typeMaxInsetsMap, null /* idSideMap */,
                        true /* ignoreVisibility */, typeMaxInsetsMap, null /* idSideMap */,
                        null /* typeVisibilityMap */);
                        null /* typeVisibilityMap */, typeMaxBoundingRectsMap);
            }
            }
        }
        }
        final int softInputAdjustMode = legacySoftInputMode & SOFT_INPUT_MASK_ADJUST;
        final int softInputAdjustMode = legacySoftInputMode & SOFT_INPUT_MASK_ADJUST;
@@ -175,7 +177,8 @@ public class InsetsState implements Parcelable {
                calculateRelativeRoundedCorners(frame),
                calculateRelativeRoundedCorners(frame),
                calculateRelativePrivacyIndicatorBounds(frame),
                calculateRelativePrivacyIndicatorBounds(frame),
                calculateRelativeDisplayShape(frame),
                calculateRelativeDisplayShape(frame),
                compatInsetsTypes, (legacySystemUiFlags & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0);
                compatInsetsTypes, (legacySystemUiFlags & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0,
                typeBoundingRectsMap, typeMaxBoundingRectsMap, frame.width(), frame.height());
    }
    }


    private DisplayCutout calculateRelativeCutout(Rect frame) {
    private DisplayCutout calculateRelativeCutout(Rect frame) {
@@ -328,12 +331,13 @@ public class InsetsState implements Parcelable {


    private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility,
    private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility,
            Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray idSideMap,
            Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray idSideMap,
            @Nullable boolean[] typeVisibilityMap) {
            @Nullable boolean[] typeVisibilityMap, Rect[][] typeBoundingRectsMap) {
        Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility);
        Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility);
        final Rect[] boundingRects = source.calculateBoundingRects(relativeFrame, ignoreVisibility);


        final int type = source.getType();
        final int type = source.getType();
        processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
        processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                insets, type);
                typeBoundingRectsMap, insets, boundingRects, type);


        if (type == Type.MANDATORY_SYSTEM_GESTURES) {
        if (type == Type.MANDATORY_SYSTEM_GESTURES) {
            // Mandatory system gestures are also system gestures.
            // Mandatory system gestures are also system gestures.
@@ -342,24 +346,25 @@ public class InsetsState implements Parcelable {
            //       ability to set systemGestureInsets() independently from
            //       ability to set systemGestureInsets() independently from
            //       mandatorySystemGestureInsets() in the Builder.
            //       mandatorySystemGestureInsets() in the Builder.
            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                    insets, Type.SYSTEM_GESTURES);
                    typeBoundingRectsMap, insets, boundingRects, Type.SYSTEM_GESTURES);
        }
        }
        if (type == Type.CAPTION_BAR) {
        if (type == Type.CAPTION_BAR) {
            // Caption should also be gesture and tappable elements. This should not be needed when
            // Caption should also be gesture and tappable elements. This should not be needed when
            // the caption is added from the shell, as the shell can add other types at the same
            // the caption is added from the shell, as the shell can add other types at the same
            // time.
            // time.
            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                    insets, Type.SYSTEM_GESTURES);
                    typeBoundingRectsMap, insets, boundingRects, Type.SYSTEM_GESTURES);
            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                    insets, Type.MANDATORY_SYSTEM_GESTURES);
                    typeBoundingRectsMap, insets, boundingRects, Type.MANDATORY_SYSTEM_GESTURES);
            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
            processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap,
                    insets, Type.TAPPABLE_ELEMENT);
                    typeBoundingRectsMap, insets, boundingRects, Type.TAPPABLE_ELEMENT);
        }
        }
    }
    }


    private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap,
    private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap,
            @InternalInsetsSide @Nullable SparseIntArray idSideMap,
            @InternalInsetsSide @Nullable SparseIntArray idSideMap,
            @Nullable boolean[] typeVisibilityMap, Insets insets, int type) {
            @Nullable boolean[] typeVisibilityMap, Rect[][] typeBoundingRectsMap,
            Insets insets, Rect[] boundingRects, int type) {
        int index = indexOf(type);
        int index = indexOf(type);


        // Don't put Insets.NONE into typeInsetsMap. Otherwise, two WindowInsets can be considered
        // Don't put Insets.NONE into typeInsetsMap. Otherwise, two WindowInsets can be considered
@@ -384,6 +389,22 @@ public class InsetsState implements Parcelable {
                idSideMap.put(source.getId(), insetSide);
                idSideMap.put(source.getId(), insetSide);
            }
            }
        }
        }

        if (typeBoundingRectsMap != null && boundingRects.length > 0) {
            final Rect[] existing = typeBoundingRectsMap[index];
            if (existing == null) {
                typeBoundingRectsMap[index] = boundingRects;
            } else {
                typeBoundingRectsMap[index] = concatenate(existing, boundingRects);
            }
        }
    }

    private static Rect[] concatenate(Rect[] a, Rect[] b) {
        final Rect[] c = new Rect[a.length + b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
    }
    }


    /**
    /**
+325 −10

File changed.

Preview size limit exceeded, changes collapsed.

Loading