diff options
| -rw-r--r-- | api/17.txt | 2 | ||||
| -rw-r--r-- | api/current.txt | 2 | ||||
| -rw-r--r-- | core/java/android/view/Display.java | 56 | ||||
| -rw-r--r-- | core/java/android/view/DisplayInfo.java | 3 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 22 | ||||
| -rw-r--r-- | core/java/android/view/WindowManager.java | 9 | ||||
| -rw-r--r-- | services/java/com/android/server/display/LocalDisplayAdapter.java | 8 | ||||
| -rw-r--r-- | services/java/com/android/server/display/LogicalDisplay.java | 3 | ||||
| -rw-r--r-- | services/java/com/android/server/display/WifiDisplayAdapter.java | 11 |
9 files changed, 99 insertions, 17 deletions
@@ -23742,6 +23742,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_SECURE = 2; // 0x2 field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1 } @@ -24788,6 +24789,7 @@ package android.view { ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int); method public boolean gatherTransparentRegion(android.graphics.Region); method public android.view.SurfaceHolder getHolder(); + method public void setSecure(boolean); method public void setZOrderMediaOverlay(boolean); method public void setZOrderOnTop(boolean); } diff --git a/api/current.txt b/api/current.txt index 31ed755..e7f02dc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -23742,6 +23742,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_SECURE = 2; // 0x2 field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1 } @@ -24788,6 +24789,7 @@ package android.view { ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int); method public boolean gatherTransparentRegion(android.graphics.Region); method public android.view.SurfaceHolder getHolder(); + method public void setSecure(boolean); method public void setZOrderMediaOverlay(boolean); method public void setZOrderOnTop(boolean); } diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 662dc45..1cd3e05 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -82,22 +82,65 @@ public final class Display { * Display flag: Indicates that the display supports compositing content * that is stored in protected graphics buffers. * <p> + * If this flag is set then the display device supports compositing protected buffers. + * </p><p> + * If this flag is not set then the display device may not support compositing + * protected buffers; the user may see a blank region on the screen instead of + * the protected content. + * </p><p> * 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> - * 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. + * An application can use the absence of this flag as a hint that it should not use protected + * buffers for this display because the content may not be visible. For example, + * if the flag is not set then the application may choose not to show content on this + * display, show an informative error message, select an alternate content stream + * or adopt a different strategy for decoding content that does not rely on + * protected buffers. * </p> + * + * @see #getFlags */ public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 0; /** + * Display flag: Indicates that the display has a secure video output and + * supports compositing secure surfaces. + * <p> + * If this flag is set then the display device has a secure video output + * and is capable of showing secure surfaces. It may also be capable of + * showing {@link #FLAG_SUPPORTS_PROTECTED_BUFFERS protected buffers}. + * </p><p> + * If this flag is not set then the display device may not have a secure video + * output; the user may see a blank region on the screen instead of + * the contents of secure surfaces or protected buffers. + * </p><p> + * Secure surfaces are used to prevent content rendered into those surfaces + * by applications from appearing in screenshots or from being viewed + * on non-secure displays. Protected buffers are used by secure video decoders + * for a similar purpose. + * </p><p> + * An application creates a window with a secure surface by specifying the + * {@link WindowManager.LayoutParams#FLAG_SECURE} window flag. + * Likewise, an application creates a {@link SurfaceView} with a secure surface + * by calling {@link SurfaceView#setSecure} before attaching the secure view to + * its containing window. + * </p><p> + * An application can use the absence of this flag as a hint that it should not create + * secure surfaces or protected buffers on this display because the content may + * not be visible. For example, if the flag is not set then the application may + * choose not to show content on this display, show an informative error message, + * select an alternate content stream or adopt a different strategy for decoding + * content that does not rely on secure surfaces or protected buffers. + * </p> + * + * @see #getFlags + */ + public static final int FLAG_SECURE = 1 << 1; + + /** * Internal method to create a display. * Applications should use {@link android.view.WindowManager#getDefaultDisplay()} * or {@link android.hardware.display.DisplayManager#getDisplay} @@ -182,6 +225,7 @@ public final class Display { * @return The display flags. * * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS + * @see #FLAG_SECURE */ public int getFlags() { synchronized (this) { diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index fb04150..ead5ff4 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -299,6 +299,9 @@ public final class DisplayInfo implements Parcelable { private static String flagsToString(int flags) { StringBuilder result = new StringBuilder(); + if ((flags & Display.FLAG_SECURE) != 0) { + result.append(", FLAG_SECURE"); + } if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 0d16dd3..9008521 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -385,7 +385,27 @@ public class SurfaceView extends View { mLayout.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; } } - + + /** + * Control whether the surface view's content should be treated as secure, + * preventing it from appearing in screenshots or from being viewed on + * non-secure displays. + * + * <p>Note that this must be set before the surface view's containing + * window is attached to the window manager. + * + * <p>See {@link android.view.Display#FLAG_SECURE} for details. + * + * @param isSecure True if the surface view is secure. + */ + public void setSecure(boolean isSecure) { + if (isSecure) { + mLayout.flags |= WindowManager.LayoutParams.FLAG_SECURE; + } else { + mLayout.flags &= ~WindowManager.LayoutParams.FLAG_SECURE; + } + } + /** * Hack to allow special layering of windows. The type is one of the * types in WindowManager.LayoutParams. This is a hack so: diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 01923e2..3b31ff6 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -628,8 +628,13 @@ public interface WindowManager extends ViewManager { @Deprecated public static final int FLAG_DITHER = 0x00001000; - /** Window flag: don't allow screen shots while this window is - * displayed. Maps to Surface.SECURE. */ + /** Window flag: Treat the content of the window as secure, preventing + * it from appearing in screenshots or from being viewed on non-secure + * displays. + * + * <p>See {@link android.view.Display#FLAG_SECURE} for more details about + * secure surfaces and secure displays. + */ public static final int FLAG_SECURE = 0x00002000; /** Window flag: a special mode where the layout parameters are used diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java index d6c5248..fa56b83 100644 --- a/services/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/java/com/android/server/display/LocalDisplayAdapter.java @@ -127,10 +127,12 @@ final class LocalDisplayAdapter extends DisplayAdapter { mInfo.height = mPhys.height; mInfo.refreshRate = mPhys.refreshRate; - // Assume that all built-in displays have secure output (eg. HDCP) and + // Assume that all built-in displays that have secure output (eg. HDCP) also // support compositing from gralloc protected buffers. - mInfo.flags = DisplayDeviceInfo.FLAG_SECURE - | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS; + if (mPhys.secure) { + mInfo.flags = DisplayDeviceInfo.FLAG_SECURE + | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS; + } if (mBuiltInDisplayId == Surface.BUILT_IN_DISPLAY_ID_MAIN) { mInfo.name = getContext().getResources().getString( diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java index aa7ea82..aa62aee 100644 --- a/services/java/com/android/server/display/LogicalDisplay.java +++ b/services/java/com/android/server/display/LogicalDisplay.java @@ -186,6 +186,9 @@ final class LogicalDisplay { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_PROTECTED_BUFFERS; } + if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SECURE) != 0) { + mBaseDisplayInfo.flags |= Display.FLAG_SECURE; + } mBaseDisplayInfo.name = deviceInfo.name; mBaseDisplayInfo.appWidth = deviceInfo.width; mBaseDisplayInfo.appHeight = deviceInfo.height; diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java index 97fc3e6..2ea83ee 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/java/com/android/server/display/WifiDisplayAdapter.java @@ -281,18 +281,19 @@ final class WifiDisplayAdapter extends DisplayAdapter { scheduleStatusChangedBroadcastLocked(); } + boolean secure = (flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0; int deviceFlags = 0; - if ((flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0) { + if (secure) { deviceFlags |= DisplayDeviceInfo.FLAG_SECURE; - } - if (mSupportsProtectedBuffers) { - deviceFlags |= DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS; + if (mSupportsProtectedBuffers) { + deviceFlags |= DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS; + } } float refreshRate = 60.0f; // TODO: get this for real String name = display.getFriendlyDisplayName(); - IBinder displayToken = Surface.createDisplay(name, false); + IBinder displayToken = Surface.createDisplay(name, secure); mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height, refreshRate, deviceFlags, surface); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED); |
