Update the cutout side override doc to encourage all side override
The default behavior of the display cutout rotation is to stick to the
same physical display side. If one target rotation is rotated from two
different rotations whose physical sides of the display cutout are
different, the cutout side at the target rotation can be different. This
is very likely to be the undesired behavior.
Update the doc to further elaborate the details and encourage all sides
override.
Bug: 302387383
Test: Rotate from 270 to 0 on movable cutout device and see no black
bar underneath the status bar.
Test: LocalDisplayAdapterTest
Change-Id: Ia53a04e1d2fa12bf33d5e0e595954730448b6fac
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index f819c9b..db665a9 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -27,9 +27,7 @@
import static android.view.DisplayCutoutProto.SIDE_OVERRIDES;
import static android.view.DisplayCutoutProto.WATERFALL_INSETS;
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 com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
@@ -168,6 +166,9 @@
// The side index is always under the natural rotation of the device.
private int[] mSideOverrides;
+ static final int[] INVALID_OVERRIDES = new int[]{INVALID_SIDE_OVERRIDE, INVALID_SIDE_OVERRIDE,
+ INVALID_SIDE_OVERRIDE, INVALID_SIDE_OVERRIDE};
+
/** @hide */
@IntDef(prefix = { "BOUNDS_POSITION_" }, value = {
BOUNDS_POSITION_LEFT,
@@ -1157,35 +1158,25 @@
final int resourceId = index >= 0 && index < array.length()
? array.getResourceId(index, ID_NULL)
: ID_NULL;
- final String[] rawOverrides = resourceId != ID_NULL
- ? array.getResources().getStringArray(resourceId)
- : res.getStringArray(R.array.config_mainBuiltInDisplayCutoutSideOverride);
+ final int[] rawOverrides = resourceId != ID_NULL
+ ? array.getResources().getIntArray(resourceId)
+ : res.getIntArray(R.array.config_mainBuiltInDisplayCutoutSideOverride);
array.recycle();
- final int[] override = new int[]{INVALID_SIDE_OVERRIDE, INVALID_SIDE_OVERRIDE,
- INVALID_SIDE_OVERRIDE, INVALID_SIDE_OVERRIDE};
- for (String rawOverride : rawOverrides) {
- int rotation;
- String[] split = rawOverride.split(" *, *");
- switch (split[0]) {
- case "0" -> rotation = ROTATION_0;
- case "90" -> rotation = ROTATION_90;
- case "180" -> rotation = ROTATION_180;
- case "270" -> rotation = ROTATION_270;
- default -> throw new IllegalArgumentException("Invalid side override definition: "
- + rawOverride);
- }
- int side;
- switch (split[1]) {
- case SIDE_STRING_LEFT -> side = BOUNDS_POSITION_LEFT;
- case SIDE_STRING_TOP -> side = BOUNDS_POSITION_TOP;
- case SIDE_STRING_RIGHT -> side = BOUNDS_POSITION_RIGHT;
- case SIDE_STRING_BOTTOM -> side = BOUNDS_POSITION_BOTTOM;
- default -> throw new IllegalArgumentException("Invalid side override definition: "
- + rawOverride);
- }
- override[rotation] = side;
+ if (rawOverrides.length == 0) {
+ return INVALID_OVERRIDES;
+ } else if (rawOverrides.length != 4) {
+ throw new IllegalArgumentException(
+ "Invalid side override definition, exact 4 overrides required: "
+ + Arrays.toString(rawOverrides));
}
- return override;
+ for (int rotation = ROTATION_0; rotation <= ROTATION_270; rotation++) {
+ if (rawOverrides[rotation] < BOUNDS_POSITION_LEFT
+ || rawOverrides[rotation] >= BOUNDS_POSITION_LENGTH) {
+ throw new IllegalArgumentException("Invalid side override definition: "
+ + Arrays.toString(rawOverrides));
+ }
+ }
+ return rawOverrides;
}
/**
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 5be29a6..042d529 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4020,16 +4020,22 @@
<bool name="config_maskMainBuiltInDisplayCutout">false</bool>
<!-- This string array provide override side of each rotation of the given insets.
- Array of "[rotation],[side]".
- Undefined rotation will apply the default behavior.
+ Array of [side] for rotation 0, 90, 180 and 270 in order.
+ The options of [side] are:
+ - Option 0 - Left.
+ - Option 1 - Top.
+ - Option 2 - Right.
+ - Option 3 - Bottom.
When there are cutouts on multiple edges of the display, the override won't take any
effect. -->
- <string-array name="config_mainBuiltInDisplayCutoutSideOverride" translatable="false">
- <!-- Example:
- <item>90,top</item>
- <item>270,bottom</item>
+ <integer-array name="config_mainBuiltInDisplayCutoutSideOverride">
+ <!-- Example of at top for rotation 0 and 90, and at bottom for rotation 180 and 270:
+ <item>1</item>
+ <item>1</item>
+ <item>3</item>
+ <item>3</item>
-->
- </string-array>
+ </integer-array>
<!-- Ultrasound support for Mic/speaker path -->
<!-- Whether the default microphone audio source supports near-ultrasound frequencies
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
index c92ce25..b99ecf3 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -178,8 +178,8 @@
.thenReturn(mockArray);
when(mMockedResources.obtainTypedArray(R.array.config_displayCutoutSideOverrideArray))
.thenReturn(mockArray);
- when(mMockedResources.getStringArray(R.array.config_mainBuiltInDisplayCutoutSideOverride))
- .thenReturn(new String[]{});
+ when(mMockedResources.getIntArray(R.array.config_mainBuiltInDisplayCutoutSideOverride))
+ .thenReturn(new int[]{});
when(mMockedResources.obtainTypedArray(R.array.config_waterfallCutoutArray))
.thenReturn(mockArray);
when(mMockedResources.obtainTypedArray(R.array.config_roundedCornerRadiusArray))