diff options
| author | Nate Myren <ntmyren@google.com> | 2021-04-21 12:05:28 -0700 |
|---|---|---|
| committer | Nate Myren <ntmyren@google.com> | 2021-05-20 09:43:49 -0700 |
| commit | 8e762afcd724085b963e7bcceba98217df244778 (patch) | |
| tree | 30d21e3c412baeb7d2f68f07610cb042f90f5aaa /core/java/android | |
| parent | 330f8f000d289d6946a99745aa8b2dcd815befdd (diff) | |
Add PrivacyIndicator APIs to WindowInsets
Add an API to WindowInsets that allows apps to see the maximum bounds
of the system privacy indicator
Fixes: 185932128
Test: atest PrivacyIndicatorBoundsTests
Change-Id: I01d9e36ccbbea15752eccadfbce4c54bdd35ed5a
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/view/IWindowManager.aidl | 7 | ||||
| -rw-r--r-- | core/java/android/view/InsetsController.java | 1 | ||||
| -rw-r--r-- | core/java/android/view/InsetsState.java | 43 | ||||
| -rw-r--r-- | core/java/android/view/PrivacyIndicatorBounds.java | 251 | ||||
| -rw-r--r-- | core/java/android/view/WindowInsets.java | 69 |
5 files changed, 357 insertions, 14 deletions
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index cd8248934be7..802163617b3b 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -385,6 +385,13 @@ interface IWindowManager oneway void setRecentsVisibility(boolean visible); /** + * Called by System UI to indicate the maximum bounds of the system Privacy Indicator, for the + * current orientation, whether the indicator is showing or not. Should be an array of length + * 4, with the bounds for ROTATION_0, 90, 180, and 270, in that order. + */ + oneway void updateStaticPrivacyIndicatorBounds(int displayId, in Rect[] staticBounds); + + /** * Called by System UI to enable or disable haptic feedback on the navigation bar buttons. */ @UnsupportedAppUsage diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index de7cc18531a9..d17b42edb815 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -690,6 +690,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mState.setDisplayFrame(newState.getDisplayFrame()); mState.setDisplayCutout(newState.getDisplayCutout()); mState.setRoundedCorners(newState.getRoundedCorners()); + mState.setPrivacyIndicatorBounds(newState.getPrivacyIndicatorBounds()); @InsetsType int disabledUserAnimationTypes = 0; @InsetsType int[] cancelledUserAnimationTypes = {0}; for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) { diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index f487c6c61973..37101b757e66 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -171,6 +171,10 @@ public class InsetsState implements Parcelable { /** The rounded corners on the display */ private RoundedCorners mRoundedCorners = RoundedCorners.NO_ROUNDED_CORNERS; + /** The bounds of the Privacy Indicator */ + private PrivacyIndicatorBounds mPrivacyIndicatorBounds = + new PrivacyIndicatorBounds(); + public InsetsState() { } @@ -243,8 +247,9 @@ public class InsetsState implements Parcelable { return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound, alwaysConsumeSystemBars, calculateRelativeCutout(frame), - calculateRelativeRoundedCorners(frame), compatInsetsTypes, - (legacySystemUiFlags & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0); + calculateRelativeRoundedCorners(frame), + calculateRelativePrivacyIndicatorBounds(frame), + compatInsetsTypes, (legacySystemUiFlags & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0); } private DisplayCutout calculateRelativeCutout(Rect frame) { @@ -282,6 +287,20 @@ public class InsetsState implements Parcelable { return mRoundedCorners.inset(insetLeft, insetTop, insetRight, insetBottom); } + private PrivacyIndicatorBounds calculateRelativePrivacyIndicatorBounds(Rect frame) { + if (mDisplayFrame.equals(frame)) { + return mPrivacyIndicatorBounds; + } + if (frame == null) { + return null; + } + final int insetLeft = frame.left - mDisplayFrame.left; + final int insetTop = frame.top - mDisplayFrame.top; + final int insetRight = mDisplayFrame.right - frame.right; + final int insetBottom = mDisplayFrame.bottom - frame.bottom; + return mPrivacyIndicatorBounds.inset(insetLeft, insetTop, insetRight, insetBottom); + } + public Rect calculateInsets(Rect frame, @InsetsType int types, boolean ignoreVisibility) { Insets insets = Insets.NONE; for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) { @@ -471,6 +490,14 @@ public class InsetsState implements Parcelable { return mRoundedCorners; } + public void setPrivacyIndicatorBounds(PrivacyIndicatorBounds bounds) { + mPrivacyIndicatorBounds = bounds; + } + + public PrivacyIndicatorBounds getPrivacyIndicatorBounds() { + return mPrivacyIndicatorBounds; + } + /** * Modifies the state of this class to exclude a certain type to make it ready for dispatching * to the client. @@ -508,6 +535,7 @@ public class InsetsState implements Parcelable { mDisplayFrame.scale(scale); mDisplayCutout.scale(scale); mRoundedCorners = mRoundedCorners.scale(scale); + mPrivacyIndicatorBounds = mPrivacyIndicatorBounds.scale(scale); for (int i = 0; i < SIZE; i++) { final InsetsSource source = mSources[i]; if (source != null) { @@ -528,6 +556,7 @@ public class InsetsState implements Parcelable { mDisplayFrame.set(other.mDisplayFrame); mDisplayCutout.set(other.mDisplayCutout); mRoundedCorners = other.getRoundedCorners(); + mPrivacyIndicatorBounds = other.getPrivacyIndicatorBounds(); if (copySources) { for (int i = 0; i < SIZE; i++) { InsetsSource source = other.mSources[i]; @@ -551,6 +580,7 @@ public class InsetsState implements Parcelable { mDisplayFrame.set(other.mDisplayFrame); mDisplayCutout.set(other.mDisplayCutout); mRoundedCorners = other.getRoundedCorners(); + mPrivacyIndicatorBounds = other.getPrivacyIndicatorBounds(); final ArraySet<Integer> t = toInternalType(types); for (int i = t.size() - 1; i >= 0; i--) { final int type = t.valueAt(i); @@ -670,6 +700,7 @@ public class InsetsState implements Parcelable { pw.println(newPrefix + "mDisplayFrame=" + mDisplayFrame); pw.println(newPrefix + "mDisplayCutout=" + mDisplayCutout.get()); pw.println(newPrefix + "mRoundedCorners=" + mRoundedCorners); + pw.println(newPrefix + "mPrivacyIndicatorBounds=" + mPrivacyIndicatorBounds); for (int i = 0; i < SIZE; i++) { InsetsSource source = mSources[i]; if (source == null) continue; @@ -764,7 +795,8 @@ public class InsetsState implements Parcelable { if (!mDisplayFrame.equals(state.mDisplayFrame) || !mDisplayCutout.equals(state.mDisplayCutout) - || !mRoundedCorners.equals(state.mRoundedCorners)) { + || !mRoundedCorners.equals(state.mRoundedCorners) + || !mPrivacyIndicatorBounds.equals(state.mPrivacyIndicatorBounds)) { return false; } for (int i = 0; i < SIZE; i++) { @@ -789,7 +821,7 @@ public class InsetsState implements Parcelable { @Override public int hashCode() { return Objects.hash(mDisplayFrame, mDisplayCutout, Arrays.hashCode(mSources), - mRoundedCorners); + mRoundedCorners, mPrivacyIndicatorBounds); } public InsetsState(Parcel in) { @@ -807,6 +839,7 @@ public class InsetsState implements Parcelable { mDisplayCutout.writeToParcel(dest, flags); dest.writeTypedArray(mSources, 0 /* parcelableFlags */); dest.writeTypedObject(mRoundedCorners, flags); + dest.writeTypedObject(mPrivacyIndicatorBounds, flags); } public static final @NonNull Creator<InsetsState> CREATOR = new Creator<InsetsState>() { @@ -825,6 +858,7 @@ public class InsetsState implements Parcelable { mDisplayCutout.readFromParcel(in); in.readTypedArray(mSources, InsetsSource.CREATOR); mRoundedCorners = in.readTypedObject(RoundedCorners.CREATOR); + mPrivacyIndicatorBounds = in.readTypedObject(PrivacyIndicatorBounds.CREATOR); } @Override @@ -840,6 +874,7 @@ public class InsetsState implements Parcelable { + "mDisplayFrame=" + mDisplayFrame + ", mDisplayCutout=" + mDisplayCutout + ", mRoundedCorners=" + mRoundedCorners + + ", mPrivacyIndicatorBounds=" + mPrivacyIndicatorBounds + ", mSources= { " + joiner + " }"; } diff --git a/core/java/android/view/PrivacyIndicatorBounds.java b/core/java/android/view/PrivacyIndicatorBounds.java new file mode 100644 index 000000000000..4cf5eda387ef --- /dev/null +++ b/core/java/android/view/PrivacyIndicatorBounds.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static android.view.Surface.ROTATION_0; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.graphics.Rect; +import android.os.Parcelable; + +import com.android.internal.util.ArrayUtils; +import com.android.internal.util.DataClass; + +/** + * A class which manages the bounds of the privacy indicator + * + * @hide + */ +@DataClass( + genEqualsHashCode = true, + genConstructor = false, + genAidl = false, + genGetters = false +) +public class PrivacyIndicatorBounds implements Parcelable { + + private final @NonNull Rect[] mStaticBounds; + private final int mRotation; + + public PrivacyIndicatorBounds() { + mStaticBounds = new Rect[4]; + mRotation = ROTATION_0; + } + + public PrivacyIndicatorBounds(@NonNull Rect[] staticBounds, @Surface.Rotation int rotation) { + mStaticBounds = staticBounds; + mRotation = rotation; + } + + /** + * Return a PrivacyIndicatorBounds with updated static bounds + */ + public PrivacyIndicatorBounds updateStaticBounds(@NonNull Rect[] staticPositions) { + return new PrivacyIndicatorBounds(staticPositions, mRotation); + } + + /** + * Update the bounds of the indicator for a specific rotation, or ROTATION_0, if the provided + * rotation integer isn't found + */ + public PrivacyIndicatorBounds updateBoundsForRotation(@Nullable Rect bounds, + @Surface.Rotation int rotation) { + if (rotation >= mStaticBounds.length || rotation < 0) { + return this; + } + Rect[] newBounds = ArrayUtils.cloneOrNull(mStaticBounds); + newBounds[rotation] = bounds; + return updateStaticBounds(newBounds); + } + + /** + * Return an inset PrivacyIndicatorBounds + */ + public PrivacyIndicatorBounds inset(int insetLeft, int insetTop, int insetRight, + int insetBottom) { + if (insetLeft == 0 && insetTop == 0 && insetRight == 0 && insetBottom == 0) { + return this; + } + Rect[] insetStaticBounds = new Rect[mStaticBounds.length]; + for (int i = 0; i < mStaticBounds.length; i++) { + insetStaticBounds[i] = + insetRect(mStaticBounds[i], insetLeft, insetTop, insetRight, insetBottom); + } + return updateStaticBounds(insetStaticBounds); + } + + private static Rect insetRect(Rect orig, int insetLeft, int insetTop, int insetRight, + int insetBottom) { + if (orig == null) { + return null; + } + int left = Math.max(0, orig.left - insetLeft); + int top = Math.max(0, orig.top - insetTop); + int right = Math.max(left, orig.right - insetRight); + int bottom = Math.max(top, orig.bottom - insetBottom); + return new Rect(left, top, right, bottom); + } + + /** + * Return a PrivacyIndicatorBounds with the static position rotated. + */ + public PrivacyIndicatorBounds rotate(@Surface.Rotation int rotation) { + if (rotation == ROTATION_0) { + return this; + } + return new PrivacyIndicatorBounds(mStaticBounds, rotation); + } + + /** + * Returns a scaled PrivacyIndicatorBounds + */ + public PrivacyIndicatorBounds scale(float scale) { + if (scale == 1f) { + return this; + } + + Rect[] scaledStaticPos = new Rect[mStaticBounds.length]; + for (int i = 0; i < mStaticBounds.length; i++) { + scaledStaticPos[i] = scaleRect(mStaticBounds[i], scale); + } + return new PrivacyIndicatorBounds(scaledStaticPos, mRotation); + } + + private static Rect scaleRect(Rect orig, float scale) { + if (orig == null) { + return null; + } + + Rect newRect = new Rect(orig); + newRect.scale(scale); + return newRect; + } + + public Rect getStaticPrivacyIndicatorBounds() { + return mStaticBounds[mRotation]; + } + + @Override + public String toString() { + return "PrivacyIndicatorBounds {static bounds=" + getStaticPrivacyIndicatorBounds() + + " rotation=" + mRotation + "}"; + } + + + + // Code below generated by codegen v1.0.23. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/PrivacyIndicatorBounds.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + @Override + @DataClass.Generated.Member + public boolean equals(@Nullable Object o) { + // You can override field equality logic by defining either of the methods like: + // boolean fieldNameEquals(PrivacyIndicatorBounds other) { ... } + // boolean fieldNameEquals(FieldType otherValue) { ... } + + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + @SuppressWarnings("unchecked") + PrivacyIndicatorBounds that = (PrivacyIndicatorBounds) o; + //noinspection PointlessBooleanExpression + return true + && java.util.Arrays.equals(mStaticBounds, that.mStaticBounds) + && mRotation == that.mRotation; + } + + @Override + @DataClass.Generated.Member + public int hashCode() { + // You can override field hashCode logic by defining methods like: + // int fieldNameHashCode() { ... } + + int _hash = 1; + _hash = 31 * _hash + java.util.Arrays.hashCode(mStaticBounds); + _hash = 31 * _hash + mRotation; + return _hash; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + dest.writeTypedArray(mStaticBounds, flags); + dest.writeInt(mRotation); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + /** @hide */ + @SuppressWarnings({"unchecked", "RedundantCast"}) + @DataClass.Generated.Member + protected PrivacyIndicatorBounds(@NonNull android.os.Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + Rect[] staticBounds = (Rect[]) in.createTypedArray(Rect.CREATOR); + int rotation = in.readInt(); + + this.mStaticBounds = staticBounds; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mStaticBounds); + this.mRotation = rotation; + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<PrivacyIndicatorBounds> CREATOR + = new Parcelable.Creator<PrivacyIndicatorBounds>() { + @Override + public PrivacyIndicatorBounds[] newArray(int size) { + return new PrivacyIndicatorBounds[size]; + } + + @Override + public PrivacyIndicatorBounds createFromParcel(@NonNull android.os.Parcel in) { + return new PrivacyIndicatorBounds(in); + } + }; + + @DataClass.Generated( + time = 1621526273838L, + codegenVersion = "1.0.23", + sourceFile = "frameworks/base/core/java/android/view/PrivacyIndicatorBounds.java", + inputSignatures = "private final @android.annotation.NonNull android.graphics.Rect[] mStaticBounds\nprivate final int mRotation\npublic android.view.PrivacyIndicatorBounds updateStaticBounds(android.graphics.Rect[])\npublic android.view.PrivacyIndicatorBounds updateBoundsForRotation(android.graphics.Rect,int)\npublic android.view.PrivacyIndicatorBounds inset(int,int,int,int)\nprivate static android.graphics.Rect insetRect(android.graphics.Rect,int,int,int,int)\npublic android.view.PrivacyIndicatorBounds rotate(int)\npublic android.view.PrivacyIndicatorBounds scale(float)\nprivate static android.graphics.Rect scaleRect(android.graphics.Rect,float)\npublic android.graphics.Rect getStaticPrivacyIndicatorBounds()\npublic @java.lang.Override java.lang.String toString()\nclass PrivacyIndicatorBounds extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genConstructor=false, genAidl=false, genGetters=false)") + @Deprecated + private void __metadata() {} + + + //@formatter:on + // End of generated code + +} diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index 41c38a113e05..0f1a9d9c0a98 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -17,6 +17,7 @@ package android.view; +import static android.view.Surface.ROTATION_0; import static android.view.WindowInsets.Type.DISPLAY_CUTOUT; import static android.view.WindowInsets.Type.FIRST; import static android.view.WindowInsets.Type.IME; @@ -83,6 +84,7 @@ public final class WindowInsets { private final boolean mIsRound; @Nullable private final DisplayCutout mDisplayCutout; @Nullable private final RoundedCorners mRoundedCorners; + @Nullable private final PrivacyIndicatorBounds mPrivacyIndicatorBounds; /** * In multi-window we force show the navigation bar. Because we don't want that the surface size @@ -131,8 +133,8 @@ public final class WindowInsets { boolean alwaysConsumeSystemBars, DisplayCutout displayCutout) { this(createCompatTypeMap(systemWindowInsetsRect), createCompatTypeMap(stableInsetsRect), createCompatVisibilityMap(createCompatTypeMap(systemWindowInsetsRect)), - isRound, alwaysConsumeSystemBars, displayCutout, null, systemBars(), - false /* compatIgnoreVisibility */); + isRound, alwaysConsumeSystemBars, displayCutout, null, null, + systemBars(), false /* compatIgnoreVisibility */); } /** @@ -152,8 +154,9 @@ public final class WindowInsets { boolean[] typeVisibilityMap, boolean isRound, boolean alwaysConsumeSystemBars, DisplayCutout displayCutout, - RoundedCorners roundedCorners, @InsetsType int compatInsetsTypes, - boolean compatIgnoreVisibility) { + RoundedCorners roundedCorners, + PrivacyIndicatorBounds privacyIndicatorBounds, + @InsetsType int compatInsetsTypes, boolean compatIgnoreVisibility) { mSystemWindowInsetsConsumed = typeInsetsMap == null; mTypeInsetsMap = mSystemWindowInsetsConsumed ? new Insets[SIZE] @@ -175,6 +178,7 @@ public final class WindowInsets { ? null : displayCutout; mRoundedCorners = roundedCorners; + mPrivacyIndicatorBounds = privacyIndicatorBounds; } /** @@ -188,6 +192,7 @@ public final class WindowInsets { src.mTypeVisibilityMap, src.mIsRound, src.mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(src), src.mRoundedCorners, + src.mPrivacyIndicatorBounds, src.mCompatInsetsTypes, src.mCompatIgnoreVisibility); } @@ -241,7 +246,7 @@ public final class WindowInsets { @UnsupportedAppUsage public WindowInsets(Rect systemWindowInsets) { this(createCompatTypeMap(systemWindowInsets), null, new boolean[SIZE], false, false, null, - null, systemBars(), false /* compatIgnoreVisibility */); + null, null, systemBars(), false /* compatIgnoreVisibility */); } /** @@ -510,6 +515,19 @@ public final class WindowInsets { } /** + * Returns the {@link Rect} of the maximum bounds of the system privacy indicator, for the + * current orientation, in relative coordinates, or null if the bounds have not been loaded yet. + * The privacy indicator shows over apps when an app uses the microphone or camera permissions, + * while an app is in immersive mode. + * + * @return A rectangle representing the maximum bounds of the indicator + */ + public @Nullable Rect getPrivacyIndicatorBounds() { + return mPrivacyIndicatorBounds == null ? null + : mPrivacyIndicatorBounds.getStaticPrivacyIndicatorBounds(); + } + + /** * Returns a copy of this WindowInsets with the cutout fully consumed. * * @return A modified copy of this WindowInsets @@ -524,7 +542,7 @@ public final class WindowInsets { mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap, mIsRound, mAlwaysConsumeSystemBars, - null /* displayCutout */, mRoundedCorners, + null /* displayCutout */, mRoundedCorners, mPrivacyIndicatorBounds, mCompatInsetsTypes, mCompatIgnoreVisibility); } @@ -576,7 +594,8 @@ public final class WindowInsets { mTypeVisibilityMap, mIsRound, mAlwaysConsumeSystemBars, displayCutoutCopyConstructorArgument(this), - mRoundedCorners, mCompatInsetsTypes, mCompatIgnoreVisibility); + mRoundedCorners, mPrivacyIndicatorBounds, mCompatInsetsTypes, + mCompatIgnoreVisibility); } // TODO(b/119190588): replace @code with @link below @@ -881,6 +900,9 @@ public final class WindowInsets { result.append("\n "); result.append(mRoundedCorners != null ? "roundedCorners=" + mRoundedCorners : ""); result.append("\n "); + result.append(mPrivacyIndicatorBounds != null ? "privacyIndicatorBounds=" + + mPrivacyIndicatorBounds : ""); + result.append("\n "); result.append(isRound() ? "round" : ""); result.append("}"); return result.toString(); @@ -975,6 +997,9 @@ public final class WindowInsets { mRoundedCorners == null ? RoundedCorners.NO_ROUNDED_CORNERS : mRoundedCorners.inset(left, top, right, bottom), + mPrivacyIndicatorBounds == null + ? null + : mPrivacyIndicatorBounds.inset(left, top, right, bottom), mCompatInsetsTypes, mCompatIgnoreVisibility); } @@ -993,7 +1018,8 @@ public final class WindowInsets { && Arrays.equals(mTypeMaxInsetsMap, that.mTypeMaxInsetsMap) && Arrays.equals(mTypeVisibilityMap, that.mTypeVisibilityMap) && Objects.equals(mDisplayCutout, that.mDisplayCutout) - && Objects.equals(mRoundedCorners, that.mRoundedCorners); + && Objects.equals(mRoundedCorners, that.mRoundedCorners) + && Objects.equals(mPrivacyIndicatorBounds, that.mPrivacyIndicatorBounds); } @Override @@ -1001,7 +1027,7 @@ public final class WindowInsets { return Objects.hash(Arrays.hashCode(mTypeInsetsMap), Arrays.hashCode(mTypeMaxInsetsMap), Arrays.hashCode(mTypeVisibilityMap), mIsRound, mDisplayCutout, mRoundedCorners, mAlwaysConsumeSystemBars, mSystemWindowInsetsConsumed, mStableInsetsConsumed, - mDisplayCutoutConsumed); + mDisplayCutoutConsumed, mPrivacyIndicatorBounds); } @@ -1066,6 +1092,8 @@ public final class WindowInsets { private boolean mIsRound; private boolean mAlwaysConsumeSystemBars; + private PrivacyIndicatorBounds mPrivacyIndicatorBounds = new PrivacyIndicatorBounds(); + /** * Creates a builder where all insets are initially consumed. */ @@ -1090,6 +1118,7 @@ public final class WindowInsets { mRoundedCorners = insets.mRoundedCorners; mIsRound = insets.mIsRound; mAlwaysConsumeSystemBars = insets.mAlwaysConsumeSystemBars; + mPrivacyIndicatorBounds = insets.mPrivacyIndicatorBounds; } /** @@ -1316,6 +1345,26 @@ public final class WindowInsets { /** @hide */ @NonNull + public Builder setPrivacyIndicatorBounds(@Nullable PrivacyIndicatorBounds bounds) { + mPrivacyIndicatorBounds = bounds; + return this; + } + + /** + * Sets the bounds of the system privacy indicator. + * + * @param bounds The bounds of the system privacy indicator + */ + @NonNull + public Builder setPrivacyIndicatorBounds(@Nullable Rect bounds) { + //TODO 188788786: refactor the indicator bounds + Rect[] boundsArr = { bounds, bounds, bounds, bounds }; + mPrivacyIndicatorBounds = new PrivacyIndicatorBounds(boundsArr, ROTATION_0); + return this; + } + + /** @hide */ + @NonNull public Builder setRound(boolean round) { mIsRound = round; return this; @@ -1338,7 +1387,7 @@ public final class WindowInsets { return new WindowInsets(mSystemInsetsConsumed ? null : mTypeInsetsMap, mStableInsetsConsumed ? null : mTypeMaxInsetsMap, mTypeVisibilityMap, mIsRound, mAlwaysConsumeSystemBars, mDisplayCutout, mRoundedCorners, - systemBars(), false /* compatIgnoreVisibility */); + mPrivacyIndicatorBounds, systemBars(), false /* compatIgnoreVisibility */); } } |
