diff options
12 files changed, 70 insertions, 36 deletions
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java index 47bda538ae52..496bc9ff5383 100644 --- a/core/java/android/view/DisplayCutout.java +++ b/core/java/android/view/DisplayCutout.java @@ -29,6 +29,7 @@ import android.graphics.Path; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; +import android.graphics.Region.Op; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -325,14 +326,9 @@ public final class DisplayCutout { * @hide */ public static DisplayCutout fromBoundingRect(int left, int top, int right, int bottom) { - Path path = new Path(); - path.reset(); - path.moveTo(left, top); - path.lineTo(left, bottom); - path.lineTo(right, bottom); - path.lineTo(right, top); - path.close(); - return fromBounds(path); + Region r = Region.obtain(); + r.set(left, top, right, bottom); + return fromBounds(r); } /** @@ -340,26 +336,19 @@ public final class DisplayCutout { * * @hide */ - public static DisplayCutout fromBounds(Path path) { - RectF clipRect = new RectF(); - path.computeBounds(clipRect, false /* unused */); - Region clipRegion = Region.obtain(); - clipRegion.set((int) clipRect.left, (int) clipRect.top, - (int) clipRect.right, (int) clipRect.bottom); - - Region bounds = new Region(); - bounds.setPath(path, clipRegion); - clipRegion.recycle(); - return new DisplayCutout(ZERO_RECT, bounds, false /* copyArguments */); + public static DisplayCutout fromBounds(Region region) { + return new DisplayCutout(ZERO_RECT, region, false /* copyArguments */); } /** - * Creates the bounding path according to @android:string/config_mainBuiltInDisplayCutout. + * Creates the display cutout according to + * @android:string/config_mainBuiltInDisplayCutoutRectApproximation, which is the closest + * rectangle-base approximation of the cutout. * * @hide */ - public static DisplayCutout fromResources(Resources res, int displayWidth, int displayHeight) { - return fromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout), + public static DisplayCutout fromResourcesRectApproximation(Resources res, int displayWidth, int displayHeight) { + return fromSpec(res.getString(R.string.config_mainBuiltInDisplayCutoutRectApproximation), displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT); } @@ -369,7 +358,8 @@ public final class DisplayCutout { * @hide */ public static Path pathFromResources(Resources res, int displayWidth, int displayHeight) { - return pathAndDisplayCutoutFromSpec(res.getString(R.string.config_mainBuiltInDisplayCutout), + return pathAndDisplayCutoutFromSpec( + res.getString(R.string.config_mainBuiltInDisplayCutout), displayWidth, displayHeight, DENSITY_DEVICE_STABLE / (float) DENSITY_DEFAULT).first; } @@ -417,6 +407,7 @@ public final class DisplayCutout { } final Path p; + final Region r = Region.obtain(); try { p = PathParser.createPathFromPathData(spec); } catch (Throwable e) { @@ -431,6 +422,8 @@ public final class DisplayCutout { m.postTranslate(offsetX, 0); p.transform(m); + addToRegion(p, r); + if (bottomSpec != null) { final Path bottomPath; try { @@ -443,9 +436,10 @@ public final class DisplayCutout { m.postTranslate(0, displayHeight); bottomPath.transform(m); p.addPath(bottomPath); + addToRegion(bottomPath, r); } - final Pair<Path, DisplayCutout> result = new Pair<>(p, fromBounds(p)); + final Pair<Path, DisplayCutout> result = new Pair<>(p, fromBounds(r)); synchronized (CACHE_LOCK) { sCachedSpec = spec; sCachedDisplayWidth = displayWidth; @@ -456,6 +450,14 @@ public final class DisplayCutout { return result; } + private static void addToRegion(Path p, Region r) { + final RectF rectF = new RectF(); + final Rect rect = new Rect(); + p.computeBounds(rectF, false /* unused */); + rectF.round(rect); + r.op(rect, Op.UNION); + } + private static Region boundingRectsToRegion(List<Rect> rects) { Region result = Region.obtain(); if (rects != null) { diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 18430a763ad5..5bd3ae50bcfb 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2961,6 +2961,14 @@ --> <string translatable="false" name="config_mainBuiltInDisplayCutout"></string> + <!-- Like config_mainBuiltInDisplayCutout, but this path is used to report the + one single bounding rect per device edge to the app via + {@link DisplayCutout#getBoundingRect}. Note that this path should try to match the visual + appearance of the cutout as much as possible, and may be smaller than + config_mainBuiltInDisplayCutout + --> + <string translatable="false" name="config_mainBuiltInDisplayCutoutRectApproximation">@string/config_mainBuiltInDisplayCutout</string> + <!-- Whether the display cutout region of the main built-in display should be forced to black in software (to avoid aliasing or emulate a cutout that is not physically existent). --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 9a4f42704a35..f3d443106d4f 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3338,6 +3338,7 @@ <java-symbol type="string" name="global_action_logout" /> <java-symbol type="string" name="config_mainBuiltInDisplayCutout" /> + <java-symbol type="string" name="config_mainBuiltInDisplayCutoutRectApproximation" /> <java-symbol type="drawable" name="messaging_user" /> <java-symbol type="bool" name="config_fillMainBuiltInDisplayCutout" /> <java-symbol type="drawable" name="ic_logout" /> diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/config.xml index 80d8066959af..9254b4d65b50 100644 --- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/config.xml +++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/config.xml @@ -37,6 +37,8 @@ @right </string> + <string translatable="false" name="config_mainBuiltInDisplayCutoutRectApproximation">@*android:string/config_mainBuiltInDisplayCutout</string> + <!-- Whether the display cutout region of the main built-in display should be forced to black in software (to avoid aliasing or emulate a cutout that is not physically existent). --> diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/config.xml index ca261f98cfae..80c997a46264 100644 --- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/config.xml +++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/config.xml @@ -49,6 +49,8 @@ @dp </string> + <string translatable="false" name="config_mainBuiltInDisplayCutoutRectApproximation">@*android:string/config_mainBuiltInDisplayCutout</string> + <!-- Whether the display cutout region of the main built-in display should be forced to black in software (to avoid aliasing or emulate a cutout that is not physically existent). --> diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml index c22b2e778ff1..6fb3c7f51e26 100644 --- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml +++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/config.xml @@ -40,6 +40,8 @@ @dp </string> + <string translatable="false" name="config_mainBuiltInDisplayCutoutRectApproximation">@*android:string/config_mainBuiltInDisplayCutout</string> + <!-- Whether the display cutout region of the main built-in display should be forced to black in software (to avoid aliasing or emulate a cutout that is not physically existent). --> diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml index 401e09211ae7..7c29ffb92f4e 100644 --- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml +++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/config.xml @@ -40,6 +40,8 @@ @dp </string> + <string translatable="false" name="config_mainBuiltInDisplayCutoutRectApproximation">@*android:string/config_mainBuiltInDisplayCutout</string> + <!-- Whether the display cutout region of the main built-in display should be forced to black in software (to avoid aliasing or emulate a cutout that is not physically existent). --> diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml index f328b83c1cbf..5fb8b9e241b8 100644 --- a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml +++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/config.xml @@ -40,6 +40,8 @@ @dp </string> + <string translatable="false" name="config_mainBuiltInDisplayCutoutRectApproximation">@*android:string/config_mainBuiltInDisplayCutout</string> + <!-- Whether the display cutout region of the main built-in display should be forced to black in software (to avoid aliasing or emulate a cutout that is not physically existent). --> diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index b9a279ad13ea..21ae048e1d75 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -31,8 +31,6 @@ import android.os.Looper; import android.os.PowerManager; import android.os.SystemProperties; import android.os.Trace; -import android.text.TextUtils; -import android.util.PathParser; import android.util.Slog; import android.util.SparseArray; import android.view.Display; @@ -404,8 +402,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) { mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND; } - mInfo.displayCutout = DisplayCutout.fromResources(res, mInfo.width, - mInfo.height); + mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res, + mInfo.width, mInfo.height); mInfo.type = Display.TYPE_BUILT_IN; mInfo.densityDpi = (int)(phys.density * 160 + 0.5f); mInfo.xDpi = phys.xDpi; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 47dbccb9a202..2887e5ef9061 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1253,11 +1253,21 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo cutout, mInitialDisplayWidth, mInitialDisplayHeight); } final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270); - final Path bounds = cutout.getBounds().getBoundaryPath(); + final List<Rect> bounds = WmDisplayCutout.computeSafeInsets( + cutout, mInitialDisplayWidth, mInitialDisplayHeight) + .getDisplayCutout().getBoundingRects(); transformPhysicalToLogicalCoordinates(rotation, mInitialDisplayWidth, mInitialDisplayHeight, mTmpMatrix); - bounds.transform(mTmpMatrix); - return WmDisplayCutout.computeSafeInsets(DisplayCutout.fromBounds(bounds), + final Region region = Region.obtain(); + for (int i = 0; i < bounds.size(); i++) { + final Rect rect = bounds.get(i); + final RectF rectF = new RectF(bounds.get(i)); + mTmpMatrix.mapRect(rectF); + rectF.round(rect); + region.op(rect, Op.UNION); + } + + return WmDisplayCutout.computeSafeInsets(DisplayCutout.fromBounds(region), rotated ? mInitialDisplayHeight : mInitialDisplayWidth, rotated ? mInitialDisplayWidth : mInitialDisplayHeight); } diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 281e0a8441e2..a626663c2e67 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -40,6 +40,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Process; import android.os.RemoteException; +import android.os.Trace; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -620,6 +621,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { private void updateInputWindows(boolean inDrag) { + Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "updateInputWindows"); + // TODO: multi-display navInputConsumer = getInputConsumer(INPUT_CONSUMER_NAVIGATION, DEFAULT_DISPLAY); pipInputConsumer = getInputConsumer(INPUT_CONSUMER_PIP, DEFAULT_DISPLAY); @@ -645,6 +648,8 @@ final class InputMonitor implements InputManagerService.WindowManagerCallbacks { mService.mInputManager.setInputWindows(mInputWindowHandles, mFocusedInputWindowHandle); clearInputWindowHandlesLw(); + + Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER); } @Override diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java index 2c47a9432eff..1d378020fa4f 100644 --- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java +++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java @@ -37,6 +37,7 @@ import android.graphics.Matrix; import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Rect; +import android.graphics.RectF; import android.os.IBinder; import android.os.UserHandle; import android.support.test.InstrumentationRegistry; @@ -172,15 +173,14 @@ public class PhoneWindowManagerTestBase { } private static DisplayCutout displayCutoutForRotation(int rotation) { - Path p = new Path(); - p.addRect(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT, - Path.Direction.CCW); + RectF rectF = new RectF(DISPLAY_WIDTH / 4, 0, DISPLAY_WIDTH * 3 / 4, DISPLAY_CUTOUT_HEIGHT); Matrix m = new Matrix(); transformPhysicalToLogicalCoordinates(rotation, DISPLAY_WIDTH, DISPLAY_HEIGHT, m); - p.transform(m); + m.mapRect(rectF); - return DisplayCutout.fromBounds(p); + return DisplayCutout.fromBoundingRect((int) rectF.left, (int) rectF.top, + (int) rectF.right, (int) rectF.bottom); } static class TestContextWrapper extends ContextWrapper { |