Merge "DisplayCutout: device-independent emulation overlay"

This commit is contained in:
TreeHugger Robot
2018-01-19 14:42:13 +00:00
committed by Android (Google) Code Review
4 changed files with 79 additions and 22 deletions

View File

@@ -23,6 +23,8 @@ import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
@@ -30,8 +32,12 @@ import android.graphics.RectF;
import android.graphics.Region;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.util.PathParser;
import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import java.util.List;
@@ -43,6 +49,9 @@ import java.util.List;
*/
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 Region EMPTY_REGION = new Region();
@@ -311,6 +320,40 @@ public final class DisplayCutout {
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.
*

View File

@@ -2780,8 +2780,22 @@
<!-- 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
{@link android.util.PathParser}.
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>
<!-- Whether the display cutout region of the main built-in display should be forced to

View File

@@ -18,17 +18,26 @@
<!-- 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
{@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">
M 687.0,0
l -66,50
l 0,50
l 66,50
l 66,0
l 66,-50
l 0,-50
l -66,-50
z
M 0,0
L -24, 0
L -21.9940446283, 20.0595537175
C -21.1582133885, 28.4178661152 -17.2, 32.0 -8.8, 32.0
L 8.8, 32.0
C 17.2, 32.0 21.1582133885, 28.4178661152 21.9940446283, 20.0595537175
L 24, 0
Z
@dp
</string>
<!-- Whether the display cutout region of the main built-in display should be forced to
@@ -37,7 +46,7 @@
<bool name="config_fillMainBuiltInDisplayCutout">true</bool>
<!-- Height of the status bar -->
<dimen name="status_bar_height">150px</dimen>
<dimen name="status_bar_height">48dp</dimen>
</resources>

View File

@@ -404,7 +404,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
&& SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
}
mInfo.displayCutout = parseDefaultDisplayCutout(res);
mInfo.displayCutout = DisplayCutout.fromResources(res, mInfo.width);
mInfo.type = Display.TYPE_BUILT_IN;
mInfo.densityDpi = (int)(phys.density * 160 + 0.5f);
mInfo.xDpi = phys.xDpi;
@@ -440,15 +440,6 @@ final class LocalDisplayAdapter extends DisplayAdapter {
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
public Runnable requestDisplayStateLocked(final int state, final int brightness) {
// Assume that the brightness is off if the display is being turned off.