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