DisplayCutout: Draw anti-aliased bounds in soft overlay

To do so, we cannot use the Region from DisplayCutout, because it is conceptionally
a binary Bitmap. Instead, we need the exact curve as a Path.

Also fixes a theoretical bug where the DisplayCutout
was cached even though the display height changed.

Change-Id: I9356f4589186fedc5dc95010c7bd1a1fa20edf5e
Fixes: 77868940
Test: Enable display cutout in developer options, verify the edges look smoth and not jagged.
Test: atest DisplayCutoutTest
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index a0fa69e..e54b083 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -14,6 +14,10 @@
 
 package com.android.systemui;
 
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
@@ -21,12 +25,14 @@
 import static com.android.systemui.tuner.TunablePadding.FLAG_START;
 import static com.android.systemui.tuner.TunablePadding.FLAG_END;
 
+import android.annotation.Dimension;
 import android.app.Fragment;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.PixelFormat;
@@ -41,6 +47,7 @@
 import android.view.DisplayInfo;
 import android.view.Gravity;
 import android.view.LayoutInflater;
+import android.view.Surface;
 import android.view.View;
 import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup;
@@ -359,6 +366,7 @@
             if (!mBoundingPath.isEmpty()) {
                 mPaint.setColor(Color.BLACK);
                 mPaint.setStyle(Paint.Style.FILL);
+                mPaint.setAntiAlias(true);
                 canvas.drawPath(mBoundingPath, mPaint);
             }
         }
@@ -388,7 +396,7 @@
             if (hasCutout()) {
                 mBounds.set(mInfo.displayCutout.getBounds());
                 localBounds(mBoundingRect);
-                mInfo.displayCutout.getBounds().getBoundaryPath(mBoundingPath);
+                updateBoundingPath();
                 invalidate();
                 newVisible = VISIBLE;
             } else {
@@ -400,6 +408,44 @@
             }
         }
 
+        private void updateBoundingPath() {
+            int lw = mInfo.logicalWidth;
+            int lh = mInfo.logicalHeight;
+
+            boolean flipped = mInfo.rotation == ROTATION_90 || mInfo.rotation == ROTATION_270;
+
+            int dw = flipped ? lh : lw;
+            int dh = flipped ? lw : lh;
+
+            mBoundingPath.set(DisplayCutout.pathFromResources(getResources(), lw, lh));
+            Matrix m = new Matrix();
+            transformPhysicalToLogicalCoordinates(mInfo.rotation, dw, dh, m);
+            mBoundingPath.transform(m);
+        }
+
+        private static void transformPhysicalToLogicalCoordinates(@Surface.Rotation int rotation,
+                @Dimension int physicalWidth, @Dimension int physicalHeight, Matrix out) {
+            switch (rotation) {
+                case ROTATION_0:
+                    out.reset();
+                    break;
+                case ROTATION_90:
+                    out.setRotate(270);
+                    out.postTranslate(0, physicalWidth);
+                    break;
+                case ROTATION_180:
+                    out.setRotate(180);
+                    out.postTranslate(physicalWidth, physicalHeight);
+                    break;
+                case ROTATION_270:
+                    out.setRotate(90);
+                    out.postTranslate(physicalHeight, 0);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown rotation: " + rotation);
+            }
+        }
+
         private boolean hasCutout() {
             final DisplayCutout displayCutout = mInfo.displayCutout;
             if (displayCutout == null) {