diff --git a/api/17.txt b/api/17.txt
index 1a6657c556dc2..f35a70637fd95 100644
--- a/api/17.txt
+++ b/api/17.txt
@@ -23714,6 +23714,7 @@ package android.view {
public final class Display {
method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
method public int getDisplayId();
+ method public int getFlags();
method public deprecated int getHeight();
method public void getMetrics(android.util.DisplayMetrics);
method public java.lang.String getName();
@@ -23728,6 +23729,7 @@ package android.view {
method public deprecated int getWidth();
method public boolean isValid();
field public static final int DEFAULT_DISPLAY = 0; // 0x0
+ field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1
}
public class DragEvent implements android.os.Parcelable {
diff --git a/api/current.txt b/api/current.txt
index 4e7d01225b213..a36727dab0c8d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23719,6 +23719,7 @@ package android.view {
public final class Display {
method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
method public int getDisplayId();
+ method public int getFlags();
method public deprecated int getHeight();
method public void getMetrics(android.util.DisplayMetrics);
method public java.lang.String getName();
@@ -23733,6 +23734,7 @@ package android.view {
method public deprecated int getWidth();
method public boolean isValid();
field public static final int DEFAULT_DISPLAY = 0; // 0x0
+ field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1
}
public class DragEvent implements android.os.Parcelable {
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index cf584581df3f6..662dc45c005b6 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -79,38 +79,23 @@ public final class Display {
public static final int DEFAULT_DISPLAY = 0;
/**
- * Display flag: Indicates that the display supports secure video output.
+ * Display flag: Indicates that the display supports compositing content
+ * that is stored in protected graphics buffers.
*
- * This flag is used to indicate that the display supports content protection
- * mechanisms for secure video output at the display interface, such as HDCP.
- * These mechanisms may be used to protect secure content as it leaves the device.
+ * Secure (DRM) video decoders may allocate protected graphics buffers to request that
+ * a hardware-protected path be provided between the video decoder and the external
+ * display sink. If a hardware-protected path is not available, then content stored
+ * in protected graphics buffers may not be composited.
*
- * While mirroring content to multiple displays, it can happen that certain
- * display devices support secure video output while other display devices do not.
- * The secure content will be shown only on the display devices that support
- * secure video output and will be blanked on other display devices that do
- * not support secure video output.
- *
- * This flag mainly applies to external display devices such as HDMI or
- * Wifi display. Built-in display devices are usually considered secure.
+ * If this flag is not set, then the display device does not support compositing
+ * protected buffers; the user may see a blank region on the screen instead of
+ * the protected content. An application can use this flag as a hint that it should
+ * select an alternate content stream or adopt a different strategy for decoding
+ * content that does not rely on protected buffers so as to ensure that the user
+ * can view the content on the display as expected.
*
- *
- * @hide pending review
*/
- public static final int FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT = 1 << 0;
-
- /**
- * Display flag: Indicates that the display supports secure in-memory video buffers.
- *
- * This flag is used to indicate that the display supports content protection
- * mechanisms for in-memory video buffers, such as secure memory areas.
- * These mechanisms may be used to protect secure video buffers in memory from
- * the video decoder to the display compositor and the video interface.
- *
- *
- * @hide pending review
- */
- public static final int FLAG_SUPPORTS_SECURE_VIDEO_BUFFERS = 1 << 1;
+ public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 0;
/**
* Internal method to create a display.
@@ -196,7 +181,7 @@ public final class Display {
*
* @return The display flags.
*
- * @hide pending review
+ * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS
*/
public int getFlags() {
synchronized (this) {
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index c968ec549a7b6..fe056348ad69c 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -299,11 +299,8 @@ public final class DisplayInfo implements Parcelable {
private static String flagsToString(int flags) {
StringBuilder result = new StringBuilder();
- if ((flags & Display.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT) != 0) {
- result.append(", FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT");
- }
- if ((flags & Display.FLAG_SUPPORTS_SECURE_VIDEO_BUFFERS) != 0) {
- result.append(", FLAG_SUPPORTS_SECURE_VIDEO_BUFFERS");
+ if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
+ result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
}
return result.toString();
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d3d994ff2c212..16960c8737039 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -967,4 +967,18 @@
true
+
+ false
+
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6499d8be71c1d..14bd52862beb5 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -261,6 +261,7 @@
+
diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java
index f0cd0f5176a29..b4dab8683693d 100644
--- a/services/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/java/com/android/server/display/DisplayDeviceInfo.java
@@ -38,9 +38,15 @@ final class DisplayDeviceInfo {
public static final int FLAG_SUPPORTS_ROTATION = 1 << 1;
/**
- * Flag: Indicates that this display device can show secure surfaces.
+ * Flag: Indicates that this display device has secure video output, such as HDCP.
*/
- public static final int FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT = 1 << 2;
+ public static final int FLAG_SECURE = 1 << 2;
+
+ /**
+ * Flag: Indicates that this display device supports compositing
+ * from gralloc protected buffers.
+ */
+ public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 3;
/**
* Touch attachment: Display does not receive touch.
@@ -182,8 +188,11 @@ final class DisplayDeviceInfo {
if ((flags & FLAG_SUPPORTS_ROTATION) != 0) {
msg.append(", FLAG_SUPPORTS_ROTATION");
}
- if ((flags & FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT) != 0) {
- msg.append(", FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT");
+ if ((flags & FLAG_SECURE) != 0) {
+ msg.append(", FLAG_SECURE");
+ }
+ if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
+ msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
}
return msg.toString();
}
diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
index f3bec1d562139..7ec537f7db108 100644
--- a/services/java/com/android/server/display/HeadlessDisplayAdapter.java
+++ b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
@@ -60,7 +60,8 @@ final class HeadlessDisplayAdapter extends DisplayAdapter {
mInfo.xDpi = 160;
mInfo.yDpi = 160;
mInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
- | DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT;
+ | DisplayDeviceInfo.FLAG_SECURE
+ | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
}
return mInfo;
diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java
index 9c51463829744..679a67e4dcb31 100644
--- a/services/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/java/com/android/server/display/LocalDisplayAdapter.java
@@ -124,11 +124,16 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mInfo.width = mPhys.width;
mInfo.height = mPhys.height;
mInfo.refreshRate = mPhys.refreshRate;
+
+ // Assume that all built-in displays have secure output (eg. HDCP) and
+ // support compositing from gralloc protected buffers.
+ mInfo.flags = DisplayDeviceInfo.FLAG_SECURE
+ | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
+
if (mBuiltInDisplayId == Surface.BUILT_IN_DISPLAY_ID_MAIN) {
mInfo.name = getContext().getResources().getString(
com.android.internal.R.string.display_manager_built_in_display_name);
- mInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
- | DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT
+ mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
| DisplayDeviceInfo.FLAG_SUPPORTS_ROTATION;
mInfo.densityDpi = (int)(mPhys.density * 160 + 0.5f);
mInfo.xDpi = mPhys.xDpi;
@@ -137,7 +142,6 @@ final class LocalDisplayAdapter extends DisplayAdapter {
} else {
mInfo.name = getContext().getResources().getString(
com.android.internal.R.string.display_manager_hdmi_display_name);
- mInfo.flags = DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT;
mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
mInfo.setAssumedDensityForExternalDisplay(mPhys.width, mPhys.height);
}
diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java
index 3607de15dd504..f4cb84da9eb48 100644
--- a/services/java/com/android/server/display/LogicalDisplay.java
+++ b/services/java/com/android/server/display/LogicalDisplay.java
@@ -179,8 +179,8 @@ final class LogicalDisplay {
if (!Objects.equal(mPrimaryDisplayDeviceInfo, deviceInfo)) {
mBaseDisplayInfo.layerStack = mLayerStack;
mBaseDisplayInfo.flags = 0;
- if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT) != 0) {
- mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT;
+ if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
+ mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_PROTECTED_BUFFERS;
}
mBaseDisplayInfo.name = deviceInfo.name;
mBaseDisplayInfo.appWidth = deviceInfo.width;
diff --git a/services/java/com/android/server/display/OverlayDisplayAdapter.java b/services/java/com/android/server/display/OverlayDisplayAdapter.java
index 0767fc05d7000..6ffb62966f80c 100644
--- a/services/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -19,14 +19,10 @@ package com.android.server.display;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.IBinder;
-import android.os.UserHandle;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.Slog;
@@ -227,7 +223,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
mInfo.densityDpi = mDensityDpi;
mInfo.xDpi = mDensityDpi;
mInfo.yDpi = mDensityDpi;
- mInfo.flags = DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT;
+ mInfo.flags = 0;
mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
}
return mInfo;
diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java
index 4a89be7d5d544..b2beb5e5bbb2f 100644
--- a/services/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/java/com/android/server/display/WifiDisplayAdapter.java
@@ -50,7 +50,8 @@ import java.util.Arrays;
final class WifiDisplayAdapter extends DisplayAdapter {
private static final String TAG = "WifiDisplayAdapter";
- private PersistentDataStore mPersistentDataStore;
+ private final PersistentDataStore mPersistentDataStore;
+ private final boolean mSupportsProtectedBuffers;
private WifiDisplayController mDisplayController;
private WifiDisplayDevice mDisplayDevice;
@@ -70,6 +71,8 @@ final class WifiDisplayAdapter extends DisplayAdapter {
PersistentDataStore persistentDataStore) {
super(syncRoot, context, handler, listener, TAG);
mPersistentDataStore = persistentDataStore;
+ mSupportsProtectedBuffers = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_wifiDisplaySupportsProtectedBuffers);
}
@Override
@@ -84,6 +87,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
pw.println("mAvailableDisplays=" + Arrays.toString(mAvailableDisplays));
pw.println("mRememberedDisplays=" + Arrays.toString(mRememberedDisplays));
pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast);
+ pw.println("mSupportsProtectedBuffers=" + mSupportsProtectedBuffers);
// Try to dump the controller state.
if (mDisplayController == null) {
@@ -217,7 +221,10 @@ final class WifiDisplayAdapter extends DisplayAdapter {
int deviceFlags = 0;
if ((flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0) {
- deviceFlags |= DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT;
+ deviceFlags |= DisplayDeviceInfo.FLAG_SECURE;
+ }
+ if (mSupportsProtectedBuffers) {
+ deviceFlags |= DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
}
float refreshRate = 60.0f; // TODO: get this for real