Loading core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -54054,8 +54054,11 @@ package android.view { method @Deprecated @NonNull public android.view.WindowInsets consumeDisplayCutout(); method @Deprecated @NonNull public android.view.WindowInsets consumeStableInsets(); 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.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 getInsetsIgnoringVisibility(int); method @Deprecated @NonNull public android.graphics.Insets getMandatorySystemGestureInsets(); Loading Loading @@ -54090,8 +54093,11 @@ package android.view { ctor public WindowInsets.Builder(); ctor public WindowInsets.Builder(@NonNull android.view.WindowInsets); 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 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 setInsetsIgnoringVisibility(int, @NonNull android.graphics.Insets) throws java.lang.IllegalArgumentException; method @Deprecated @NonNull public android.view.WindowInsets.Builder setMandatorySystemGestureInsets(@NonNull android.graphics.Insets); core/java/android/view/InsetsFrameProvider.java +31 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Insets; import android.graphics.Rect; import android.os.IBinder; Loading Loading @@ -109,6 +110,12 @@ public class InsetsFrameProvider implements Parcelable { */ 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. * Loading Loading @@ -205,6 +212,22 @@ public class InsetsFrameProvider implements Parcelable { 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 public int describeContents() { return 0; Loading @@ -231,6 +254,9 @@ public class InsetsFrameProvider implements Parcelable { sb.append(", mMinimalInsetsSizeInDisplayCutoutSafe=") .append(mMinimalInsetsSizeInDisplayCutoutSafe); } if (mBoundingRects != null) { sb.append(", mBoundingRects=").append(Arrays.toString(mBoundingRects)); } sb.append("}"); return sb.toString(); } Loading @@ -257,6 +283,7 @@ public class InsetsFrameProvider implements Parcelable { mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR); mArbitraryRectangle = in.readTypedObject(Rect.CREATOR); mMinimalInsetsSizeInDisplayCutoutSafe = in.readTypedObject(Insets.CREATOR); mBoundingRects = in.createTypedArray(Rect.CREATOR); } @Override Loading @@ -268,6 +295,7 @@ public class InsetsFrameProvider implements Parcelable { out.writeTypedArray(mInsetsSizeOverrides, flags); out.writeTypedObject(mArbitraryRectangle, flags); out.writeTypedObject(mMinimalInsetsSizeInDisplayCutoutSafe, flags); out.writeTypedArray(mBoundingRects, flags); } public boolean idEquals(InsetsFrameProvider o) { Loading @@ -288,14 +316,15 @@ public class InsetsFrameProvider implements Parcelable { && Arrays.equals(mInsetsSizeOverrides, other.mInsetsSizeOverrides) && Objects.equals(mArbitraryRectangle, other.mArbitraryRectangle) && Objects.equals(mMinimalInsetsSizeInDisplayCutoutSafe, other.mMinimalInsetsSizeInDisplayCutoutSafe); other.mMinimalInsetsSizeInDisplayCutoutSafe) && Arrays.equals(mBoundingRects, other.mBoundingRects); } @Override public int hashCode() { return Objects.hash(mId, mSource, mFlags, mInsetsSize, Arrays.hashCode(mInsetsSizeOverrides), mArbitraryRectangle, mMinimalInsetsSizeInDisplayCutoutSafe); mMinimalInsetsSizeInDisplayCutoutSafe, Arrays.hashCode(mBoundingRects)); } public static final @NonNull Parcelable.Creator<InsetsFrameProvider> CREATOR = Loading core/java/android/view/InsetsSource.java +116 −2 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ import android.view.WindowInsets.Type.InsetsType; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; import java.util.StringJoiner; Loading Loading @@ -105,6 +107,12 @@ public class InsetsSource implements Parcelable { }) 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; /** Loading @@ -117,6 +125,7 @@ public class InsetsSource implements Parcelable { /** Frame of the source in screen coordinate space */ private final Rect mFrame; private @Nullable Rect mVisibleFrame; private @Nullable Rect[] mBoundingRects; private boolean mVisible; Loading @@ -127,6 +136,7 @@ public class InsetsSource implements Parcelable { private @InternalInsetsSide int mSideHint = SIDE_NONE; private final Rect mTmpFrame = new Rect(); private final Rect mTmpBoundingRect = new Rect(); public InsetsSource(int id, @InsetsType int type) { mId = id; Loading @@ -145,6 +155,9 @@ public class InsetsSource implements Parcelable { : null; mFlags = other.mFlags; mSideHint = other.mSideHint; mBoundingRects = other.mBoundingRects != null ? other.mBoundingRects.clone() : null; } public void set(InsetsSource other) { Loading @@ -155,6 +168,9 @@ public class InsetsSource implements Parcelable { : null; mFlags = other.mFlags; mSideHint = other.mSideHint; mBoundingRects = other.mBoundingRects != null ? other.mBoundingRects.clone() : null; } public InsetsSource setFrame(int left, int top, int right, int bottom) { Loading Loading @@ -199,6 +215,15 @@ public class InsetsSource implements Parcelable { 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() { return mId; } Loading Loading @@ -227,6 +252,13 @@ public class InsetsSource implements Parcelable { 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. * Loading Loading @@ -312,6 +344,82 @@ public class InsetsSource implements Parcelable { 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 * intersection. Loading Loading @@ -467,6 +575,7 @@ public class InsetsSource implements Parcelable { pw.print(" visible="); pw.print(mVisible); pw.print(" flags="); pw.print(flagsToString(mFlags)); pw.print(" sideHint="); pw.print(sideToString(mSideHint)); pw.print(" boundingRects="); pw.print(Arrays.toString(mBoundingRects)); pw.println(); } Loading @@ -492,12 +601,14 @@ public class InsetsSource implements Parcelable { if (mSideHint != that.mSideHint) return false; if (excludeInvisibleImeFrames && !mVisible && mType == WindowInsets.Type.ime()) return true; 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 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) { Loading @@ -512,6 +623,7 @@ public class InsetsSource implements Parcelable { mVisible = in.readBoolean(); mFlags = in.readInt(); mSideHint = in.readInt(); mBoundingRects = in.createTypedArray(Rect.CREATOR); } @Override Loading @@ -533,6 +645,7 @@ public class InsetsSource implements Parcelable { dest.writeBoolean(mVisible); dest.writeInt(mFlags); dest.writeInt(mSideHint); dest.writeTypedArray(mBoundingRects, flags); } @Override Loading @@ -543,6 +656,7 @@ public class InsetsSource implements Parcelable { + " mVisible=" + mVisible + " mFlags=" + flagsToString(mFlags) + " mSideHint=" + sideToString(mSideHint) + " mBoundingRects=" + Arrays.toString(mBoundingRects) + "}"; } Loading core/java/android/view/InsetsState.java +31 −10 Original line number Diff line number Diff line Loading @@ -128,6 +128,8 @@ public class InsetsState implements Parcelable { final Rect relativeFrameMax = new Rect(frame); @InsetsType int forceConsumingTypes = 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--) { final InsetsSource source = mSources.valueAt(i); final @InsetsType int type = source.getType(); Loading @@ -141,7 +143,7 @@ public class InsetsState implements Parcelable { } 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 // target. Loading @@ -154,7 +156,7 @@ public class InsetsState implements Parcelable { } processSource(ignoringVisibilitySource, relativeFrameMax, true /* ignoreVisibility */, typeMaxInsetsMap, null /* idSideMap */, null /* typeVisibilityMap */); null /* typeVisibilityMap */, typeMaxBoundingRectsMap); } } final int softInputAdjustMode = legacySoftInputMode & SOFT_INPUT_MASK_ADJUST; Loading @@ -175,7 +177,8 @@ public class InsetsState implements Parcelable { calculateRelativeRoundedCorners(frame), calculateRelativePrivacyIndicatorBounds(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) { Loading Loading @@ -328,12 +331,13 @@ public class InsetsState implements Parcelable { private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility, Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray idSideMap, @Nullable boolean[] typeVisibilityMap) { @Nullable boolean[] typeVisibilityMap, Rect[][] typeBoundingRectsMap) { Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility); final Rect[] boundingRects = source.calculateBoundingRects(relativeFrame, ignoreVisibility); final int type = source.getType(); processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, type); typeBoundingRectsMap, insets, boundingRects, type); if (type == Type.MANDATORY_SYSTEM_GESTURES) { // Mandatory system gestures are also system gestures. Loading @@ -342,24 +346,25 @@ public class InsetsState implements Parcelable { // ability to set systemGestureInsets() independently from // mandatorySystemGestureInsets() in the Builder. processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, Type.SYSTEM_GESTURES); typeBoundingRectsMap, insets, boundingRects, Type.SYSTEM_GESTURES); } if (type == Type.CAPTION_BAR) { // 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 // time. processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, Type.SYSTEM_GESTURES); typeBoundingRectsMap, insets, boundingRects, Type.SYSTEM_GESTURES); processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, Type.MANDATORY_SYSTEM_GESTURES); typeBoundingRectsMap, insets, boundingRects, Type.MANDATORY_SYSTEM_GESTURES); processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, Type.TAPPABLE_ELEMENT); typeBoundingRectsMap, insets, boundingRects, Type.TAPPABLE_ELEMENT); } } private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap, @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); // Don't put Insets.NONE into typeInsetsMap. Otherwise, two WindowInsets can be considered Loading @@ -384,6 +389,22 @@ public class InsetsState implements Parcelable { 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; } /** Loading core/java/android/view/WindowInsets.java +325 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -54054,8 +54054,11 @@ package android.view { method @Deprecated @NonNull public android.view.WindowInsets consumeDisplayCutout(); method @Deprecated @NonNull public android.view.WindowInsets consumeStableInsets(); 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.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 getInsetsIgnoringVisibility(int); method @Deprecated @NonNull public android.graphics.Insets getMandatorySystemGestureInsets(); Loading Loading @@ -54090,8 +54093,11 @@ package android.view { ctor public WindowInsets.Builder(); ctor public WindowInsets.Builder(@NonNull android.view.WindowInsets); 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 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 setInsetsIgnoringVisibility(int, @NonNull android.graphics.Insets) throws java.lang.IllegalArgumentException; method @Deprecated @NonNull public android.view.WindowInsets.Builder setMandatorySystemGestureInsets(@NonNull android.graphics.Insets);
core/java/android/view/InsetsFrameProvider.java +31 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Insets; import android.graphics.Rect; import android.os.IBinder; Loading Loading @@ -109,6 +110,12 @@ public class InsetsFrameProvider implements Parcelable { */ 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. * Loading Loading @@ -205,6 +212,22 @@ public class InsetsFrameProvider implements Parcelable { 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 public int describeContents() { return 0; Loading @@ -231,6 +254,9 @@ public class InsetsFrameProvider implements Parcelable { sb.append(", mMinimalInsetsSizeInDisplayCutoutSafe=") .append(mMinimalInsetsSizeInDisplayCutoutSafe); } if (mBoundingRects != null) { sb.append(", mBoundingRects=").append(Arrays.toString(mBoundingRects)); } sb.append("}"); return sb.toString(); } Loading @@ -257,6 +283,7 @@ public class InsetsFrameProvider implements Parcelable { mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR); mArbitraryRectangle = in.readTypedObject(Rect.CREATOR); mMinimalInsetsSizeInDisplayCutoutSafe = in.readTypedObject(Insets.CREATOR); mBoundingRects = in.createTypedArray(Rect.CREATOR); } @Override Loading @@ -268,6 +295,7 @@ public class InsetsFrameProvider implements Parcelable { out.writeTypedArray(mInsetsSizeOverrides, flags); out.writeTypedObject(mArbitraryRectangle, flags); out.writeTypedObject(mMinimalInsetsSizeInDisplayCutoutSafe, flags); out.writeTypedArray(mBoundingRects, flags); } public boolean idEquals(InsetsFrameProvider o) { Loading @@ -288,14 +316,15 @@ public class InsetsFrameProvider implements Parcelable { && Arrays.equals(mInsetsSizeOverrides, other.mInsetsSizeOverrides) && Objects.equals(mArbitraryRectangle, other.mArbitraryRectangle) && Objects.equals(mMinimalInsetsSizeInDisplayCutoutSafe, other.mMinimalInsetsSizeInDisplayCutoutSafe); other.mMinimalInsetsSizeInDisplayCutoutSafe) && Arrays.equals(mBoundingRects, other.mBoundingRects); } @Override public int hashCode() { return Objects.hash(mId, mSource, mFlags, mInsetsSize, Arrays.hashCode(mInsetsSizeOverrides), mArbitraryRectangle, mMinimalInsetsSizeInDisplayCutoutSafe); mMinimalInsetsSizeInDisplayCutoutSafe, Arrays.hashCode(mBoundingRects)); } public static final @NonNull Parcelable.Creator<InsetsFrameProvider> CREATOR = Loading
core/java/android/view/InsetsSource.java +116 −2 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ import android.view.WindowInsets.Type.InsetsType; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; import java.util.StringJoiner; Loading Loading @@ -105,6 +107,12 @@ public class InsetsSource implements Parcelable { }) 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; /** Loading @@ -117,6 +125,7 @@ public class InsetsSource implements Parcelable { /** Frame of the source in screen coordinate space */ private final Rect mFrame; private @Nullable Rect mVisibleFrame; private @Nullable Rect[] mBoundingRects; private boolean mVisible; Loading @@ -127,6 +136,7 @@ public class InsetsSource implements Parcelable { private @InternalInsetsSide int mSideHint = SIDE_NONE; private final Rect mTmpFrame = new Rect(); private final Rect mTmpBoundingRect = new Rect(); public InsetsSource(int id, @InsetsType int type) { mId = id; Loading @@ -145,6 +155,9 @@ public class InsetsSource implements Parcelable { : null; mFlags = other.mFlags; mSideHint = other.mSideHint; mBoundingRects = other.mBoundingRects != null ? other.mBoundingRects.clone() : null; } public void set(InsetsSource other) { Loading @@ -155,6 +168,9 @@ public class InsetsSource implements Parcelable { : null; mFlags = other.mFlags; mSideHint = other.mSideHint; mBoundingRects = other.mBoundingRects != null ? other.mBoundingRects.clone() : null; } public InsetsSource setFrame(int left, int top, int right, int bottom) { Loading Loading @@ -199,6 +215,15 @@ public class InsetsSource implements Parcelable { 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() { return mId; } Loading Loading @@ -227,6 +252,13 @@ public class InsetsSource implements Parcelable { 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. * Loading Loading @@ -312,6 +344,82 @@ public class InsetsSource implements Parcelable { 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 * intersection. Loading Loading @@ -467,6 +575,7 @@ public class InsetsSource implements Parcelable { pw.print(" visible="); pw.print(mVisible); pw.print(" flags="); pw.print(flagsToString(mFlags)); pw.print(" sideHint="); pw.print(sideToString(mSideHint)); pw.print(" boundingRects="); pw.print(Arrays.toString(mBoundingRects)); pw.println(); } Loading @@ -492,12 +601,14 @@ public class InsetsSource implements Parcelable { if (mSideHint != that.mSideHint) return false; if (excludeInvisibleImeFrames && !mVisible && mType == WindowInsets.Type.ime()) return true; 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 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) { Loading @@ -512,6 +623,7 @@ public class InsetsSource implements Parcelable { mVisible = in.readBoolean(); mFlags = in.readInt(); mSideHint = in.readInt(); mBoundingRects = in.createTypedArray(Rect.CREATOR); } @Override Loading @@ -533,6 +645,7 @@ public class InsetsSource implements Parcelable { dest.writeBoolean(mVisible); dest.writeInt(mFlags); dest.writeInt(mSideHint); dest.writeTypedArray(mBoundingRects, flags); } @Override Loading @@ -543,6 +656,7 @@ public class InsetsSource implements Parcelable { + " mVisible=" + mVisible + " mFlags=" + flagsToString(mFlags) + " mSideHint=" + sideToString(mSideHint) + " mBoundingRects=" + Arrays.toString(mBoundingRects) + "}"; } Loading
core/java/android/view/InsetsState.java +31 −10 Original line number Diff line number Diff line Loading @@ -128,6 +128,8 @@ public class InsetsState implements Parcelable { final Rect relativeFrameMax = new Rect(frame); @InsetsType int forceConsumingTypes = 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--) { final InsetsSource source = mSources.valueAt(i); final @InsetsType int type = source.getType(); Loading @@ -141,7 +143,7 @@ public class InsetsState implements Parcelable { } 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 // target. Loading @@ -154,7 +156,7 @@ public class InsetsState implements Parcelable { } processSource(ignoringVisibilitySource, relativeFrameMax, true /* ignoreVisibility */, typeMaxInsetsMap, null /* idSideMap */, null /* typeVisibilityMap */); null /* typeVisibilityMap */, typeMaxBoundingRectsMap); } } final int softInputAdjustMode = legacySoftInputMode & SOFT_INPUT_MASK_ADJUST; Loading @@ -175,7 +177,8 @@ public class InsetsState implements Parcelable { calculateRelativeRoundedCorners(frame), calculateRelativePrivacyIndicatorBounds(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) { Loading Loading @@ -328,12 +331,13 @@ public class InsetsState implements Parcelable { private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility, Insets[] typeInsetsMap, @Nullable @InternalInsetsSide SparseIntArray idSideMap, @Nullable boolean[] typeVisibilityMap) { @Nullable boolean[] typeVisibilityMap, Rect[][] typeBoundingRectsMap) { Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility); final Rect[] boundingRects = source.calculateBoundingRects(relativeFrame, ignoreVisibility); final int type = source.getType(); processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, type); typeBoundingRectsMap, insets, boundingRects, type); if (type == Type.MANDATORY_SYSTEM_GESTURES) { // Mandatory system gestures are also system gestures. Loading @@ -342,24 +346,25 @@ public class InsetsState implements Parcelable { // ability to set systemGestureInsets() independently from // mandatorySystemGestureInsets() in the Builder. processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, Type.SYSTEM_GESTURES); typeBoundingRectsMap, insets, boundingRects, Type.SYSTEM_GESTURES); } if (type == Type.CAPTION_BAR) { // 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 // time. processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, Type.SYSTEM_GESTURES); typeBoundingRectsMap, insets, boundingRects, Type.SYSTEM_GESTURES); processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, Type.MANDATORY_SYSTEM_GESTURES); typeBoundingRectsMap, insets, boundingRects, Type.MANDATORY_SYSTEM_GESTURES); processSourceAsPublicType(source, typeInsetsMap, idSideMap, typeVisibilityMap, insets, Type.TAPPABLE_ELEMENT); typeBoundingRectsMap, insets, boundingRects, Type.TAPPABLE_ELEMENT); } } private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap, @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); // Don't put Insets.NONE into typeInsetsMap. Otherwise, two WindowInsets can be considered Loading @@ -384,6 +389,22 @@ public class InsetsState implements Parcelable { 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; } /** Loading
core/java/android/view/WindowInsets.java +325 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes