Loading core/java/android/view/DisplayCutout.java +43 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,8 @@ import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static android.view.Surface.ROTATION_90; import android.content.res.Resources; import android.graphics.Matrix; import android.graphics.Path; import android.graphics.Path; import android.graphics.Point; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; Loading @@ -30,8 +32,12 @@ import android.graphics.RectF; import android.graphics.Region; import android.graphics.Region; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import android.util.PathParser; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import java.util.List; import java.util.List; Loading @@ -43,6 +49,9 @@ import java.util.List; */ */ public final class DisplayCutout { public final class DisplayCutout { private static final String TAG = "DisplayCutout"; private static final String DP_MARKER = "@dp"; private static final Rect ZERO_RECT = new Rect(); private static final Rect ZERO_RECT = new Rect(); private static final Region EMPTY_REGION = new Region(); private static final Region EMPTY_REGION = new Region(); Loading Loading @@ -311,6 +320,40 @@ public final class DisplayCutout { return new DisplayCutout(ZERO_RECT, bounds); return new DisplayCutout(ZERO_RECT, bounds); } } /** * Creates an instance according to @android:string/config_mainBuiltInDisplayCutout. * * @hide */ public static DisplayCutout fromResources(Resources res, int displayWidth) { String spec = res.getString(R.string.config_mainBuiltInDisplayCutout); if (TextUtils.isEmpty(spec)) { return null; } spec = spec.trim(); final boolean inDp = spec.endsWith(DP_MARKER); if (inDp) { spec = spec.substring(0, spec.length() - DP_MARKER.length()); } Path p; try { p = PathParser.createPathFromPathData(spec); } catch (Throwable e) { Log.wtf(TAG, "Could not inflate cutout: ", e); return null; } final Matrix m = new Matrix(); if (inDp) { final float dpToPx = res.getDisplayMetrics().density; m.postScale(dpToPx, dpToPx); } m.postTranslate(displayWidth / 2f, 0); p.transform(m); return fromBounds(p); } /** /** * Helper class for passing {@link DisplayCutout} through binder. * Helper class for passing {@link DisplayCutout} through binder. * * Loading core/res/res/values/config.xml +15 −1 Original line number Original line Diff line number Diff line Loading @@ -2780,8 +2780,22 @@ <!-- The bounding path of the cutout region of the main built-in display. <!-- The bounding path of the cutout region of the main built-in display. Must either be empty if there is no cutout region, or a string that is parsable by Must either be empty if there is no cutout region, or a string that is parsable by {@link android.util.PathParser}. {@link android.util.PathParser}. The path is assumed to be specified in display coordinates with pixel units and in The path is assumed to be specified in display coordinates with pixel units and in the display's native orientation. --> the display's native orientation, with the origin of the coordinate system at the center top of the display. To facilitate writing device-independent emulation overlays, the marker `@dp` can be appended after the path string to interpret coordinates in dp instead of px units. Note that a physical cutout should be configured in pixels for the best results. Example for a 10px x 10px square top-center cutout: <string ...>M -5,0 L -5,10 L 5,10 L 5,0 Z</string> Example for a 10dp x 10dp square top-center cutout: <string ...>M -5,0 L -5,10 L 5,10 L 5,0 Z @dp</string> @see https://www.w3.org/TR/SVG/paths.html#PathData --> <string translatable="false" name="config_mainBuiltInDisplayCutout"></string> <string translatable="false" name="config_mainBuiltInDisplayCutout"></string> <!-- Whether the display cutout region of the main built-in display should be forced to <!-- Whether the display cutout region of the main built-in display should be forced to Loading packages/overlays/DisplayCutoutEmulationOverlay/res/values/config.xml +20 −11 Original line number Original line Diff line number Diff line Loading @@ -18,17 +18,26 @@ <!-- The bounding path of the cutout region of the main built-in display. <!-- The bounding path of the cutout region of the main built-in display. Must either be empty if there is no cutout region, or a string that is parsable by Must either be empty if there is no cutout region, or a string that is parsable by {@link android.util.PathParser}. --> {@link android.util.PathParser}. The path is assumed to be specified in display coordinates with pixel units and in the display's native orientation, with the origin of the coordinate system at the center top of the display. To facilitate writing device-independent emulation overlays, the marker `@dp` can be appended after the path string to interpret coordinates in dp instead of px units. Note that a physical cutout should be configured in pixels for the best results. --> <string translatable="false" name="config_mainBuiltInDisplayCutout"> <string translatable="false" name="config_mainBuiltInDisplayCutout"> M 687.0,0 M 0,0 l -66,50 L -24, 0 l 0,50 L -21.9940446283, 20.0595537175 l 66,50 C -21.1582133885, 28.4178661152 -17.2, 32.0 -8.8, 32.0 l 66,0 L 8.8, 32.0 l 66,-50 C 17.2, 32.0 21.1582133885, 28.4178661152 21.9940446283, 20.0595537175 l 0,-50 L 24, 0 l -66,-50 Z z @dp </string> </string> <!-- Whether the display cutout region of the main built-in display should be forced to <!-- Whether the display cutout region of the main built-in display should be forced to Loading @@ -37,7 +46,7 @@ <bool name="config_fillMainBuiltInDisplayCutout">true</bool> <bool name="config_fillMainBuiltInDisplayCutout">true</bool> <!-- Height of the status bar --> <!-- Height of the status bar --> <dimen name="status_bar_height">150px</dimen> <dimen name="status_bar_height">48dp</dimen> </resources> </resources> Loading services/core/java/com/android/server/display/LocalDisplayAdapter.java +1 −10 Original line number Original line Diff line number Diff line Loading @@ -404,7 +404,7 @@ 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; } } mInfo.displayCutout = parseDefaultDisplayCutout(res); mInfo.displayCutout = DisplayCutout.fromResources(res, mInfo.width); mInfo.type = Display.TYPE_BUILT_IN; mInfo.type = Display.TYPE_BUILT_IN; mInfo.densityDpi = (int)(phys.density * 160 + 0.5f); mInfo.densityDpi = (int)(phys.density * 160 + 0.5f); mInfo.xDpi = phys.xDpi; mInfo.xDpi = phys.xDpi; Loading Loading @@ -440,15 +440,6 @@ final class LocalDisplayAdapter extends DisplayAdapter { return mInfo; return mInfo; } } private DisplayCutout parseDefaultDisplayCutout(Resources res) { String cutoutString = res.getString( com.android.internal.R.string.config_mainBuiltInDisplayCutout); if (TextUtils.isEmpty(cutoutString)) { return null; } return DisplayCutout.fromBounds(PathParser.createPathFromPathData(cutoutString)); } @Override @Override public Runnable requestDisplayStateLocked(final int state, final int brightness) { public Runnable requestDisplayStateLocked(final int state, final int brightness) { // Assume that the brightness is off if the display is being turned off. // Assume that the brightness is off if the display is being turned off. Loading Loading
core/java/android/view/DisplayCutout.java +43 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,8 @@ import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static android.view.Surface.ROTATION_90; import android.content.res.Resources; import android.graphics.Matrix; import android.graphics.Path; import android.graphics.Path; import android.graphics.Point; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Rect; Loading @@ -30,8 +32,12 @@ import android.graphics.RectF; import android.graphics.Region; import android.graphics.Region; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; import android.util.PathParser; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoOutputStream; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import java.util.List; import java.util.List; Loading @@ -43,6 +49,9 @@ import java.util.List; */ */ public final class DisplayCutout { public final class DisplayCutout { private static final String TAG = "DisplayCutout"; private static final String DP_MARKER = "@dp"; private static final Rect ZERO_RECT = new Rect(); private static final Rect ZERO_RECT = new Rect(); private static final Region EMPTY_REGION = new Region(); private static final Region EMPTY_REGION = new Region(); Loading Loading @@ -311,6 +320,40 @@ public final class DisplayCutout { return new DisplayCutout(ZERO_RECT, bounds); return new DisplayCutout(ZERO_RECT, bounds); } } /** * Creates an instance according to @android:string/config_mainBuiltInDisplayCutout. * * @hide */ public static DisplayCutout fromResources(Resources res, int displayWidth) { String spec = res.getString(R.string.config_mainBuiltInDisplayCutout); if (TextUtils.isEmpty(spec)) { return null; } spec = spec.trim(); final boolean inDp = spec.endsWith(DP_MARKER); if (inDp) { spec = spec.substring(0, spec.length() - DP_MARKER.length()); } Path p; try { p = PathParser.createPathFromPathData(spec); } catch (Throwable e) { Log.wtf(TAG, "Could not inflate cutout: ", e); return null; } final Matrix m = new Matrix(); if (inDp) { final float dpToPx = res.getDisplayMetrics().density; m.postScale(dpToPx, dpToPx); } m.postTranslate(displayWidth / 2f, 0); p.transform(m); return fromBounds(p); } /** /** * Helper class for passing {@link DisplayCutout} through binder. * Helper class for passing {@link DisplayCutout} through binder. * * Loading
core/res/res/values/config.xml +15 −1 Original line number Original line Diff line number Diff line Loading @@ -2780,8 +2780,22 @@ <!-- The bounding path of the cutout region of the main built-in display. <!-- The bounding path of the cutout region of the main built-in display. Must either be empty if there is no cutout region, or a string that is parsable by Must either be empty if there is no cutout region, or a string that is parsable by {@link android.util.PathParser}. {@link android.util.PathParser}. The path is assumed to be specified in display coordinates with pixel units and in The path is assumed to be specified in display coordinates with pixel units and in the display's native orientation. --> the display's native orientation, with the origin of the coordinate system at the center top of the display. To facilitate writing device-independent emulation overlays, the marker `@dp` can be appended after the path string to interpret coordinates in dp instead of px units. Note that a physical cutout should be configured in pixels for the best results. Example for a 10px x 10px square top-center cutout: <string ...>M -5,0 L -5,10 L 5,10 L 5,0 Z</string> Example for a 10dp x 10dp square top-center cutout: <string ...>M -5,0 L -5,10 L 5,10 L 5,0 Z @dp</string> @see https://www.w3.org/TR/SVG/paths.html#PathData --> <string translatable="false" name="config_mainBuiltInDisplayCutout"></string> <string translatable="false" name="config_mainBuiltInDisplayCutout"></string> <!-- Whether the display cutout region of the main built-in display should be forced to <!-- Whether the display cutout region of the main built-in display should be forced to Loading
packages/overlays/DisplayCutoutEmulationOverlay/res/values/config.xml +20 −11 Original line number Original line Diff line number Diff line Loading @@ -18,17 +18,26 @@ <!-- The bounding path of the cutout region of the main built-in display. <!-- The bounding path of the cutout region of the main built-in display. Must either be empty if there is no cutout region, or a string that is parsable by Must either be empty if there is no cutout region, or a string that is parsable by {@link android.util.PathParser}. --> {@link android.util.PathParser}. The path is assumed to be specified in display coordinates with pixel units and in the display's native orientation, with the origin of the coordinate system at the center top of the display. To facilitate writing device-independent emulation overlays, the marker `@dp` can be appended after the path string to interpret coordinates in dp instead of px units. Note that a physical cutout should be configured in pixels for the best results. --> <string translatable="false" name="config_mainBuiltInDisplayCutout"> <string translatable="false" name="config_mainBuiltInDisplayCutout"> M 687.0,0 M 0,0 l -66,50 L -24, 0 l 0,50 L -21.9940446283, 20.0595537175 l 66,50 C -21.1582133885, 28.4178661152 -17.2, 32.0 -8.8, 32.0 l 66,0 L 8.8, 32.0 l 66,-50 C 17.2, 32.0 21.1582133885, 28.4178661152 21.9940446283, 20.0595537175 l 0,-50 L 24, 0 l -66,-50 Z z @dp </string> </string> <!-- Whether the display cutout region of the main built-in display should be forced to <!-- Whether the display cutout region of the main built-in display should be forced to Loading @@ -37,7 +46,7 @@ <bool name="config_fillMainBuiltInDisplayCutout">true</bool> <bool name="config_fillMainBuiltInDisplayCutout">true</bool> <!-- Height of the status bar --> <!-- Height of the status bar --> <dimen name="status_bar_height">150px</dimen> <dimen name="status_bar_height">48dp</dimen> </resources> </resources> Loading
services/core/java/com/android/server/display/LocalDisplayAdapter.java +1 −10 Original line number Original line Diff line number Diff line Loading @@ -404,7 +404,7 @@ 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; } } mInfo.displayCutout = parseDefaultDisplayCutout(res); mInfo.displayCutout = DisplayCutout.fromResources(res, mInfo.width); mInfo.type = Display.TYPE_BUILT_IN; mInfo.type = Display.TYPE_BUILT_IN; mInfo.densityDpi = (int)(phys.density * 160 + 0.5f); mInfo.densityDpi = (int)(phys.density * 160 + 0.5f); mInfo.xDpi = phys.xDpi; mInfo.xDpi = phys.xDpi; Loading Loading @@ -440,15 +440,6 @@ final class LocalDisplayAdapter extends DisplayAdapter { return mInfo; return mInfo; } } private DisplayCutout parseDefaultDisplayCutout(Resources res) { String cutoutString = res.getString( com.android.internal.R.string.config_mainBuiltInDisplayCutout); if (TextUtils.isEmpty(cutoutString)) { return null; } return DisplayCutout.fromBounds(PathParser.createPathFromPathData(cutoutString)); } @Override @Override public Runnable requestDisplayStateLocked(final int state, final int brightness) { public Runnable requestDisplayStateLocked(final int state, final int brightness) { // Assume that the brightness is off if the display is being turned off. // Assume that the brightness is off if the display is being turned off. Loading