Merge "[DO NOT MERGE] Support display cutout for multi-display devices" into sc-v2-dev

This commit is contained in:
Shawn Lin
2021-07-28 06:31:21 +00:00
committed by Android (Google) Code Review
6 changed files with 249 additions and 19 deletions

View File

@@ -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;
}
/**

View File

@@ -5047,4 +5047,80 @@
<!-- the number of the max cached processes in the system. -->
<integer name="config_customizedMaxCachedProcesses">32</integer>
<!-- The display cutout configs for secondary built-in display. -->
<string name="config_secondaryBuiltInDisplayCutout" translatable="false"></string>
<string name="config_secondaryBuiltInDisplayCutoutRectApproximation" translatable="false">
@string/config_secondaryBuiltInDisplayCutout
</string>
<bool name="config_fillSecondaryBuiltInDisplayCutout">false</bool>
<bool name="config_maskSecondaryBuiltInDisplayCutout">false</bool>
<!-- An array contains unique ids of all built-in displays and the unique id of a display can be
obtained from {@link Display#getUniqueId}. This array should be set for multi-display
devices if there are different display related configs(e.g. display cutout, rounded corner)
between each built-in display.
It is used as an index for multi-display related configs:
First look up the index of the unique id of the given built-in display unique id in this
array and use this index to get the info in corresponding config arrays such as:
- config_displayCutoutPathArray
- config_displayCutoutApproximationRectArray
- config_fillBuiltInDisplayCutoutArray
- config_maskBuiltInDisplayCutoutArray
- config_waterfallCutoutArray
Leave this array empty for single display device and the system will load the default main
built-in related configs.
-->
<string-array name="config_displayUniqueIdArray" translatable="false">
<!-- Example:
<item>"local:1234567891"</item> // main built-in display
<item>"local:1234567892"</item> // secondary built-in display
-->
</string-array>
<!-- The display cutout path config for each display in a multi-display device. -->
<string-array name="config_displayCutoutPathArray" translatable="false">
<item>@string/config_mainBuiltInDisplayCutout</item>
<item>@string/config_secondaryBuiltInDisplayCutout</item>
</string-array>
<!-- The display cutout approximation rect config for each display in a multi-display device.
-->
<string-array name="config_displayCutoutApproximationRectArray" translatable="false">
<item>@string/config_mainBuiltInDisplayCutoutRectApproximation</item>
<item>@string/config_secondaryBuiltInDisplayCutoutRectApproximation</item>
</string-array>
<!-- The maskBuiltInDisplayCutout config for each display in a multi-display device. -->
<array name="config_maskBuiltInDisplayCutoutArray" translatable="false">
<item>@bool/config_maskMainBuiltInDisplayCutout</item>
<item>@bool/config_maskSecondaryBuiltInDisplayCutout</item>
</array>
<!-- The fillBuiltInDisplayCutout config for each display in a multi-display device. -->
<array name="config_fillBuiltInDisplayCutoutArray" translatable="false">
<item>@bool/config_fillMainBuiltInDisplayCutout</item>
<item>@bool/config_fillSecondaryBuiltInDisplayCutout</item>
</array>
<array name="config_mainBuiltInDisplayWaterfallCutout" translatable="false">
<item>@dimen/waterfall_display_left_edge_size</item>
<item>@dimen/waterfall_display_top_edge_size</item>
<item>@dimen/waterfall_display_right_edge_size</item>
<item>@dimen/waterfall_display_bottom_edge_size</item>
</array>
<array name="config_secondaryBuiltInDisplayWaterfallCutout" translatable="false">
<item>@dimen/secondary_waterfall_display_left_edge_size</item>
<item>@dimen/secondary_waterfall_display_top_edge_size</item>
<item>@dimen/secondary_waterfall_display_right_edge_size</item>
<item>@dimen/secondary_waterfall_display_bottom_edge_size</item>
</array>
<!-- The waterfall cutout config for each display in a multi-display device. -->
<array name="config_waterfallCutoutArray" translatable="false">
<item>@array/config_mainBuiltInDisplayWaterfallCutout</item>
<item>@array/config_secondaryBuiltInDisplayWaterfallCutout</item>
</array>
</resources>

View File

@@ -920,7 +920,7 @@
<dimen name="chooser_action_button_icon_size">18dp</dimen>
<!-- For Waterfall Display -->
<!-- For main built-in Waterfall Display -->
<dimen name="waterfall_display_left_edge_size">0px</dimen>
<dimen name="waterfall_display_top_edge_size">0px</dimen>
<dimen name="waterfall_display_right_edge_size">0px</dimen>
@@ -943,4 +943,10 @@
<dimen name="starting_surface_icon_size">160dp</dimen>
<!-- The default width/height of the icon on the spec of adaptive icon drawable. -->
<dimen name="starting_surface_default_icon_size">108dp</dimen>
<!-- For secondary built-in Waterfall Display -->
<dimen name="secondary_waterfall_display_left_edge_size">0px</dimen>
<dimen name="secondary_waterfall_display_top_edge_size">0px</dimen>
<dimen name="secondary_waterfall_display_right_edge_size">0px</dimen>
<dimen name="secondary_waterfall_display_bottom_edge_size">0px</dimen>
</resources>

View File

@@ -4426,4 +4426,21 @@
<java-symbol type="bool" name="config_volumeShowRemoteSessions" />
<java-symbol type="integer" name="config_customizedMaxCachedProcesses" />
<java-symbol type="string" name="config_secondaryBuiltInDisplayCutout" />
<java-symbol type="string" name="config_secondaryBuiltInDisplayCutoutRectApproximation" />
<java-symbol type="bool" name="config_fillSecondaryBuiltInDisplayCutout" />
<java-symbol type="bool" name="config_maskSecondaryBuiltInDisplayCutout" />
<java-symbol type="array" name="config_displayUniqueIdArray" />
<java-symbol type="array" name="config_displayCutoutPathArray" />
<java-symbol type="array" name="config_displayCutoutApproximationRectArray" />
<java-symbol type="array" name="config_fillBuiltInDisplayCutoutArray" />
<java-symbol type="array" name="config_maskBuiltInDisplayCutoutArray" />
<java-symbol type="dimen" name="secondary_waterfall_display_left_edge_size" />
<java-symbol type="dimen" name="secondary_waterfall_display_top_edge_size" />
<java-symbol type="dimen" name="secondary_waterfall_display_right_edge_size" />
<java-symbol type="dimen" name="secondary_waterfall_display_bottom_edge_size" />
<java-symbol type="array" name="config_mainBuiltInDisplayWaterfallCutout" />
<java-symbol type="array" name="config_secondaryBuiltInDisplayWaterfallCutout" />
<java-symbol type="array" name="config_waterfallCutoutArray" />
</resources>

View File

@@ -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 {

View File

@@ -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;