Merge "Support scaled cutout & roundedcorners when resolution is overridden" into tm-dev
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<Path, DisplayCutout> 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<Path, DisplayCutout> 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;
|
||||
|
||||
@@ -67,6 +67,8 @@ public class RoundedCorners implements Parcelable {
|
||||
private static Pair<Integer, Integer> 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<Integer, Integer> radii, int displayWidth,
|
||||
int displayHeight) {
|
||||
return fromRadii(radii, displayWidth, displayHeight, displayWidth, displayHeight);
|
||||
}
|
||||
|
||||
private static RoundedCorners fromRadii(Pair<Integer, Integer> 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;
|
||||
}
|
||||
|
||||
@@ -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 */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -213,6 +213,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mExecutor.runAllReady();
|
||||
}
|
||||
});
|
||||
doReturn(1f).when(mScreenDecorations).getPhysicalPixelDisplaySizeRatio();
|
||||
reset(mTunerService);
|
||||
|
||||
try {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<DisplayCutout, WmDisplayCutout> 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();
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user