Merge "DisplayCutout: Cache inflations from resources"
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 2723030..f5b7068 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -23,6 +23,8 @@
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Path;
@@ -38,6 +40,7 @@
import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import java.util.Objects;
@@ -73,6 +76,17 @@
public static final DisplayCutout NO_CUTOUT = new DisplayCutout(ZERO_RECT, EMPTY_REGION,
new Size(0, 0));
+
+ 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 float sCachedDensity;
+ @GuardedBy("CACHE_LOCK")
+ private static DisplayCutout sCachedCutout;
+
private final Rect mSafeInsets;
private final Region mBounds;
private final Size mFrameSize;
@@ -350,10 +364,26 @@
* @hide
*/
public static DisplayCutout fromResources(Resources res, int displayWidth) {
- String spec = res.getString(R.string.config_mainBuiltInDisplayCutout);
+ return fromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout),
+ displayWidth, res.getDisplayMetrics().density);
+ }
+
+ /**
+ * Creates an instance according to the supplied {@link android.util.PathParser.PathData} spec.
+ *
+ * @hide
+ */
+ @VisibleForTesting(visibility = PRIVATE)
+ public static DisplayCutout fromSpec(String spec, int displayWidth, float density) {
if (TextUtils.isEmpty(spec)) {
return null;
}
+ synchronized (CACHE_LOCK) {
+ if (spec.equals(sCachedSpec) && sCachedDisplayWidth == displayWidth
+ && sCachedDensity == density) {
+ return sCachedCutout;
+ }
+ }
spec = spec.trim();
final boolean inDp = spec.endsWith(DP_MARKER);
if (inDp) {
@@ -370,12 +400,19 @@
final Matrix m = new Matrix();
if (inDp) {
- final float dpToPx = res.getDisplayMetrics().density;
- m.postScale(dpToPx, dpToPx);
+ m.postScale(density, density);
}
m.postTranslate(displayWidth / 2f, 0);
p.transform(m);
- return fromBounds(p);
+
+ final DisplayCutout result = fromBounds(p);
+ synchronized (CACHE_LOCK) {
+ sCachedSpec = spec;
+ sCachedDisplayWidth = displayWidth;
+ sCachedDensity = density;
+ sCachedCutout = result;
+ }
+ return result;
}
/**
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index ee4bc34..d807353 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -18,10 +18,14 @@
import static android.view.DisplayCutout.NO_CUTOUT;
import static android.view.DisplayCutout.fromBoundingRect;
+import static android.view.DisplayCutout.fromSpec;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.sameInstance;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import android.graphics.Rect;
@@ -271,6 +275,30 @@
}
@Test
+ public void fromSpec_caches() {
+ DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 1f);
+ assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), sameInstance(cached));
+ }
+
+ @Test
+ public void fromSpec_wontCacheIfSpecChanges() {
+ DisplayCutout cached = fromSpec("L1,0 L1000,1000 L0,1 z", 200, 1f);
+ assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), not(sameInstance(cached)));
+ }
+
+ @Test
+ public void fromSpec_wontCacheIfScreenWidthChanges() {
+ DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 2000, 1f);
+ assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), not(sameInstance(cached)));
+ }
+
+ @Test
+ public void fromSpec_wontCacheIfDensityChanges() {
+ DisplayCutout cached = fromSpec("L1,0 L1,1 L0,1 z", 200, 2f);
+ assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 1f), not(sameInstance(cached)));
+ }
+
+ @Test
public void parcel_unparcel_nocutout() {
Parcel p = Parcel.obtain();