diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index e1a4402d89644..0257e55073dc8 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -31,6 +31,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Path;
@@ -872,6 +873,135 @@ public final class DisplayCutout {
false /* copyArguments */);
}
+ /**
+ * Gets the index of the given display unique id in {@link R.array#config_displayUniqueIdArray}
+ * which is used to get the related cutout configs for that display.
+ *
+ * For multi-display device, {@link R.array#config_displayUniqueIdArray} should be set for each
+ * display if there are different type of cutouts on each display.
+ * For single display device, {@link R.array#config_displayUniqueIdArray} should not to be set
+ * and the system will load the default configs for main built-in display.
+ */
+ private static int getDisplayCutoutConfigIndex(Resources res, String displayUniqueId) {
+ int index = -1;
+ if (displayUniqueId == null || displayUniqueId.isEmpty()) {
+ return index;
+ }
+ final String[] ids = res.getStringArray(R.array.config_displayUniqueIdArray);
+ final int size = ids.length;
+ for (int i = 0; i < size; i++) {
+ if (displayUniqueId.equals(ids[i])) {
+ index = i;
+ break;
+ }
+ }
+ return index;
+ }
+
+ /**
+ * Gets the display cutout by the given display unique id.
+ *
+ * Loads the default config {@link R.string#config_mainBuiltInDisplayCutout) if
+ * {@link R.array#config_displayUniqueIdArray} is not set.
+ */
+ private static String getDisplayCutoutPath(Resources res, String displayUniqueId) {
+ final int index = getDisplayCutoutConfigIndex(res, displayUniqueId);
+ final String[] array = res.getStringArray(R.array.config_displayCutoutPathArray);
+ if (index >= 0 && index < array.length) {
+ return array[index];
+ }
+ return res.getString(R.string.config_mainBuiltInDisplayCutout);
+ }
+
+ /**
+ * Gets the display cutout approximation rect by the given display unique id.
+ *
+ * Loads the default config {@link R.string#config_mainBuiltInDisplayCutoutRectApproximation} if
+ * {@link R.array#config_displayUniqueIdArray} is not set.
+ */
+ private static String getDisplayCutoutApproximationRect(Resources res, String displayUniqueId) {
+ final int index = getDisplayCutoutConfigIndex(res, displayUniqueId);
+ final String[] array = res.getStringArray(
+ R.array.config_displayCutoutApproximationRectArray);
+ if (index >= 0 && index < array.length) {
+ return array[index];
+ }
+ return res.getString(R.string.config_mainBuiltInDisplayCutoutRectApproximation);
+ }
+
+ /**
+ * Gets whether to mask a built-in display cutout of a display which is determined by the
+ * given display unique id.
+ *
+ * Loads the default config {@link R.bool#config_maskMainBuiltInDisplayCutout} if
+ * {@link R.array#config_displayUniqueIdArray} is not set.
+ *
+ * @hide
+ */
+ public static boolean getMaskBuiltInDisplayCutout(Resources res, String displayUniqueId) {
+ final int index = getDisplayCutoutConfigIndex(res, displayUniqueId);
+ final TypedArray array = res.obtainTypedArray(R.array.config_maskBuiltInDisplayCutoutArray);
+ boolean maskCutout;
+ if (index >= 0 && index < array.length()) {
+ maskCutout = array.getBoolean(index, false);
+ } else {
+ maskCutout = res.getBoolean(R.bool.config_maskMainBuiltInDisplayCutout);
+ }
+ array.recycle();
+ return maskCutout;
+ }
+
+ /**
+ * Gets whether to fill a built-in display cutout of a display which is determined by the
+ * given display unique id.
+ *
+ * Loads the default config{@link R.bool#config_fillMainBuiltInDisplayCutout} if
+ * {@link R.array#config_displayUniqueIdArray} is not set.
+ *
+ * @hide
+ */
+ public static boolean getFillBuiltInDisplayCutout(Resources res, String displayUniqueId) {
+ final int index = getDisplayCutoutConfigIndex(res, displayUniqueId);
+ final TypedArray array = res.obtainTypedArray(R.array.config_fillBuiltInDisplayCutoutArray);
+ boolean fillCutout;
+ if (index >= 0 && index < array.length()) {
+ fillCutout = array.getBoolean(index, false);
+ } else {
+ fillCutout = res.getBoolean(R.bool.config_fillMainBuiltInDisplayCutout);
+ }
+ array.recycle();
+ return fillCutout;
+ }
+
+ /**
+ * Gets the waterfall cutout by the given display unique id.
+ *
+ * Loads the default waterfall dimens if {@link R.array#config_displayUniqueIdArray} is not set.
+ * {@link R.dimen#waterfall_display_left_edge_size},
+ * {@link R.dimen#waterfall_display_top_edge_size},
+ * {@link R.dimen#waterfall_display_right_edge_size},
+ * {@link R.dimen#waterfall_display_bottom_edge_size}
+ */
+ private static Insets getWaterfallInsets(Resources res, String displayUniqueId) {
+ Insets insets;
+ final int index = getDisplayCutoutConfigIndex(res, displayUniqueId);
+ final TypedArray array = res.obtainTypedArray(R.array.config_waterfallCutoutArray);
+ if (index >= 0 && index < array.length() && array.getResourceId(index, 0) > 0) {
+ final int resourceId = array.getResourceId(index, 0);
+ final TypedArray waterfall = res.obtainTypedArray(resourceId);
+ insets = Insets.of(
+ waterfall.getDimensionPixelSize(0 /* waterfall left edge size */, 0),
+ waterfall.getDimensionPixelSize(1 /* waterfall top edge size */, 0),
+ waterfall.getDimensionPixelSize(2 /* waterfall right edge size */, 0),
+ waterfall.getDimensionPixelSize(3 /* waterfall bottom edge size */, 0));
+ waterfall.recycle();
+ } else {
+ insets = loadWaterfallInset(res);
+ }
+ array.recycle();
+ return insets;
+ }
+
/**
* Creates the display cutout according to
* @android:string/config_mainBuiltInDisplayCutoutRectApproximation, which is the closest
@@ -879,12 +1009,12 @@ public final class DisplayCutout {
*
* @hide
*/
- public static DisplayCutout fromResourcesRectApproximation(Resources res, int displayWidth,
- int displayHeight) {
- return pathAndDisplayCutoutFromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout),
- res.getString(R.string.config_mainBuiltInDisplayCutoutRectApproximation),
+ public static DisplayCutout fromResourcesRectApproximation(Resources res,
+ String displayUniqueId, int displayWidth, int displayHeight) {
+ return pathAndDisplayCutoutFromSpec(getDisplayCutoutPath(res, displayUniqueId),
+ getDisplayCutoutApproximationRect(res, displayUniqueId),
displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT,
- loadWaterfallInset(res)).second;
+ getWaterfallInsets(res, displayUniqueId)).second;
}
/**
@@ -892,11 +1022,11 @@ public final class DisplayCutout {
*
* @hide
*/
- public static Path pathFromResources(Resources res, int displayWidth, int displayHeight) {
- return pathAndDisplayCutoutFromSpec(
- res.getString(R.string.config_mainBuiltInDisplayCutout), null,
+ 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,
- loadWaterfallInset(res)).first;
+ getWaterfallInsets(res, displayUniqueId)).first;
}
/**
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ef8e938cbca76..1586f164a0a5d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5047,4 +5047,80 @@
32
+
+
+
+
+ @string/config_secondaryBuiltInDisplayCutout
+
+ false
+ false
+
+
+
+
+
+
+
+
+ - @string/config_mainBuiltInDisplayCutout
+ - @string/config_secondaryBuiltInDisplayCutout
+
+
+
+
+ - @string/config_mainBuiltInDisplayCutoutRectApproximation
+ - @string/config_secondaryBuiltInDisplayCutoutRectApproximation
+
+
+
+
+ - @bool/config_maskMainBuiltInDisplayCutout
+ - @bool/config_maskSecondaryBuiltInDisplayCutout
+
+
+
+
+ - @bool/config_fillMainBuiltInDisplayCutout
+ - @bool/config_fillSecondaryBuiltInDisplayCutout
+
+
+
+ - @dimen/waterfall_display_left_edge_size
+ - @dimen/waterfall_display_top_edge_size
+ - @dimen/waterfall_display_right_edge_size
+ - @dimen/waterfall_display_bottom_edge_size
+
+
+
+ - @dimen/secondary_waterfall_display_left_edge_size
+ - @dimen/secondary_waterfall_display_top_edge_size
+ - @dimen/secondary_waterfall_display_right_edge_size
+ - @dimen/secondary_waterfall_display_bottom_edge_size
+
+
+
+
+ - @array/config_mainBuiltInDisplayWaterfallCutout
+ - @array/config_secondaryBuiltInDisplayWaterfallCutout
+
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index de7a1175b4a30..7be9c7b42e5a3 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -920,7 +920,7 @@
18dp
-
+
0px
0px
0px
@@ -943,4 +943,10 @@
160dp
108dp
+
+
+ 0px
+ 0px
+ 0px
+ 0px
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 908721fc5ed9a..cd590cbbe2b0c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4426,4 +4426,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index e9c5653775306..f653088e552a0 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -797,8 +797,8 @@ public class ScreenDecorations extends SystemUI implements Tunable {
}
static boolean shouldDrawCutout(Context context) {
- return context.getResources().getBoolean(
- com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout);
+ return DisplayCutout.getFillBuiltInDisplayCutout(
+ context.getResources(), context.getDisplay().getUniqueId());
}
private void updateLayoutParams() {
@@ -1085,7 +1085,8 @@ public class ScreenDecorations extends SystemUI implements Tunable {
int dw = flipped ? lh : lw;
int dh = flipped ? lw : lh;
- Path path = DisplayCutout.pathFromResources(getResources(), dw, dh);
+ Path path = DisplayCutout.pathFromResources(
+ getResources(), getDisplay().getUniqueId(), dw, dh);
if (path != null) {
mBoundingPath.set(path);
} else {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index f953cc8c8a271..17697127d5080 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -601,12 +601,6 @@ final class LocalDisplayAdapter extends DisplayAdapter {
&& SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
}
- if (res.getBoolean(
- com.android.internal.R.bool.config_maskMainBuiltInDisplayCutout)) {
- mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT;
- }
- mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
- mInfo.width, mInfo.height);
mInfo.roundedCorners = RoundedCorners.fromResources(
res, mInfo.width, mInfo.height);
} else {
@@ -620,6 +614,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
}
+ if (DisplayCutout.getMaskBuiltInDisplayCutout(res, mInfo.uniqueId)) {
+ mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT;
+ }
+ mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
+ mInfo.uniqueId, mInfo.width, mInfo.height);
+
if (mStaticDisplayInfo.isInternal) {
mInfo.type = Display.TYPE_INTERNAL;
mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;