Replace DisplayManager.getStableDisplaySize with max Display.Mode

The DisplayManager.getStableDisplaySize is not the right way to get the
size we want for screen decorations and display team is going to get rid
of it.

Instead, we use the maximum display size supported by the display as the
base size to define the cutout and rounded corner configs.

Also fixed a bug that DisplayCutoutBaseView didn't update the
shoudDrawCutout config when display change.

Bug: 230227839
Test: 1. On foldable device, fold and unfold the device and check if the
         cutout is correctly drawn.
      2. On device supporting multiple resolutions, switch resolution
         between FHD & QHD and check if the cutout is correctly drawn.
Test: atest LocalDisplayAdapterTest DisplayCutoutTest
           ScreenDecorationsTest RoundedCornersTest
           DisplayCutoutBaseViewTest
Change-Id: I7a602b5abd7d6a21d17eae4f8e99414eaf765fa5
diff --git a/core/java/android/util/DisplayUtils.java b/core/java/android/util/DisplayUtils.java
index 9b76fc2..cbb38a4 100644
--- a/core/java/android/util/DisplayUtils.java
+++ b/core/java/android/util/DisplayUtils.java
@@ -17,6 +17,7 @@
 package android.util;
 
 import android.content.res.Resources;
+import android.view.Display;
 
 import com.android.internal.R;
 
@@ -53,15 +54,33 @@
     }
 
     /**
-     * Get the display size ratio based on the stable display size.
+     * Returns the Display.Mode with maximum resolution.
+     */
+    public static Display.Mode getMaximumResolutionDisplayMode(Display.Mode[] modes) {
+        if (modes == null || modes.length == 0) {
+            return null;
+        }
+        int maxWidth = 0;
+        Display.Mode target = null;
+        for (Display.Mode mode : modes) {
+            if (mode.getPhysicalWidth() > maxWidth) {
+                maxWidth = mode.getPhysicalWidth();
+                target = mode;
+            }
+        }
+        return target;
+    }
+
+    /**
+     * Get the display size ratio based on the physical display size.
      */
     public static float getPhysicalPixelDisplaySizeRatio(
-            int stableWidth, int stableHeight, int currentWidth, int currentHeight) {
-        if (stableWidth == currentWidth && stableHeight == currentHeight) {
+            int physicalWidth, int physicalHeight, int currentWidth, int currentHeight) {
+        if (physicalWidth == currentWidth && physicalHeight == currentHeight) {
             return 1f;
         }
-        final float widthRatio = (float) currentWidth / stableWidth;
-        final float heightRatio = (float) currentHeight / stableHeight;
+        final float widthRatio = (float) currentWidth / physicalWidth;
+        final float heightRatio = (float) currentHeight / physicalHeight;
         return Math.min(widthRatio, heightRatio);
     }
 }
