diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2018-08-22 16:21:04 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-08-22 16:21:04 +0000 |
commit | 1d1b6dfb36800732cfefc8429ff621c0eef527e3 (patch) | |
tree | 7df2701f2384861e00e709b91db9e902c8263a50 | |
parent | 2dbd4e0e7a89d3db0d5fddf41946f91b824f63a1 (diff) | |
parent | dc30b7f2d34e4c22e6b29f40c8318c30e468079f (diff) | |
download | base-1d1b6dfb36800732cfefc8429ff621c0eef527e3.tar.gz |
Merge cherrypicks of [4844655, 4844656, 4844102, 4844103, 4844104, 4844105, 4844695, 4844696, 4844697, 4844698, 4844699, 4844700, 4844701, 4844715] into pi-dr1-release
Change-Id: I192b2a5c403401c352551636e51f922684a98d0a
21 files changed, 227 insertions, 35 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 9b6764d96fb2..14cae95508e7 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -413,4 +413,9 @@ public abstract class ActivityManagerInternal { * @return The intent used to launch the home activity. */ public abstract Intent getHomeIntent(); + + /** + * WindowManager notifies AM when display size of the default display changes. + */ + public abstract void notifyDefaultDisplaySizeChanged(); } diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java index 496bc9ff5383..5f80d31651a8 100644 --- a/core/java/android/view/DisplayCutout.java +++ b/core/java/android/view/DisplayCutout.java @@ -325,6 +325,7 @@ public final class DisplayCutout { * * @hide */ + @VisibleForTesting public static DisplayCutout fromBoundingRect(int left, int top, int right, int bottom) { Region r = Region.obtain(); r.set(left, top, right, bottom); @@ -422,8 +423,11 @@ public final class DisplayCutout { m.postTranslate(offsetX, 0); 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) { final Path bottomPath; try { @@ -436,10 +440,17 @@ public final class DisplayCutout { m.postTranslate(0, displayHeight); bottomPath.transform(m); 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) { sCachedSpec = spec; sCachedDisplayWidth = displayWidth; @@ -450,12 +461,11 @@ public final class DisplayCutout { 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 Rect rect = new Rect(); p.computeBounds(rectF, false /* unused */); - rectF.round(rect); - r.op(rect, Op.UNION); + rectF.round(inoutRect); + inoutRegion.op(inoutRect, Op.UNION); } private static Region boundingRectsToRegion(List<Rect> rects) { diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 8f56ef951d8f..cfee43626cdd 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2981,6 +2981,10 @@ --> <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 --> <!-- Whether the default microphone audio source supports near-ultrasound frequencies (range of 18 - 21 kHz). --> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 471170bbe93b..73cb59e84644 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -61,6 +61,15 @@ <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. --> <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. --> <dimen name="docked_stack_divider_thickness">48dp</dimen> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 00bd77d32935..9afeca6557bb 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3407,6 +3407,8 @@ <java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" /> <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_disableApkUnlessMatchedSku_skus_list" /> </resources> diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java index 6ee74cb9a742..fe45fe7d3aaf 100644 --- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java +++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java @@ -19,6 +19,7 @@ package android.view; import static android.view.DisplayCutout.NO_CUTOUT; import static android.view.DisplayCutout.fromSpec; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.sameInstance; import static org.junit.Assert.assertEquals; @@ -220,6 +221,19 @@ public class DisplayCutoutTest { } @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 public void parcel_unparcel_nocutout() { Parcel p = Parcel.obtain(); diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 3c84e5a91026..7d90e02d0f2f 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -939,9 +939,9 @@ <dimen name="bottom_padding">48dp</dimen> <dimen name="edge_margin">8dp</dimen> - <dimen name="rounded_corner_radius">0dp</dimen> - <dimen name="rounded_corner_radius_top">0dp</dimen> - <dimen name="rounded_corner_radius_bottom">0dp</dimen> + <dimen name="rounded_corner_radius">@*android:dimen/rounded_corner_radius</dimen> + <dimen name="rounded_corner_radius_top">@*android:dimen/rounded_corner_radius_top</dimen> + <dimen name="rounded_corner_radius_bottom">@*android:dimen/rounded_corner_radius_bottom</dimen> <dimen name="rounded_corner_content_padding">0dp</dimen> <dimen name="nav_content_padding">0dp</dimen> <dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 194679cc626e..e0f6806c4a27 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -82,9 +82,9 @@ public class ScreenDecorations extends SystemUI implements Tunable { private DisplayManager mDisplayManager; private DisplayManager.DisplayListener mDisplayListener; - private int mRoundedDefault; - private int mRoundedDefaultTop; - private int mRoundedDefaultBottom; + @VisibleForTesting protected int mRoundedDefault; + @VisibleForTesting protected int mRoundedDefaultTop; + @VisibleForTesting protected int mRoundedDefaultBottom; private View mOverlay; private View mBottomOverlay; private float mDensity; @@ -97,12 +97,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { @Override public void start() { mWindowManager = mContext.getSystemService(WindowManager.class); - mRoundedDefault = mContext.getResources().getDimensionPixelSize( - R.dimen.rounded_corner_radius); - mRoundedDefaultTop = mContext.getResources().getDimensionPixelSize( - R.dimen.rounded_corner_radius_top); - mRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize( - R.dimen.rounded_corner_radius_bottom); + updateRoundedCornerRadii(); if (hasRoundedCorners() || shouldDrawCutout()) { setupDecorations(); } @@ -221,6 +216,7 @@ public class ScreenDecorations extends SystemUI implements Tunable { protected void onConfigurationChanged(Configuration newConfig) { mPendingRotationChange = false; updateOrientation(); + updateRoundedCornerRadii(); if (shouldDrawCutout() && mOverlay == null) { setupDecorations(); } @@ -241,6 +237,26 @@ public class ScreenDecorations extends SystemUI implements Tunable { } } + private void updateRoundedCornerRadii() { + final int newRoundedDefault = mContext.getResources().getDimensionPixelSize( + R.dimen.rounded_corner_radius); + final int newRoundedDefaultTop = mContext.getResources().getDimensionPixelSize( + R.dimen.rounded_corner_radius_top); + final int newRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize( + R.dimen.rounded_corner_radius_bottom); + + final boolean roundedCornersChanged = mRoundedDefault != newRoundedDefault + || mRoundedDefaultBottom != newRoundedDefaultBottom + || mRoundedDefaultTop != newRoundedDefaultTop; + + if (roundedCornersChanged) { + mRoundedDefault = newRoundedDefault; + mRoundedDefaultTop = newRoundedDefaultTop; + mRoundedDefaultBottom = newRoundedDefaultBottom; + onTuningChanged(SIZE, null); + } + } + private void updateViews() { View topLeft = mOverlay.findViewById(R.id.left); View topRight = mOverlay.findViewById(R.id.right); diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index f1bf31d7a58a..642b97a2c91f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -21,6 +21,7 @@ import static com.android.systemui.tuner.TunablePadding.FLAG_START; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -195,4 +196,17 @@ public class ScreenDecorationsTest extends SysuiTestCase { verify(padding).destroy(); } + @Test + public void testUpdateRoundedCorners() { + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false); + mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20); + + mScreenDecorations.start(); + assertEquals(mScreenDecorations.mRoundedDefault, 20); + + mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 5); + mScreenDecorations.onConfigurationChanged(null); + assertEquals(mScreenDecorations.mRoundedDefault, 5); + } } diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml index 754ba722d081..b08924b8adb6 100644 --- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml @@ -16,7 +16,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Corner display cutout</string> + <string name="display_cutout_emulation_overlay">Corner cutout</string> </resources> diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml index 68c2dcbbe3f6..0a106fa0c08f 100644 --- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml @@ -16,7 +16,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Double display cutout</string> + <string name="display_cutout_emulation_overlay">Double cutout</string> </resources> diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml index 49896773ac55..0bf83306f875 100644 --- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml @@ -18,7 +18,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Narrow display cutout</string> + <string name="display_cutout_emulation_overlay">Narrow cutout</string> </resources> diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml index 6dcbbd923601..bcc7c9756a6e 100644 --- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml @@ -16,7 +16,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Tall display cutout</string> + <string name="display_cutout_emulation_overlay">Tall cutout</string> </resources> diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml index f4b9f7ea7c37..0fcbdebbd345 100644 --- a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml @@ -16,7 +16,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Wide display cutout</string> + <string name="display_cutout_emulation_overlay">Wide cutout</string> </resources> diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 189506cb0f40..3faa1deb5c40 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -26849,6 +26849,21 @@ public class ActivityManagerService extends IActivityManager.Stub return ActivityManagerService.this.getHomeIntent(); } } + + @Override + public void notifyDefaultDisplaySizeChanged() { + synchronized (this) { + if (mSystemServiceManager.isBootCompleted()) { + Slog.i(TAG, "Killing processes because of display size change"); + killAllBackgroundProcessesExcept(-1, ActivityManager.PROCESS_STATE_SERVICE); + + // TODO: Ugly hack to unblock the release + if (mHomeProcess != null) { + removeProcessLocked(mHomeProcess, false, true, "kill home screen size"); + } + } + } + } } /** diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index 349e1c8b713e..512e85192d36 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -104,6 +104,12 @@ final class DisplayDeviceInfo { 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. */ public static final int TOUCH_NONE = 0; @@ -453,6 +459,9 @@ final class DisplayDeviceInfo { if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD"); } + if ((flags & FLAG_MASK_DISPLAY_CUTOUT) != 0) { + msg.append(", FLAG_MASK_DISPLAY_CUTOUT"); + } return msg.toString(); } } diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 21ae048e1d75..16d82df4dd5b 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -402,6 +402,10 @@ final class LocalDisplayAdapter extends DisplayAdapter { && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) { mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND; } + if (res.getBoolean( + com.android.internal.R.bool.config_maskMainBuiltInDisplayCutout)) { + mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT; + } mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res, mInfo.width, mInfo.height); mInfo.type = Display.TYPE_BUILT_IN; diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 23ee56b24b19..373de63c0ec9 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -23,6 +23,8 @@ import android.view.DisplayInfo; import android.view.Surface; import android.view.SurfaceControl; +import com.android.server.wm.utils.InsetUtils; + import java.io.PrintWriter; import java.util.Arrays; import java.util.List; @@ -251,14 +253,18 @@ final class LogicalDisplay { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { 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.address = deviceInfo.address; mBaseDisplayInfo.name = deviceInfo.name; mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId; - mBaseDisplayInfo.appWidth = deviceInfo.width; - mBaseDisplayInfo.appHeight = deviceInfo.height; - mBaseDisplayInfo.logicalWidth = deviceInfo.width; - mBaseDisplayInfo.logicalHeight = deviceInfo.height; + mBaseDisplayInfo.appWidth = maskedWidth; + mBaseDisplayInfo.appHeight = maskedHeight; + mBaseDisplayInfo.logicalWidth = maskedWidth; + mBaseDisplayInfo.logicalHeight = maskedHeight; mBaseDisplayInfo.rotation = Surface.ROTATION_0; mBaseDisplayInfo.modeId = deviceInfo.modeId; mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId; @@ -275,13 +281,15 @@ final class LogicalDisplay { mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos; mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos; mBaseDisplayInfo.state = deviceInfo.state; - mBaseDisplayInfo.smallestNominalAppWidth = deviceInfo.width; - mBaseDisplayInfo.smallestNominalAppHeight = deviceInfo.height; - mBaseDisplayInfo.largestNominalAppWidth = deviceInfo.width; - mBaseDisplayInfo.largestNominalAppHeight = deviceInfo.height; + mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth; + mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight; + mBaseDisplayInfo.largestNominalAppWidth = maskedWidth; + mBaseDisplayInfo.largestNominalAppHeight = maskedHeight; mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid; 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; mInfo = null; @@ -289,6 +297,18 @@ final class LogicalDisplay { } /** + * 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 * 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 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. // physWidth / displayInfo.logicalWidth => letter box // or physHeight / displayInfo.logicalHeight => pillar box @@ -375,6 +401,9 @@ final class LogicalDisplay { mTempDisplayRect.set(displayRectLeft, displayRectTop, displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight); + // Now add back the offset for the masked area. + mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top); + mTempDisplayRect.left += mDisplayOffsetX; mTempDisplayRect.right += mDisplayOffsetX; mTempDisplayRect.top += mDisplayOffsetY; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 2887e5ef9061..2941e93d12dc 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1775,8 +1775,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final int newDensity = mDisplayInfo.logicalDensityDpi; final DisplayCutout newCutout = mDisplayInfo.displayCutout; - final boolean displayMetricsChanged = mInitialDisplayWidth != newWidth - || mInitialDisplayHeight != newHeight + final boolean sizeChanged = mInitialDisplayWidth != newWidth + || mInitialDisplayHeight != newHeight; + final boolean displayMetricsChanged = sizeChanged || mInitialDisplayDensity != mDisplayInfo.logicalDensityDpi || !Objects.equals(mInitialDisplayCutout, newCutout); @@ -1798,6 +1799,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mInitialDisplayCutout = newCutout; mService.reconfigureDisplayLocked(this); } + + if (isDefaultDisplay && sizeChanged) { + mService.mH.post(mService.mAmInternal::notifyDefaultDisplaySizeChanged); + } } /** Sets the maximum width the screen resolution can be */ diff --git a/services/core/java/com/android/server/wm/utils/InsetUtils.java b/services/core/java/com/android/server/wm/utils/InsetUtils.java index b4a998add374..c8600dd151d2 100644 --- a/services/core/java/com/android/server/wm/utils/InsetUtils.java +++ b/services/core/java/com/android/server/wm/utils/InsetUtils.java @@ -17,6 +17,7 @@ package com.android.server.wm.utils; import android.graphics.Rect; +import android.view.Surface; /** * Utility methods to handle insets represented as rects. @@ -27,6 +28,32 @@ public class 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}. */ public static void addInsets(Rect inOutInsets, Rect insetsToAdd) { diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java index d0f0fe315bcf..08bcc3d751f2 100644 --- a/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java @@ -16,6 +16,11 @@ 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 android.graphics.Rect; @@ -39,5 +44,29 @@ public class InsetUtilsTest { InsetUtils.addInsets(rect1, rect2); 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; + } } |