diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 8ac84f7ae6416..01b37c81ca24c 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -78,6 +78,40 @@ public final class Display { */ public static final int DEFAULT_DISPLAY = 0; + /** + * Display flag: Indicates that the display supports secure video output. + *
+ * 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. + *
+ * 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. + *
+ * + * @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 decrypted 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; + /** * Internal method to create a display. * Applications should use {@link android.view.WindowManager#getDefaultDisplay()} @@ -157,6 +191,20 @@ public final class Display { return mLayerStack; } + /** + * Returns a combination of flags that describe the capabilities of the display. + * + * @return The display flags. + * + * @hide pending review + */ + public int getFlags() { + synchronized (this) { + updateDisplayInfoLocked(); + return mDisplayInfo.flags; + } + } + /** * Gets the compatibility info used by this display instance. * diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index b728d71cae70b..c968ec549a7b6 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -33,6 +33,11 @@ public final class DisplayInfo implements Parcelable { */ public int layerStack; + /** + * Display flags. + */ + public int flags; + /** * The human-readable name of the display. */ @@ -189,6 +194,7 @@ public final class DisplayInfo implements Parcelable { public void copyFrom(DisplayInfo other) { layerStack = other.layerStack; + flags = other.flags; name = other.name; appWidth = other.appWidth; appHeight = other.appHeight; @@ -207,6 +213,7 @@ public final class DisplayInfo implements Parcelable { public void readFromParcel(Parcel source) { layerStack = source.readInt(); + flags = source.readInt(); name = source.readString(); appWidth = source.readInt(); appHeight = source.readInt(); @@ -226,6 +233,7 @@ public final class DisplayInfo implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(layerStack); + dest.writeInt(flags); dest.writeString(name); dest.writeInt(appWidth); dest.writeInt(appHeight); @@ -286,6 +294,17 @@ public final class DisplayInfo implements Parcelable { + ", rotation " + rotation + ", density " + logicalDensityDpi + ", " + physicalXDpi + " x " + physicalYDpi + " dpi" - + ", layerStack " + layerStack + "}"; + + ", layerStack " + layerStack + flagsToString(flags) + "}"; + } + + 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"); + } + return result.toString(); } } diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java index 7c57694042a58..1420a506c8b49 100644 --- a/services/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/java/com/android/server/display/DisplayDeviceInfo.java @@ -30,17 +30,17 @@ final class DisplayDeviceInfo { */ public static final int FLAG_DEFAULT_DISPLAY = 1 << 0; - /** - * Flag: Indicates that this display device can show secure surfaces. - */ - public static final int FLAG_SECURE = 1 << 1; - /** * Flag: Indicates that this display device can rotate to show contents in a * different orientation. Otherwise the rotation is assumed to be fixed in the * natural orientation and the display manager should transform the content to fit. */ - public static final int FLAG_SUPPORTS_ROTATION = 1 << 2; + public static final int FLAG_SUPPORTS_ROTATION = 1 << 1; + + /** + * Flag: Indicates that this display device can show secure surfaces. + */ + public static final int FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT = 1 << 2; /** * Touch attachment: Display does not receive touch. @@ -179,8 +179,11 @@ final class DisplayDeviceInfo { if ((flags & FLAG_DEFAULT_DISPLAY) != 0) { msg.append(", FLAG_DEFAULT_DISPLAY"); } - if ((flags & FLAG_SECURE) != 0) { - msg.append(", FLAG_SECURE"); + if ((flags & FLAG_SUPPORTS_ROTATION) != 0) { + msg.append(", FLAG_DEFAULT_DISPLAY"); + } + if ((flags & FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT) != 0) { + msg.append(", FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT"); } return msg.toString(); } diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java index 7629db61371c2..f3bec1d562139 100644 --- a/services/java/com/android/server/display/HeadlessDisplayAdapter.java +++ b/services/java/com/android/server/display/HeadlessDisplayAdapter.java @@ -60,7 +60,7 @@ final class HeadlessDisplayAdapter extends DisplayAdapter { mInfo.xDpi = 160; mInfo.yDpi = 160; mInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY - | DisplayDeviceInfo.FLAG_SECURE; + | DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT; 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 80c860ba88f46..eab4c9a200894 100644 --- a/services/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/java/com/android/server/display/LocalDisplayAdapter.java @@ -124,7 +124,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { mInfo.name = getContext().getResources().getString( com.android.internal.R.string.display_manager_built_in_display_name); mInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY - | DisplayDeviceInfo.FLAG_SECURE + | DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT | DisplayDeviceInfo.FLAG_SUPPORTS_ROTATION; mInfo.densityDpi = (int)(mPhys.density * 160 + 0.5f); mInfo.xDpi = mPhys.xDpi; @@ -133,7 +133,7 @@ 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_SECURE; + 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 2e752603360f4..3607de15dd504 100644 --- a/services/java/com/android/server/display/LogicalDisplay.java +++ b/services/java/com/android/server/display/LogicalDisplay.java @@ -17,6 +17,7 @@ package com.android.server.display; import android.graphics.Rect; +import android.view.Display; import android.view.DisplayInfo; import android.view.Surface; @@ -177,6 +178,10 @@ final class LogicalDisplay { DisplayDeviceInfo deviceInfo = mPrimaryDisplayDevice.getDisplayDeviceInfoLocked(); 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; + } mBaseDisplayInfo.name = deviceInfo.name; mBaseDisplayInfo.appWidth = deviceInfo.width; mBaseDisplayInfo.appHeight = deviceInfo.height; diff --git a/services/java/com/android/server/display/OverlayDisplayAdapter.java b/services/java/com/android/server/display/OverlayDisplayAdapter.java index 9b0e534c5ed11..75ddd244d9c24 100644 --- a/services/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/java/com/android/server/display/OverlayDisplayAdapter.java @@ -227,7 +227,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { mInfo.densityDpi = mDensityDpi; mInfo.xDpi = mDensityDpi; mInfo.yDpi = mDensityDpi; - mInfo.flags = DisplayDeviceInfo.FLAG_SECURE; + mInfo.flags = DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT; 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 b75940e36982b..b57d3dc8125ca 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/java/com/android/server/display/WifiDisplayAdapter.java @@ -149,7 +149,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { int deviceFlags = 0; if ((flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0) { - deviceFlags |= DisplayDeviceInfo.FLAG_SECURE; + deviceFlags |= DisplayDeviceInfo.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT; } float refreshRate = 60.0f; // TODO: get this for real diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java index 8256733a25b8e..141cbd702077d 100644 --- a/services/java/com/android/server/display/WifiDisplayController.java +++ b/services/java/com/android/server/display/WifiDisplayController.java @@ -62,7 +62,7 @@ import java.util.Enumeration; */ final class WifiDisplayController implements DumpUtils.Dump { private static final String TAG = "WifiDisplayController"; - private static final boolean DEBUG = true; + private static final boolean DEBUG = false; private static final int DEFAULT_CONTROL_PORT = 7236; private static final int MAX_THROUGHPUT = 50;