DisplayCutout: Support more than one cutout
Also makes API more restrictive. Also moves window manager specific
logic out of the framework. Also fixes SystemUI such that it can properly
deal with more than one cutout.
Bug: 74195186
Test: atest DisplayCutoutTest WmDisplayCutoutTest DisplayContentTests WindowFrameTests
Change-Id: Ib7b89e119ce2d3961687579bb81eadce1159a600
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 903f3aa..ec2390f 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -31,6 +31,7 @@
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.graphics.Region;
import android.hardware.display.DisplayManager;
import android.provider.Settings.Secure;
import android.support.annotation.VisibleForTesting;
@@ -312,6 +313,7 @@
private final DisplayInfo mInfo = new DisplayInfo();
private final Paint mPaint = new Paint();
+ private final Region mBounds = new Region();
private final Rect mBoundingRect = new Rect();
private final Path mBoundingPath = new Path();
private final int[] mLocation = new int[2];
@@ -370,11 +372,13 @@
private void update() {
requestLayout();
getDisplay().getDisplayInfo(mInfo);
+ mBounds.setEmpty();
mBoundingRect.setEmpty();
mBoundingPath.reset();
int newVisible;
if (hasCutout()) {
- mBoundingRect.set(mInfo.displayCutout.getBoundingRect());
+ mBounds.set(mInfo.displayCutout.getBounds());
+ localBounds(mBoundingRect);
mInfo.displayCutout.getBounds().getBoundaryPath(mBoundingPath);
newVisible = VISIBLE;
} else {
@@ -402,7 +406,7 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- if (mBoundingRect.isEmpty()) {
+ if (mBounds.isEmpty()) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
@@ -410,5 +414,50 @@
resolveSizeAndState(mBoundingRect.width(), widthMeasureSpec, 0),
resolveSizeAndState(mBoundingRect.height(), heightMeasureSpec, 0));
}
+
+ public static void boundsFromDirection(DisplayCutout displayCutout, int gravity, Rect out) {
+ Region bounds = displayCutout.getBounds();
+ switch (gravity) {
+ case Gravity.TOP:
+ bounds.op(0, 0, Integer.MAX_VALUE, displayCutout.getSafeInsetTop(),
+ Region.Op.INTERSECT);
+ out.set(bounds.getBounds());
+ break;
+ case Gravity.LEFT:
+ bounds.op(0, 0, displayCutout.getSafeInsetLeft(), Integer.MAX_VALUE,
+ Region.Op.INTERSECT);
+ out.set(bounds.getBounds());
+ break;
+ case Gravity.BOTTOM:
+ bounds.op(0, displayCutout.getSafeInsetTop() + 1, Integer.MAX_VALUE,
+ Integer.MAX_VALUE, Region.Op.INTERSECT);
+ out.set(bounds.getBounds());
+ break;
+ case Gravity.RIGHT:
+ bounds.op(displayCutout.getSafeInsetLeft() + 1, 0, Integer.MAX_VALUE,
+ Integer.MAX_VALUE, Region.Op.INTERSECT);
+ out.set(bounds.getBounds());
+ break;
+ }
+ bounds.recycle();
+ }
+
+ private void localBounds(Rect out) {
+ final DisplayCutout displayCutout = mInfo.displayCutout;
+
+ if (mStart) {
+ if (displayCutout.getSafeInsetLeft() > 0) {
+ boundsFromDirection(displayCutout, Gravity.LEFT, out);
+ } else if (displayCutout.getSafeInsetTop() > 0) {
+ boundsFromDirection(displayCutout, Gravity.TOP, out);
+ }
+ } else {
+ if (displayCutout.getSafeInsetRight() > 0) {
+ boundsFromDirection(displayCutout, Gravity.RIGHT, out);
+ } else if (displayCutout.getSafeInsetBottom() > 0) {
+ boundsFromDirection(displayCutout, Gravity.BOTTOM, out);
+ }
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index c5269ad..04c5f2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
+
import android.annotation.ColorInt;
import android.content.Context;
import android.content.res.Configuration;
@@ -27,6 +29,7 @@
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.DisplayCutout;
+import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
@@ -42,6 +45,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.ScreenDecorations;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
@@ -252,10 +256,13 @@
updateLayoutParamsNoCutout();
}
+ Rect bounds = new Rect();
+ boundsFromDirection(dc, Gravity.TOP, bounds);
+
mCutoutSpace.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams lp = (LayoutParams) mCutoutSpace.getLayoutParams();
- lp.width = dc.getBoundingRect().width();
- lp.height = dc.getBoundingRect().height();
+ lp.width = bounds.width();
+ lp.height = bounds.height();
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
lp = (LayoutParams) mCarrierLabel.getLayoutParams();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 900ec0b..0933c99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -18,6 +18,8 @@
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
+
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
@@ -25,6 +27,7 @@
import android.util.AttributeSet;
import android.util.EventLog;
import android.view.DisplayCutout;
+import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -301,8 +304,12 @@
mCutoutSpace.setVisibility(View.VISIBLE);
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mCutoutSpace.getLayoutParams();
- lp.width = mDisplayCutout.getBoundingRect().width();
- lp.height = mDisplayCutout.getBoundingRect().height();
+
+ Rect bounds = new Rect();
+ boundsFromDirection(mDisplayCutout, Gravity.TOP, bounds);
+
+ lp.width = bounds.width();
+ lp.height = bounds.height();
}
private void updateSafeInsets() {