Loading core/java/android/util/RotationUtils.java 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.util; 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 android.graphics.Insets; import android.view.Surface.Rotation; /** * A class containing utility methods related to rotation. * * @hide */ public class RotationUtils { /** * Rotates an Insets according to the given rotation. */ public static Insets rotateInsets(Insets insets, @Rotation int rotation) { if (insets == null || insets == Insets.NONE) { return insets; } Insets rotated; switch (rotation) { case ROTATION_0: rotated = insets; break; case ROTATION_90: rotated = Insets.of( insets.top, insets.right, insets.bottom, insets.left); break; case ROTATION_180: rotated = Insets.of( insets.right, insets.bottom, insets.left, insets.top); break; case ROTATION_270: rotated = Insets.of( insets.bottom, insets.left, insets.top, insets.right); break; default: throw new IllegalArgumentException("unknown rotation: " + rotation); } return rotated; } } core/res/res/values/dimens.xml +4 −2 Original line number Diff line number Diff line Loading @@ -33,9 +33,11 @@ <dimen name="toast_y_offset">24dp</dimen> <!-- Height of the status bar --> <dimen name="status_bar_height">@dimen/status_bar_height_portrait</dimen> <!-- Height of the status bar in portrait --> <!-- Height of the status bar in portrait. The height should be Max((status bar content height + waterfall top size), top cutout size) --> <dimen name="status_bar_height_portrait">24dp</dimen> <!-- Height of the status bar in landscape --> <!-- Height of the status bar in landscape. The height should be Max((status bar content height + waterfall top size), top cutout size) --> <dimen name="status_bar_height_landscape">@dimen/status_bar_height_portrait</dimen> <!-- Height of area above QQS where battery/time go --> <dimen name="quick_qs_offset_height">48dp</dimen> Loading packages/SystemUI/src/com/android/systemui/wm/DisplayLayout.java +51 −55 Original line number Diff line number Diff line Loading @@ -31,9 +31,11 @@ import android.annotation.NonNull; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.Rect; import android.os.SystemProperties; import android.provider.Settings; import android.util.RotationUtils; import android.util.Size; import android.view.Display; import android.view.DisplayCutout; Loading @@ -43,8 +45,6 @@ import android.view.Surface; import com.android.internal.R; import java.util.List; /** * Contains information about the layout-properties of a display. This refers to internal layout * like insets/cutout/rotation. In general, this can be thought of as the System-UI analog to Loading Loading @@ -323,28 +323,38 @@ public class DisplayLayout { if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) { return null; } final Insets waterfallInsets = RotationUtils.rotateInsets(cutout.getWaterfallInsets(), rotation); if (rotation == ROTATION_0) { return computeSafeInsets( cutout, displayWidth, displayHeight); return computeSafeInsets(cutout, displayWidth, displayHeight); } final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); Rect[] cutoutRects = computeSafeInsets(cutout, displayWidth, displayHeight) .getBoundingRectsAll(); Rect[] cutoutRects = cutout.getBoundingRectsAll(); final Rect[] newBounds = new Rect[cutoutRects.length]; final Rect displayBounds = new Rect(0, 0, displayWidth, displayHeight); for (int i = 0; i < cutoutRects.length; ++i) { newBounds[i] = new Rect(cutoutRects[i]); rotateBounds(newBounds[i], displayBounds, rotation); final Rect rect = new Rect(cutoutRects[i]); if (!rect.isEmpty()) { rotateBounds(rect, displayBounds, rotation); } return computeSafeInsets(DisplayCutout.fromBounds(newBounds), newBounds[getBoundIndexFromRotation(i, rotation)] = rect; } return computeSafeInsets( DisplayCutout.fromBoundsAndWaterfall(newBounds, waterfallInsets), rotated ? displayHeight : displayWidth, rotated ? displayWidth : displayHeight); } private static int getBoundIndexFromRotation(int index, int rotation) { return (index - rotation) < 0 ? index - rotation + DisplayCutout.BOUNDS_POSITION_LENGTH : index - rotation; } /** Calculate safe insets. */ public static DisplayCutout computeSafeInsets(DisplayCutout inner, int displayWidth, int displayHeight) { if (inner == DisplayCutout.NO_CUTOUT || inner.isBoundsEmpty()) { if (inner == DisplayCutout.NO_CUTOUT) { return null; } Loading @@ -353,59 +363,45 @@ public class DisplayLayout { return inner.replaceSafeInsets(safeInsets); } private static Rect computeSafeInsets(Size displaySize, DisplayCutout cutout) { if (displaySize.getWidth() < displaySize.getHeight()) { final List<Rect> boundingRects = cutout.replaceSafeInsets( new Rect(0, displaySize.getHeight() / 2, 0, displaySize.getHeight() / 2)) .getBoundingRects(); int topInset = findInsetForSide(displaySize, boundingRects, Gravity.TOP); int bottomInset = findInsetForSide(displaySize, boundingRects, Gravity.BOTTOM); return new Rect(0, topInset, 0, bottomInset); } else if (displaySize.getWidth() > displaySize.getHeight()) { final List<Rect> boundingRects = cutout.replaceSafeInsets( new Rect(displaySize.getWidth() / 2, 0, displaySize.getWidth() / 2, 0)) .getBoundingRects(); int leftInset = findInsetForSide(displaySize, boundingRects, Gravity.LEFT); int right = findInsetForSide(displaySize, boundingRects, Gravity.RIGHT); return new Rect(leftInset, 0, right, 0); } else { private static Rect computeSafeInsets( Size displaySize, DisplayCutout cutout) { if (displaySize.getWidth() == displaySize.getHeight()) { throw new UnsupportedOperationException("not implemented: display=" + displaySize + " cutout=" + cutout); } int leftInset = Math.max(cutout.getWaterfallInsets().left, findCutoutInsetForSide(displaySize, cutout.getBoundingRectLeft(), Gravity.LEFT)); int topInset = Math.max(cutout.getWaterfallInsets().top, findCutoutInsetForSide(displaySize, cutout.getBoundingRectTop(), Gravity.TOP)); int rightInset = Math.max(cutout.getWaterfallInsets().right, findCutoutInsetForSide(displaySize, cutout.getBoundingRectRight(), Gravity.RIGHT)); int bottomInset = Math.max(cutout.getWaterfallInsets().bottom, findCutoutInsetForSide(displaySize, cutout.getBoundingRectBottom(), Gravity.BOTTOM)); return new Rect(leftInset, topInset, rightInset, bottomInset); } private static int findCutoutInsetForSide(Size display, Rect boundingRect, int gravity) { if (boundingRect.isEmpty()) { return 0; } private static int findInsetForSide(Size display, List<Rect> boundingRects, int gravity) { int inset = 0; final int size = boundingRects.size(); for (int i = 0; i < size; i++) { Rect boundingRect = boundingRects.get(i); switch (gravity) { case Gravity.TOP: if (boundingRect.top == 0) { inset = Math.max(inset, boundingRect.bottom); } break; return Math.max(inset, boundingRect.bottom); case Gravity.BOTTOM: if (boundingRect.bottom == display.getHeight()) { inset = Math.max(inset, display.getHeight() - boundingRect.top); } break; return Math.max(inset, display.getHeight() - boundingRect.top); case Gravity.LEFT: if (boundingRect.left == 0) { inset = Math.max(inset, boundingRect.right); } break; return Math.max(inset, boundingRect.right); case Gravity.RIGHT: if (boundingRect.right == display.getWidth()) { inset = Math.max(inset, display.getWidth() - boundingRect.left); } break; return Math.max(inset, display.getWidth() - boundingRect.left); default: throw new IllegalArgumentException("unknown gravity: " + gravity); } } return inset; } static boolean hasNavigationBar(DisplayInfo info, Context context, int displayId) { if (displayId == Display.DEFAULT_DISPLAY) { Loading services/core/java/com/android/server/wm/DisplayContent.java +6 −4 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ import android.provider.Settings; import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.IntArray; import android.util.RotationUtils; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; Loading Loading @@ -1603,17 +1604,18 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) { return WmDisplayCutout.NO_CUTOUT; } final Insets waterfallInsets = RotationUtils.rotateInsets(cutout.getWaterfallInsets(), rotation); if (rotation == ROTATION_0) { return WmDisplayCutout.computeSafeInsets( cutout, mInitialDisplayWidth, mInitialDisplayHeight); } final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final Rect[] newBounds = mRotationUtil.getRotatedBounds( WmDisplayCutout.computeSafeInsets( cutout, mInitialDisplayWidth, mInitialDisplayHeight) .getDisplayCutout().getBoundingRectsAll(), cutout.getBoundingRectsAll(), rotation, mInitialDisplayWidth, mInitialDisplayHeight); return WmDisplayCutout.computeSafeInsets(DisplayCutout.fromBounds(newBounds), return WmDisplayCutout.computeSafeInsets( DisplayCutout.fromBoundsAndWaterfall(newBounds, waterfallInsets), rotated ? mInitialDisplayHeight : mInitialDisplayWidth, rotated ? mInitialDisplayWidth : mInitialDisplayHeight); } Loading services/core/java/com/android/server/wm/utils/WmDisplayCutout.java +38 −49 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.util.Size; import android.view.DisplayCutout; import android.view.Gravity; import java.util.List; import java.util.Objects; /** Loading @@ -41,12 +40,17 @@ public class WmDisplayCutout { mFrameSize = frameSize; } public static WmDisplayCutout computeSafeInsets(DisplayCutout inner, int displayWidth, int displayHeight) { if (inner == DisplayCutout.NO_CUTOUT || inner.isBoundsEmpty()) { /** * Compute the safe insets according to the given DisplayCutout and the display size. * * @return return a WmDisplayCutout with calculated safe insets. * @hide */ public static WmDisplayCutout computeSafeInsets( DisplayCutout inner, int displayWidth, int displayHeight) { if (inner == DisplayCutout.NO_CUTOUT) { return NO_CUTOUT; } final Size displaySize = new Size(displayWidth, displayHeight); final Rect safeInsets = computeSafeInsets(displaySize, inner); return new WmDisplayCutout(inner.replaceSafeInsets(safeInsets), displaySize); Loading Loading @@ -112,58 +116,43 @@ public class WmDisplayCutout { } private static Rect computeSafeInsets(Size displaySize, DisplayCutout cutout) { if (displaySize.getWidth() < displaySize.getHeight()) { final List<Rect> boundingRects = cutout.replaceSafeInsets( new Rect(0, displaySize.getHeight() / 2, 0, displaySize.getHeight() / 2)) .getBoundingRects(); int topInset = findInsetForSide(displaySize, boundingRects, Gravity.TOP); int bottomInset = findInsetForSide(displaySize, boundingRects, Gravity.BOTTOM); return new Rect(0, topInset, 0, bottomInset); } else if (displaySize.getWidth() > displaySize.getHeight()) { final List<Rect> boundingRects = cutout.replaceSafeInsets( new Rect(displaySize.getWidth() / 2, 0, displaySize.getWidth() / 2, 0)) .getBoundingRects(); int leftInset = findInsetForSide(displaySize, boundingRects, Gravity.LEFT); int right = findInsetForSide(displaySize, boundingRects, Gravity.RIGHT); return new Rect(leftInset, 0, right, 0); } else { if (displaySize.getWidth() == displaySize.getHeight()) { throw new UnsupportedOperationException("not implemented: display=" + displaySize + " cutout=" + cutout); } int leftInset = Math.max(cutout.getWaterfallInsets().left, findCutoutInsetForSide(displaySize, cutout.getBoundingRectLeft(), Gravity.LEFT)); int topInset = Math.max(cutout.getWaterfallInsets().top, findCutoutInsetForSide(displaySize, cutout.getBoundingRectTop(), Gravity.TOP)); int rightInset = Math.max(cutout.getWaterfallInsets().right, findCutoutInsetForSide(displaySize, cutout.getBoundingRectRight(), Gravity.RIGHT)); int bottomInset = Math.max(cutout.getWaterfallInsets().bottom, findCutoutInsetForSide(displaySize, cutout.getBoundingRectBottom(), Gravity.BOTTOM)); return new Rect(leftInset, topInset, rightInset, bottomInset); } private static int findCutoutInsetForSide(Size display, Rect boundingRect, int gravity) { if (boundingRect.isEmpty()) { return 0; } private static int findInsetForSide(Size display, List<Rect> boundingRects, int gravity) { int inset = 0; final int size = boundingRects.size(); for (int i = 0; i < size; i++) { Rect boundingRect = boundingRects.get(i); switch (gravity) { case Gravity.TOP: if (boundingRect.top == 0) { inset = Math.max(inset, boundingRect.bottom); } break; return Math.max(inset, boundingRect.bottom); case Gravity.BOTTOM: if (boundingRect.bottom == display.getHeight()) { inset = Math.max(inset, display.getHeight() - boundingRect.top); } break; return Math.max(inset, display.getHeight() - boundingRect.top); case Gravity.LEFT: if (boundingRect.left == 0) { inset = Math.max(inset, boundingRect.right); } break; return Math.max(inset, boundingRect.right); case Gravity.RIGHT: if (boundingRect.right == display.getWidth()) { inset = Math.max(inset, display.getWidth() - boundingRect.left); } break; return Math.max(inset, display.getWidth() - boundingRect.left); default: throw new IllegalArgumentException("unknown gravity: " + gravity); } } return inset; } public DisplayCutout getDisplayCutout() { return mInner; Loading Loading
core/java/android/util/RotationUtils.java 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.util; 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 android.graphics.Insets; import android.view.Surface.Rotation; /** * A class containing utility methods related to rotation. * * @hide */ public class RotationUtils { /** * Rotates an Insets according to the given rotation. */ public static Insets rotateInsets(Insets insets, @Rotation int rotation) { if (insets == null || insets == Insets.NONE) { return insets; } Insets rotated; switch (rotation) { case ROTATION_0: rotated = insets; break; case ROTATION_90: rotated = Insets.of( insets.top, insets.right, insets.bottom, insets.left); break; case ROTATION_180: rotated = Insets.of( insets.right, insets.bottom, insets.left, insets.top); break; case ROTATION_270: rotated = Insets.of( insets.bottom, insets.left, insets.top, insets.right); break; default: throw new IllegalArgumentException("unknown rotation: " + rotation); } return rotated; } }
core/res/res/values/dimens.xml +4 −2 Original line number Diff line number Diff line Loading @@ -33,9 +33,11 @@ <dimen name="toast_y_offset">24dp</dimen> <!-- Height of the status bar --> <dimen name="status_bar_height">@dimen/status_bar_height_portrait</dimen> <!-- Height of the status bar in portrait --> <!-- Height of the status bar in portrait. The height should be Max((status bar content height + waterfall top size), top cutout size) --> <dimen name="status_bar_height_portrait">24dp</dimen> <!-- Height of the status bar in landscape --> <!-- Height of the status bar in landscape. The height should be Max((status bar content height + waterfall top size), top cutout size) --> <dimen name="status_bar_height_landscape">@dimen/status_bar_height_portrait</dimen> <!-- Height of area above QQS where battery/time go --> <dimen name="quick_qs_offset_height">48dp</dimen> Loading
packages/SystemUI/src/com/android/systemui/wm/DisplayLayout.java +51 −55 Original line number Diff line number Diff line Loading @@ -31,9 +31,11 @@ import android.annotation.NonNull; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.Rect; import android.os.SystemProperties; import android.provider.Settings; import android.util.RotationUtils; import android.util.Size; import android.view.Display; import android.view.DisplayCutout; Loading @@ -43,8 +45,6 @@ import android.view.Surface; import com.android.internal.R; import java.util.List; /** * Contains information about the layout-properties of a display. This refers to internal layout * like insets/cutout/rotation. In general, this can be thought of as the System-UI analog to Loading Loading @@ -323,28 +323,38 @@ public class DisplayLayout { if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) { return null; } final Insets waterfallInsets = RotationUtils.rotateInsets(cutout.getWaterfallInsets(), rotation); if (rotation == ROTATION_0) { return computeSafeInsets( cutout, displayWidth, displayHeight); return computeSafeInsets(cutout, displayWidth, displayHeight); } final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); Rect[] cutoutRects = computeSafeInsets(cutout, displayWidth, displayHeight) .getBoundingRectsAll(); Rect[] cutoutRects = cutout.getBoundingRectsAll(); final Rect[] newBounds = new Rect[cutoutRects.length]; final Rect displayBounds = new Rect(0, 0, displayWidth, displayHeight); for (int i = 0; i < cutoutRects.length; ++i) { newBounds[i] = new Rect(cutoutRects[i]); rotateBounds(newBounds[i], displayBounds, rotation); final Rect rect = new Rect(cutoutRects[i]); if (!rect.isEmpty()) { rotateBounds(rect, displayBounds, rotation); } return computeSafeInsets(DisplayCutout.fromBounds(newBounds), newBounds[getBoundIndexFromRotation(i, rotation)] = rect; } return computeSafeInsets( DisplayCutout.fromBoundsAndWaterfall(newBounds, waterfallInsets), rotated ? displayHeight : displayWidth, rotated ? displayWidth : displayHeight); } private static int getBoundIndexFromRotation(int index, int rotation) { return (index - rotation) < 0 ? index - rotation + DisplayCutout.BOUNDS_POSITION_LENGTH : index - rotation; } /** Calculate safe insets. */ public static DisplayCutout computeSafeInsets(DisplayCutout inner, int displayWidth, int displayHeight) { if (inner == DisplayCutout.NO_CUTOUT || inner.isBoundsEmpty()) { if (inner == DisplayCutout.NO_CUTOUT) { return null; } Loading @@ -353,59 +363,45 @@ public class DisplayLayout { return inner.replaceSafeInsets(safeInsets); } private static Rect computeSafeInsets(Size displaySize, DisplayCutout cutout) { if (displaySize.getWidth() < displaySize.getHeight()) { final List<Rect> boundingRects = cutout.replaceSafeInsets( new Rect(0, displaySize.getHeight() / 2, 0, displaySize.getHeight() / 2)) .getBoundingRects(); int topInset = findInsetForSide(displaySize, boundingRects, Gravity.TOP); int bottomInset = findInsetForSide(displaySize, boundingRects, Gravity.BOTTOM); return new Rect(0, topInset, 0, bottomInset); } else if (displaySize.getWidth() > displaySize.getHeight()) { final List<Rect> boundingRects = cutout.replaceSafeInsets( new Rect(displaySize.getWidth() / 2, 0, displaySize.getWidth() / 2, 0)) .getBoundingRects(); int leftInset = findInsetForSide(displaySize, boundingRects, Gravity.LEFT); int right = findInsetForSide(displaySize, boundingRects, Gravity.RIGHT); return new Rect(leftInset, 0, right, 0); } else { private static Rect computeSafeInsets( Size displaySize, DisplayCutout cutout) { if (displaySize.getWidth() == displaySize.getHeight()) { throw new UnsupportedOperationException("not implemented: display=" + displaySize + " cutout=" + cutout); } int leftInset = Math.max(cutout.getWaterfallInsets().left, findCutoutInsetForSide(displaySize, cutout.getBoundingRectLeft(), Gravity.LEFT)); int topInset = Math.max(cutout.getWaterfallInsets().top, findCutoutInsetForSide(displaySize, cutout.getBoundingRectTop(), Gravity.TOP)); int rightInset = Math.max(cutout.getWaterfallInsets().right, findCutoutInsetForSide(displaySize, cutout.getBoundingRectRight(), Gravity.RIGHT)); int bottomInset = Math.max(cutout.getWaterfallInsets().bottom, findCutoutInsetForSide(displaySize, cutout.getBoundingRectBottom(), Gravity.BOTTOM)); return new Rect(leftInset, topInset, rightInset, bottomInset); } private static int findCutoutInsetForSide(Size display, Rect boundingRect, int gravity) { if (boundingRect.isEmpty()) { return 0; } private static int findInsetForSide(Size display, List<Rect> boundingRects, int gravity) { int inset = 0; final int size = boundingRects.size(); for (int i = 0; i < size; i++) { Rect boundingRect = boundingRects.get(i); switch (gravity) { case Gravity.TOP: if (boundingRect.top == 0) { inset = Math.max(inset, boundingRect.bottom); } break; return Math.max(inset, boundingRect.bottom); case Gravity.BOTTOM: if (boundingRect.bottom == display.getHeight()) { inset = Math.max(inset, display.getHeight() - boundingRect.top); } break; return Math.max(inset, display.getHeight() - boundingRect.top); case Gravity.LEFT: if (boundingRect.left == 0) { inset = Math.max(inset, boundingRect.right); } break; return Math.max(inset, boundingRect.right); case Gravity.RIGHT: if (boundingRect.right == display.getWidth()) { inset = Math.max(inset, display.getWidth() - boundingRect.left); } break; return Math.max(inset, display.getWidth() - boundingRect.left); default: throw new IllegalArgumentException("unknown gravity: " + gravity); } } return inset; } static boolean hasNavigationBar(DisplayInfo info, Context context, int displayId) { if (displayId == Display.DEFAULT_DISPLAY) { Loading
services/core/java/com/android/server/wm/DisplayContent.java +6 −4 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ import android.provider.Settings; import android.util.ArraySet; import android.util.DisplayMetrics; import android.util.IntArray; import android.util.RotationUtils; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; Loading Loading @@ -1603,17 +1604,18 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (cutout == null || cutout == DisplayCutout.NO_CUTOUT) { return WmDisplayCutout.NO_CUTOUT; } final Insets waterfallInsets = RotationUtils.rotateInsets(cutout.getWaterfallInsets(), rotation); if (rotation == ROTATION_0) { return WmDisplayCutout.computeSafeInsets( cutout, mInitialDisplayWidth, mInitialDisplayHeight); } final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); final Rect[] newBounds = mRotationUtil.getRotatedBounds( WmDisplayCutout.computeSafeInsets( cutout, mInitialDisplayWidth, mInitialDisplayHeight) .getDisplayCutout().getBoundingRectsAll(), cutout.getBoundingRectsAll(), rotation, mInitialDisplayWidth, mInitialDisplayHeight); return WmDisplayCutout.computeSafeInsets(DisplayCutout.fromBounds(newBounds), return WmDisplayCutout.computeSafeInsets( DisplayCutout.fromBoundsAndWaterfall(newBounds, waterfallInsets), rotated ? mInitialDisplayHeight : mInitialDisplayWidth, rotated ? mInitialDisplayWidth : mInitialDisplayHeight); } Loading
services/core/java/com/android/server/wm/utils/WmDisplayCutout.java +38 −49 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.util.Size; import android.view.DisplayCutout; import android.view.Gravity; import java.util.List; import java.util.Objects; /** Loading @@ -41,12 +40,17 @@ public class WmDisplayCutout { mFrameSize = frameSize; } public static WmDisplayCutout computeSafeInsets(DisplayCutout inner, int displayWidth, int displayHeight) { if (inner == DisplayCutout.NO_CUTOUT || inner.isBoundsEmpty()) { /** * Compute the safe insets according to the given DisplayCutout and the display size. * * @return return a WmDisplayCutout with calculated safe insets. * @hide */ public static WmDisplayCutout computeSafeInsets( DisplayCutout inner, int displayWidth, int displayHeight) { if (inner == DisplayCutout.NO_CUTOUT) { return NO_CUTOUT; } final Size displaySize = new Size(displayWidth, displayHeight); final Rect safeInsets = computeSafeInsets(displaySize, inner); return new WmDisplayCutout(inner.replaceSafeInsets(safeInsets), displaySize); Loading Loading @@ -112,58 +116,43 @@ public class WmDisplayCutout { } private static Rect computeSafeInsets(Size displaySize, DisplayCutout cutout) { if (displaySize.getWidth() < displaySize.getHeight()) { final List<Rect> boundingRects = cutout.replaceSafeInsets( new Rect(0, displaySize.getHeight() / 2, 0, displaySize.getHeight() / 2)) .getBoundingRects(); int topInset = findInsetForSide(displaySize, boundingRects, Gravity.TOP); int bottomInset = findInsetForSide(displaySize, boundingRects, Gravity.BOTTOM); return new Rect(0, topInset, 0, bottomInset); } else if (displaySize.getWidth() > displaySize.getHeight()) { final List<Rect> boundingRects = cutout.replaceSafeInsets( new Rect(displaySize.getWidth() / 2, 0, displaySize.getWidth() / 2, 0)) .getBoundingRects(); int leftInset = findInsetForSide(displaySize, boundingRects, Gravity.LEFT); int right = findInsetForSide(displaySize, boundingRects, Gravity.RIGHT); return new Rect(leftInset, 0, right, 0); } else { if (displaySize.getWidth() == displaySize.getHeight()) { throw new UnsupportedOperationException("not implemented: display=" + displaySize + " cutout=" + cutout); } int leftInset = Math.max(cutout.getWaterfallInsets().left, findCutoutInsetForSide(displaySize, cutout.getBoundingRectLeft(), Gravity.LEFT)); int topInset = Math.max(cutout.getWaterfallInsets().top, findCutoutInsetForSide(displaySize, cutout.getBoundingRectTop(), Gravity.TOP)); int rightInset = Math.max(cutout.getWaterfallInsets().right, findCutoutInsetForSide(displaySize, cutout.getBoundingRectRight(), Gravity.RIGHT)); int bottomInset = Math.max(cutout.getWaterfallInsets().bottom, findCutoutInsetForSide(displaySize, cutout.getBoundingRectBottom(), Gravity.BOTTOM)); return new Rect(leftInset, topInset, rightInset, bottomInset); } private static int findCutoutInsetForSide(Size display, Rect boundingRect, int gravity) { if (boundingRect.isEmpty()) { return 0; } private static int findInsetForSide(Size display, List<Rect> boundingRects, int gravity) { int inset = 0; final int size = boundingRects.size(); for (int i = 0; i < size; i++) { Rect boundingRect = boundingRects.get(i); switch (gravity) { case Gravity.TOP: if (boundingRect.top == 0) { inset = Math.max(inset, boundingRect.bottom); } break; return Math.max(inset, boundingRect.bottom); case Gravity.BOTTOM: if (boundingRect.bottom == display.getHeight()) { inset = Math.max(inset, display.getHeight() - boundingRect.top); } break; return Math.max(inset, display.getHeight() - boundingRect.top); case Gravity.LEFT: if (boundingRect.left == 0) { inset = Math.max(inset, boundingRect.right); } break; return Math.max(inset, boundingRect.right); case Gravity.RIGHT: if (boundingRect.right == display.getWidth()) { inset = Math.max(inset, display.getWidth() - boundingRect.left); } break; return Math.max(inset, display.getWidth() - boundingRect.left); default: throw new IllegalArgumentException("unknown gravity: " + gravity); } } return inset; } public DisplayCutout getDisplayCutout() { return mInner; Loading