Merge "DisplayCutout: Draw anti-aliased bounds in soft overlay" into pi-dev

am: 2370f368d4

Change-Id: Ifae0d5e2c5bc226eaaf4462dd9b9cb044c8340b8
This commit is contained in:
Adrian Roos
2018-04-11 10:06:56 -07:00
committed by android-build-merger
3 changed files with 81 additions and 7 deletions

View File

@@ -31,6 +31,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.PathParser;
import android.util.proto.ProtoOutputStream;
@@ -75,15 +76,19 @@ public final class DisplayCutout {
false /* copyArguments */);
private static final Pair<Path, DisplayCutout> NULL_PAIR = new Pair<>(null, null);
private static final Object CACHE_LOCK = new Object();
@GuardedBy("CACHE_LOCK")
private static String sCachedSpec;
@GuardedBy("CACHE_LOCK")
private static int sCachedDisplayWidth;
@GuardedBy("CACHE_LOCK")
private static int sCachedDisplayHeight;
@GuardedBy("CACHE_LOCK")
private static float sCachedDensity;
@GuardedBy("CACHE_LOCK")
private static DisplayCutout sCachedCutout;
private static Pair<Path, DisplayCutout> sCachedCutout = NULL_PAIR;
private final Rect mSafeInsets;
private final Region mBounds;
@@ -347,7 +352,7 @@ public final class DisplayCutout {
}
/**
* Creates an instance according to @android:string/config_mainBuiltInDisplayCutout.
* Creates the bounding path according to @android:string/config_mainBuiltInDisplayCutout.
*
* @hide
*/
@@ -356,6 +361,16 @@ public final class DisplayCutout {
displayWidth, displayHeight, res.getDisplayMetrics().density);
}
/**
* Creates an instance according to @android:string/config_mainBuiltInDisplayCutout.
*
* @hide
*/
public static Path pathFromResources(Resources res, int displayWidth, int displayHeight) {
return pathAndDisplayCutoutFromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout),
displayWidth, displayHeight, res.getDisplayMetrics().density).first;
}
/**
* Creates an instance according to the supplied {@link android.util.PathParser.PathData} spec.
*
@@ -364,11 +379,17 @@ public final class DisplayCutout {
@VisibleForTesting(visibility = PRIVATE)
public static DisplayCutout fromSpec(String spec, int displayWidth, int displayHeight,
float density) {
return pathAndDisplayCutoutFromSpec(spec, displayWidth, displayHeight, density).second;
}
private static Pair<Path, DisplayCutout> pathAndDisplayCutoutFromSpec(String spec,
int displayWidth, int displayHeight, float density) {
if (TextUtils.isEmpty(spec)) {
return null;
return NULL_PAIR;
}
synchronized (CACHE_LOCK) {
if (spec.equals(sCachedSpec) && sCachedDisplayWidth == displayWidth
&& sCachedDisplayHeight == displayHeight
&& sCachedDensity == density) {
return sCachedCutout;
}
@@ -398,7 +419,7 @@ public final class DisplayCutout {
p = PathParser.createPathFromPathData(spec);
} catch (Throwable e) {
Log.wtf(TAG, "Could not inflate cutout: ", e);
return null;
return NULL_PAIR;
}
final Matrix m = new Matrix();
@@ -414,7 +435,7 @@ public final class DisplayCutout {
bottomPath = PathParser.createPathFromPathData(bottomSpec);
} catch (Throwable e) {
Log.wtf(TAG, "Could not inflate bottom cutout: ", e);
return null;
return NULL_PAIR;
}
// Keep top transform
m.postTranslate(0, displayHeight);
@@ -422,10 +443,11 @@ public final class DisplayCutout {
p.addPath(bottomPath);
}
final DisplayCutout result = fromBounds(p);
final Pair<Path, DisplayCutout> result = new Pair<>(p, fromBounds(p));
synchronized (CACHE_LOCK) {
sCachedSpec = spec;
sCachedDisplayWidth = displayWidth;
sCachedDisplayHeight = displayHeight;
sCachedDensity = density;
sCachedCutout = result;
}

View File

@@ -207,6 +207,12 @@ public class DisplayCutoutTest {
assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached)));
}
@Test
public void fromSpec_wontCacheIfScreenHeightChanges() {
DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 4000, 1f);
assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached)));
}
@Test
public void fromSpec_wontCacheIfDensityChanges() {
DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 2f);

View File

@@ -14,6 +14,10 @@
package com.android.systemui;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
@@ -21,12 +25,14 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M
import static com.android.systemui.tuner.TunablePadding.FLAG_START;
import static com.android.systemui.tuner.TunablePadding.FLAG_END;
import android.annotation.Dimension;
import android.app.Fragment;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
@@ -41,6 +47,7 @@ import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
@@ -359,6 +366,7 @@ public class ScreenDecorations extends SystemUI implements Tunable {
if (!mBoundingPath.isEmpty()) {
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
canvas.drawPath(mBoundingPath, mPaint);
}
}
@@ -388,7 +396,7 @@ public class ScreenDecorations extends SystemUI implements Tunable {
if (hasCutout()) {
mBounds.set(mInfo.displayCutout.getBounds());
localBounds(mBoundingRect);
mInfo.displayCutout.getBounds().getBoundaryPath(mBoundingPath);
updateBoundingPath();
invalidate();
newVisible = VISIBLE;
} else {
@@ -400,6 +408,44 @@ public class ScreenDecorations extends SystemUI implements Tunable {
}
}
private void updateBoundingPath() {
int lw = mInfo.logicalWidth;
int lh = mInfo.logicalHeight;
boolean flipped = mInfo.rotation == ROTATION_90 || mInfo.rotation == ROTATION_270;
int dw = flipped ? lh : lw;
int dh = flipped ? lw : lh;
mBoundingPath.set(DisplayCutout.pathFromResources(getResources(), lw, lh));
Matrix m = new Matrix();
transformPhysicalToLogicalCoordinates(mInfo.rotation, dw, dh, m);
mBoundingPath.transform(m);
}
private static void transformPhysicalToLogicalCoordinates(@Surface.Rotation int rotation,
@Dimension int physicalWidth, @Dimension int physicalHeight, Matrix out) {
switch (rotation) {
case ROTATION_0:
out.reset();
break;
case ROTATION_90:
out.setRotate(270);
out.postTranslate(0, physicalWidth);
break;
case ROTATION_180:
out.setRotate(180);
out.postTranslate(physicalWidth, physicalHeight);
break;
case ROTATION_270:
out.setRotate(90);
out.postTranslate(physicalHeight, 0);
break;
default:
throw new IllegalArgumentException("Unknown rotation: " + rotation);
}
}
private boolean hasCutout() {
final DisplayCutout displayCutout = mInfo.displayCutout;
if (displayCutout == null) {