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

Commit 5d92e724 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "DisplayCutout: Support more than one cutout" into pi-dev

parents 661ab621 6a4fa0ec
Loading
Loading
Loading
Loading
+3 −3
Original line number Original line Diff line number Diff line
@@ -46625,8 +46625,8 @@ package android.view {
  }
  }
  public final class DisplayCutout {
  public final class DisplayCutout {
    ctor public DisplayCutout(android.graphics.Rect, android.graphics.Region);
    ctor public DisplayCutout(android.graphics.Rect, java.util.List<android.graphics.Rect>);
    method public android.graphics.Region getBounds();
    method public java.util.List<android.graphics.Rect> getBoundingRects();
    method public int getSafeInsetBottom();
    method public int getSafeInsetBottom();
    method public int getSafeInsetLeft();
    method public int getSafeInsetLeft();
    method public int getSafeInsetRight();
    method public int getSafeInsetRight();
@@ -49700,9 +49700,9 @@ package android.view {
    field public static final int LAST_SUB_WINDOW = 1999; // 0x7cf
    field public static final int LAST_SUB_WINDOW = 1999; // 0x7cf
    field public static final int LAST_SYSTEM_WINDOW = 2999; // 0xbb7
    field public static final int LAST_SYSTEM_WINDOW = 2999; // 0xbb7
    field public static final int LAYOUT_CHANGED = 1; // 0x1
    field public static final int LAYOUT_CHANGED = 1; // 0x1
    field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS = 1; // 0x1
    field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0; // 0x0
    field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0; // 0x0
    field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER = 2; // 0x2
    field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER = 2; // 0x2
    field public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES = 1; // 0x1
    field public static final int MEMORY_TYPE_CHANGED = 256; // 0x100
    field public static final int MEMORY_TYPE_CHANGED = 256; // 0x100
    field public static final deprecated int MEMORY_TYPE_GPU = 2; // 0x2
    field public static final deprecated int MEMORY_TYPE_GPU = 2; // 0x2
    field public static final deprecated int MEMORY_TYPE_HARDWARE = 1; // 0x1
    field public static final deprecated int MEMORY_TYPE_HARDWARE = 1; // 0x1
+118 −122
Original line number Original line Diff line number Diff line
@@ -18,10 +18,6 @@ package android.view;


import static android.view.DisplayCutoutProto.BOUNDS;
import static android.view.DisplayCutoutProto.BOUNDS;
import static android.view.DisplayCutoutProto.INSETS;
import static android.view.DisplayCutoutProto.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;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;


@@ -36,23 +32,24 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.Log;
import android.util.Log;
import android.util.PathParser;
import android.util.PathParser;
import android.util.Size;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;


import com.android.internal.R;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;


import java.util.Objects;
import java.util.ArrayList;
import java.util.List;


/**
/**
 * Represents a part of the display that is not functional for displaying content.
 * Represents the area of the display that is not functional for displaying content.
 *
 *
 * <p>{@code DisplayCutout} is immutable.
 * <p>{@code DisplayCutout} is immutable.
 */
 */
public final class DisplayCutout {
public final class DisplayCutout {


    private static final String TAG = "DisplayCutout";
    private static final String TAG = "DisplayCutout";
    private static final String BOTTOM_MARKER = "@bottom";
    private static final String DP_MARKER = "@dp";
    private static final String DP_MARKER = "@dp";


    /**
    /**
@@ -74,7 +71,7 @@ public final class DisplayCutout {
     * @hide
     * @hide
     */
     */
    public static final DisplayCutout NO_CUTOUT = new DisplayCutout(ZERO_RECT, EMPTY_REGION,
    public static final DisplayCutout NO_CUTOUT = new DisplayCutout(ZERO_RECT, EMPTY_REGION,
            new Size(0, 0));
            false /* copyArguments */);




    private static final Object CACHE_LOCK = new Object();
    private static final Object CACHE_LOCK = new Object();
@@ -89,38 +86,38 @@ public final class DisplayCutout {


    private final Rect mSafeInsets;
    private final Rect mSafeInsets;
    private final Region mBounds;
    private final Region mBounds;
    private final Size mFrameSize;  // TODO: move frameSize, calculateRelativeTo, etc. into WM.


    /**
    /**
     * Creates a DisplayCutout instance.
     * Creates a DisplayCutout instance.
     *
     *
     * @param safeInsets the insets from each edge which avoid the display cutout as returned by
     * @param safeInsets the insets from each edge which avoid the display cutout as returned by
     *                   {@link #getSafeInsetTop()} etc.
     *                   {@link #getSafeInsetTop()} etc.
     * @param bounds the bounds of the display cutout as returned by {@link #getBounds()}.
     * @param boundingRects the bounding rects of the display cutouts as returned by
     *               {@link #getBoundingRects()} ()}.
     */
     */
    // TODO(b/73953958): @VisibleForTesting(visibility = PRIVATE)
    // TODO(b/73953958): @VisibleForTesting(visibility = PRIVATE)
    public DisplayCutout(Rect safeInsets, Region bounds) {
    public DisplayCutout(Rect safeInsets, List<Rect> boundingRects) {
        this(safeInsets != null ? new Rect(safeInsets) : ZERO_RECT,
        this(safeInsets != null ? new Rect(safeInsets) : ZERO_RECT,
                bounds != null ? Region.obtain(bounds) : Region.obtain(),
                boundingRectsToRegion(boundingRects),
                null /* frameSize */);
                true /* copyArguments */);
    }
    }


    /**
    /**
     * Creates a DisplayCutout instance.
     * Creates a DisplayCutout instance.
     *
     *
     * NOTE: the Rects passed into this instance are not copied and MUST remain unchanged.
     * @param copyArguments if true, create a copy of the arguments. If false, the passed arguments
     *
     *                      are not copied and MUST remain unchanged forever.
     * @hide
     */
     */
    @VisibleForTesting
    private DisplayCutout(Rect safeInsets, Region bounds, boolean copyArguments) {
    public DisplayCutout(Rect safeInsets, Region bounds, Size frameSize) {
        mSafeInsets = safeInsets == null ? ZERO_RECT :
        mSafeInsets = safeInsets != null ? safeInsets : ZERO_RECT;
                (copyArguments ? new Rect(safeInsets) : safeInsets);
        mBounds = bounds != null ? bounds : Region.obtain();
        mBounds = bounds == null ? Region.obtain() :
        mFrameSize = frameSize;
                (copyArguments ? Region.obtain(bounds) : bounds);
    }
    }


    /**
    /**
     * Returns true if there is no cutout or it is outside of the content view.
     * Returns true if the safe insets are empty (and therefore the current view does not
     * overlap with the cutout or cutout area).
     *
     *
     * @hide
     * @hide
     */
     */
@@ -128,6 +125,15 @@ public final class DisplayCutout {
        return mSafeInsets.equals(ZERO_RECT);
        return mSafeInsets.equals(ZERO_RECT);
    }
    }


    /**
     * Returns true if there is no cutout, i.e. the bounds are empty.
     *
     * @hide
     */
    public boolean isBoundsEmpty() {
        return mBounds.isEmpty();
    }

    /** Returns the inset from the top which avoids the display cutout in pixels. */
    /** Returns the inset from the top which avoids the display cutout in pixels. */
    public int getSafeInsetTop() {
    public int getSafeInsetTop() {
        return mSafeInsets.top;
        return mSafeInsets.top;
@@ -161,23 +167,60 @@ public final class DisplayCutout {
    /**
    /**
     * Returns the bounding region of the cutout.
     * Returns the bounding region of the cutout.
     *
     *
     * <p>
     * <strong>Note:</strong> There may be more than one cutout, in which case the returned
     * {@code Region} will be non-contiguous and its bounding rect will be meaningless without
     * intersecting it first.
     *
     * Example:
     * <pre>
     *     // Getting the bounding rectangle of the top display cutout
     *     Region bounds = displayCutout.getBounds();
     *     bounds.op(0, 0, Integer.MAX_VALUE, displayCutout.getSafeInsetTop(), Region.Op.INTERSECT);
     *     Rect topDisplayCutout = bounds.getBoundingRect();
     * </pre>
     *
     * @return the bounding region of the cutout. Coordinates are relative
     * @return the bounding region of the cutout. Coordinates are relative
     *         to the top-left corner of the content view and in pixel units.
     *         to the top-left corner of the content view and in pixel units.
     * @hide
     */
     */
    public Region getBounds() {
    public Region getBounds() {
        return Region.obtain(mBounds);
        return Region.obtain(mBounds);
    }
    }


    /**
    /**
     * Returns the bounding rect of the cutout.
     * Returns a list of {@code Rect}s, each of which is the bounding rectangle for a non-functional
     * area on the display.
     *
     *
     * @return the bounding rect of the cutout. Coordinates are relative
     * There will be at most one non-functional area per short edge of the device, and none on
     *         to the top-left corner of the content view.
     * the long edges.
     * @hide
     *
     * @return a list of bounding {@code Rect}s, one for each display cutout area.
     */
     */
    public Rect getBoundingRect() {
    public List<Rect> getBoundingRects() {
        // TODO(roosa): Inline.
        List<Rect> result = new ArrayList<>();
        return mBounds.getBounds();
        Region bounds = Region.obtain();
        // top
        bounds.set(mBounds);
        bounds.op(0, 0, Integer.MAX_VALUE, getSafeInsetTop(), Region.Op.INTERSECT);
        if (!bounds.isEmpty()) {
            result.add(bounds.getBounds());
        }
        // left
        bounds.set(mBounds);
        bounds.op(0, 0, getSafeInsetLeft(), Integer.MAX_VALUE, Region.Op.INTERSECT);
        if (!bounds.isEmpty()) {
            result.add(bounds.getBounds());
        }
        // right & bottom
        bounds.set(mBounds);
        bounds.op(getSafeInsetLeft() + 1, getSafeInsetTop() + 1,
                Integer.MAX_VALUE, Integer.MAX_VALUE, Region.Op.INTERSECT);
        if (!bounds.isEmpty()) {
            result.add(bounds.getBounds());
        }
        bounds.recycle();
        return result;
    }
    }


    @Override
    @Override
@@ -195,8 +238,7 @@ public final class DisplayCutout {
        if (o instanceof DisplayCutout) {
        if (o instanceof DisplayCutout) {
            DisplayCutout c = (DisplayCutout) o;
            DisplayCutout c = (DisplayCutout) o;
            return mSafeInsets.equals(c.mSafeInsets)
            return mSafeInsets.equals(c.mSafeInsets)
                    && mBounds.equals(c.mBounds)
                    && mBounds.equals(c.mBounds);
                    && Objects.equals(mFrameSize, c.mFrameSize);
        }
        }
        return false;
        return false;
    }
    }
@@ -204,7 +246,7 @@ public final class DisplayCutout {
    @Override
    @Override
    public String toString() {
    public String toString() {
        return "DisplayCutout{insets=" + mSafeInsets
        return "DisplayCutout{insets=" + mSafeInsets
                + " boundingRect=" + getBoundingRect()
                + " boundingRect=" + mBounds.getBounds()
                + "}";
                + "}";
    }
    }


@@ -249,88 +291,19 @@ public final class DisplayCutout {
        }
        }


        bounds.translate(-insetLeft, -insetTop);
        bounds.translate(-insetLeft, -insetTop);
        Size frame = mFrameSize == null ? null : new Size(
        return new DisplayCutout(safeInsets, bounds, false /* copyArguments */);
                mFrameSize.getWidth() - insetLeft - insetRight,
                mFrameSize.getHeight() - insetTop - insetBottom);

        return new DisplayCutout(safeInsets, bounds, frame);
    }
    }


    /**
    /**
     * Recalculates the cutout relative to the given reference frame.
     * Returns a copy of this instance with the safe insets replaced with the parameter.
     *
     *
     * The safe insets must already have been computed, e.g. with {@link #computeSafeInsets}.
     * @param safeInsets the new safe insets in pixels
     * @return a copy of this instance with the safe insets replaced with the argument.
     *
     *
     * @return a copy of this instance with the safe insets recalculated
     * @hide
     * @hide
     */
     */
    public DisplayCutout calculateRelativeTo(Rect frame) {
    public DisplayCutout replaceSafeInsets(Rect safeInsets) {
        return inset(frame.left, frame.top,
        return new DisplayCutout(new Rect(safeInsets), mBounds, false /* copyArguments */);
                mFrameSize.getWidth() - frame.right, mFrameSize.getHeight() - frame.bottom);
    }

    /**
     * Calculates the safe insets relative to the given display size.
     *
     * @return a copy of this instance with the safe insets calculated
     * @hide
     */
    public DisplayCutout computeSafeInsets(int width, int height) {
        if (this == NO_CUTOUT || mBounds.isEmpty()) {
            return NO_CUTOUT;
        }

        return computeSafeInsets(new Size(width, height), mBounds);
    }

    private static DisplayCutout computeSafeInsets(Size displaySize, Region bounds) {
        Rect boundingRect = bounds.getBounds();
        Rect safeRect = new Rect();

        int bestArea = 0;
        int bestVariant = 0;
        for (int variant = ROTATION_0; variant <= ROTATION_270; variant++) {
            int area = calculateInsetVariantArea(displaySize, boundingRect, variant, safeRect);
            if (bestArea < area) {
                bestArea = area;
                bestVariant = variant;
            }
        }
        calculateInsetVariantArea(displaySize, boundingRect, bestVariant, safeRect);
        if (safeRect.isEmpty()) {
            // The entire displaySize overlaps with the cutout.
            safeRect.set(0, displaySize.getHeight(), 0, 0);
        } else {
            // Convert safeRect to insets relative to displaySize. We're reusing the rect here to
            // avoid an allocation.
            safeRect.set(
                    Math.max(0, safeRect.left),
                    Math.max(0, safeRect.top),
                    Math.max(0, displaySize.getWidth() - safeRect.right),
                    Math.max(0, displaySize.getHeight() - safeRect.bottom));
        }

        return new DisplayCutout(safeRect, bounds, displaySize);
    }

    private static int calculateInsetVariantArea(Size display, Rect boundingRect, int variant,
            Rect outSafeRect) {
        switch (variant) {
            case ROTATION_0:
                outSafeRect.set(0, 0, display.getWidth(), boundingRect.top);
                break;
            case ROTATION_90:
                outSafeRect.set(0, 0, boundingRect.left, display.getHeight());
                break;
            case ROTATION_180:
                outSafeRect.set(0, boundingRect.bottom, display.getWidth(), display.getHeight());
                break;
            case ROTATION_270:
                outSafeRect.set(boundingRect.right, 0, display.getWidth(), display.getHeight());
                break;
        }

        return outSafeRect.isEmpty() ? 0 : outSafeRect.width() * outSafeRect.height();
    }
    }


    private static int atLeastZero(int value) {
    private static int atLeastZero(int value) {
@@ -369,7 +342,7 @@ public final class DisplayCutout {
        Region bounds = new Region();
        Region bounds = new Region();
        bounds.setPath(path, clipRegion);
        bounds.setPath(path, clipRegion);
        clipRegion.recycle();
        clipRegion.recycle();
        return new DisplayCutout(ZERO_RECT, bounds, null /* frameSize */);
        return new DisplayCutout(ZERO_RECT, bounds, false /* copyArguments */);
    }
    }


    /**
    /**
@@ -377,9 +350,9 @@ public final class DisplayCutout {
     *
     *
     * @hide
     * @hide
     */
     */
    public static DisplayCutout fromResources(Resources res, int displayWidth) {
    public static DisplayCutout fromResources(Resources res, int displayWidth, int displayHeight) {
        return fromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout),
        return fromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout),
                displayWidth, res.getDisplayMetrics().density);
                displayWidth, displayHeight, res.getDisplayMetrics().density);
    }
    }


    /**
    /**
@@ -388,7 +361,8 @@ public final class DisplayCutout {
     * @hide
     * @hide
     */
     */
    @VisibleForTesting(visibility = PRIVATE)
    @VisibleForTesting(visibility = PRIVATE)
    public static DisplayCutout fromSpec(String spec, int displayWidth, float density) {
    public static DisplayCutout fromSpec(String spec, int displayWidth, int displayHeight,
            float density) {
        if (TextUtils.isEmpty(spec)) {
        if (TextUtils.isEmpty(spec)) {
            return null;
            return null;
        }
        }
@@ -404,7 +378,14 @@ public final class DisplayCutout {
            spec = spec.substring(0, spec.length() - DP_MARKER.length());
            spec = spec.substring(0, spec.length() - DP_MARKER.length());
        }
        }


        Path p;
        String bottomSpec = null;
        if (spec.contains(BOTTOM_MARKER)) {
            String[] splits = spec.split(BOTTOM_MARKER, 2);
            spec = splits[0].trim();
            bottomSpec = splits[1].trim();
        }

        final Path p;
        try {
        try {
            p = PathParser.createPathFromPathData(spec);
            p = PathParser.createPathFromPathData(spec);
        } catch (Throwable e) {
        } catch (Throwable e) {
@@ -419,6 +400,20 @@ public final class DisplayCutout {
        m.postTranslate(displayWidth / 2f, 0);
        m.postTranslate(displayWidth / 2f, 0);
        p.transform(m);
        p.transform(m);


        if (bottomSpec != null) {
            final Path bottomPath;
            try {
                bottomPath = PathParser.createPathFromPathData(bottomSpec);
            } catch (Throwable e) {
                Log.wtf(TAG, "Could not inflate bottom cutout: ", e);
                return null;
            }
            // Keep top transform
            m.postTranslate(0, displayHeight);
            bottomPath.transform(m);
            p.addPath(bottomPath);
        }

        final DisplayCutout result = fromBounds(p);
        final DisplayCutout result = fromBounds(p);
        synchronized (CACHE_LOCK) {
        synchronized (CACHE_LOCK) {
            sCachedSpec = spec;
            sCachedSpec = spec;
@@ -429,6 +424,16 @@ public final class DisplayCutout {
        return result;
        return result;
    }
    }


    private static Region boundingRectsToRegion(List<Rect> rects) {
        Region result = Region.obtain();
        if (rects != null) {
            for (Rect r : rects) {
                result.op(r, Region.Op.UNION);
            }
        }
        return result;
    }

    /**
    /**
     * Helper class for passing {@link DisplayCutout} through binder.
     * Helper class for passing {@link DisplayCutout} through binder.
     *
     *
@@ -472,12 +477,6 @@ public final class DisplayCutout {
                out.writeInt(1);
                out.writeInt(1);
                out.writeTypedObject(cutout.mSafeInsets, flags);
                out.writeTypedObject(cutout.mSafeInsets, flags);
                out.writeTypedObject(cutout.mBounds, flags);
                out.writeTypedObject(cutout.mBounds, flags);
                if (cutout.mFrameSize != null) {
                    out.writeInt(cutout.mFrameSize.getWidth());
                    out.writeInt(cutout.mFrameSize.getHeight());
                } else {
                    out.writeInt(-1);
                }
            }
            }
        }
        }


@@ -520,10 +519,7 @@ public final class DisplayCutout {
            Rect safeInsets = in.readTypedObject(Rect.CREATOR);
            Rect safeInsets = in.readTypedObject(Rect.CREATOR);
            Region bounds = in.readTypedObject(Region.CREATOR);
            Region bounds = in.readTypedObject(Region.CREATOR);


            int width = in.readInt();
            return new DisplayCutout(safeInsets, bounds, false /* copyArguments */);
            Size frameSize = width >= 0 ? new Size(width, in.readInt()) : null;

            return new DisplayCutout(safeInsets, bounds, frameSize);
        }
        }


        public DisplayCutout get() {
        public DisplayCutout get() {
+20 −8
Original line number Original line Diff line number Diff line
@@ -2241,18 +2241,20 @@ public interface WindowManager extends ViewManager {


        /**
        /**
         * The window is allowed to extend into the {@link DisplayCutout} area, only if the
         * The window is allowed to extend into the {@link DisplayCutout} area, only if the
         * {@link DisplayCutout} is fully contained within the status bar. Otherwise, the window is
         * {@link DisplayCutout} is fully contained within a system bar. Otherwise, the window is
         * laid out such that it does not overlap with the {@link DisplayCutout} area.
         * laid out such that it does not overlap with the {@link DisplayCutout} area.
         *
         *
         * <p>
         * <p>
         * In practice, this means that if the window did not set FLAG_FULLSCREEN or
         * In practice, this means that if the window did not set FLAG_FULLSCREEN or
         * SYSTEM_UI_FLAG_FULLSCREEN, it can extend into the cutout area in portrait.
         * SYSTEM_UI_FLAG_FULLSCREEN, it can extend into the cutout area in portrait if the cutout
         * Otherwise (i.e. fullscreen or landscape) it is laid out such that it does overlap the
         * is at the top edge. Similarly for SYSTEM_UI_FLAG_HIDE_NAVIGATION and a cutout at the
         * bottom of the screen.
         * Otherwise (i.e. fullscreen or landscape) it is laid out such that it does not overlap the
         * cutout area.
         * cutout area.
         *
         *
         * <p>
         * <p>
         * The usual precautions for not overlapping with the status bar are sufficient for ensuring
         * The usual precautions for not overlapping with the status and navigation bar are
         * that no important content overlaps with the DisplayCutout.
         * sufficient for ensuring that no important content overlaps with the DisplayCutout.
         *
         *
         * @see DisplayCutout
         * @see DisplayCutout
         * @see WindowInsets
         * @see WindowInsets
@@ -2260,8 +2262,18 @@ public interface WindowManager extends ViewManager {
        public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0;
        public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0;


        /**
        /**
         * The window is always allowed to extend into the {@link DisplayCutout} area,
         * @deprecated use {@link #LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES}
         * even if fullscreen or in landscape.
         * @hide
         */
        @Deprecated
        public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS = 1;

        /**
         * The window is always allowed to extend into the {@link DisplayCutout} areas on the short
         * edges of the screen.
         *
         * The window will never extend into a {@link DisplayCutout} area on the long edges of the
         * screen.
         *
         *
         * <p>
         * <p>
         * The window must make sure that no important content overlaps with the
         * The window must make sure that no important content overlaps with the
@@ -2270,7 +2282,7 @@ public interface WindowManager extends ViewManager {
         * @see DisplayCutout
         * @see DisplayCutout
         * @see WindowInsets#getDisplayCutout()
         * @see WindowInsets#getDisplayCutout()
         */
         */
        public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS = 1;
        public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES = 1;


        /**
        /**
         * The window is never allowed to overlap with the DisplayCutout area.
         * The window is never allowed to overlap with the DisplayCutout area.
+9 −6
Original line number Original line Diff line number Diff line
@@ -2125,29 +2125,32 @@
        Defaults to {@code default}.
        Defaults to {@code default}.


        @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
        @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
        @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
        @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
        @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
        @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
        @see android.view.DisplayCutout
        @see android.view.DisplayCutout
        @see android.R.attr#layoutInDisplayCutoutMode -->
        @see android.R.attr#layoutInDisplayCutoutMode -->
        <attr name="windowLayoutInDisplayCutoutMode">
        <attr name="windowLayoutInDisplayCutoutMode">
            <!-- The window is allowed to extend into the {@code DisplayCutout} area, only if the
            <!-- The window is allowed to extend into the {@code DisplayCutout} area, only if the
            {@code DisplayCutout} is fully contained within the status bar. Otherwise, the window is
            {@code DisplayCutout} is fully contained within a system bar. Otherwise, the window is
            laid out such that it does not overlap with the {@code DisplayCutout} area.
            laid out such that it does not overlap with the {@code DisplayCutout} area.


            @see android.view.DisplayCutout
            @see android.view.DisplayCutout
            @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
            @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
            -->
            -->
            <enum name="default" value="0" />
            <enum name="default" value="0" />
            <!-- The window is always allowed to extend into the {@code DisplayCutout} area,
            <!--
            even if fullscreen or in landscape.
            The window is always allowed to extend into the {@code DisplayCutout} areas on the short
            edges of the screen even if fullscreen or in landscape.
            The window will never extend into a {@link DisplayCutout} area on the long edges of the
            screen.
            <p>
            <p>
            The window must make sure that no important content overlaps with the
            The window must make sure that no important content overlaps with the
            {@link DisplayCutout}.
            {@link DisplayCutout}.


            @see android.view.DisplayCutout
            @see android.view.DisplayCutout
            @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
            @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
            -->
            -->
            <enum name="always" value="1" />
            <enum name="shortEdges" value="1" />
            <!-- The window is never allowed to overlap with the DisplayCutout area.
            <!-- The window is never allowed to overlap with the DisplayCutout area.
            <p>
            <p>
            This should be used with windows that transiently set {@code SYSTEM_UI_FLAG_FULLSCREEN}
            This should be used with windows that transiently set {@code SYSTEM_UI_FLAG_FULLSCREEN}
+2 −2
Original line number Original line Diff line number Diff line
@@ -25,8 +25,8 @@
    <style name="LayoutInDisplayCutoutModeDefault">
    <style name="LayoutInDisplayCutoutModeDefault">
        <item name="android:windowLayoutInDisplayCutoutMode">default</item>
        <item name="android:windowLayoutInDisplayCutoutMode">default</item>
    </style>
    </style>
    <style name="LayoutInDisplayCutoutModeAlways">
    <style name="LayoutInDisplayCutoutModeShortEdges">
        <item name="android:windowLayoutInDisplayCutoutMode">always</item>
        <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
    </style>
    </style>
    <style name="LayoutInDisplayCutoutModeNever">
    <style name="LayoutInDisplayCutoutModeNever">
        <item name="android:windowLayoutInDisplayCutoutMode">never</item>
        <item name="android:windowLayoutInDisplayCutoutMode">never</item>
Loading