Merge "Cutout: Add developer setting to mask the display cutout" into pi-dev
am: c05c2d1e48
Change-Id: I728ce64b53d02f5a75f04071a04f5e6d0f61987c
This commit is contained in:
@@ -325,6 +325,7 @@ public final class DisplayCutout {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
public static DisplayCutout fromBoundingRect(int left, int top, int right, int bottom) {
|
public static DisplayCutout fromBoundingRect(int left, int top, int right, int bottom) {
|
||||||
Region r = Region.obtain();
|
Region r = Region.obtain();
|
||||||
r.set(left, top, right, bottom);
|
r.set(left, top, right, bottom);
|
||||||
@@ -422,8 +423,11 @@ public final class DisplayCutout {
|
|||||||
m.postTranslate(offsetX, 0);
|
m.postTranslate(offsetX, 0);
|
||||||
p.transform(m);
|
p.transform(m);
|
||||||
|
|
||||||
addToRegion(p, r);
|
final Rect tmpRect = new Rect();
|
||||||
|
toRectAndAddToRegion(p, r, tmpRect);
|
||||||
|
final int topInset = tmpRect.bottom;
|
||||||
|
|
||||||
|
final int bottomInset;
|
||||||
if (bottomSpec != null) {
|
if (bottomSpec != null) {
|
||||||
final Path bottomPath;
|
final Path bottomPath;
|
||||||
try {
|
try {
|
||||||
@@ -436,10 +440,17 @@ public final class DisplayCutout {
|
|||||||
m.postTranslate(0, displayHeight);
|
m.postTranslate(0, displayHeight);
|
||||||
bottomPath.transform(m);
|
bottomPath.transform(m);
|
||||||
p.addPath(bottomPath);
|
p.addPath(bottomPath);
|
||||||
addToRegion(bottomPath, r);
|
toRectAndAddToRegion(bottomPath, r, tmpRect);
|
||||||
|
bottomInset = displayHeight - tmpRect.top;
|
||||||
|
} else {
|
||||||
|
bottomInset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Pair<Path, DisplayCutout> result = new Pair<>(p, fromBounds(r));
|
// Reuse tmpRect as the inset rect we store into the DisplayCutout instance.
|
||||||
|
tmpRect.set(0, topInset, 0, bottomInset);
|
||||||
|
final DisplayCutout cutout = new DisplayCutout(tmpRect, r, false /* copyArguments */);
|
||||||
|
|
||||||
|
final Pair<Path, DisplayCutout> result = new Pair<>(p, cutout);
|
||||||
synchronized (CACHE_LOCK) {
|
synchronized (CACHE_LOCK) {
|
||||||
sCachedSpec = spec;
|
sCachedSpec = spec;
|
||||||
sCachedDisplayWidth = displayWidth;
|
sCachedDisplayWidth = displayWidth;
|
||||||
@@ -450,12 +461,11 @@ public final class DisplayCutout {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addToRegion(Path p, Region r) {
|
private static void toRectAndAddToRegion(Path p, Region inoutRegion, Rect inoutRect) {
|
||||||
final RectF rectF = new RectF();
|
final RectF rectF = new RectF();
|
||||||
final Rect rect = new Rect();
|
|
||||||
p.computeBounds(rectF, false /* unused */);
|
p.computeBounds(rectF, false /* unused */);
|
||||||
rectF.round(rect);
|
rectF.round(inoutRect);
|
||||||
r.op(rect, Op.UNION);
|
inoutRegion.op(inoutRect, Op.UNION);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Region boundingRectsToRegion(List<Rect> rects) {
|
private static Region boundingRectsToRegion(List<Rect> rects) {
|
||||||
|
|||||||
@@ -2986,6 +2986,10 @@
|
|||||||
-->
|
-->
|
||||||
<bool name="config_fillMainBuiltInDisplayCutout">false</bool>
|
<bool name="config_fillMainBuiltInDisplayCutout">false</bool>
|
||||||
|
|
||||||
|
<!-- If true, and there is a cutout on the main built in display, the cutout will be masked
|
||||||
|
by shrinking the display such that it does not overlap the cutout area. -->
|
||||||
|
<bool name="config_maskMainBuiltInDisplayCutout">false</bool>
|
||||||
|
|
||||||
<!-- Ultrasound support for Mic/speaker path -->
|
<!-- Ultrasound support for Mic/speaker path -->
|
||||||
<!-- Whether the default microphone audio source supports near-ultrasound frequencies
|
<!-- Whether the default microphone audio source supports near-ultrasound frequencies
|
||||||
(range of 18 - 21 kHz). -->
|
(range of 18 - 21 kHz). -->
|
||||||
|
|||||||
@@ -61,6 +61,15 @@
|
|||||||
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
|
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
|
||||||
<dimen name="status_bar_edge_ignore">5dp</dimen>
|
<dimen name="status_bar_edge_ignore">5dp</dimen>
|
||||||
|
|
||||||
|
<!-- Default radius of the software rounded corners. -->
|
||||||
|
<dimen name="rounded_corner_radius">0dp</dimen>
|
||||||
|
<!-- Radius of the software rounded corners at the top of the display in its natural
|
||||||
|
orientation. If zero, the value of rounded_corner_radius is used. -->
|
||||||
|
<dimen name="rounded_corner_radius_top">0dp</dimen>
|
||||||
|
<!-- Radius of the software rounded corners at the bottom of the display in its natural
|
||||||
|
orientation. If zero, the value of rounded_corner_radius is used. -->
|
||||||
|
<dimen name="rounded_corner_radius_bottom">0dp</dimen>
|
||||||
|
|
||||||
<!-- Width of the window of the divider bar used to resize docked stacks. -->
|
<!-- Width of the window of the divider bar used to resize docked stacks. -->
|
||||||
<dimen name="docked_stack_divider_thickness">48dp</dimen>
|
<dimen name="docked_stack_divider_thickness">48dp</dimen>
|
||||||
|
|
||||||
|
|||||||
@@ -3408,6 +3408,8 @@
|
|||||||
<java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" />
|
<java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" />
|
||||||
<java-symbol type="integer" name="config_defaultNotificationVibrationIntensity" />
|
<java-symbol type="integer" name="config_defaultNotificationVibrationIntensity" />
|
||||||
|
|
||||||
|
<java-symbol type="bool" name="config_maskMainBuiltInDisplayCutout" />
|
||||||
|
|
||||||
<java-symbol type="array" name="config_disableApksUnlessMatchedSku_apk_list" />
|
<java-symbol type="array" name="config_disableApksUnlessMatchedSku_apk_list" />
|
||||||
<java-symbol type="array" name="config_disableApkUnlessMatchedSku_skus_list" />
|
<java-symbol type="array" name="config_disableApkUnlessMatchedSku_skus_list" />
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package android.view;
|
|||||||
import static android.view.DisplayCutout.NO_CUTOUT;
|
import static android.view.DisplayCutout.NO_CUTOUT;
|
||||||
import static android.view.DisplayCutout.fromSpec;
|
import static android.view.DisplayCutout.fromSpec;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.Matchers.sameInstance;
|
import static org.hamcrest.Matchers.sameInstance;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -219,6 +220,19 @@ public class DisplayCutoutTest {
|
|||||||
assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached)));
|
assertThat(fromSpec("L1,0 L1,1 L0,1 z", 200, 400, 1f), not(sameInstance(cached)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromSpec_setsSafeInsets_top() {
|
||||||
|
DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z", 200, 400, 2f);
|
||||||
|
assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 20, 0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromSpec_setsSafeInsets_top_and_bottom() {
|
||||||
|
DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z"
|
||||||
|
+ "@bottom M -50,0 v -10,0 h 100 v 20 z", 200, 400, 2f);
|
||||||
|
assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 20, 0, 10)));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parcel_unparcel_nocutout() {
|
public void parcel_unparcel_nocutout() {
|
||||||
Parcel p = Parcel.obtain();
|
Parcel p = Parcel.obtain();
|
||||||
|
|||||||
@@ -943,9 +943,9 @@
|
|||||||
<dimen name="bottom_padding">48dp</dimen>
|
<dimen name="bottom_padding">48dp</dimen>
|
||||||
<dimen name="edge_margin">8dp</dimen>
|
<dimen name="edge_margin">8dp</dimen>
|
||||||
|
|
||||||
<dimen name="rounded_corner_radius">0dp</dimen>
|
<dimen name="rounded_corner_radius">@*android:dimen/rounded_corner_radius</dimen>
|
||||||
<dimen name="rounded_corner_radius_top">0dp</dimen>
|
<dimen name="rounded_corner_radius_top">@*android:dimen/rounded_corner_radius_top</dimen>
|
||||||
<dimen name="rounded_corner_radius_bottom">0dp</dimen>
|
<dimen name="rounded_corner_radius_bottom">@*android:dimen/rounded_corner_radius_bottom</dimen>
|
||||||
<dimen name="rounded_corner_content_padding">0dp</dimen>
|
<dimen name="rounded_corner_content_padding">0dp</dimen>
|
||||||
<dimen name="nav_content_padding">0dp</dimen>
|
<dimen name="nav_content_padding">0dp</dimen>
|
||||||
<dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen>
|
<dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen>
|
||||||
|
|||||||
@@ -103,6 +103,12 @@ final class DisplayDeviceInfo {
|
|||||||
*/
|
*/
|
||||||
public static final int FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 10;
|
public static final int FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag: The display cutout of this display is masked.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int FLAG_MASK_DISPLAY_CUTOUT = 1 << 11;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Touch attachment: Display does not receive touch.
|
* Touch attachment: Display does not receive touch.
|
||||||
*/
|
*/
|
||||||
@@ -453,6 +459,9 @@ final class DisplayDeviceInfo {
|
|||||||
if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
|
if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
|
||||||
msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD");
|
msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD");
|
||||||
}
|
}
|
||||||
|
if ((flags & FLAG_MASK_DISPLAY_CUTOUT) != 0) {
|
||||||
|
msg.append(", FLAG_MASK_DISPLAY_CUTOUT");
|
||||||
|
}
|
||||||
return msg.toString();
|
return msg.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -402,6 +402,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
&& SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
|
&& SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
|
||||||
mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
|
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.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
|
||||||
mInfo.width, mInfo.height);
|
mInfo.width, mInfo.height);
|
||||||
mInfo.type = Display.TYPE_BUILT_IN;
|
mInfo.type = Display.TYPE_BUILT_IN;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import android.view.DisplayInfo;
|
|||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
|
|
||||||
|
import com.android.server.wm.utils.InsetUtils;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -251,14 +253,18 @@ final class LogicalDisplay {
|
|||||||
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
|
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
|
||||||
mBaseDisplayInfo.flags |= Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
|
mBaseDisplayInfo.flags |= Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
|
||||||
}
|
}
|
||||||
|
Rect maskingInsets = getMaskingInsets(deviceInfo);
|
||||||
|
int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
|
||||||
|
int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;
|
||||||
|
|
||||||
mBaseDisplayInfo.type = deviceInfo.type;
|
mBaseDisplayInfo.type = deviceInfo.type;
|
||||||
mBaseDisplayInfo.address = deviceInfo.address;
|
mBaseDisplayInfo.address = deviceInfo.address;
|
||||||
mBaseDisplayInfo.name = deviceInfo.name;
|
mBaseDisplayInfo.name = deviceInfo.name;
|
||||||
mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId;
|
mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId;
|
||||||
mBaseDisplayInfo.appWidth = deviceInfo.width;
|
mBaseDisplayInfo.appWidth = maskedWidth;
|
||||||
mBaseDisplayInfo.appHeight = deviceInfo.height;
|
mBaseDisplayInfo.appHeight = maskedHeight;
|
||||||
mBaseDisplayInfo.logicalWidth = deviceInfo.width;
|
mBaseDisplayInfo.logicalWidth = maskedWidth;
|
||||||
mBaseDisplayInfo.logicalHeight = deviceInfo.height;
|
mBaseDisplayInfo.logicalHeight = maskedHeight;
|
||||||
mBaseDisplayInfo.rotation = Surface.ROTATION_0;
|
mBaseDisplayInfo.rotation = Surface.ROTATION_0;
|
||||||
mBaseDisplayInfo.modeId = deviceInfo.modeId;
|
mBaseDisplayInfo.modeId = deviceInfo.modeId;
|
||||||
mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
|
mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
|
||||||
@@ -275,19 +281,33 @@ final class LogicalDisplay {
|
|||||||
mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
|
mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
|
||||||
mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
|
mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
|
||||||
mBaseDisplayInfo.state = deviceInfo.state;
|
mBaseDisplayInfo.state = deviceInfo.state;
|
||||||
mBaseDisplayInfo.smallestNominalAppWidth = deviceInfo.width;
|
mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth;
|
||||||
mBaseDisplayInfo.smallestNominalAppHeight = deviceInfo.height;
|
mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight;
|
||||||
mBaseDisplayInfo.largestNominalAppWidth = deviceInfo.width;
|
mBaseDisplayInfo.largestNominalAppWidth = maskedWidth;
|
||||||
mBaseDisplayInfo.largestNominalAppHeight = deviceInfo.height;
|
mBaseDisplayInfo.largestNominalAppHeight = maskedHeight;
|
||||||
mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid;
|
mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid;
|
||||||
mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName;
|
mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName;
|
||||||
mBaseDisplayInfo.displayCutout = deviceInfo.displayCutout;
|
boolean maskCutout =
|
||||||
|
(deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
|
||||||
|
mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout;
|
||||||
|
|
||||||
mPrimaryDisplayDeviceInfo = deviceInfo;
|
mPrimaryDisplayDeviceInfo = deviceInfo;
|
||||||
mInfo = null;
|
mInfo = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns insets in ROTATION_0 for areas that are masked.
|
||||||
|
*/
|
||||||
|
private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) {
|
||||||
|
boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
|
||||||
|
if (maskCutout && deviceInfo.displayCutout != null) {
|
||||||
|
return deviceInfo.displayCutout.getSafeInsets();
|
||||||
|
} else {
|
||||||
|
return new Rect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the layer stack and transformation to the given display device
|
* Applies the layer stack and transformation to the given display device
|
||||||
* so that it shows the contents of this logical display.
|
* so that it shows the contents of this logical display.
|
||||||
@@ -349,6 +369,12 @@ final class LogicalDisplay {
|
|||||||
int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width;
|
int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width;
|
||||||
int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height;
|
int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height;
|
||||||
|
|
||||||
|
Rect maskingInsets = getMaskingInsets(displayDeviceInfo);
|
||||||
|
InsetUtils.rotateInsets(maskingInsets, orientation);
|
||||||
|
// Don't consider the masked area as available when calculating the scaling below.
|
||||||
|
physWidth -= maskingInsets.left + maskingInsets.right;
|
||||||
|
physHeight -= maskingInsets.top + maskingInsets.bottom;
|
||||||
|
|
||||||
// Determine whether the width or height is more constrained to be scaled.
|
// Determine whether the width or height is more constrained to be scaled.
|
||||||
// physWidth / displayInfo.logicalWidth => letter box
|
// physWidth / displayInfo.logicalWidth => letter box
|
||||||
// or physHeight / displayInfo.logicalHeight => pillar box
|
// or physHeight / displayInfo.logicalHeight => pillar box
|
||||||
@@ -375,6 +401,9 @@ final class LogicalDisplay {
|
|||||||
mTempDisplayRect.set(displayRectLeft, displayRectTop,
|
mTempDisplayRect.set(displayRectLeft, displayRectTop,
|
||||||
displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);
|
displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);
|
||||||
|
|
||||||
|
// Now add back the offset for the masked area.
|
||||||
|
mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top);
|
||||||
|
|
||||||
mTempDisplayRect.left += mDisplayOffsetX;
|
mTempDisplayRect.left += mDisplayOffsetX;
|
||||||
mTempDisplayRect.right += mDisplayOffsetX;
|
mTempDisplayRect.right += mDisplayOffsetX;
|
||||||
mTempDisplayRect.top += mDisplayOffsetY;
|
mTempDisplayRect.top += mDisplayOffsetY;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.wm.utils;
|
package com.android.server.wm.utils;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.view.Surface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods to handle insets represented as rects.
|
* Utility methods to handle insets represented as rects.
|
||||||
@@ -26,6 +27,32 @@ public class InsetUtils {
|
|||||||
private InsetUtils() {
|
private InsetUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms insets given in one rotation into insets in a different rotation.
|
||||||
|
*
|
||||||
|
* @param inOutInsets the insets to transform, is set to the transformed insets
|
||||||
|
* @param rotationDelta the delta between the new and old rotation.
|
||||||
|
* Must be one of Surface.ROTATION_0/90/180/270.
|
||||||
|
*/
|
||||||
|
public static void rotateInsets(Rect inOutInsets, int rotationDelta) {
|
||||||
|
final Rect r = inOutInsets;
|
||||||
|
switch (rotationDelta) {
|
||||||
|
case Surface.ROTATION_0:
|
||||||
|
return;
|
||||||
|
case Surface.ROTATION_90:
|
||||||
|
r.set(r.top, r.right, r.bottom, r.left);
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_180:
|
||||||
|
r.set(r.right, r.bottom, r.left, r.top);
|
||||||
|
break;
|
||||||
|
case Surface.ROTATION_270:
|
||||||
|
r.set(r.bottom, r.left, r.top, r.right);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unknown rotation: " + rotationDelta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds {@code insetsToAdd} to {@code inOutInsets}.
|
* Adds {@code insetsToAdd} to {@code inOutInsets}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,6 +16,11 @@
|
|||||||
|
|
||||||
package com.android.server.wm.utils;
|
package com.android.server.wm.utils;
|
||||||
|
|
||||||
|
import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
|
||||||
|
import static android.view.Surface.ROTATION_0;
|
||||||
|
import static android.view.Surface.ROTATION_180;
|
||||||
|
import static android.view.Surface.ROTATION_270;
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -39,5 +44,29 @@ public class InsetUtilsTest {
|
|||||||
InsetUtils.addInsets(rect1, rect2);
|
InsetUtils.addInsets(rect1, rect2);
|
||||||
assertEquals(new Rect(60, 80, 100, 120), rect1);
|
assertEquals(new Rect(60, 80, 100, 120), rect1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void rotate() {
|
||||||
|
final Rect original = new Rect(1, 2, 3, 4);
|
||||||
|
|
||||||
|
assertEquals("rot0", original, rotateCopy(original, ROTATION_0));
|
||||||
|
|
||||||
|
final Rect rot90 = rotateCopy(original, ROTATION_90);
|
||||||
|
assertEquals("rot90", new Rect(2, 3, 4, 1), rot90);
|
||||||
|
|
||||||
|
final Rect rot180 = rotateCopy(original, ROTATION_180);
|
||||||
|
assertEquals("rot180", new Rect(3, 4, 1, 2), rot180);
|
||||||
|
assertEquals("rot90(rot90)=rot180", rotateCopy(rot90, ROTATION_90), rot180);
|
||||||
|
|
||||||
|
final Rect rot270 = rotateCopy(original, ROTATION_270);
|
||||||
|
assertEquals("rot270", new Rect(4, 1, 2, 3), rot270);
|
||||||
|
assertEquals("rot90(rot180)=rot270", rotateCopy(rot180, ROTATION_90), rot270);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Rect rotateCopy(Rect insets, int rotationDelta) {
|
||||||
|
final Rect copy = new Rect(insets);
|
||||||
|
InsetUtils.rotateInsets(copy, rotationDelta);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user