summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-10-01 21:07:03 -0700
committerJeff Brown <jeffbrown@google.com>2012-10-02 16:25:10 -0700
commit77aebfdbae489c3712ae3f9bca29d01fb1f09dc2 (patch)
tree5f3cf170ce629f5b2f74374ea4b21197ed7a841d
parent4253abbcfa3165ad7d06c4de97cd780c4e96f94a (diff)
downloadframeworks_base-77aebfdbae489c3712ae3f9bca29d01fb1f09dc2.zip
frameworks_base-77aebfdbae489c3712ae3f9bca29d01fb1f09dc2.tar.gz
frameworks_base-77aebfdbae489c3712ae3f9bca29d01fb1f09dc2.tar.bz2
Add new Display API for secure video capabilities.
Added a new API to determine whether the display supports protected buffers so that an application can choose a different content stream or change how it decodes the content so that it will be viewable on the display. At present, wifi display does not fully support protected buffers although this may be enhanced in the future. Bug: 6986623 Change-Id: If53a53d72b0ec92753cc4b29f99fcb131e00449b
-rw-r--r--api/17.txt2
-rw-r--r--api/current.txt2
-rw-r--r--core/java/android/view/Display.java43
-rw-r--r--core/java/android/view/DisplayInfo.java7
-rwxr-xr-xcore/res/res/values/config.xml14
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--services/java/com/android/server/display/DisplayDeviceInfo.java17
-rw-r--r--services/java/com/android/server/display/HeadlessDisplayAdapter.java3
-rw-r--r--services/java/com/android/server/display/LocalDisplayAdapter.java10
-rw-r--r--services/java/com/android/server/display/LogicalDisplay.java4
-rw-r--r--services/java/com/android/server/display/OverlayDisplayAdapter.java6
-rw-r--r--services/java/com/android/server/display/WifiDisplayAdapter.java11
12 files changed, 69 insertions, 51 deletions
diff --git a/api/17.txt b/api/17.txt
index 1a6657c..f35a706 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 4e7d012..a36727d 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 cf58458..662dc45 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.
* <p>
- * 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.
* </p><p>
- * 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.
- * </p><p>
- * This flag mainly applies to external display devices such as HDMI or
- * Wifi display. Built-in display devices are usually considered secure.
- * </p>
- *
- * @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.
- * <p>
- * 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.
+ * 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.
* </p>
- *
- * @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 c968ec5..fe05634 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 d3d994f..16960c8 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -967,4 +967,18 @@
<!-- Whether safe headphone volume is enabled or not (country specific). -->
<bool name="config_safe_media_volume_enabled">true</bool>
+ <!-- Set to true if the wifi display supports compositing content stored
+ in gralloc protected buffers. For this to be true, there must exist
+ a protected hardware path for surface flinger to composite and send
+ protected buffers to the wifi display video encoder.
+
+ If this flag is false, we advise applications not to use protected
+ buffers (if possible) when presenting content to a wifi display because
+ the content may be blanked.
+
+ This flag controls whether the {@link Display#FLAG_SUPPORTS_PROTECTED_BUFFERS}
+ flag is set for wifi displays.
+ -->
+ <bool name="config_wifiDisplaySupportsProtectedBuffers">false</bool>
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6499d8b..14bd528 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -261,6 +261,7 @@
<java-symbol type="bool" name="config_ui_enableFadingMarquee" />
<java-symbol type="bool" name="config_use_strict_phone_number_comparation" />
<java-symbol type="bool" name="config_voice_capable" />
+ <java-symbol type="bool" name="config_wifiDisplaySupportsProtectedBuffers" />
<java-symbol type="bool" name="preferences_prefer_dual_pane" />
<java-symbol type="bool" name="skip_restoring_network_selection" />
<java-symbol type="bool" name="split_action_bar_is_narrow" />
diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java
index f0cd0f5..b4dab86 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 f3bec1d..7ec537f 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 9c51463..679a67e 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 3607de1..f4cb84d 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 0767fc0..6ffb629 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 4a89be7..b2beb5e 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