summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorNate Myren <ntmyren@google.com>2021-04-21 12:05:28 -0700
committerNate Myren <ntmyren@google.com>2021-05-20 09:43:49 -0700
commit8e762afcd724085b963e7bcceba98217df244778 (patch)
tree30d21e3c412baeb7d2f68f07610cb042f90f5aaa /core/java/android
parent330f8f000d289d6946a99745aa8b2dcd815befdd (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.aidl7
-rw-r--r--core/java/android/view/InsetsController.java1
-rw-r--r--core/java/android/view/InsetsState.java43
-rw-r--r--core/java/android/view/PrivacyIndicatorBounds.java251
-rw-r--r--core/java/android/view/WindowInsets.java69
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 */);
}
}