Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f26b64b9 authored by Shawn Lin's avatar Shawn Lin Committed by Android (Google) Code Review
Browse files

Merge "Support display cutout for multi-display devices"

parents f704b059 0a2167a0
Loading
Loading
Loading
Loading
+139 −9
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.content.res.Resources;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Insets;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Path;
@@ -872,6 +873,135 @@ public final class DisplayCutout {
                false /* copyArguments */);
                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
     * Creates the display cutout according to
     * @android:string/config_mainBuiltInDisplayCutoutRectApproximation, which is the closest
     * @android:string/config_mainBuiltInDisplayCutoutRectApproximation, which is the closest
@@ -879,12 +1009,12 @@ public final class DisplayCutout {
     *
     *
     * @hide
     * @hide
     */
     */
    public static DisplayCutout fromResourcesRectApproximation(Resources res, int displayWidth,
    public static DisplayCutout fromResourcesRectApproximation(Resources res,
            int displayHeight) {
            String displayUniqueId, int displayWidth, int displayHeight) {
        return pathAndDisplayCutoutFromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout),
        return pathAndDisplayCutoutFromSpec(getDisplayCutoutPath(res, displayUniqueId),
                res.getString(R.string.config_mainBuiltInDisplayCutoutRectApproximation),
                getDisplayCutoutApproximationRect(res, displayUniqueId),
                displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT,
                displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT,
                loadWaterfallInset(res)).second;
                getWaterfallInsets(res, displayUniqueId)).second;
    }
    }


    /**
    /**
@@ -892,11 +1022,11 @@ public final class DisplayCutout {
     *
     *
     * @hide
     * @hide
     */
     */
    public static Path pathFromResources(Resources res, int displayWidth, int displayHeight) {
    public static Path pathFromResources(Resources res, String displayUniqueId, int displayWidth,
        return pathAndDisplayCutoutFromSpec(
            int displayHeight) {
                res.getString(R.string.config_mainBuiltInDisplayCutout), null,
        return pathAndDisplayCutoutFromSpec(getDisplayCutoutPath(res, displayUniqueId), null,
                displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT,
                displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT,
                loadWaterfallInset(res)).first;
                getWaterfallInsets(res, displayUniqueId)).first;
    }
    }


    /**
    /**
+76 −0
Original line number Original line Diff line number Diff line
@@ -5081,4 +5081,80 @@


    <!-- Whether this device should support taking app snapshots on closure -->
    <!-- Whether this device should support taking app snapshots on closure -->
    <bool name="config_disableTaskSnapshots">false</bool>
    <bool name="config_disableTaskSnapshots">false</bool>

    <!-- 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>
</resources>
+7 −1
Original line number Original line Diff line number Diff line
@@ -920,7 +920,7 @@


    <dimen name="chooser_action_button_icon_size">18dp</dimen>
    <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_left_edge_size">0px</dimen>
    <dimen name="waterfall_display_top_edge_size">0px</dimen>
    <dimen name="waterfall_display_top_edge_size">0px</dimen>
    <dimen name="waterfall_display_right_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>
    <dimen name="starting_surface_icon_size">160dp</dimen>
    <!-- The default width/height of the icon on the spec of adaptive icon drawable. -->
    <!-- The default width/height of the icon on the spec of adaptive icon drawable. -->
    <dimen name="starting_surface_default_icon_size">108dp</dimen>
    <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>
</resources>
+17 −0
Original line number Original line Diff line number Diff line
@@ -4443,4 +4443,21 @@
  <java-symbol type="integer" name="config_customizedMaxCachedProcesses" />
  <java-symbol type="integer" name="config_customizedMaxCachedProcesses" />


  <java-symbol type="bool" name="config_disableTaskSnapshots" />
  <java-symbol type="bool" name="config_disableTaskSnapshots" />

  <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>
</resources>
+4 −3
Original line number Original line Diff line number Diff line
@@ -797,8 +797,8 @@ public class ScreenDecorations extends SystemUI implements Tunable {
    }
    }


    static boolean shouldDrawCutout(Context context) {
    static boolean shouldDrawCutout(Context context) {
        return context.getResources().getBoolean(
        return DisplayCutout.getFillBuiltInDisplayCutout(
                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout);
                context.getResources(), context.getDisplay().getUniqueId());
    }
    }


    private void updateLayoutParams() {
    private void updateLayoutParams() {
@@ -1085,7 +1085,8 @@ public class ScreenDecorations extends SystemUI implements Tunable {
            int dw = flipped ? lh : lw;
            int dw = flipped ? lh : lw;
            int dh = flipped ? lw : lh;
            int dh = flipped ? lw : lh;


            Path path = DisplayCutout.pathFromResources(getResources(), dw, dh);
            Path path = DisplayCutout.pathFromResources(
                    getResources(), getDisplay().getUniqueId(), dw, dh);
            if (path != null) {
            if (path != null) {
                mBoundingPath.set(path);
                mBoundingPath.set(path);
            } else {
            } else {
Loading