Merge "Allow Overlay Display to take display flags" into rvc-dev
This commit is contained in:
@@ -10737,13 +10737,33 @@ public final class Settings {
|
|||||||
* The associated value is a specially formatted string that describes the
|
* The associated value is a specially formatted string that describes the
|
||||||
* size and density of simulated secondary display devices.
|
* size and density of simulated secondary display devices.
|
||||||
* <p>
|
* <p>
|
||||||
* Format: {width}x{height}/{dpi};...
|
* Format:
|
||||||
|
* <pre>
|
||||||
|
* [display1];[display2];...
|
||||||
|
* </pre>
|
||||||
|
* with each display specified as:
|
||||||
|
* <pre>
|
||||||
|
* [mode1]|[mode2]|...,[flag1],[flag2],...
|
||||||
|
* </pre>
|
||||||
|
* with each mode specified as:
|
||||||
|
* <pre>
|
||||||
|
* [width]x[height]/[densityDpi]
|
||||||
|
* </pre>
|
||||||
|
* Supported flags:
|
||||||
|
* <ul>
|
||||||
|
* <li><pre>secure</pre>: creates a secure display</li>
|
||||||
|
* <li><pre>own_content_only</pre>: only shows this display's own content</li>
|
||||||
|
* <li><pre>should_show_system_decorations</pre>: supports system decorations</li>
|
||||||
|
* </ul>
|
||||||
* </p><p>
|
* </p><p>
|
||||||
* Example:
|
* Example:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><code>1280x720/213</code>: make one overlay that is 1280x720 at 213dpi.</li>
|
* <li><code>1280x720/213</code>: make one overlay that is 1280x720 at 213dpi.</li>
|
||||||
* <li><code>1920x1080/320;1280x720/213</code>: make two overlays, the first
|
* <li><code>1920x1080/320,secure;1280x720/213</code>: make two overlays, the first at
|
||||||
* at 1080p and the second at 720p.</li>
|
* 1080p and secure; the second at 720p.</li>
|
||||||
|
* <li><code>1920x1080/320|3840x2160/640</code>: make one overlay that is 1920x1080 at
|
||||||
|
* 213dpi by default, but can also be upscaled to 3840x2160 at 640dpi by the system if the
|
||||||
|
* display device allows.</li>
|
||||||
* <li>If the value is empty, then no overlay display devices are created.</li>
|
* <li>If the value is empty, then no overlay display devices are created.</li>
|
||||||
* </ul></p>
|
* </ul></p>
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -16,12 +16,14 @@
|
|||||||
|
|
||||||
package com.android.server.display;
|
package com.android.server.display;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
@@ -54,6 +56,10 @@ import java.util.regex.Pattern;
|
|||||||
* {@link android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES} setting. This setting should be
|
* {@link android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES} setting. This setting should be
|
||||||
* formatted as follows:
|
* formatted as follows:
|
||||||
* <pre>
|
* <pre>
|
||||||
|
* [display1];[display2];...
|
||||||
|
* </pre>
|
||||||
|
* with each display specified as:
|
||||||
|
* <pre>
|
||||||
* [mode1]|[mode2]|...,[flag1],[flag2],...
|
* [mode1]|[mode2]|...,[flag1],[flag2],...
|
||||||
* </pre>
|
* </pre>
|
||||||
* with each mode specified as:
|
* with each mode specified as:
|
||||||
@@ -63,22 +69,56 @@ import java.util.regex.Pattern;
|
|||||||
* Supported flags:
|
* Supported flags:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><pre>secure</pre>: creates a secure display</li>
|
* <li><pre>secure</pre>: creates a secure display</li>
|
||||||
|
* <li><pre>own_content_only</pre>: only shows this display's own content</li>
|
||||||
|
* <li><pre>should_show_system_decorations</pre>: supports system decorations</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </p>
|
* </p><p>
|
||||||
|
* Example:
|
||||||
|
* <ul>
|
||||||
|
* <li><code>1280x720/213</code>: make one overlay that is 1280x720 at 213dpi.</li>
|
||||||
|
* <li><code>1920x1080/320,secure;1280x720/213</code>: make two overlays, the first at 1080p and
|
||||||
|
* secure; the second at 720p.</li>
|
||||||
|
* <li><code>1920x1080/320|3840x2160/640</code>: make one overlay that is 1920x1080 at
|
||||||
|
* 213dpi by default, but can also be upscaled to 3840x2160 at 640dpi by the system if the
|
||||||
|
* display device allows.</li>
|
||||||
|
* <li>If the value is empty, then no overlay display devices are created.</li>
|
||||||
|
* </ul></p>
|
||||||
*/
|
*/
|
||||||
final class OverlayDisplayAdapter extends DisplayAdapter {
|
final class OverlayDisplayAdapter extends DisplayAdapter {
|
||||||
static final String TAG = "OverlayDisplayAdapter";
|
static final String TAG = "OverlayDisplayAdapter";
|
||||||
static final boolean DEBUG = false;
|
static final boolean DEBUG = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When this flag is set, the overlay display is considered secure.
|
||||||
|
* @see DisplayDeviceInfo#FLAG_SECURE
|
||||||
|
*/
|
||||||
|
private static final String OVERLAY_DISPLAY_FLAG_SECURE = "secure";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When this flag is set, only show this display's own content; do not mirror the content of
|
||||||
|
* another display.
|
||||||
|
* @see DisplayDeviceInfo#FLAG_OWN_CONTENT_ONLY
|
||||||
|
*/
|
||||||
|
private static final String OVERLAY_DISPLAY_FLAG_OWN_CONTENT_ONLY = "own_content_only";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When this flag is set, the overlay display should support system decorations.
|
||||||
|
* @see DisplayDeviceInfo#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
|
||||||
|
*/
|
||||||
|
private static final String OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS =
|
||||||
|
"should_show_system_decorations";
|
||||||
|
|
||||||
private static final int MIN_WIDTH = 100;
|
private static final int MIN_WIDTH = 100;
|
||||||
private static final int MIN_HEIGHT = 100;
|
private static final int MIN_HEIGHT = 100;
|
||||||
private static final int MAX_WIDTH = 4096;
|
private static final int MAX_WIDTH = 4096;
|
||||||
private static final int MAX_HEIGHT = 4096;
|
private static final int MAX_HEIGHT = 4096;
|
||||||
|
|
||||||
private static final Pattern DISPLAY_PATTERN =
|
private static final String DISPLAY_SPLITTER = ";";
|
||||||
Pattern.compile("([^,]+)(,[a-z]+)*");
|
private static final String MODE_SPLITTER = "\\|";
|
||||||
private static final Pattern MODE_PATTERN =
|
private static final String FLAG_SPLITTER = ",";
|
||||||
Pattern.compile("(\\d+)x(\\d+)/(\\d+)");
|
|
||||||
|
private static final Pattern DISPLAY_PATTERN = Pattern.compile("([^,]+)(,[,_a-z]+)*");
|
||||||
|
private static final Pattern MODE_PATTERN = Pattern.compile("(\\d+)x(\\d+)/(\\d+)");
|
||||||
|
|
||||||
// Unique id prefix for overlay displays.
|
// Unique id prefix for overlay displays.
|
||||||
private static final String UNIQUE_ID_PREFIX = "overlay:";
|
private static final String UNIQUE_ID_PREFIX = "overlay:";
|
||||||
@@ -154,7 +194,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (String part : value.split(";")) {
|
for (String part : value.split(DISPLAY_SPLITTER)) {
|
||||||
Matcher displayMatcher = DISPLAY_PATTERN.matcher(part);
|
Matcher displayMatcher = DISPLAY_PATTERN.matcher(part);
|
||||||
if (displayMatcher.matches()) {
|
if (displayMatcher.matches()) {
|
||||||
if (count >= 4) {
|
if (count >= 4) {
|
||||||
@@ -164,7 +204,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
String modeString = displayMatcher.group(1);
|
String modeString = displayMatcher.group(1);
|
||||||
String flagString = displayMatcher.group(2);
|
String flagString = displayMatcher.group(2);
|
||||||
ArrayList<OverlayMode> modes = new ArrayList<>();
|
ArrayList<OverlayMode> modes = new ArrayList<>();
|
||||||
for (String mode : modeString.split("\\|")) {
|
for (String mode : modeString.split(MODE_SPLITTER)) {
|
||||||
Matcher modeMatcher = MODE_PATTERN.matcher(mode);
|
Matcher modeMatcher = MODE_PATTERN.matcher(mode);
|
||||||
if (modeMatcher.matches()) {
|
if (modeMatcher.matches()) {
|
||||||
try {
|
try {
|
||||||
@@ -192,12 +232,13 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
com.android.internal.R.string.display_manager_overlay_display_name,
|
com.android.internal.R.string.display_manager_overlay_display_name,
|
||||||
number);
|
number);
|
||||||
int gravity = chooseOverlayGravity(number);
|
int gravity = chooseOverlayGravity(number);
|
||||||
boolean secure = flagString != null && flagString.contains(",secure");
|
OverlayFlags flags = OverlayFlags.parseFlags(flagString);
|
||||||
|
|
||||||
Slog.i(TAG, "Showing overlay display device #" + number
|
Slog.i(TAG, "Showing overlay display device #" + number
|
||||||
+ ": name=" + name + ", modes=" + Arrays.toString(modes.toArray()));
|
+ ": name=" + name + ", modes=" + Arrays.toString(modes.toArray())
|
||||||
|
+ ", flags=" + flags);
|
||||||
|
|
||||||
mOverlays.add(new OverlayDisplayHandle(name, modes, gravity, secure, number));
|
mOverlays.add(new OverlayDisplayHandle(name, modes, gravity, flags, number));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,7 +264,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
private final String mName;
|
private final String mName;
|
||||||
private final float mRefreshRate;
|
private final float mRefreshRate;
|
||||||
private final long mDisplayPresentationDeadlineNanos;
|
private final long mDisplayPresentationDeadlineNanos;
|
||||||
private final boolean mSecure;
|
private final OverlayFlags mFlags;
|
||||||
private final List<OverlayMode> mRawModes;
|
private final List<OverlayMode> mRawModes;
|
||||||
private final Display.Mode[] mModes;
|
private final Display.Mode[] mModes;
|
||||||
private final int mDefaultMode;
|
private final int mDefaultMode;
|
||||||
@@ -234,16 +275,15 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
private DisplayDeviceInfo mInfo;
|
private DisplayDeviceInfo mInfo;
|
||||||
private int mActiveMode;
|
private int mActiveMode;
|
||||||
|
|
||||||
public OverlayDisplayDevice(IBinder displayToken, String name,
|
OverlayDisplayDevice(IBinder displayToken, String name,
|
||||||
List<OverlayMode> modes, int activeMode, int defaultMode,
|
List<OverlayMode> modes, int activeMode, int defaultMode,
|
||||||
float refreshRate, long presentationDeadlineNanos,
|
float refreshRate, long presentationDeadlineNanos,
|
||||||
boolean secure, int state,
|
OverlayFlags flags, int state, SurfaceTexture surfaceTexture, int number) {
|
||||||
SurfaceTexture surfaceTexture, int number) {
|
|
||||||
super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number);
|
super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number);
|
||||||
mName = name;
|
mName = name;
|
||||||
mRefreshRate = refreshRate;
|
mRefreshRate = refreshRate;
|
||||||
mDisplayPresentationDeadlineNanos = presentationDeadlineNanos;
|
mDisplayPresentationDeadlineNanos = presentationDeadlineNanos;
|
||||||
mSecure = secure;
|
mFlags = flags;
|
||||||
mState = state;
|
mState = state;
|
||||||
mSurfaceTexture = surfaceTexture;
|
mSurfaceTexture = surfaceTexture;
|
||||||
mRawModes = modes;
|
mRawModes = modes;
|
||||||
@@ -304,9 +344,15 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos +
|
mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos +
|
||||||
1000000000L / (int) mRefreshRate; // display's deadline + 1 frame
|
1000000000L / (int) mRefreshRate; // display's deadline + 1 frame
|
||||||
mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION;
|
mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION;
|
||||||
if (mSecure) {
|
if (mFlags.mSecure) {
|
||||||
mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
|
mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
|
||||||
}
|
}
|
||||||
|
if (mFlags.mOwnContentOnly) {
|
||||||
|
mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
|
||||||
|
}
|
||||||
|
if (mFlags.mShouldShowSystemDecorations) {
|
||||||
|
mInfo.flags |= DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
|
||||||
|
}
|
||||||
mInfo.type = Display.TYPE_OVERLAY;
|
mInfo.type = Display.TYPE_OVERLAY;
|
||||||
mInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL;
|
mInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL;
|
||||||
mInfo.state = mState;
|
mInfo.state = mState;
|
||||||
@@ -363,19 +409,23 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
private final String mName;
|
private final String mName;
|
||||||
private final List<OverlayMode> mModes;
|
private final List<OverlayMode> mModes;
|
||||||
private final int mGravity;
|
private final int mGravity;
|
||||||
private final boolean mSecure;
|
private final OverlayFlags mFlags;
|
||||||
private final int mNumber;
|
private final int mNumber;
|
||||||
|
|
||||||
private OverlayDisplayWindow mWindow;
|
private OverlayDisplayWindow mWindow;
|
||||||
private OverlayDisplayDevice mDevice;
|
private OverlayDisplayDevice mDevice;
|
||||||
private int mActiveMode;
|
private int mActiveMode;
|
||||||
|
|
||||||
public OverlayDisplayHandle(String name, List<OverlayMode> modes, int gravity,
|
OverlayDisplayHandle(
|
||||||
boolean secure, int number) {
|
String name,
|
||||||
|
List<OverlayMode> modes,
|
||||||
|
int gravity,
|
||||||
|
OverlayFlags flags,
|
||||||
|
int number) {
|
||||||
mName = name;
|
mName = name;
|
||||||
mModes = modes;
|
mModes = modes;
|
||||||
mGravity = gravity;
|
mGravity = gravity;
|
||||||
mSecure = secure;
|
mFlags = flags;
|
||||||
mNumber = number;
|
mNumber = number;
|
||||||
|
|
||||||
mActiveMode = 0;
|
mActiveMode = 0;
|
||||||
@@ -405,10 +455,10 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate,
|
public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate,
|
||||||
long presentationDeadlineNanos, int state) {
|
long presentationDeadlineNanos, int state) {
|
||||||
synchronized (getSyncRoot()) {
|
synchronized (getSyncRoot()) {
|
||||||
IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure);
|
IBinder displayToken = SurfaceControl.createDisplay(mName, mFlags.mSecure);
|
||||||
mDevice = new OverlayDisplayDevice(displayToken, mName, mModes, mActiveMode,
|
mDevice = new OverlayDisplayDevice(displayToken, mName, mModes, mActiveMode,
|
||||||
DEFAULT_MODE_INDEX, refreshRate, presentationDeadlineNanos,
|
DEFAULT_MODE_INDEX, refreshRate, presentationDeadlineNanos,
|
||||||
mSecure, state, surfaceTexture, mNumber) {
|
mFlags, state, surfaceTexture, mNumber) {
|
||||||
@Override
|
@Override
|
||||||
public void onModeChangedLocked(int index) {
|
public void onModeChangedLocked(int index) {
|
||||||
onActiveModeChangedLocked(index);
|
onActiveModeChangedLocked(index);
|
||||||
@@ -446,7 +496,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
pw.println(" mModes=" + Arrays.toString(mModes.toArray()));
|
pw.println(" mModes=" + Arrays.toString(mModes.toArray()));
|
||||||
pw.println(" mActiveMode=" + mActiveMode);
|
pw.println(" mActiveMode=" + mActiveMode);
|
||||||
pw.println(" mGravity=" + mGravity);
|
pw.println(" mGravity=" + mGravity);
|
||||||
pw.println(" mSecure=" + mSecure);
|
pw.println(" mFlags=" + mFlags);
|
||||||
pw.println(" mNumber=" + mNumber);
|
pw.println(" mNumber=" + mNumber);
|
||||||
|
|
||||||
// Try to dump the window state.
|
// Try to dump the window state.
|
||||||
@@ -463,8 +513,8 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
public void run() {
|
public void run() {
|
||||||
OverlayMode mode = mModes.get(mActiveMode);
|
OverlayMode mode = mModes.get(mActiveMode);
|
||||||
OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(),
|
OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(),
|
||||||
mName, mode.mWidth, mode.mHeight, mode.mDensityDpi, mGravity, mSecure,
|
mName, mode.mWidth, mode.mHeight, mode.mDensityDpi, mGravity,
|
||||||
OverlayDisplayHandle.this);
|
mFlags.mSecure, OverlayDisplayHandle.this);
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
synchronized (getSyncRoot()) {
|
synchronized (getSyncRoot()) {
|
||||||
@@ -531,4 +581,60 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
|||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Represents the flags of the overlay display. */
|
||||||
|
private static final class OverlayFlags {
|
||||||
|
/** See {@link #OVERLAY_DISPLAY_FLAG_SECURE}. */
|
||||||
|
final boolean mSecure;
|
||||||
|
|
||||||
|
/** See {@link #OVERLAY_DISPLAY_FLAG_OWN_CONTENT_ONLY}. */
|
||||||
|
final boolean mOwnContentOnly;
|
||||||
|
|
||||||
|
/** See {@link #OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS}. */
|
||||||
|
final boolean mShouldShowSystemDecorations;
|
||||||
|
|
||||||
|
OverlayFlags(
|
||||||
|
boolean secure,
|
||||||
|
boolean ownContentOnly,
|
||||||
|
boolean shouldShowSystemDecorations) {
|
||||||
|
mSecure = secure;
|
||||||
|
mOwnContentOnly = ownContentOnly;
|
||||||
|
mShouldShowSystemDecorations = shouldShowSystemDecorations;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OverlayFlags parseFlags(@Nullable String flagString) {
|
||||||
|
if (TextUtils.isEmpty(flagString)) {
|
||||||
|
return new OverlayFlags(
|
||||||
|
false /* secure */,
|
||||||
|
false /* ownContentOnly */,
|
||||||
|
false /* shouldShowSystemDecorations */);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean secure = false;
|
||||||
|
boolean ownContentOnly = false;
|
||||||
|
boolean shouldShowSystemDecorations = false;
|
||||||
|
for (String flag: flagString.split(FLAG_SPLITTER)) {
|
||||||
|
if (OVERLAY_DISPLAY_FLAG_SECURE.equals(flag)) {
|
||||||
|
secure = true;
|
||||||
|
}
|
||||||
|
if (OVERLAY_DISPLAY_FLAG_OWN_CONTENT_ONLY.equals(flag)) {
|
||||||
|
ownContentOnly = true;
|
||||||
|
}
|
||||||
|
if (OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS.equals(flag)) {
|
||||||
|
shouldShowSystemDecorations = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new OverlayFlags(secure, ownContentOnly, shouldShowSystemDecorations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new StringBuilder("{")
|
||||||
|
.append("secure=").append(mSecure)
|
||||||
|
.append(", ownContentOnly=").append(mOwnContentOnly)
|
||||||
|
.append(", shouldShowSystemDecorations=").append(mShouldShowSystemDecorations)
|
||||||
|
.append("}")
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user