diff --git a/core/java/android/view/CutoutSpecification.java b/core/java/android/view/CutoutSpecification.java
index bb6005c..f8aa934 100644
--- a/core/java/android/view/CutoutSpecification.java
+++ b/core/java/android/view/CutoutSpecification.java
@@ -203,8 +203,8 @@
     public static class Parser {
         private final boolean mIsShortEdgeOnTop;
         private final float mStableDensity;
-        private final int mStableDisplayWidth;
-        private final int mStableDisplayHeight;
+        private final int mPhysicalDisplayWidth;
+        private final int mPhysicalDisplayHeight;
         private final float mPhysicalPixelDisplaySizeRatio;
         private final Matrix mMatrix;
         private Insets mInsets;
@@ -238,25 +238,26 @@
         private boolean mIsCloserToStartSide;
 
         @VisibleForTesting(visibility = PACKAGE)
-        public Parser(float stableDensity, int stableDisplayWidth, int stableDisplayHeight) {
-            this(stableDensity, stableDisplayWidth, stableDisplayHeight, 1f);
+        public Parser(float stableDensity, int physicalDisplayWidth,
+                int physicalDisplayHeight) {
+            this(stableDensity, physicalDisplayWidth, physicalDisplayHeight, 1f);
         }
 
         /**
          * The constructor of the CutoutSpecification parser to parse the specification of cutout.
          * @param stableDensity the display density.
-         * @param stableDisplayWidth the display width.
-         * @param stableDisplayHeight the display height.
+         * @param physicalDisplayWidth the display width.
+         * @param physicalDisplayHeight the display height.
          * @param physicalPixelDisplaySizeRatio the display size ratio based on stable display size.
          */
-        Parser(float stableDensity, int stableDisplayWidth, int stableDisplayHeight,
+        Parser(float stableDensity, int physicalDisplayWidth, int physicalDisplayHeight,
                 float physicalPixelDisplaySizeRatio) {
             mStableDensity = stableDensity;
-            mStableDisplayWidth = stableDisplayWidth;
-            mStableDisplayHeight = stableDisplayHeight;
+            mPhysicalDisplayWidth = physicalDisplayWidth;
+            mPhysicalDisplayHeight = physicalDisplayHeight;
             mPhysicalPixelDisplaySizeRatio = physicalPixelDisplaySizeRatio;
             mMatrix = new Matrix();
-            mIsShortEdgeOnTop = mStableDisplayWidth < mStableDisplayHeight;
+            mIsShortEdgeOnTop = mPhysicalDisplayWidth < mPhysicalDisplayHeight;
         }
 
         private void computeBoundsRectAndAddToRegion(Path p, Region inoutRegion, Rect inoutRect) {
@@ -281,18 +282,18 @@
         private void translateMatrix() {
             final float offsetX;
             if (mPositionFromRight) {
-                offsetX = mStableDisplayWidth;
+                offsetX = mPhysicalDisplayWidth;
             } else if (mPositionFromLeft) {
                 offsetX = 0;
             } else {
-                offsetX = mStableDisplayWidth / 2f;
+                offsetX = mPhysicalDisplayWidth / 2f;
             }
 
             final float offsetY;
             if (mPositionFromBottom) {
-                offsetY = mStableDisplayHeight;
+                offsetY = mPhysicalDisplayHeight;
             } else if (mPositionFromCenterVertical) {
-                offsetY = mStableDisplayHeight / 2f;
+                offsetY = mPhysicalDisplayHeight / 2f;
             } else {
                 offsetY = 0;
             }
@@ -305,14 +306,14 @@
         }
 
         private int computeSafeInsets(int gravity, Rect rect) {
-            if (gravity == LEFT && rect.right > 0 && rect.right < mStableDisplayWidth) {
+            if (gravity == LEFT && rect.right > 0 && rect.right < mPhysicalDisplayWidth) {
                 return rect.right;
-            } else if (gravity == TOP && rect.bottom > 0 && rect.bottom < mStableDisplayHeight) {
+            } else if (gravity == TOP && rect.bottom > 0 && rect.bottom < mPhysicalDisplayHeight) {
                 return rect.bottom;
-            } else if (gravity == RIGHT && rect.left > 0 && rect.left < mStableDisplayWidth) {
-                return mStableDisplayWidth - rect.left;
-            } else if (gravity == BOTTOM && rect.top > 0 && rect.top < mStableDisplayHeight) {
-                return mStableDisplayHeight - rect.top;
+            } else if (gravity == RIGHT && rect.left > 0 && rect.left < mPhysicalDisplayWidth) {
+                return mPhysicalDisplayWidth - rect.left;
+            } else if (gravity == BOTTOM && rect.top > 0 && rect.top < mPhysicalDisplayHeight) {
+                return mPhysicalDisplayHeight - rect.top;
             }
             return 0;
         }
@@ -415,12 +416,12 @@
 
             if (mIsShortEdgeOnTop) {
                 mIsTouchShortEdgeStart = mTmpRect.top <= 0;
-                mIsTouchShortEdgeEnd = mTmpRect.bottom >= mStableDisplayHeight;
-                mIsCloserToStartSide = mTmpRect.centerY() < mStableDisplayHeight / 2;
+                mIsTouchShortEdgeEnd = mTmpRect.bottom >= mPhysicalDisplayHeight;
+                mIsCloserToStartSide = mTmpRect.centerY() < mPhysicalDisplayHeight / 2;
             } else {
                 mIsTouchShortEdgeStart = mTmpRect.left <= 0;
-                mIsTouchShortEdgeEnd = mTmpRect.right >= mStableDisplayWidth;
-                mIsCloserToStartSide = mTmpRect.centerX() < mStableDisplayWidth / 2;
+                mIsTouchShortEdgeEnd = mTmpRect.right >= mPhysicalDisplayWidth;
+                mIsCloserToStartSide = mTmpRect.centerX() < mPhysicalDisplayWidth / 2;
             }
 
             setEdgeCutout(newPath);
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index ece8460..83a7b3f 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -77,8 +77,8 @@
 
     private static final Rect ZERO_RECT = new Rect();
     private static final CutoutPathParserInfo EMPTY_PARSER_INFO = new CutoutPathParserInfo(
-            0 /* displayWidth */, 0 /* stableDisplayHeight */,
-            0 /* stableDisplayHeight */, 0 /* displayHeight */, 0f /* density */,
+            0 /* displayWidth */, 0 /* physicalDisplayHeight */,
+            0 /* physicalDisplayHeight */, 0 /* displayHeight */, 0f /* density */,
             "" /* cutoutSpec */, 0 /* ROTATION_0 */, 0f /* scale */,
             0f /* physicalPixelDisplaySizeRatio*/);
 
@@ -258,21 +258,21 @@
     public static class CutoutPathParserInfo {
         private final int mDisplayWidth;
         private final int mDisplayHeight;
-        private final int mStableDisplayWidth;
-        private final int mStableDisplayHeight;
+        private final int mPhysicalDisplayWidth;
+        private final int mPhysicalDisplayHeight;
         private final float mDensity;
         private final String mCutoutSpec;
         private final @Rotation int mRotation;
         private final float mScale;
         private final float mPhysicalPixelDisplaySizeRatio;
 
-        public CutoutPathParserInfo(int displayWidth, int displayHeight, int stableDisplayWidth,
-                int stableDisplayHeight, float density, @Nullable String cutoutSpec,
+        public CutoutPathParserInfo(int displayWidth, int displayHeight, int physicalDisplayWidth,
+                int physicalDisplayHeight, float density, @Nullable String cutoutSpec,
                 @Rotation int rotation, float scale, float physicalPixelDisplaySizeRatio) {
             mDisplayWidth = displayWidth;
             mDisplayHeight = displayHeight;
-            mStableDisplayWidth = stableDisplayWidth;
-            mStableDisplayHeight = stableDisplayHeight;
+            mPhysicalDisplayWidth = physicalDisplayWidth;
+            mPhysicalDisplayHeight = physicalDisplayHeight;
             mDensity = density;
             mCutoutSpec = cutoutSpec == null ? "" : cutoutSpec;
             mRotation = rotation;
@@ -283,8 +283,8 @@
         public CutoutPathParserInfo(@NonNull CutoutPathParserInfo cutoutPathParserInfo) {
             mDisplayWidth = cutoutPathParserInfo.mDisplayWidth;
             mDisplayHeight = cutoutPathParserInfo.mDisplayHeight;
-            mStableDisplayWidth = cutoutPathParserInfo.mStableDisplayWidth;
-            mStableDisplayHeight = cutoutPathParserInfo.mStableDisplayHeight;
+            mPhysicalDisplayWidth = cutoutPathParserInfo.mPhysicalDisplayWidth;
+            mPhysicalDisplayHeight = cutoutPathParserInfo.mPhysicalDisplayHeight;
             mDensity = cutoutPathParserInfo.mDensity;
             mCutoutSpec = cutoutPathParserInfo.mCutoutSpec;
             mRotation = cutoutPathParserInfo.mRotation;
@@ -300,12 +300,12 @@
             return mDisplayHeight;
         }
 
-        public int getStableDisplayWidth() {
-            return mStableDisplayWidth;
+        public int getPhysicalDisplayWidth() {
+            return mPhysicalDisplayWidth;
         }
 
-        public int getStableDisplayHeight() {
-            return mStableDisplayHeight;
+        public int getPhysicalDisplayHeight() {
+            return mPhysicalDisplayHeight;
         }
 
         public float getDensity() {
@@ -342,8 +342,8 @@
             result = result * 48271 + Integer.hashCode(mRotation);
             result = result * 48271 + Float.hashCode(mScale);
             result = result * 48271 + Float.hashCode(mPhysicalPixelDisplaySizeRatio);
-            result = result * 48271 + Integer.hashCode(mStableDisplayWidth);
-            result = result * 48271 + Integer.hashCode(mStableDisplayHeight);
+            result = result * 48271 + Integer.hashCode(mPhysicalDisplayWidth);
+            result = result * 48271 + Integer.hashCode(mPhysicalDisplayHeight);
             return result;
         }
 
@@ -355,8 +355,8 @@
             if (o instanceof CutoutPathParserInfo) {
                 CutoutPathParserInfo c = (CutoutPathParserInfo) o;
                 return mDisplayWidth == c.mDisplayWidth && mDisplayHeight == c.mDisplayHeight
-                        && mStableDisplayWidth == c.mStableDisplayWidth
-                        && mStableDisplayHeight == c.mStableDisplayHeight
+                        && mPhysicalDisplayWidth == c.mPhysicalDisplayWidth
+                        && mPhysicalDisplayHeight == c.mPhysicalDisplayHeight
                         && mDensity == c.mDensity && mCutoutSpec.equals(c.mCutoutSpec)
                         && mRotation == c.mRotation && mScale == c.mScale
                         && mPhysicalPixelDisplaySizeRatio == c.mPhysicalPixelDisplaySizeRatio;
@@ -368,8 +368,8 @@
         public String toString() {
             return "CutoutPathParserInfo{displayWidth=" + mDisplayWidth
                     + " displayHeight=" + mDisplayHeight
-                    + " stableDisplayHeight=" + mStableDisplayWidth
-                    + " stableDisplayHeight=" + mStableDisplayHeight
+                    + " physicalDisplayWidth=" + mPhysicalDisplayWidth
+                    + " physicalDisplayHeight=" + mPhysicalDisplayHeight
                     + " density={" + mDensity + "}"
                     + " cutoutSpec={" + mCutoutSpec + "}"
                     + " rotation={" + mRotation + "}"
@@ -750,8 +750,8 @@
             }
         }
         final CutoutSpecification cutoutSpec = new CutoutSpecification.Parser(
-                mCutoutPathParserInfo.getDensity(), mCutoutPathParserInfo.getStableDisplayWidth(),
-                mCutoutPathParserInfo.getStableDisplayHeight(),
+                mCutoutPathParserInfo.getDensity(), mCutoutPathParserInfo.getPhysicalDisplayWidth(),
+                mCutoutPathParserInfo.getPhysicalDisplayHeight(),
                 mCutoutPathParserInfo.getPhysicalPixelDisplaySizeRatio())
                 .parse(mCutoutPathParserInfo.getCutoutSpec());
 
@@ -1053,11 +1053,11 @@
      * @hide
      */
     public static DisplayCutout fromResourcesRectApproximation(Resources res,
-            String displayUniqueId, int stableDisplayWidth, int stableDisplayHeight,
+            String displayUniqueId, int physicalDisplayWidth, int physicalDisplayHeight,
             int displayWidth, int displayHeight) {
         return pathAndDisplayCutoutFromSpec(getDisplayCutoutPath(res, displayUniqueId),
-                getDisplayCutoutApproximationRect(res, displayUniqueId), stableDisplayWidth,
-                stableDisplayHeight, displayWidth, displayHeight,
+                getDisplayCutoutApproximationRect(res, displayUniqueId), physicalDisplayWidth,
+                physicalDisplayHeight, displayWidth, displayHeight,
                 DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT,
                 getWaterfallInsets(res, displayUniqueId)).second;
     }
@@ -1080,8 +1080,8 @@
      *
      * @param pathSpec the spec string read from config_mainBuiltInDisplayCutout.
      * @param rectSpec the spec string read from config_mainBuiltInDisplayCutoutRectApproximation.
-     * @param stableDisplayWidth the stable display width.
-     * @param stableDisplayHeight the stable display height.
+     * @param physicalDisplayWidth the max physical display width the display supports.
+     * @param physicalDisplayHeight the max physical display height the display supports.
      * @param displayWidth the display width.
      * @param displayHeight the display height.
      * @param density the display density.
@@ -1089,7 +1089,7 @@
      * @return a Pair contains the cutout path and the corresponding DisplayCutout instance.
      */
     private static Pair<Path, DisplayCutout> pathAndDisplayCutoutFromSpec(
-            String pathSpec, String rectSpec, int stableDisplayWidth, int stableDisplayHeight,
+            String pathSpec, String rectSpec, int physicalDisplayWidth, int physicalDisplayHeight,
             int displayWidth, int displayHeight, float density, Insets waterfallInsets) {
         // Always use the rect approximation spec to create the cutout if it's not null because
         // transforming and sending a Region constructed from a path is very costly.
@@ -1099,7 +1099,7 @@
         }
 
         final float physicalPixelDisplaySizeRatio = DisplayUtils.getPhysicalPixelDisplaySizeRatio(
-                stableDisplayWidth, stableDisplayHeight, displayWidth, displayHeight);
+                physicalDisplayWidth, physicalDisplayHeight, displayWidth, displayHeight);
 
         synchronized (CACHE_LOCK) {
             if (spec.equals(sCachedSpec) && sCachedDisplayWidth == displayWidth
@@ -1114,7 +1114,8 @@
         spec = spec.trim();
 
         CutoutSpecification cutoutSpec = new CutoutSpecification.Parser(density,
-                stableDisplayWidth, stableDisplayHeight, physicalPixelDisplaySizeRatio).parse(spec);
+                physicalDisplayWidth, physicalDisplayHeight, physicalPixelDisplaySizeRatio)
+                .parse(spec);
         Rect safeInset = cutoutSpec.getSafeInset();
         final Rect boundLeft = cutoutSpec.getLeftBound();
         final Rect boundTop = cutoutSpec.getTopBound();
@@ -1131,7 +1132,7 @@
         }
 
         final CutoutPathParserInfo cutoutPathParserInfo = new CutoutPathParserInfo(
-                displayWidth, displayHeight, stableDisplayWidth, stableDisplayHeight, density,
+                displayWidth, displayHeight, physicalDisplayWidth, physicalDisplayHeight, density,
                 pathSpec.trim(), ROTATION_0, 1f /* scale */, physicalPixelDisplaySizeRatio);
 
         final DisplayCutout cutout = new DisplayCutout(
@@ -1182,9 +1183,9 @@
         Collections.rotate(Arrays.asList(newBounds), -rotation);
         final CutoutPathParserInfo info = getCutoutPathParserInfo();
         final CutoutPathParserInfo newInfo = new CutoutPathParserInfo(
-                info.getDisplayWidth(), info.getDisplayHeight(), info.getStableDisplayWidth(),
-                info.getStableDisplayHeight(), info.getDensity(), info.getCutoutSpec(), toRotation,
-                info.getScale(), info.getPhysicalPixelDisplaySizeRatio());
+                info.getDisplayWidth(), info.getDisplayHeight(), info.getPhysicalDisplayWidth(),
+                info.getPhysicalDisplayHeight(), info.getDensity(), info.getCutoutSpec(),
+                toRotation, info.getScale(), info.getPhysicalPixelDisplaySizeRatio());
         final boolean swapAspect = (rotation % 2) != 0;
         final int endWidth = swapAspect ? startHeight : startWidth;
         final int endHeight = swapAspect ? startWidth : startHeight;
@@ -1284,8 +1285,8 @@
                 out.writeTypedObject(cutout.mWaterfallInsets, flags);
                 out.writeInt(cutout.mCutoutPathParserInfo.getDisplayWidth());
                 out.writeInt(cutout.mCutoutPathParserInfo.getDisplayHeight());
-                out.writeInt(cutout.mCutoutPathParserInfo.getStableDisplayWidth());
-                out.writeInt(cutout.mCutoutPathParserInfo.getStableDisplayHeight());
+                out.writeInt(cutout.mCutoutPathParserInfo.getPhysicalDisplayWidth());
+                out.writeInt(cutout.mCutoutPathParserInfo.getPhysicalDisplayHeight());
                 out.writeFloat(cutout.mCutoutPathParserInfo.getDensity());
                 out.writeString(cutout.mCutoutPathParserInfo.getCutoutSpec());
                 out.writeInt(cutout.mCutoutPathParserInfo.getRotation());
@@ -1336,16 +1337,16 @@
             Insets waterfallInsets = in.readTypedObject(Insets.CREATOR);
             int displayWidth = in.readInt();
             int displayHeight = in.readInt();
-            int stableDisplayWidth = in.readInt();
-            int stableDisplayHeight = in.readInt();
+            int physicalDisplayWidth = in.readInt();
+            int physicalDisplayHeight = in.readInt();
             float density = in.readFloat();
             String cutoutSpec = in.readString();
             int rotation = in.readInt();
             float scale = in.readFloat();
             float physicalPixelDisplaySizeRatio = in.readFloat();
             final CutoutPathParserInfo info = new CutoutPathParserInfo(
-                    displayWidth, displayHeight, stableDisplayWidth, stableDisplayHeight, density,
-                    cutoutSpec, rotation, scale, physicalPixelDisplaySizeRatio);
+                    displayWidth, displayHeight, physicalDisplayWidth, physicalDisplayHeight,
+                    density, cutoutSpec, rotation, scale, physicalPixelDisplaySizeRatio);
 
             return new DisplayCutout(
                     safeInsets, waterfallInsets, bounds, info, false /* copyArguments */);
@@ -1373,8 +1374,8 @@
             final CutoutPathParserInfo info = new CutoutPathParserInfo(
                     mInner.mCutoutPathParserInfo.getDisplayWidth(),
                     mInner.mCutoutPathParserInfo.getDisplayHeight(),
-                    mInner.mCutoutPathParserInfo.getStableDisplayWidth(),
-                    mInner.mCutoutPathParserInfo.getStableDisplayHeight(),
+                    mInner.mCutoutPathParserInfo.getPhysicalDisplayWidth(),
+                    mInner.mCutoutPathParserInfo.getPhysicalDisplayHeight(),
                     mInner.mCutoutPathParserInfo.getDensity(),
                     mInner.mCutoutPathParserInfo.getCutoutSpec(),
                     mInner.mCutoutPathParserInfo.getRotation(),
diff --git a/core/java/android/view/RoundedCorners.java b/core/java/android/view/RoundedCorners.java
index 9f30487..f68cc69 100644
--- a/core/java/android/view/RoundedCorners.java
+++ b/core/java/android/view/RoundedCorners.java
@@ -98,10 +98,10 @@
      * @android:dimen/rounded_corner_radius_top and @android:dimen/rounded_corner_radius_bottom
      */
     public static RoundedCorners fromResources(
-            Resources res, String displayUniqueId, int stableDisplayWidth, int stableDisplayHeight,
-            int displayWidth, int displayHeight) {
-        return fromRadii(loadRoundedCornerRadii(res, displayUniqueId), stableDisplayWidth,
-                stableDisplayHeight, displayWidth, displayHeight);
+            Resources res, String displayUniqueId, int physicalDisplayWidth,
+            int physicalDisplayHeight, int displayWidth, int displayHeight) {
+        return fromRadii(loadRoundedCornerRadii(res, displayUniqueId), physicalDisplayWidth,
+                physicalDisplayHeight, displayWidth, displayHeight);
     }
 
     /**
@@ -113,14 +113,14 @@
         return fromRadii(radii, displayWidth, displayHeight, displayWidth, displayHeight);
     }
 
-    private static RoundedCorners fromRadii(Pair<Integer, Integer> radii, int stableDisplayWidth,
-            int stableDisplayHeight, int displayWidth, int displayHeight) {
+    private static RoundedCorners fromRadii(Pair<Integer, Integer> radii, int physicalDisplayWidth,
+            int physicalDisplayHeight, int displayWidth, int displayHeight) {
         if (radii == null) {
             return null;
         }
 
         final float physicalPixelDisplaySizeRatio = DisplayUtils.getPhysicalPixelDisplaySizeRatio(
-                stableDisplayWidth, stableDisplayHeight, displayWidth, displayHeight);
+                physicalDisplayWidth, physicalDisplayHeight, displayWidth, displayHeight);
 
         synchronized (CACHE_LOCK) {
             if (radii.equals(sCachedRadii) && sCachedDisplayWidth == displayWidth
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 70766cc..16f14c9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3527,6 +3527,9 @@
          appended after the path string to interpret coordinates in dp instead of px units.
          Note that a physical cutout should be configured in pixels for the best results.
 
+         If the display supports multiple resolutions, please define the path config based on the
+         highest resolution so that it can be scaled correctly in each resolution.
+
          Example for a 10px x 10px square top-center cutout:
                 <string ...>M -5,0 L -5,10 L 5,10 L 5,0 Z</string>
          Example for a 10dp x 10dp square top-center cutout:
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
index fedb998..47f1e2e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java
@@ -423,8 +423,8 @@
         }
         final DisplayCutout.CutoutPathParserInfo info = cutout.getCutoutPathParserInfo();
         final DisplayCutout.CutoutPathParserInfo newInfo = new DisplayCutout.CutoutPathParserInfo(
-                info.getDisplayWidth(), info.getDisplayHeight(), info.getStableDisplayWidth(),
-                info.getStableDisplayHeight(), info.getDensity(), info.getCutoutSpec(), rotation,
+                info.getDisplayWidth(), info.getDisplayHeight(), info.getPhysicalDisplayWidth(),
+                info.getPhysicalDisplayHeight(), info.getDensity(), info.getCutoutSpec(), rotation,
                 info.getScale(), info.getPhysicalPixelDisplaySizeRatio());
         return computeSafeInsets(
                 DisplayCutout.constructDisplayCutout(newBounds, waterfallInsets, newInfo),
diff --git a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
index 032a27a..8ab1ab7 100644
--- a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
+++ b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
@@ -46,8 +46,9 @@
  */
 open class DisplayCutoutBaseView : View, RegionInterceptableView {
 
-    private val shouldDrawCutout: Boolean = DisplayCutout.getFillBuiltInDisplayCutout(
+    private var shouldDrawCutout: Boolean = DisplayCutout.getFillBuiltInDisplayCutout(
             context.resources, context.display?.uniqueId)
+    private var displayUniqueId: String? = null
     private var displayMode: Display.Mode? = null
     protected val location = IntArray(2)
     protected var displayRotation = 0
@@ -78,6 +79,7 @@
 
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
+        displayUniqueId = context.display?.uniqueId
         updateCutout()
         updateProtectionBoundingPath()
         onUpdate()
@@ -87,6 +89,12 @@
         val oldMode: Display.Mode? = displayMode
         displayMode = display.mode
 
+        if (displayUniqueId != context.display?.uniqueId) {
+            displayUniqueId = context.display?.uniqueId
+            shouldDrawCutout = DisplayCutout.getFillBuiltInDisplayCutout(
+                    context.resources, displayUniqueId)
+        }
+
         // Skip if display mode or cutout hasn't changed.
         if (!displayModeChanged(oldMode, displayMode) &&
                 display.cutout == displayInfo.displayCutout) {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 088dfb4..c04463a 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -39,7 +39,6 @@
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.PixelFormat;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
@@ -926,11 +925,15 @@
 
     @VisibleForTesting
     float getPhysicalPixelDisplaySizeRatio() {
-        final Point stableDisplaySize = mDisplayManager.getStableDisplaySize();
         mContext.getDisplay().getDisplayInfo(mDisplayInfo);
+        final Display.Mode maxDisplayMode =
+                DisplayUtils.getMaximumResolutionDisplayMode(mDisplayInfo.supportedModes);
+        if (maxDisplayMode == null) {
+            return 1f;
+        }
         return DisplayUtils.getPhysicalPixelDisplaySizeRatio(
-                stableDisplaySize.x, stableDisplaySize.y, mDisplayInfo.getNaturalWidth(),
-                mDisplayInfo.getNaturalHeight());
+                maxDisplayMode.getPhysicalWidth(), maxDisplayMode.getPhysicalHeight(),
+                mDisplayInfo.getNaturalWidth(), mDisplayInfo.getNaturalHeight());
     }
 
     @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt
index 55f0591..a4e0825 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt
@@ -169,6 +169,7 @@
 
         cutoutBaseView = spy(DisplayCutoutBaseView(mContext))
         whenever(cutoutBaseView.display).thenReturn(mockDisplay)
+        whenever(mockDisplay.uniqueId).thenReturn("mockDisplayUniqueId")
         whenever(cutoutBaseView.rootView).thenReturn(mockRootView)
         whenever(cutoutBaseView.getPhysicalPixelDisplaySizeRatio()).thenReturn(1f)
         whenever(mockDisplay.getDisplayInfo(eq(cutoutBaseView.displayInfo))
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index fa2f500..2a21928 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -22,8 +22,6 @@
 import android.app.ActivityThread;
 import android.content.Context;
 import android.content.res.Resources;
-import android.graphics.Point;
-import android.hardware.display.DisplayManager;
 import android.hardware.sidekick.SidekickInternal;
 import android.os.Build;
 import android.os.Handler;
@@ -32,6 +30,7 @@
 import android.os.PowerManager;
 import android.os.SystemProperties;
 import android.os.Trace;
+import android.util.DisplayUtils;
 import android.util.LongSparseArray;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -680,15 +679,17 @@
                     mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT;
                 }
 
-                final Point stableDisplaySize = getOverlayContext()
-                        .getSystemService(DisplayManager.class).getStableDisplaySize();
+                final Display.Mode maxDisplayMode =
+                        DisplayUtils.getMaximumResolutionDisplayMode(mInfo.supportedModes);
+                final int maxWidth =
+                        maxDisplayMode == null ? mInfo.width : maxDisplayMode.getPhysicalWidth();
+                final int maxHeight =
+                        maxDisplayMode == null ? mInfo.height : maxDisplayMode.getPhysicalHeight();
                 mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
-                        mInfo.uniqueId, stableDisplaySize.x, stableDisplaySize.y, mInfo.width,
-                        mInfo.height);
+                        mInfo.uniqueId, maxWidth, maxHeight, mInfo.width, mInfo.height);
 
                 mInfo.roundedCorners = RoundedCorners.fromResources(
-                        res, mInfo.uniqueId, stableDisplaySize.x, stableDisplaySize.y, mInfo.width,
-                        mInfo.height);
+                        res, mInfo.uniqueId, maxWidth, maxHeight, mInfo.width, mInfo.height);
                 mInfo.installOrientation = mStaticDisplayInfo.installOrientation;
 
                 if (mStaticDisplayInfo.isInternal) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c60dfa1..94f4382 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -190,6 +190,7 @@
 import android.provider.Settings;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
+import android.util.DisplayUtils;
 import android.util.IntArray;
 import android.util.RotationUtils;
 import android.util.Size;
@@ -359,7 +360,7 @@
     float mInitialPhysicalXDpi = 0.0f;
     float mInitialPhysicalYDpi = 0.0f;
 
-    private Point mStableDisplaySize;
+    private Point mPhysicalDisplaySize;
 
     DisplayCutout mInitialDisplayCutout;
     private final RotationCache<DisplayCutout, WmDisplayCutout> mDisplayCutoutCache
@@ -2731,7 +2732,12 @@
         mInitialRoundedCorners = mDisplayInfo.roundedCorners;
         mCurrentPrivacyIndicatorBounds = new PrivacyIndicatorBounds(new Rect[4],
                 mDisplayInfo.rotation);
-        mStableDisplaySize = mWmService.mDisplayManager.getStableDisplaySize();
+        final Display.Mode maxDisplayMode =
+                DisplayUtils.getMaximumResolutionDisplayMode(mDisplayInfo.supportedModes);
+        mPhysicalDisplaySize = new Point(
+                maxDisplayMode == null ? mInitialDisplayWidth : maxDisplayMode.getPhysicalWidth(),
+                maxDisplayMode == null ? mInitialDisplayHeight : maxDisplayMode.getPhysicalHeight()
+        );
     }
 
     /**
@@ -2927,7 +2933,7 @@
         }
         return DisplayCutout.fromResourcesRectApproximation(
                 mDisplayPolicy.getSystemUiContext().getResources(), mDisplayInfo.uniqueId,
-                mStableDisplaySize.x, mStableDisplaySize.y, displayWidth, displayHeight);
+                mPhysicalDisplaySize.x, mPhysicalDisplaySize.y, displayWidth, displayHeight);
     }
 
     RoundedCorners loadRoundedCorners(int displayWidth, int displayHeight) {
@@ -2936,7 +2942,7 @@
         }
         return RoundedCorners.fromResources(
                 mDisplayPolicy.getSystemUiContext().getResources(),  mDisplayInfo.uniqueId,
-                mStableDisplaySize.x, mStableDisplaySize.y, displayWidth, displayHeight);
+                mPhysicalDisplaySize.x, mPhysicalDisplaySize.y, displayWidth, displayHeight);
     }
 
     @Override
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index cc64797..617321b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -35,8 +35,6 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
-import android.graphics.Point;
-import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerInternal.RefreshRateRange;
 import android.os.Binder;
 import android.os.Handler;
@@ -95,11 +93,6 @@
     @Mock
     private LogicalLight mMockedBacklight;
 
-    @Mock
-    private DisplayManager mMockDisplayManager;
-    @Mock
-    private Point mMockDisplayStableSize;
-
     private Handler mHandler;
 
     private TestListener mListener = new TestListener();
@@ -130,8 +123,6 @@
                 mListener, mInjector);
         spyOn(mAdapter);
         doReturn(mMockedContext).when(mAdapter).getOverlayContext();
-        doReturn(mMockDisplayManager).when(mMockedContext).getSystemService(DisplayManager.class);
-        doReturn(mMockDisplayStableSize).when(mMockDisplayManager).getStableDisplaySize();
 
         TypedArray mockNitsRange = createFloatTypedArray(DISPLAY_RANGE_NITS);
         when(mMockedResources.obtainTypedArray(R.array.config_screenBrightnessNits))