DisplayCutout: Dispatch all non-zero safeInsets

Ensures that even if the display cutout does not overlap
a window, the safe insets are still dispatched if the window
overlaps any part of the cutout area and the safe insets
are therefore non-zero.

To do that, we need to compute the insets once against the
display size, then only shrink or expand the safe insets
accordingly.

Bug: 73533636
Test: atest DisplayCutoutTest
Change-Id: I1ea449178e29c7effdd92cac78af1a3875ca7e70
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 0b72c22..2723030 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -26,7 +26,6 @@
 import android.content.res.Resources;
 import android.graphics.Matrix;
 import android.graphics.Path;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region;
@@ -35,12 +34,13 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.PathParser;
+import android.util.Size;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.util.List;
+import java.util.Objects;
 
 /**
  * Represents a part of the display that is not functional for displaying content.
@@ -70,10 +70,12 @@
      *
      * @hide
      */
-    public static final DisplayCutout NO_CUTOUT = new DisplayCutout(ZERO_RECT, EMPTY_REGION);
+    public static final DisplayCutout NO_CUTOUT = new DisplayCutout(ZERO_RECT, EMPTY_REGION,
+            new Size(0, 0));
 
     private final Rect mSafeInsets;
     private final Region mBounds;
+    private final Size mFrameSize;
 
     /**
      * Creates a DisplayCutout instance.
@@ -83,9 +85,10 @@
      * @hide
      */
     @VisibleForTesting
