diff --git a/core/java/android/util/DisplayUtils.java b/core/java/android/util/DisplayUtils.java index 4fe7f8369f734..9b76fc2ff0286 100644 --- a/core/java/android/util/DisplayUtils.java +++ b/core/java/android/util/DisplayUtils.java @@ -21,7 +21,7 @@ import android.content.res.Resources; import com.android.internal.R; /** - * Utils for loading resources for multi-display. + * Utils for loading display related resources and calculations. * * @hide */ @@ -51,4 +51,17 @@ public class DisplayUtils { } return index; } + + /** + * Get the display size ratio based on the stable display size. + */ + public static float getPhysicalPixelDisplaySizeRatio( + int stableWidth, int stableHeight, int currentWidth, int currentHeight) { + if (stableWidth == currentWidth && stableHeight == currentHeight) { + return 1f; + } + final float widthRatio = (float) currentWidth / stableWidth; + final float heightRatio = (float) currentHeight / stableHeight; + return Math.min(widthRatio, heightRatio); + } } diff --git a/core/java/android/view/CutoutSpecification.java b/core/java/android/view/CutoutSpecification.java index 850e9fc0db7eb..bb6005c763139 100644 --- a/core/java/android/view/CutoutSpecification.java +++ b/core/java/android/view/CutoutSpecification.java @@ -94,7 +94,7 @@ public class CutoutSpecification { private final Rect mTopBound; private final Rect mRightBound; private final Rect mBottomBound; - private final Insets mInsets; + private Insets mInsets; private CutoutSpecification(@NonNull Parser parser) { mPath = parser.mPath; @@ -104,6 +104,8 @@ public class CutoutSpecification { mBottomBound = parser.mBottomBound; mInsets = parser.mInsets; + applyPhysicalPixelDisplaySizeRatio(parser.mPhysicalPixelDisplaySizeRatio); + if (DEBUG) { Log.d(TAG, String.format(Locale.ENGLISH, "left cutout = %s, top cutout = %s, right cutout = %s, bottom cutout = %s", @@ -114,6 +116,38 @@ public class CutoutSpecification { } } + private void applyPhysicalPixelDisplaySizeRatio(float physicalPixelDisplaySizeRatio) { + if (physicalPixelDisplaySizeRatio == 1f) { + return; + } + + if (mPath != null && !mPath.isEmpty()) { + final Matrix matrix = new Matrix(); + matrix.postScale(physicalPixelDisplaySizeRatio, physicalPixelDisplaySizeRatio); + mPath.transform(matrix); + } + + scaleBounds(mLeftBound, physicalPixelDisplaySizeRatio); + scaleBounds(mTopBound, physicalPixelDisplaySizeRatio); + scaleBounds(mRightBound, physicalPixelDisplaySizeRatio); + scaleBounds(mBottomBound, physicalPixelDisplaySizeRatio); + mInsets = scaleInsets(mInsets, physicalPixelDisplaySizeRatio); + } + + private void scaleBounds(Rect r, float ratio) { + if (r != null && !r.isEmpty()) { + r.scale(ratio); + } + } + + private Insets scaleInsets(Insets insets, float ratio) { + return Insets.of( + (int) (insets.left * ratio + 0.5f), + (int) (insets.top * ratio + 0.5f), + (int) (insets.right * ratio + 0.5f), + (int) (insets.bottom * ratio + 0.5f)); + } + @VisibleForTesting(visibility = PACKAGE) @Nullable public Path getPath() { @@ -168,9 +202,10 @@ public class CutoutSpecification { @VisibleForTesting(visibility = PACKAGE) public static class Parser { private final boolean mIsShortEdgeOnTop; - private final float mDensity; - private final int mDisplayWidth; - private final int mDisplayHeight; + private final float mStableDensity; + private final int mStableDisplayWidth; + private final int mStableDisplayHeight; + private final float mPhysicalPixelDisplaySizeRatio; private final Matrix mMatrix; private Insets mInsets; private int mSafeInsetLeft; @@ -202,19 +237,26 @@ public class CutoutSpecification { private boolean mIsTouchShortEdgeEnd; private boolean mIsCloserToStartSide; + @VisibleForTesting(visibility = PACKAGE) + public Parser(float stableDensity, int stableDisplayWidth, int stableDisplayHeight) { + this(stableDensity, stableDisplayWidth, stableDisplayHeight, 1f); + } + /** * The constructor of the CutoutSpecification parser to parse the specification of cutout. - * @param density the display density. - * @param displayWidth the display width. - * @param displayHeight the display height. + * @param stableDensity the display density. + * @param stableDisplayWidth the display width. + * @param stableDisplayHeight the display height. + * @param physicalPixelDisplaySizeRatio the display size ratio based on stable display size. */ - @VisibleForTesting(visibility = PACKAGE) - public Parser(float density, int displayWidth, int displayHeight) { - mDensity = density; - mDisplayWidth = displayWidth; - mDisplayHeight = displayHeight; + Parser(float stableDensity, int stableDisplayWidth, int stableDisplayHeight, + float physicalPixelDisplaySizeRatio) { + mStableDensity = stableDensity; + mStableDisplayWidth = stableDisplayWidth; + mStableDisplayHeight = stableDisplayHeight; + mPhysicalPixelDisplaySizeRatio = physicalPixelDisplaySizeRatio; mMatrix = new Matrix(); - mIsShortEdgeOnTop = mDisplayWidth < mDisplayHeight; + mIsShortEdgeOnTop = mStableDisplayWidth < mStableDisplayHeight; } private void computeBoundsRectAndAddToRegion(Path p, Region inoutRegion, Rect inoutRect) { @@ -239,38 +281,38 @@ public class CutoutSpecification { private void translateMatrix() { final float offsetX; if (mPositionFromRight) { - offsetX = mDisplayWidth; + offsetX = mStableDisplayWidth; } else if (mPositionFromLeft) { offsetX = 0; } else { - offsetX = mDisplayWidth / 2f; + offsetX = mStableDisplayWidth / 2f; } final float offsetY; if (mPositionFromBottom) { - offsetY = mDisplayHeight; + offsetY = mStableDisplayHeight; } else if (mPositionFromCenterVertical) { - offsetY = mDisplayHeight / 2f; + offsetY = mStableDisplayHeight / 2f; } else { offsetY = 0; } mMatrix.reset(); if (mInDp) { - mMatrix.postScale(mDensity, mDensity); + mMatrix.postScale(mStableDensity, mStableDensity); } mMatrix.postTranslate(offsetX, offsetY); } private int computeSafeInsets(int gravity, Rect rect) { - if (gravity == LEFT && rect.right > 0 && rect.right < mDisplayWidth) { + if (gravity == LEFT && rect.right > 0 && rect.right < mStableDisplayWidth) { return rect.right; - } else if (gravity == TOP && rect.bottom > 0 && rect.bottom < mDisplayHeight) { + } else if (gravity == TOP && rect.bottom > 0 && rect.bottom < mStableDisplayHeight) { return rect.bottom; - } else if (gravity == RIGHT && rect.left > 0 && rect.left < mDisplayWidth) { - return mDisplayWidth - rect.left; - } else if (gravity == BOTTOM && rect.top > 0 && rect.top < mDisplayHeight) { - return mDisplayHeight - rect.top; + } 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; } return 0; } @@ -373,12 +415,12 @@ public class CutoutSpecification { if (mIsShortEdgeOnTop) { mIsTouchShortEdgeStart = mTmpRect.top <= 0; - mIsTouchShortEdgeEnd = mTmpRect.bottom >= mDisplayHeight; - mIsCloserToStartSide = mTmpRect.centerY() < mDisplayHeight / 2; + mIsTouchShortEdgeEnd = mTmpRect.bottom >= mStableDisplayHeight; + mIsCloserToStartSide = mTmpRect.centerY() < mStableDisplayHeight / 2; } else { mIsTouchShortEdgeStart = mTmpRect.left <= 0; - mIsTouchShortEdgeEnd = mTmpRect.right >= mDisplayWidth; - mIsCloserToStartSide = mTmpRect.centerX() < mDisplayWidth / 2; + mIsTouchShortEdgeEnd = mTmpRect.right >= mStableDisplayWidth; + mIsCloserToStartSide = mTmpRect.centerX() < mStableDisplayWidth / 2; } setEdgeCutout(newPath); @@ -476,7 +518,6 @@ public class CutoutSpecification { } parseSpecWithoutDp(spec); - mInsets = Insets.of(mSafeInsetLeft, mSafeInsetTop, mSafeInsetRight, mSafeInsetBottom); return new CutoutSpecification(this); } diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java index b3b7f10d8c7ef..ece8460014f53 100644 --- a/core/java/android/view/DisplayCutout.java +++ b/core/java/android/view/DisplayCutout.java @@ -77,8 +77,10 @@ public final class DisplayCutout { private static final Rect ZERO_RECT = new Rect(); private static final CutoutPathParserInfo EMPTY_PARSER_INFO = new CutoutPathParserInfo( - 0 /* displayWidth */, 0 /* displayHeight */, 0f /* density */, "" /* cutoutSpec */, - 0 /* rotation */, 0f /* scale */); + 0 /* displayWidth */, 0 /* stableDisplayHeight */, + 0 /* stableDisplayHeight */, 0 /* displayHeight */, 0f /* density */, + "" /* cutoutSpec */, 0 /* ROTATION_0 */, 0f /* scale */, + 0f /* physicalPixelDisplaySizeRatio*/); /** * An instance where {@link #isEmpty()} returns {@code true}. @@ -105,6 +107,8 @@ public final class DisplayCutout { private static Pair sCachedCutout = NULL_PAIR; @GuardedBy("CACHE_LOCK") private static Insets sCachedWaterfallInsets; + @GuardedBy("CACHE_LOCK") + private static float sCachedPhysicalPixelDisplaySizeRatio; @GuardedBy("CACHE_LOCK") private static CutoutPathParserInfo sCachedCutoutPathParserInfo; @@ -254,28 +258,38 @@ public final class DisplayCutout { public static class CutoutPathParserInfo { private final int mDisplayWidth; private final int mDisplayHeight; + private final int mStableDisplayWidth; + private final int mStableDisplayHeight; 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, float density, - @Nullable String cutoutSpec, @Rotation int rotation, float scale) { + public CutoutPathParserInfo(int displayWidth, int displayHeight, int stableDisplayWidth, + int stableDisplayHeight, float density, @Nullable String cutoutSpec, + @Rotation int rotation, float scale, float physicalPixelDisplaySizeRatio) { mDisplayWidth = displayWidth; mDisplayHeight = displayHeight; + mStableDisplayWidth = stableDisplayWidth; + mStableDisplayHeight = stableDisplayHeight; mDensity = density; mCutoutSpec = cutoutSpec == null ? "" : cutoutSpec; mRotation = rotation; mScale = scale; + mPhysicalPixelDisplaySizeRatio = physicalPixelDisplaySizeRatio; } public CutoutPathParserInfo(@NonNull CutoutPathParserInfo cutoutPathParserInfo) { mDisplayWidth = cutoutPathParserInfo.mDisplayWidth; mDisplayHeight = cutoutPathParserInfo.mDisplayHeight; + mStableDisplayWidth = cutoutPathParserInfo.mStableDisplayWidth; + mStableDisplayHeight = cutoutPathParserInfo.mStableDisplayHeight; mDensity = cutoutPathParserInfo.mDensity; mCutoutSpec = cutoutPathParserInfo.mCutoutSpec; mRotation = cutoutPathParserInfo.mRotation; mScale = cutoutPathParserInfo.mScale; + mPhysicalPixelDisplaySizeRatio = cutoutPathParserInfo.mPhysicalPixelDisplaySizeRatio; } public int getDisplayWidth() { @@ -286,6 +300,14 @@ public final class DisplayCutout { return mDisplayHeight; } + public int getStableDisplayWidth() { + return mStableDisplayWidth; + } + + public int getStableDisplayHeight() { + return mStableDisplayHeight; + } + public float getDensity() { return mDensity; } @@ -302,6 +324,10 @@ public final class DisplayCutout { return mScale; } + public float getPhysicalPixelDisplaySizeRatio() { + return mPhysicalPixelDisplaySizeRatio; + } + private boolean hasCutout() { return !mCutoutSpec.isEmpty(); } @@ -315,6 +341,9 @@ public final class DisplayCutout { result = result * 48271 + mCutoutSpec.hashCode(); 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); return result; } @@ -326,8 +355,11 @@ public final class DisplayCutout { if (o instanceof CutoutPathParserInfo) { CutoutPathParserInfo c = (CutoutPathParserInfo) o; return mDisplayWidth == c.mDisplayWidth && mDisplayHeight == c.mDisplayHeight + && mStableDisplayWidth == c.mStableDisplayWidth + && mStableDisplayHeight == c.mStableDisplayHeight && mDensity == c.mDensity && mCutoutSpec.equals(c.mCutoutSpec) - && mRotation == c.mRotation && mScale == c.mScale; + && mRotation == c.mRotation && mScale == c.mScale + && mPhysicalPixelDisplaySizeRatio == c.mPhysicalPixelDisplaySizeRatio; } return false; } @@ -336,10 +368,13 @@ public final class DisplayCutout { public String toString() { return "CutoutPathParserInfo{displayWidth=" + mDisplayWidth + " displayHeight=" + mDisplayHeight + + " stableDisplayHeight=" + mStableDisplayWidth + + " stableDisplayHeight=" + mStableDisplayHeight + " density={" + mDensity + "}" + " cutoutSpec={" + mCutoutSpec + "}" + " rotation={" + mRotation + "}" + " scale={" + mScale + "}" + + " physicalPixelDisplaySizeRatio={" + mPhysicalPixelDisplaySizeRatio + "}" + "}"; } } @@ -715,8 +750,9 @@ public final class DisplayCutout { } } final CutoutSpecification cutoutSpec = new CutoutSpecification.Parser( - mCutoutPathParserInfo.getDensity(), mCutoutPathParserInfo.getDisplayWidth(), - mCutoutPathParserInfo.getDisplayHeight()) + mCutoutPathParserInfo.getDensity(), mCutoutPathParserInfo.getStableDisplayWidth(), + mCutoutPathParserInfo.getStableDisplayHeight(), + mCutoutPathParserInfo.getPhysicalPixelDisplaySizeRatio()) .parse(mCutoutPathParserInfo.getCutoutSpec()); final Path cutoutPath = cutoutSpec.getPath(); @@ -1014,29 +1050,18 @@ public final class DisplayCutout { * Creates the display cutout according to * @android:string/config_mainBuiltInDisplayCutoutRectApproximation, which is the closest * rectangle-base approximation of the cutout. - * * @hide */ public static DisplayCutout fromResourcesRectApproximation(Resources res, - String displayUniqueId, int displayWidth, int displayHeight) { + String displayUniqueId, int stableDisplayWidth, int stableDisplayHeight, + int displayWidth, int displayHeight) { return pathAndDisplayCutoutFromSpec(getDisplayCutoutPath(res, displayUniqueId), - getDisplayCutoutApproximationRect(res, displayUniqueId), - displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT, + getDisplayCutoutApproximationRect(res, displayUniqueId), stableDisplayWidth, + stableDisplayHeight, displayWidth, displayHeight, + DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT, getWaterfallInsets(res, displayUniqueId)).second; } - /** - * Creates an instance according to @android:string/config_mainBuiltInDisplayCutout. - * - * @hide - */ - public static Path pathFromResources(Resources res, String displayUniqueId, int displayWidth, - int displayHeight) { - return pathAndDisplayCutoutFromSpec(getDisplayCutoutPath(res, displayUniqueId), null, - displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT, - getWaterfallInsets(res, displayUniqueId)).first; - } - /** * Creates an instance according to the supplied {@link android.util.PathParser.PathData} spec. * @@ -1046,8 +1071,8 @@ public final class DisplayCutout { public static DisplayCutout fromSpec(String pathSpec, int displayWidth, int displayHeight, float density, Insets waterfallInsets) { return pathAndDisplayCutoutFromSpec( - pathSpec, null, displayWidth, displayHeight, density, waterfallInsets) - .second; + pathSpec, null, displayWidth, displayHeight, displayWidth, displayHeight, density, + waterfallInsets).second; } /** @@ -1055,6 +1080,8 @@ public final class DisplayCutout { * * @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 displayWidth the display width. * @param displayHeight the display height. * @param density the display density. @@ -1062,8 +1089,8 @@ public final class DisplayCutout { * @return a Pair contains the cutout path and the corresponding DisplayCutout instance. */ private static Pair pathAndDisplayCutoutFromSpec( - String pathSpec, String rectSpec, int displayWidth, int displayHeight, float density, - Insets waterfallInsets) { + String pathSpec, String rectSpec, int stableDisplayWidth, int stableDisplayHeight, + 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. String spec = rectSpec != null ? rectSpec : pathSpec; @@ -1071,11 +1098,15 @@ public final class DisplayCutout { return NULL_PAIR; } + final float physicalPixelDisplaySizeRatio = DisplayUtils.getPhysicalPixelDisplaySizeRatio( + stableDisplayWidth, stableDisplayHeight, displayWidth, displayHeight); + synchronized (CACHE_LOCK) { if (spec.equals(sCachedSpec) && sCachedDisplayWidth == displayWidth && sCachedDisplayHeight == displayHeight && sCachedDensity == density - && waterfallInsets.equals(sCachedWaterfallInsets)) { + && waterfallInsets.equals(sCachedWaterfallInsets) + && sCachedPhysicalPixelDisplaySizeRatio == physicalPixelDisplaySizeRatio) { return sCachedCutout; } } @@ -1083,7 +1114,7 @@ public final class DisplayCutout { spec = spec.trim(); CutoutSpecification cutoutSpec = new CutoutSpecification.Parser(density, - displayWidth, displayHeight).parse(spec); + stableDisplayWidth, stableDisplayHeight, physicalPixelDisplaySizeRatio).parse(spec); Rect safeInset = cutoutSpec.getSafeInset(); final Rect boundLeft = cutoutSpec.getLeftBound(); final Rect boundTop = cutoutSpec.getTopBound(); @@ -1099,8 +1130,9 @@ public final class DisplayCutout { Math.max(waterfallInsets.bottom, safeInset.bottom)); } - final CutoutPathParserInfo cutoutPathParserInfo = new CutoutPathParserInfo(displayWidth, - displayHeight, density, pathSpec.trim(), ROTATION_0, 1f /* scale */); + final CutoutPathParserInfo cutoutPathParserInfo = new CutoutPathParserInfo( + displayWidth, displayHeight, stableDisplayWidth, stableDisplayHeight, density, + pathSpec.trim(), ROTATION_0, 1f /* scale */, physicalPixelDisplaySizeRatio); final DisplayCutout cutout = new DisplayCutout( safeInset, waterfallInsets, boundLeft, boundTop, boundRight, boundBottom, @@ -1113,6 +1145,7 @@ public final class DisplayCutout { sCachedDensity = density; sCachedCutout = result; sCachedWaterfallInsets = waterfallInsets; + sCachedPhysicalPixelDisplaySizeRatio = physicalPixelDisplaySizeRatio; } return result; } @@ -1149,8 +1182,9 @@ public final class DisplayCutout { Collections.rotate(Arrays.asList(newBounds), -rotation); final CutoutPathParserInfo info = getCutoutPathParserInfo(); final CutoutPathParserInfo newInfo = new CutoutPathParserInfo( - info.getDisplayWidth(), info.getDisplayHeight(), info.getDensity(), - info.getCutoutSpec(), toRotation, info.getScale()); + info.getDisplayWidth(), info.getDisplayHeight(), info.getStableDisplayWidth(), + info.getStableDisplayHeight(), 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; @@ -1250,10 +1284,13 @@ public final class DisplayCutout { 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.writeFloat(cutout.mCutoutPathParserInfo.getDensity()); out.writeString(cutout.mCutoutPathParserInfo.getCutoutSpec()); out.writeInt(cutout.mCutoutPathParserInfo.getRotation()); out.writeFloat(cutout.mCutoutPathParserInfo.getScale()); + out.writeFloat(cutout.mCutoutPathParserInfo.getPhysicalPixelDisplaySizeRatio()); } } @@ -1299,12 +1336,16 @@ public final class DisplayCutout { Insets waterfallInsets = in.readTypedObject(Insets.CREATOR); int displayWidth = in.readInt(); int displayHeight = in.readInt(); + int stableDisplayWidth = in.readInt(); + int stableDisplayHeight = 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, density, cutoutSpec, rotation, scale); + displayWidth, displayHeight, stableDisplayWidth, stableDisplayHeight, density, + cutoutSpec, rotation, scale, physicalPixelDisplaySizeRatio); return new DisplayCutout( safeInsets, waterfallInsets, bounds, info, false /* copyArguments */); @@ -1332,10 +1373,13 @@ public final class DisplayCutout { final CutoutPathParserInfo info = new CutoutPathParserInfo( mInner.mCutoutPathParserInfo.getDisplayWidth(), mInner.mCutoutPathParserInfo.getDisplayHeight(), + mInner.mCutoutPathParserInfo.getStableDisplayWidth(), + mInner.mCutoutPathParserInfo.getStableDisplayHeight(), mInner.mCutoutPathParserInfo.getDensity(), mInner.mCutoutPathParserInfo.getCutoutSpec(), mInner.mCutoutPathParserInfo.getRotation(), - scale); + scale, + mInner.mCutoutPathParserInfo.getPhysicalPixelDisplaySizeRatio()); mInner = new DisplayCutout(safeInsets, Insets.of(waterfallInsets), bounds, info); } @@ -1387,7 +1431,7 @@ public final class DisplayCutout { if (mCutoutPath != null) { // Create a fake CutoutPathParserInfo and set it to sCachedCutoutPathParserInfo so // that when getCutoutPath() is called, it will return the cached Path. - info = new CutoutPathParserInfo(0, 0, 0, "test", 0, 1f); + info = new CutoutPathParserInfo(0, 0, 0, 0, 0, "test", ROTATION_0, 1f, 1f); synchronized (CACHE_LOCK) { DisplayCutout.sCachedCutoutPathParserInfo = info; DisplayCutout.sCachedCutoutPath = mCutoutPath; diff --git a/core/java/android/view/RoundedCorners.java b/core/java/android/view/RoundedCorners.java index 3eade77a0232f..9f30487d5a36e 100644 --- a/core/java/android/view/RoundedCorners.java +++ b/core/java/android/view/RoundedCorners.java @@ -67,6 +67,8 @@ public class RoundedCorners implements Parcelable { private static Pair sCachedRadii; @GuardedBy("CACHE_LOCK") private static RoundedCorners sCachedRoundedCorners; + @GuardedBy("CACHE_LOCK") + private static float sCachedPhysicalPixelDisplaySizeRatio; @VisibleForTesting public final RoundedCorner[] mRoundedCorners; @@ -96,8 +98,10 @@ public class RoundedCorners implements Parcelable { * @android:dimen/rounded_corner_radius_top and @android:dimen/rounded_corner_radius_bottom */ public static RoundedCorners fromResources( - Resources res, String displayUniqueId, int displayWidth, int displayHeight) { - return fromRadii(loadRoundedCornerRadii(res, displayUniqueId), displayWidth, displayHeight); + Resources res, String displayUniqueId, int stableDisplayWidth, int stableDisplayHeight, + int displayWidth, int displayHeight) { + return fromRadii(loadRoundedCornerRadii(res, displayUniqueId), stableDisplayWidth, + stableDisplayHeight, displayWidth, displayHeight); } /** @@ -106,20 +110,33 @@ public class RoundedCorners implements Parcelable { @VisibleForTesting public static RoundedCorners fromRadii(Pair radii, int displayWidth, int displayHeight) { + return fromRadii(radii, displayWidth, displayHeight, displayWidth, displayHeight); + } + + private static RoundedCorners fromRadii(Pair radii, int stableDisplayWidth, + int stableDisplayHeight, int displayWidth, int displayHeight) { if (radii == null) { return null; } + final float physicalPixelDisplaySizeRatio = DisplayUtils.getPhysicalPixelDisplaySizeRatio( + stableDisplayWidth, stableDisplayHeight, displayWidth, displayHeight); + synchronized (CACHE_LOCK) { if (radii.equals(sCachedRadii) && sCachedDisplayWidth == displayWidth - && sCachedDisplayHeight == displayHeight) { + && sCachedDisplayHeight == displayHeight + && sCachedPhysicalPixelDisplaySizeRatio == physicalPixelDisplaySizeRatio) { return sCachedRoundedCorners; } } final RoundedCorner[] roundedCorners = new RoundedCorner[ROUNDED_CORNER_POSITION_LENGTH]; - final int topRadius = radii.first > 0 ? radii.first : 0; - final int bottomRadius = radii.second > 0 ? radii.second : 0; + int topRadius = radii.first > 0 ? radii.first : 0; + int bottomRadius = radii.second > 0 ? radii.second : 0; + if (physicalPixelDisplaySizeRatio != 1f) { + topRadius = (int) (topRadius * physicalPixelDisplaySizeRatio + 0.5); + bottomRadius = (int) (bottomRadius * physicalPixelDisplaySizeRatio + 0.5); + } for (int i = 0; i < ROUNDED_CORNER_POSITION_LENGTH; i++) { roundedCorners[i] = createRoundedCorner( i, @@ -134,6 +151,7 @@ public class RoundedCorners implements Parcelable { sCachedDisplayHeight = displayHeight; sCachedRadii = radii; sCachedRoundedCorners = result; + sCachedPhysicalPixelDisplaySizeRatio = physicalPixelDisplaySizeRatio; } return result; } diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java index 4319b97037308..faeae2cb66988 100644 --- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java +++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java @@ -609,7 +609,8 @@ public class DisplayCutoutTest { private static DisplayCutout.CutoutPathParserInfo createParserInfo( @Surface.Rotation int rotation) { return new DisplayCutout.CutoutPathParserInfo( - 0 /* displayWidth */, 0 /* displayHeight */, 0f /* density */, "" /* cutoutSpec */, - rotation, 0f /* scale */); + 0 /* displayWidth */, 0 /* displayHeight */, 0 /* displayWidth */, + 0 /* displayHeight */, 0f /* density */, "" /* cutoutSpec */, + rotation, 0f /* scale */, 0f /* displaySizeRatio */); } } 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 79d795ee613fc..fedb9983a65eb 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,9 @@ public class DisplayLayout { } final DisplayCutout.CutoutPathParserInfo info = cutout.getCutoutPathParserInfo(); final DisplayCutout.CutoutPathParserInfo newInfo = new DisplayCutout.CutoutPathParserInfo( - info.getDisplayWidth(), info.getDisplayHeight(), info.getDensity(), - info.getCutoutSpec(), rotation, info.getScale()); + info.getDisplayWidth(), info.getDisplayHeight(), info.getStableDisplayWidth(), + info.getStableDisplayHeight(), info.getDensity(), info.getCutoutSpec(), rotation, + info.getScale(), info.getPhysicalPixelDisplaySizeRatio()); return computeSafeInsets( DisplayCutout.constructDisplayCutout(newBounds, waterfallInsets, newInfo), rotated ? displayHeight : displayWidth, diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 38f9ac1b4cdc4..b98fc03e3acd8 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -19,8 +19,6 @@ import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT; import static android.view.DisplayCutout.BOUNDS_POSITION_LENGTH; import static android.view.DisplayCutout.BOUNDS_POSITION_RIGHT; import static android.view.DisplayCutout.BOUNDS_POSITION_TOP; -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; @@ -38,10 +36,10 @@ import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; -import android.graphics.Matrix; 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; @@ -51,10 +49,12 @@ import android.os.Handler; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings.Secure; +import android.util.DisplayUtils; import android.util.Log; import android.util.Size; import android.view.DisplayCutout; import android.view.DisplayCutout.BoundsPosition; +import android.view.DisplayInfo; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -320,13 +320,15 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab } private void startOnScreenDecorationsThread() { + mWindowManager = mContext.getSystemService(WindowManager.class); + mDisplayManager = mContext.getSystemService(DisplayManager.class); mRotation = mContext.getDisplay().getRotation(); mDisplayUniqueId = mContext.getDisplay().getUniqueId(); mRoundedCornerResDelegate = new RoundedCornerResDelegate(mContext.getResources(), mDisplayUniqueId); + mRoundedCornerResDelegate.setPhysicalPixelDisplaySizeRatio( + getPhysicalPixelDisplaySizeRatio()); mRoundedCornerFactory = new RoundedCornerDecorProviderFactory(mRoundedCornerResDelegate); - mWindowManager = mContext.getSystemService(WindowManager.class); - mDisplayManager = mContext.getSystemService(DisplayManager.class); mHwcScreenDecorationSupport = mContext.getDisplay().getDisplayDecorationSupport(); updateHwLayerRoundedCornerDrawable(); setupDecorations(); @@ -402,6 +404,16 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab updateOverlayProviderViews(); } + + final float newRatio = getPhysicalPixelDisplaySizeRatio(); + if (mRoundedCornerResDelegate.getPhysicalPixelDisplaySizeRatio() != newRatio) { + mRoundedCornerResDelegate.setPhysicalPixelDisplaySizeRatio(newRatio); + if (mScreenDecorHwcLayer != null) { + updateHwLayerRoundedCornerExistAndSize(); + } + updateOverlayProviderViews(); + } + if (mCutoutViews != null) { final int size = mCutoutViews.length; for (int i = 0; i < size; i++) { @@ -878,6 +890,16 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab } } + @VisibleForTesting + float getPhysicalPixelDisplaySizeRatio() { + final Point stableDisplaySize = mDisplayManager.getStableDisplaySize(); + final DisplayInfo displayInfo = new DisplayInfo(); + mContext.getDisplay().getDisplayInfo(displayInfo); + return DisplayUtils.getPhysicalPixelDisplaySizeRatio( + stableDisplaySize.x, stableDisplaySize.y, displayInfo.logicalWidth, + displayInfo.logicalHeight); + } + @Override protected void onConfigurationChanged(Configuration newConfig) { if (DEBUG_DISABLE_SCREEN_DECORATIONS) { @@ -1182,25 +1204,12 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab } private void updateBoundingPath() { - int lw = displayInfo.logicalWidth; - int lh = displayInfo.logicalHeight; - - boolean flipped = displayInfo.rotation == ROTATION_90 - || displayInfo.rotation == ROTATION_270; - - int dw = flipped ? lh : lw; - int dh = flipped ? lw : lh; - - Path path = DisplayCutout.pathFromResources( - getResources(), getDisplay().getUniqueId(), dw, dh); + final Path path = displayInfo.displayCutout.getCutoutPath(); if (path != null) { cutoutPath.set(path); } else { cutoutPath.reset(); } - Matrix m = new Matrix(); - transformPhysicalToLogicalCoordinates(displayInfo.rotation, dw, dh, m); - cutoutPath.transform(m); } private void updateGravity() { diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt index 3731eca4ee86b..b5a0cfcb1c184 100644 --- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt +++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt @@ -68,6 +68,15 @@ class RoundedCornerResDelegate( reloadMeasures() } + var physicalPixelDisplaySizeRatio: Float = 1f + set(value) { + if (field == value) { + return + } + field = value + reloadMeasures() + } + init { reloadRes() reloadMeasures() @@ -134,6 +143,19 @@ class RoundedCornerResDelegate( bottomRoundedSize = Size(length, length) } } + + if (physicalPixelDisplaySizeRatio != 1f) { + if (topRoundedSize.width != 0) { + topRoundedSize = Size( + (physicalPixelDisplaySizeRatio * topRoundedSize.width + 0.5f).toInt(), + (physicalPixelDisplaySizeRatio * topRoundedSize.height + 0.5f).toInt()) + } + if (bottomRoundedSize.width != 0) { + bottomRoundedSize = Size( + (physicalPixelDisplaySizeRatio * bottomRoundedSize.width + 0.5f).toInt(), + (physicalPixelDisplaySizeRatio * bottomRoundedSize.height + 0.5f).toInt()) + } + } } private fun getDrawable( @@ -160,5 +182,6 @@ class RoundedCornerResDelegate( pw.println(" topRoundedSize(w,h)=(${topRoundedSize.width},${topRoundedSize.height})") pw.println(" bottomRoundedSize(w,h)=(${bottomRoundedSize.width}," + "${bottomRoundedSize.height})") + pw.println(" physicalPixelDisplaySizeRatio=$physicalPixelDisplaySizeRatio") } } \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index d8d73db2ca8c2..7c211b22e6575 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -213,6 +213,7 @@ public class ScreenDecorationsTest extends SysuiTestCase { mExecutor.runAllReady(); } }); + doReturn(1f).when(mScreenDecorations).getPhysicalPixelDisplaySizeRatio(); reset(mTunerService); try { diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt index adb9c4d206e15..670a15a59bb6d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt @@ -133,6 +133,22 @@ class RoundedCornerResDelegateTest : SysuiTestCase() { assertEquals(Size(4, 4), roundedCornerResDelegate.bottomRoundedSize) } + @Test + fun testPhysicalPixelDisplaySizeChanged() { + setupResources( + roundedTopDrawable = getTestsDrawable(R.drawable.rounded4px), + roundedBottomDrawable = getTestsDrawable(R.drawable.rounded4px)) + + roundedCornerResDelegate = RoundedCornerResDelegate(mContext.resources, null) + assertEquals(Size(4, 4), roundedCornerResDelegate.topRoundedSize) + assertEquals(Size(4, 4), roundedCornerResDelegate.bottomRoundedSize) + + roundedCornerResDelegate.physicalPixelDisplaySizeRatio = 0.5f + + assertEquals(Size(2, 2), roundedCornerResDelegate.topRoundedSize) + assertEquals(Size(2, 2), roundedCornerResDelegate.bottomRoundedSize) + } + private fun getTestsDrawable(@DrawableRes drawableId: Int): Drawable? { return mContext.createPackageContext("com.android.systemui.tests", 0) .getDrawable(drawableId) diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 982ac3c844829..fa2f5000abbc9 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -22,6 +22,8 @@ import static android.view.Display.Mode.INVALID_MODE_ID; 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; @@ -677,11 +679,16 @@ final class LocalDisplayAdapter extends DisplayAdapter { if (DisplayCutout.getMaskBuiltInDisplayCutout(res, mInfo.uniqueId)) { mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT; } + + final Point stableDisplaySize = getOverlayContext() + .getSystemService(DisplayManager.class).getStableDisplaySize(); mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res, - mInfo.uniqueId, mInfo.width, mInfo.height); + mInfo.uniqueId, stableDisplaySize.x, stableDisplaySize.y, mInfo.width, + mInfo.height); mInfo.roundedCorners = RoundedCorners.fromResources( - res, mInfo.uniqueId, mInfo.width, mInfo.height); + res, mInfo.uniqueId, stableDisplaySize.x, stableDisplaySize.y, 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 4660757024095..01d1614610a21 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -358,6 +358,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp float mInitialPhysicalXDpi = 0.0f; float mInitialPhysicalYDpi = 0.0f; + private Point mStableDisplaySize; + DisplayCutout mInitialDisplayCutout; private final RotationCache mDisplayCutoutCache = new RotationCache<>(this::calculateDisplayCutoutForRotationUncached); @@ -379,6 +381,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ int mBaseDisplayWidth = 0; int mBaseDisplayHeight = 0; + DisplayCutout mBaseDisplayCutout; + RoundedCorners mBaseRoundedCorners; boolean mIsSizeForced = false; /** @@ -2078,7 +2082,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } WmDisplayCutout calculateDisplayCutoutForRotation(int rotation) { - return mDisplayCutoutCache.getOrCompute(mInitialDisplayCutout, rotation); + return mDisplayCutoutCache.getOrCompute( + mIsSizeForced ? mBaseDisplayCutout : mInitialDisplayCutout, rotation); } static WmDisplayCutout calculateDisplayCutoutForRotationAndDisplaySizeUncached( @@ -2101,11 +2106,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp private WmDisplayCutout calculateDisplayCutoutForRotationUncached( DisplayCutout cutout, int rotation) { return calculateDisplayCutoutForRotationAndDisplaySizeUncached(cutout, rotation, - mInitialDisplayWidth, mInitialDisplayHeight); + mIsSizeForced ? mBaseDisplayWidth : mInitialDisplayWidth, + mIsSizeForced ? mBaseDisplayHeight : mInitialDisplayHeight); } RoundedCorners calculateRoundedCornersForRotation(int rotation) { - return mRoundedCornerCache.getOrCompute(mInitialRoundedCorners, rotation); + return mRoundedCornerCache.getOrCompute( + mIsSizeForced ? mBaseRoundedCorners : mInitialRoundedCorners, rotation); } private RoundedCorners calculateRoundedCornersForRotationUncached( @@ -2118,7 +2125,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return roundedCorners; } - return roundedCorners.rotate(rotation, mInitialDisplayWidth, mInitialDisplayHeight); + return roundedCorners.rotate( + rotation, + mIsSizeForced ? mBaseDisplayWidth : mInitialDisplayWidth, + mIsSizeForced ? mBaseDisplayHeight : mInitialDisplayHeight); } PrivacyIndicatorBounds calculatePrivacyIndicatorBoundsForRotation(int rotation) { @@ -2719,6 +2729,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mInitialRoundedCorners = mDisplayInfo.roundedCorners; mCurrentPrivacyIndicatorBounds = new PrivacyIndicatorBounds(new Rect[4], mDisplayInfo.rotation); + mStableDisplaySize = mWmService.mDisplayManager.getStableDisplaySize(); } /** @@ -2814,6 +2825,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mBaseDisplayDensity = baseDensity; mBaseDisplayPhysicalXDpi = baseXDpi; mBaseDisplayPhysicalYDpi = baseYDpi; + if (mIsSizeForced) { + mBaseDisplayCutout = loadDisplayCutout(baseWidth, baseHeight); + mBaseRoundedCorners = loadRoundedCorners(baseWidth, baseHeight); + } if (mMaxUiWidth > 0 && mBaseDisplayWidth > mMaxUiWidth) { final float ratio = mMaxUiWidth / (float) mBaseDisplayWidth; @@ -2904,6 +2919,24 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mWmService.mDisplayWindowSettings.setForcedSize(this, width, height); } + DisplayCutout loadDisplayCutout(int displayWidth, int displayHeight) { + if (mDisplayPolicy == null) { + return null; + } + return DisplayCutout.fromResourcesRectApproximation( + mDisplayPolicy.getSystemUiContext().getResources(), mDisplayInfo.uniqueId, + mStableDisplaySize.x, mStableDisplaySize.y, displayWidth, displayHeight); + } + + RoundedCorners loadRoundedCorners(int displayWidth, int displayHeight) { + if (mDisplayPolicy == null) { + return null; + } + return RoundedCorners.fromResources( + mDisplayPolicy.getSystemUiContext().getResources(), mDisplayInfo.uniqueId, + mStableDisplaySize.x, mStableDisplaySize.y, displayWidth, displayHeight); + } + @Override void getStableRect(Rect out) { final InsetsState state = mDisplayContent.getInsetsStateController().getRawInsetsState(); 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 617321beadd2b..cc64797578e7c 100644 --- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java @@ -35,6 +35,8 @@ import static org.mockito.Mockito.when; 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; @@ -93,6 +95,11 @@ public class LocalDisplayAdapterTest { @Mock private LogicalLight mMockedBacklight; + @Mock + private DisplayManager mMockDisplayManager; + @Mock + private Point mMockDisplayStableSize; + private Handler mHandler; private TestListener mListener = new TestListener(); @@ -123,6 +130,8 @@ public class LocalDisplayAdapterTest { 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)) diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 118f159bee7bc..56244cb92a971 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -854,7 +854,8 @@ public class DisplayContentTests extends WindowTestsBase { final Rect[] bounds = new Rect[]{zeroRect, new Rect(left, top, right, bottom), zeroRect, zeroRect}; final DisplayCutout.CutoutPathParserInfo info = new DisplayCutout.CutoutPathParserInfo( - displayWidth, displayHeight, density, "", Surface.ROTATION_0, 1f); + displayWidth, displayHeight, displayWidth, displayHeight, density, "", + Surface.ROTATION_0, 1f, 1f); final DisplayCutout cutout = new WmDisplayCutout( DisplayCutout.constructDisplayCutout(bounds, Insets.NONE, info), null) .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout(); @@ -874,7 +875,8 @@ public class DisplayContentTests extends WindowTestsBase { final Rect[] bounds90 = new Rect[]{new Rect(top, left, bottom, right), zeroRect, zeroRect, zeroRect}; final DisplayCutout.CutoutPathParserInfo info90 = new DisplayCutout.CutoutPathParserInfo( - displayWidth, displayHeight, density, "", Surface.ROTATION_90, 1f); + displayWidth, displayHeight, displayWidth, displayHeight, density, "", + Surface.ROTATION_90, 1f, 1f); assertEquals(new WmDisplayCutout( DisplayCutout.constructDisplayCutout(bounds90, Insets.NONE, info90), null) .computeSafeInsets(displayHeight, displayWidth).getDisplayCutout(),