-    public DisplayCutout(Rect safeInsets, Region bounds) {
+    public DisplayCutout(Rect safeInsets, Region bounds, Size frameSize) {
         mSafeInsets = safeInsets != null ? safeInsets : ZERO_RECT;
         mBounds = bounds != null ? bounds : Region.obtain();
+        mFrameSize = frameSize;
     }
 
     /**
@@ -164,7 +167,8 @@
         if (o instanceof DisplayCutout) {
             DisplayCutout c = (DisplayCutout) o;
             return mSafeInsets.equals(c.mSafeInsets)
-                    && mBounds.equals(c.mBounds);
+                    && mBounds.equals(c.mBounds)
+                    && Objects.equals(mFrameSize, c.mFrameSize);
         }
         return false;
     }
@@ -217,70 +221,84 @@
         }
 
         bounds.translate(-insetLeft, -insetTop);
+        Size frame = mFrameSize == null ? null : new Size(
+                mFrameSize.getWidth() - insetLeft - insetRight,
+                mFrameSize.getHeight() - insetTop - insetBottom);
 
-        return new DisplayCutout(safeInsets, bounds);
+        return new DisplayCutout(safeInsets, bounds, frame);
     }
 
     /**
-     * Calculates the safe insets relative to the given reference frame.
+     * Recalculates the cutout relative to the given reference frame.
+     *
+     * The safe insets must already have been computed, e.g. with {@link #computeSafeInsets}.
+     *
+     * @return a copy of this instance with the safe insets recalculated
+     * @hide
+     */
+    public DisplayCutout calculateRelativeTo(Rect frame) {
+        return inset(frame.left, frame.top,
+                mFrameSize.getWidth() - frame.right, mFrameSize.getHeight() - frame.bottom);
+    }
+
+    /**
+     * Calculates the safe insets relative to the given display size.
      *
      * @return a copy of this instance with the safe insets calculated
      * @hide
      */
-    public DisplayCutout calculateRelativeTo(Rect frame) {
-        if (mBounds.isEmpty() || !Rect.intersects(frame, mBounds.getBounds())) {
+    public DisplayCutout computeSafeInsets(int width, int height) {
+        if (this == NO_CUTOUT || mBounds.isEmpty()) {
             return NO_CUTOUT;
         }
 
-        return DisplayCutout.calculateRelativeTo(frame, Region.obtain(mBounds));
+        return computeSafeInsets(new Size(width, height), mBounds);
     }
 
-    private static DisplayCutout calculateRelativeTo(Rect frame, Region bounds) {
+    private static DisplayCutout computeSafeInsets(Size displaySize, Region bounds) {
         Rect boundingRect = bounds.getBounds();
         Rect safeRect = new Rect();
 
         int bestArea = 0;
         int bestVariant = 0;
         for (int variant = ROTATION_0; variant <= ROTATION_270; variant++) {
-            int area = calculateInsetVariantArea(frame, boundingRect, variant, safeRect);
+            int area = calculateInsetVariantArea(displaySize, boundingRect, variant, safeRect);
             if (bestArea < area) {
                 bestArea = area;
                 bestVariant = variant;
             }
         }
-        calculateInsetVariantArea(frame, boundingRect, bestVariant, safeRect);
+        calculateInsetVariantArea(displaySize, boundingRect, bestVariant, safeRect);
         if (safeRect.isEmpty()) {
-            // The entire frame overlaps with the cutout.
-            safeRect.set(0, frame.height(), 0, 0);
+            // The entire displaySize overlaps with the cutout.
+            safeRect.set(0, displaySize.getHeight(), 0, 0);
         } else {
-            // Convert safeRect to insets relative to frame. We're reusing the rect here to avoid
-            // an allocation.
+            // Convert safeRect to insets relative to displaySize. We're reusing the rect here to
+            // avoid an allocation.
             safeRect.set(
-                    Math.max(0, safeRect.left - frame.left),
-                    Math.max(0, safeRect.top - frame.top),
-                    Math.max(0, frame.right - safeRect.right),
-                    Math.max(0, frame.bottom - safeRect.bottom));
+                    Math.max(0, safeRect.left),
+                    Math.max(0, safeRect.top),
+                    Math.max(0, displaySize.getWidth() - safeRect.right),
+                    Math.max(0, displaySize.getHeight() - safeRect.bottom));
         }
 
-        bounds.translate(-frame.left, -frame.top);
-
-        return new DisplayCutout(safeRect, bounds);
+        return new DisplayCutout(safeRect, bounds, displaySize);
     }
 
-    private static int calculateInsetVariantArea(Rect frame, Rect boundingRect, int variant,
+    private static int calculateInsetVariantArea(Size display, Rect boundingRect, int variant,
             Rect outSafeRect) {
         switch (variant) {
             case ROTATION_0:
-                outSafeRect.set(frame.left, frame.top, frame.right, boundingRect.top);
+                outSafeRect.set(0, 0, display.getWidth(), boundingRect.top);
                 break;
             case ROTATION_90:
-                outSafeRect.set(frame.left, frame.top, boundingRect.left, frame.bottom);
+                outSafeRect.set(0, 0, boundingRect.left, display.getHeight());
                 break;
             case ROTATION_180:
-                outSafeRect.set(frame.left, boundingRect.bottom, frame.right, frame.bottom);
+                outSafeRect.set(0, boundingRect.bottom, display.getWidth(), display.getHeight());
                 break;
             case ROTATION_270:
-                outSafeRect.set(boundingRect.right, frame.top, frame.right, frame.bottom);
+                outSafeRect.set(boundingRect.right, 0, display.getWidth(), display.getHeight());
                 break;
         }
 
@@ -293,21 +311,17 @@
 
 
     /**
-     * Creates an instance from a bounding polygon.
+     * Creates an instance from a bounding rect.
      *
      * @hide
      */
-    public static DisplayCutout fromBoundingPolygon(List<Point> points) {
+    public static DisplayCutout fromBoundingRect(int left, int top, int right, int bottom) {
         Path path = new Path();
         path.reset();
-        for (int i = 0; i < points.size(); i++) {
-            Point point = points.get(i);
-            if (i == 0) {
-                path.moveTo(point.x, point.y);
-            } else {
-                path.lineTo(point.x, point.y);
-            }
-        }
+        path.moveTo(left, top);
+        path.lineTo(left, bottom);
+        path.lineTo(right, bottom);
+        path.lineTo(right, top);
         path.close();
         return fromBounds(path);
     }
@@ -327,7 +341,7 @@
         Region bounds = new Region();
         bounds.setPath(path, clipRegion);
         clipRegion.recycle();
-        return new DisplayCutout(ZERO_RECT, bounds);
+        return new DisplayCutout(ZERO_RECT, bounds, null /* frameSize */);
     }
 
     /**
@@ -407,6 +421,12 @@
                 out.writeInt(1);
                 out.writeTypedObject(cutout.mSafeInsets, flags);
                 out.writeTypedObject(cutout.mBounds, flags);
+                if (cutout.mFrameSize != null) {
+                    out.writeInt(cutout.mFrameSize.getWidth());
+                    out.writeInt(cutout.mFrameSize.getHeight());
+                } else {
+                    out.writeInt(-1);
+                }
             }
         }
 
@@ -449,7 +469,10 @@
             Rect safeInsets = in.readTypedObject(Rect.CREATOR);
             Region bounds = in.readTypedObject(Region.CREATOR);
 
-            return new DisplayCutout(safeInsets, bounds);
+            int width = in.readInt();
+            Size frameSize = width >= 0 ? new Size(width, in.readInt()) : null;
+
+            return new DisplayCutout(safeInsets, bounds, frameSize);
         }
 
         public DisplayCutout get() {
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index 0d8c679..ee4bc34 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -17,26 +17,25 @@
 package android.view;
 
 import static android.view.DisplayCutout.NO_CUTOUT;
+import static android.view.DisplayCutout.fromBoundingRect;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.os.Parcel;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.Size;
 import android.view.DisplayCutout.ParcelableWrapper;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.Arrays;
-
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
@@ -45,7 +44,7 @@
     /** This is not a consistent cutout. Useful for verifying insets in one go though. */
     final DisplayCutout mCutoutNumbers = new DisplayCutout(
             new Rect(1, 2, 3, 4),
-            new Region(5, 6, 7, 8));
+            new Region(5, 6, 7, 8), new Size(9, 10));
 
     final DisplayCutout mCutoutTop = createCutoutTop();
 
@@ -155,50 +154,94 @@
     }
 
     @Test
-    public void calculateRelativeTo_top() throws Exception {
-        DisplayCutout cutout = mCutoutTop.calculateRelativeTo(new Rect(0, 0, 200, 400));
+    public void computeSafeInsets_top() throws Exception {
+        DisplayCutout cutout = fromBoundingRect(0, 0, 100, 20)
+                .computeSafeInsets(200, 400);
 
-        assertEquals(new Rect(0, 100, 0, 0), cutout.getSafeInsets());
+        assertEquals(new Rect(0, 20, 0, 0), cutout.getSafeInsets());
+    }
+
+    @Test
+    public void computeSafeInsets_left() throws Exception {
+        DisplayCutout cutout = fromBoundingRect(0, 0, 20, 100)
+                .computeSafeInsets(400, 200);
+
+        assertEquals(new Rect(20, 0, 0, 0), cutout.getSafeInsets());
+    }
+
+    @Test
+    public void computeSafeInsets_bottom() throws Exception {
+        DisplayCutout cutout = fromBoundingRect(0, 180, 100, 200)
+                .computeSafeInsets(100, 200);
+
+        assertEquals(new Rect(0, 0, 0, 20), cutout.getSafeInsets());
+    }
+
+    @Test
+    public void computeSafeInsets_right() throws Exception {
+        DisplayCutout cutout = fromBoundingRect(180, 0, 200, 100)
+                .computeSafeInsets(200, 100);
+
+        assertEquals(new Rect(0, 0, 20, 0), cutout.getSafeInsets());
+    }
+
+    @Test
+    public void computeSafeInsets_bounds() throws Exception {
+        DisplayCutout cutout = mCutoutTop.computeSafeInsets(1000, 2000);
+
+        assertEquals(mCutoutTop.getBoundingRect(), cutout.getBounds().getBounds());
+    }
+
+    @Test
+    public void calculateRelativeTo_top() throws Exception {
+        DisplayCutout cutout = fromBoundingRect(0, 0, 100, 20)
+                .computeSafeInsets(200, 400)
+                .calculateRelativeTo(new Rect(5, 5, 95, 195));
+
+        assertEquals(new Rect(0, 15, 0, 0), cutout.getSafeInsets());
     }
 
     @Test
     public void calculateRelativeTo_left() throws Exception {
-        DisplayCutout cutout = mCutoutTop.calculateRelativeTo(new Rect(0, 0, 400, 200));
+        DisplayCutout cutout = fromBoundingRect(0, 0, 20, 100)
+                .computeSafeInsets(400, 200)
+                .calculateRelativeTo(new Rect(5, 5, 195, 95));
 
-        assertEquals(new Rect(75, 0, 0, 0), cutout.getSafeInsets());
+        assertEquals(new Rect(15, 0, 0, 0), cutout.getSafeInsets());
     }
 
     @Test
     public void calculateRelativeTo_bottom() throws Exception {
-        DisplayCutout cutout = mCutoutTop.calculateRelativeTo(new Rect(0, -300, 200, 100));
+        DisplayCutout cutout = fromBoundingRect(0, 180, 100, 200)
+                .computeSafeInsets(100, 200)
+                .calculateRelativeTo(new Rect(5, 5, 95, 195));
 
-        assertEquals(new Rect(0, 0, 0, 100), cutout.getSafeInsets());
+        assertEquals(new Rect(0, 0, 0, 15), cutout.getSafeInsets());
     }
 
     @Test
     public void calculateRelativeTo_right() throws Exception {
-        DisplayCutout cutout = mCutoutTop.calculateRelativeTo(new Rect(-400, -200, 100, 100));
+        DisplayCutout cutout = fromBoundingRect(180, 0, 200, 100)
+                .computeSafeInsets(200, 100)
+                .calculateRelativeTo(new Rect(5, 5, 195, 95));
 
-        assertEquals(new Rect(0, 0, 50, 0), cutout.getSafeInsets());
+        assertEquals(new Rect(0, 0, 15, 0), cutout.getSafeInsets());
     }
 
     @Test
     public void calculateRelativeTo_bounds() throws Exception {
-        DisplayCutout cutout = mCutoutTop.calculateRelativeTo(new Rect(-1000, -2000, 100, 200));
+        DisplayCutout cutout = fromBoundingRect(0, 0, 100, 20)
+                .computeSafeInsets(200, 400)
+                .calculateRelativeTo(new Rect(5, 10, 95, 180));
 
-        assertEquals(new Rect(1050, 2000, 1075, 2100), cutout.getBoundingRect());
+        assertEquals(new Rect(-5, -10, 95, 10), cutout.getBounds().getBounds());
     }
 
     @Test
     public void fromBoundingPolygon() throws Exception {
         assertEquals(
                 new Rect(50, 0, 75, 100),
-                DisplayCutout.fromBoundingPolygon(
-                        Arrays.asList(
-                                new Point(75, 0),
-                                new Point(50, 0),
-                                new Point(75, 100),
-                                new Point(50, 100))).getBounds().getBounds());
+                DisplayCutout.fromBoundingRect(50, 0, 75, 100).getBounds().getBounds());
     }
 
     @Test
@@ -215,6 +258,19 @@
     }
 
     @Test
+    public void parcel_unparcel_withFrame() {
+        Parcel p = Parcel.obtain();
+
+        new ParcelableWrapper(mCutoutNumbers).writeToParcel(p, 0);
+        int posAfterWrite = p.dataPosition();
+
+        p.setDataPosition(0);
+
+        assertEquals(mCutoutNumbers, ParcelableWrapper.CREATOR.createFromParcel(p).get());
+        assertEquals(posAfterWrite, p.dataPosition());
+    }
+
+    @Test
     public void parcel_unparcel_nocutout() {
         Parcel p = Parcel.obtain();
 
@@ -264,6 +320,7 @@
     private static DisplayCutout createCutoutWithInsets(int left, int top, int right, int bottom) {
         return new DisplayCutout(
                 new Rect(left, top, right, bottom),
-                new Region(50, 0, 75, 100));
+                new Region(50, 0, 75, 100),
+                null);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 0b3e9e5..903f3aa 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -387,11 +387,10 @@
         }
 
         private boolean hasCutout() {
-            if (mInfo.displayCutout == null) {
+            final DisplayCutout displayCutout = mInfo.displayCutout;
+            if (displayCutout == null) {
                 return false;
             }
-            DisplayCutout displayCutout = mInfo.displayCutout.calculateRelativeTo(
-                    new Rect(0, 0, mInfo.logicalWidth, mInfo.logicalHeight));
             if (mStart) {
                 return displayCutout.getSafeInsetLeft() > 0
                         || displayCutout.getSafeInsetTop() > 0;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index d22828d..841586a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -138,6 +138,7 @@
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.MutableBoolean;
+import android.util.Size;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
@@ -1197,14 +1198,20 @@
 
     DisplayCutout calculateDisplayCutoutForCurrentRotation() {
         final DisplayCutout cutout = mInitialDisplayCutout;
-        if (cutout == null || cutout == DisplayCutout.NO_CUTOUT || mRotation == ROTATION_0) {
+        if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) {
             return cutout;
         }
+        if (mRotation == ROTATION_0) {
+            return cutout.computeSafeInsets(mInitialDisplayWidth, mInitialDisplayHeight);
+        }
+        final boolean rotated = (mRotation == ROTATION_90 || mRotation == ROTATION_270);
         final Path bounds = cutout.getBounds().getBoundaryPath();
         transformPhysicalToLogicalCoordinates(mRotation, mInitialDisplayWidth,
                 mInitialDisplayHeight, mTmpMatrix);
         bounds.transform(mTmpMatrix);
-        return DisplayCutout.fromBounds(bounds);
+        return DisplayCutout.fromBounds(bounds).computeSafeInsets(
+                rotated ? mInitialDisplayHeight : mInitialDisplayWidth,
+                rotated ? mInitialDisplayWidth : mInitialDisplayHeight);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DisplayFrames.java b/services/core/java/com/android/server/wm/DisplayFrames.java
index 13d0c86..57ce15bc 100644
--- a/services/core/java/com/android/server/wm/DisplayFrames.java
+++ b/services/core/java/com/android/server/wm/DisplayFrames.java
@@ -22,17 +22,12 @@
 import static com.android.server.wm.proto.DisplayFramesProto.STABLE_BOUNDS;
 
 import android.annotation.NonNull;
-import android.content.res.Resources;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.util.proto.ProtoOutputStream;
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 
-import com.android.internal.annotations.VisibleForTesting;
-
 import java.io.PrintWriter;
-import java.util.Arrays;
 
 /**
  * Container class for all the display frames that affect how we do window layout on a display.
@@ -173,7 +168,7 @@
         mStableFullscreen.set(mUnrestricted);
         mCurrent.set(mUnrestricted);
 
-        mDisplayCutout = mDisplayInfoCutout.calculateRelativeTo(mOverscan);
+        mDisplayCutout = mDisplayInfoCutout;
         mDisplayCutoutSafe.set(Integer.MIN_VALUE, Integer.MIN_VALUE,
                 Integer.MAX_VALUE, Integer.MAX_VALUE);
         if (!mDisplayCutout.isEmpty()) {
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 63ac4af..a8556bd 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -22,6 +22,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.DisplayCutout.fromBoundingRect;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -38,7 +39,6 @@
 
 import android.annotation.SuppressLint;
 import android.content.res.Configuration;
-import android.graphics.Path;
 import android.graphics.Rect;
 import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
@@ -396,7 +396,9 @@
             final DisplayContent dc = createNewDisplay();
             dc.mInitialDisplayWidth = 200;
             dc.mInitialDisplayHeight = 400;
-            final DisplayCutout cutout = createCutout(new Rect(80, 0, 120, 10));
+            Rect r = new Rect(80, 0, 120, 10);
+            final DisplayCutout cutout = fromBoundingRect(r.left, r.top, r.right, r.bottom)
+                    .computeSafeInsets(200, 400);
 
             dc.mInitialDisplayCutout = cutout;
             dc.setRotation(Surface.ROTATION_0);
@@ -412,13 +414,17 @@
             final DisplayContent dc = createNewDisplay();
             dc.mInitialDisplayWidth = 200;
             dc.mInitialDisplayHeight = 400;
-            final DisplayCutout cutout = createCutout(new Rect(80, 0, 120, 10));
+            Rect r1 = new Rect(80, 0, 120, 10);
+            final DisplayCutout cutout = fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom)
+                    .computeSafeInsets(200, 400);
 
             dc.mInitialDisplayCutout = cutout;
             dc.setRotation(Surface.ROTATION_90);
             dc.computeScreenConfiguration(new Configuration()); // recomputes dc.mDisplayInfo.
 
-            assertEquals(createCutout(new Rect(0, 80, 10, 120)), dc.getDisplayInfo().displayCutout);
+            final Rect r = new Rect(0, 80, 10, 120);
+            assertEquals(fromBoundingRect(r.left, r.top, r.right, r.bottom)
+                    .computeSafeInsets(400, 200), dc.getDisplayInfo().displayCutout);
         }
     }
 
@@ -487,10 +493,4 @@
                 y,
                 metaState);
     }
-
-    private DisplayCutout createCutout(Rect r) {
-        Path p = new Path();
-        p.addRect(r.left, r.top, r.right, r.bottom, Path.Direction.CCW);
-        return DisplayCutout.fromBounds(p);
-    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 0959df2..7d6301cc 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -22,7 +22,6 @@
 
 import android.app.ActivityManager.TaskDescription;
 import android.content.res.Configuration;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
@@ -33,13 +32,12 @@
 import android.view.IWindow;
 import android.view.WindowManager;
 
+import static android.view.DisplayCutout.fromBoundingRect;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.FILL_PARENT;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import java.util.Arrays;
-
 /**
  * Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery.
  *
@@ -430,7 +428,8 @@
 
         final Rect pf = new Rect(0, 0, 1000, 1000);
         // Create a display cutout of size 50x50, aligned top-center
-        final DisplayCutout cutout = createDisplayCutoutFromRect(500, 0, 550, 50);
+        final DisplayCutout cutout = fromBoundingRect(500, 0, 550, 50)
+                .computeSafeInsets(pf.width(), pf.height());
 
         w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf, cutout);
 
@@ -448,12 +447,4 @@
         return new WindowStateWithTask(attrs, task);
     }
 
-    private DisplayCutout createDisplayCutoutFromRect(int left, int top, int right, int bottom) {
-        return DisplayCutout.fromBoundingPolygon(Arrays.asList(
-                new Point(left, top),
-                new Point(left, bottom),
-                new Point(right, bottom),
-                new Point(right, top)
-        ));
-    }
 }