diff options
17 files changed, 259 insertions, 56 deletions
diff --git a/api/current.txt b/api/current.txt index 429caa5a2777..7d83fcfe98c8 100644 --- a/api/current.txt +++ b/api/current.txt @@ -40,6 +40,9 @@ package android { field public static final java.lang.String CALL_PHONE = "android.permission.CALL_PHONE"; field public static final java.lang.String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED"; field public static final java.lang.String CAMERA = "android.permission.CAMERA"; + field public static final java.lang.String CAPTURE_AUDIO_OUTPUT = "android.permission.CAPTURE_AUDIO_OUTPUT"; + field public static final java.lang.String CAPTURE_SECURE_VIDEO_OUTPUT = "android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"; + field public static final java.lang.String CAPTURE_VIDEO_OUTPUT = "android.permission.CAPTURE_VIDEO_OUTPUT"; field public static final java.lang.String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE"; field public static final java.lang.String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION"; field public static final java.lang.String CHANGE_NETWORK_STATE = "android.permission.CHANGE_NETWORK_STATE"; @@ -10798,13 +10801,16 @@ package android.hardware.camera2 { package android.hardware.display { public final class DisplayManager { - method public android.hardware.display.VirtualDisplay createPrivateVirtualDisplay(java.lang.String, int, int, int, android.view.Surface); + method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, android.view.Surface, int); method public android.view.Display getDisplay(int); method public android.view.Display[] getDisplays(); method public android.view.Display[] getDisplays(java.lang.String); method public void registerDisplayListener(android.hardware.display.DisplayManager.DisplayListener, android.os.Handler); method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener); field public static final java.lang.String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION"; + field public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 2; // 0x2 + field public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1; // 0x1 + field public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 4; // 0x4 } public static abstract interface DisplayManager.DisplayListener { @@ -25610,6 +25616,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_PRESENTATION = 8; // 0x8 field public static final int FLAG_PRIVATE = 4; // 0x4 field public static final int FLAG_SECURE = 2; // 0x2 field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1 diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java index 9e2e4ba11f56..7d6573685152 100644 --- a/core/java/android/hardware/display/DisplayManager.java +++ b/core/java/android/hardware/display/DisplayManager.java @@ -69,16 +69,110 @@ public final class DisplayManager { * Display category: Presentation displays. * <p> * This category can be used to identify secondary displays that are suitable for - * use as presentation displays. + * use as presentation displays such as HDMI or Wireless displays. Applications + * may automatically project their content to presentation displays to provide + * richer second screen experiences. * </p> * * @see android.app.Presentation for information about presenting content * on secondary displays. + * @see Display#FLAG_PRESENTATION * @see #getDisplays(String) */ public static final String DISPLAY_CATEGORY_PRESENTATION = "android.hardware.display.category.PRESENTATION"; + /** + * Virtual display flag: Create a public display. + * + * <h3>Public virtual displays</h3> + * <p> + * When this flag is set, the virtual display is public. + * </p><p> + * A public virtual display behaves just like most any other display that is connected + * to the system such as an HDMI or Wireless display. Applications can open + * windows on the display and the system may mirror the contents of other displays + * onto it. + * </p><p> + * Creating a public virtual display requires the + * {@link android.Manifest.permission#CAPTURE_VIDEO_OUTPUT} + * or {@link android.Manifest.permission#CAPTURE_SECURE_VIDEO_OUTPUT} permission. + * These permissions are reserved for use by system components and are not available to + * third-party applications. + * </p> + * + * <h3>Private virtual displays</h3> + * <p> + * When this flag is not set, the virtual display is private as defined by the + * {@link Display#FLAG_PRIVATE} display flag. + * </p> + * A private virtual display belongs to the application that created it. + * Only the a owner of a private virtual display is allowed to place windows upon it. + * The private virtual display also does not participate in display mirroring: it will + * neither receive mirrored content from another display nor allow its own content to + * be mirrored elsewhere. More precisely, the only processes that are allowed to + * enumerate or interact with the private display are those that have the same UID as the + * application that originally created the private virtual display. + * </p> + * + * @see #createVirtualDisplay + */ + public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1 << 0; + + /** + * Virtual display flag: Create a presentation display. + * + * <h3>Presentation virtual displays</h3> + * <p> + * When this flag is set, the virtual display is registered as a presentation + * display in the {@link #DISPLAY_CATEGORY_PRESENTATION presentation display category}. + * Applications may automatically project their content to presentation displays + * to provide richer second screen experiences. + * </p> + * + * <h3>Non-presentation virtual displays</h3> + * <p> + * When this flag is not set, the virtual display is not registered as a presentation + * display. Applications can still project their content on the display but they + * will typically not do so automatically. This option is appropriate for + * more special-purpose displays. + * </p> + * + * @see android.app.Presentation for information about presenting content + * on secondary displays. + * @see #createVirtualDisplay + * @see #DISPLAY_CATEGORY_PRESENTATION + * @see Display#FLAG_PRESENTATION + */ + public static final int VIRTUAL_DISPLAY_FLAG_PRESENTATION = 1 << 1; + + /** + * Virtual display flag: Create a secure display. + * + * <h3>Secure virtual displays</h3> + * <p> + * When this flag is set, the virtual display is considered secure as defined + * by the {@link Display#FLAG_SECURE} display flag. The caller promises to take + * reasonable measures, such as over-the-air encryption, to prevent the contents + * of the display from being intercepted or recorded on a persistent medium. + * </p><p> + * Creating a secure virtual display requires the + * {@link android.Manifest.permission#CAPTURE_SECURE_VIDEO_OUTPUT} permission. + * This permission is reserved for use by system components and is not available to + * third-party applications. + * </p> + * + * <h3>Non-secure virtual displays</h3> + * <p> + * When this flag is not set, the virtual display is considered unsecure. + * The content of secure windows will be blanked if shown on this display. + * </p> + * + * @see Display#FLAG_SECURE for information about secure displays. + * @see #createVirtualDisplay + */ + public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 1 << 2; + /** @hide */ public DisplayManager(Context context) { mContext = context; @@ -130,12 +224,12 @@ public final class DisplayManager { synchronized (mLock) { try { if (category == null) { - addMatchingDisplaysLocked(mTempDisplays, displayIds, -1); + addAllDisplaysLocked(mTempDisplays, displayIds); } else if (category.equals(DISPLAY_CATEGORY_PRESENTATION)) { - addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI); - addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_HDMI); - addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY); - addMatchingDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_VIRTUAL); + addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_WIFI); + addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_HDMI); + addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_OVERLAY); + addPresentationDisplaysLocked(mTempDisplays, displayIds, Display.TYPE_VIRTUAL); } return mTempDisplays.toArray(new Display[mTempDisplays.size()]); } finally { @@ -144,12 +238,22 @@ public final class DisplayManager { } } - private void addMatchingDisplaysLocked( + private void addAllDisplaysLocked(ArrayList<Display> displays, int[] displayIds) { + for (int i = 0; i < displayIds.length; i++) { + Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/); + if (display != null) { + displays.add(display); + } + } + } + + private void addPresentationDisplaysLocked( ArrayList<Display> displays, int[] displayIds, int matchType) { for (int i = 0; i < displayIds.length; i++) { Display display = getOrCreateDisplayLocked(displayIds[i], true /*assumeValid*/); if (display != null - && (matchType < 0 || display.getType() == matchType)) { + && (display.getFlags() & Display.FLAG_PRESENTATION) != 0 + && display.getType() == matchType) { displays.add(display); } } @@ -277,23 +381,19 @@ public final class DisplayManager { } /** - * Creates a private virtual display. + * Creates a virtual display. * <p> * The content of a virtual display is rendered to a {@link Surface} provided - * by the application that created the virtual display. - * </p><p> - * Only the application that created a private virtual display is allowed to - * place windows upon it. The private virtual display also does not participate - * in display mirroring: it will neither receive mirrored content from another - * display nor allow its own content to be mirrored elsewhere. More precisely, - * the only processes that are allowed to enumerate or interact with a private - * display are those that have the same UID as the application that originally - * created the private virtual display. + * by the application. * </p><p> - * The private virtual display should be {@link VirtualDisplay#release released} - * when no longer needed. Because a private virtual display renders to a surface + * The virtual display should be {@link VirtualDisplay#release released} + * when no longer needed. Because a virtual display renders to a surface * provided by the application, it will be released automatically when the * process terminates and all remaining windows on it will be forcibly removed. + * </p><p> + * The behavior of the virtual display depends on the flags that are provided + * to this method. By default, virtual displays are created to be private, + * non-presentation and unsecure. Permissions may be required to use certain flags. * </p> * * @param name The name of the virtual display, must be non-empty. @@ -302,13 +402,19 @@ public final class DisplayManager { * @param densityDpi The density of the virtual display in dpi, must be greater than 0. * @param surface The surface to which the content of the virtual display should * be rendered, must be non-null. + * @param flags A combination of virtual display flags: + * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION} + * or {@link #VIRTUAL_DISPLAY_FLAG_SECURE}. * @return The newly created virtual display, or null if the application could * not create the virtual display. + * + * @throws SecurityException if the caller does not have permission to create + * a virtual display with the specified flags. */ - public VirtualDisplay createPrivateVirtualDisplay(String name, - int width, int height, int densityDpi, Surface surface) { - return mGlobal.createPrivateVirtualDisplay(mContext, - name, width, height, densityDpi, surface); + public VirtualDisplay createVirtualDisplay(String name, + int width, int height, int densityDpi, Surface surface, int flags) { + return mGlobal.createVirtualDisplay(mContext, + name, width, height, densityDpi, surface, flags); } /** diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java index 320185d906d8..10c14ff6c0fe 100644 --- a/core/java/android/hardware/display/DisplayManagerGlobal.java +++ b/core/java/android/hardware/display/DisplayManagerGlobal.java @@ -329,8 +329,8 @@ public final class DisplayManagerGlobal { } } - public VirtualDisplay createPrivateVirtualDisplay(Context context, String name, - int width, int height, int densityDpi, Surface surface) { + public VirtualDisplay createVirtualDisplay(Context context, String name, + int width, int height, int densityDpi, Surface surface, int flags) { if (TextUtils.isEmpty(name)) { throw new IllegalArgumentException("name must be non-null and non-empty"); } @@ -345,20 +345,20 @@ public final class DisplayManagerGlobal { Binder token = new Binder(); int displayId; try { - displayId = mDm.createPrivateVirtualDisplay(token, context.getPackageName(), - name, width, height, densityDpi, surface); + displayId = mDm.createVirtualDisplay(token, context.getPackageName(), + name, width, height, densityDpi, surface, flags); } catch (RemoteException ex) { - Log.e(TAG, "Could not create private virtual display: " + name, ex); + Log.e(TAG, "Could not create virtual display: " + name, ex); return null; } if (displayId < 0) { - Log.e(TAG, "Could not create private virtual display: " + name); + Log.e(TAG, "Could not create virtual display: " + name); return null; } Display display = getRealDisplay(displayId); if (display == null) { Log.wtf(TAG, "Could not obtain display info for newly created " - + "private virtual display: " + name); + + "virtual display: " + name); try { mDm.releaseVirtualDisplay(token); } catch (RemoteException ex) { diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl index cd4896a5c11f..afaf436fc187 100644 --- a/core/java/android/hardware/display/IDisplayManager.aidl +++ b/core/java/android/hardware/display/IDisplayManager.aidl @@ -48,9 +48,10 @@ interface IDisplayManager { // No permissions required. WifiDisplayStatus getWifiDisplayStatus(); - // No permissions required. - int createPrivateVirtualDisplay(IBinder token, String packageName, - String name, int width, int height, int densityDpi, in Surface surface); + // Requires CAPTURE_VIDEO_OUTPUT or CAPTURE_SECURE_VIDEO_OUTPUT for certain + // combinations of flags. + int createVirtualDisplay(IBinder token, String packageName, + String name, int width, int height, int densityDpi, in Surface surface, int flags); // No permissions required but must be same Uid as the creator. void releaseVirtualDisplay(in IBinder token); diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java index 145a217dbd27..908aadd5a314 100644 --- a/core/java/android/hardware/display/VirtualDisplay.java +++ b/core/java/android/hardware/display/VirtualDisplay.java @@ -21,7 +21,7 @@ import android.view.Display; /** * Represents a virtual display. * - * @see DisplayManager#createPrivateVirtualDisplay + * @see DisplayManager#createVirtualDisplay */ public final class VirtualDisplay { private final DisplayManagerGlobal mGlobal; diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 5f614b150ad8..354ea6613a39 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -149,14 +149,23 @@ public final class Display { /** * Display flag: Indicates that the display is private. Only the application that * owns the display can create windows on it. + * + * @see #getFlags + */ + public static final int FLAG_PRIVATE = 1 << 2; + + /** + * Display flag: Indicates that the display is a presentation display. * <p> - * This flag is associated with displays that were created using - * {@link android.hardware.display.DisplayManager#createPrivateVirtualDisplay}. + * This flag identifies secondary displays that are suitable for + * use as presentation displays such as HDMI or Wireless displays. Applications + * may automatically project their content to presentation displays to provide + * richer second screen experiences. * </p> * * @see #getFlags */ - public static final int FLAG_PRIVATE = 1 << 2; + public static final int FLAG_PRESENTATION = 1 << 3; /** * Display type: Unknown display type. diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 9a9c4cd3b4c0..8944207eb447 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -466,6 +466,9 @@ public final class DisplayInfo implements Parcelable { if ((flags & Display.FLAG_PRIVATE) != 0) { result.append(", FLAG_PRIVATE"); } + if ((flags & Display.FLAG_PRESENTATION) != 0) { + result.append(", FLAG_PRESENTATION"); + } return result.toString(); } } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 74d383f2b49b..a9a14ad8cf25 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2026,6 +2026,27 @@ android:description="@string/permdesc_controlWifiDisplay" android:protectionLevel="signature" /> + <!-- Allows an application to capture audio output. + <p>Not for use by third-party applications.</p> --> + <permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" + android:label="@string/permlab_captureAudioOutput" + android:description="@string/permdesc_captureAudioOutput" + android:protectionLevel="signature|system" /> + + <!-- Allows an application to capture video output. + <p>Not for use by third-party applications.</p> --> + <permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" + android:label="@string/permlab_captureVideoOutput" + android:description="@string/permdesc_captureVideoOutput" + android:protectionLevel="signature|system" /> + + <!-- Allows an application to capture secure video output. + <p>Not for use by third-party applications.</p> --> + <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT" + android:label="@string/permlab_captureSecureVideoOutput" + android:description="@string/permdesc_captureSecureVideoOutput" + android:protectionLevel="signature|system" /> + <!-- Required to be able to disable the device (very dangerous!). <p>Not for use by third-party applications.. --> <permission android:name="android.permission.BRICK" diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index a9d1c8615f8a..4830a19232b5 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1394,9 +1394,19 @@ <string name="permdesc_configureWifiDisplay">Allows the app to configure and connect to Wifi displays.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permlab_controlWifiDisplay">control Wifi displays</string> + <string name="permlab_captureAudioOutput">capture audio output</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permdesc_controlWifiDisplay">Allows the app to control low-level features of Wifi displays.</string> + <string name="permdesc_captureAudioOutput">Allows the app to capture and redirect audio output.</string> + + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_captureVideoOutput">capture video output</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_captureVideoOutput">Allows the app to capture and redirect video output.</string> + + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_captureSecureVideoOutput">capture secure video output</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_captureSecureVideoOutput">Allows the app to capture and redirect secure video output.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_modifyAudioSettings">change your audio settings</string> diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java index 11f8d6a3943e..11c5d879b498 100644 --- a/services/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/java/com/android/server/display/DisplayDeviceInfo.java @@ -73,6 +73,11 @@ final class DisplayDeviceInfo { public static final int FLAG_NEVER_BLANK = 1 << 5; /** + * Flag: Indicates that the display is suitable for presentations. + */ + public static final int FLAG_PRESENTATION = 1 << 6; + + /** * Touch attachment: Display does not receive touch. */ public static final int TOUCH_NONE = 0; @@ -289,6 +294,9 @@ final class DisplayDeviceInfo { if ((flags & FLAG_NEVER_BLANK) != 0) { msg.append(", FLAG_NEVER_BLANK"); } + if ((flags & FLAG_PRESENTATION) != 0) { + msg.append(", FLAG_PRESENTATION"); + } return msg.toString(); } } diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java index c339c26e51e5..19a11c0f4071 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -21,6 +21,7 @@ import com.android.internal.util.IndentingPrintWriter; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; +import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.IDisplayManager; import android.hardware.display.IDisplayManagerCallback; @@ -589,8 +590,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } @Override // Binder call - public int createPrivateVirtualDisplay(IBinder appToken, String packageName, - String name, int width, int height, int densityDpi, Surface surface) { + public int createVirtualDisplay(IBinder appToken, String packageName, + String name, int width, int height, int densityDpi, Surface surface, int flags) { final int callingUid = Binder.getCallingUid(); if (!validatePackageName(callingUid, packageName)) { throw new SecurityException("packageName must match the calling uid"); @@ -608,6 +609,25 @@ public final class DisplayManagerService extends IDisplayManager.Stub { if (surface == null) { throw new IllegalArgumentException("surface must not be null"); } + if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { + if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT) + != PackageManager.PERMISSION_GRANTED + && mContext.checkCallingPermission( + android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " + + "CAPTURE_SECURE_VIDEO_OUTPUT permission to create a " + + "public virtual display."); + } + } + if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { + if (mContext.checkCallingPermission( + android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT " + + "to create a secure virtual display."); + } + } final long token = Binder.clearCallingIdentity(); try { @@ -618,9 +638,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub { return -1; } - DisplayDevice device = mVirtualDisplayAdapter.createPrivateVirtualDisplayLocked( + DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked( appToken, callingUid, packageName, name, width, height, densityDpi, - surface); + surface, flags); if (device == null) { return -1; } @@ -632,7 +652,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } // Something weird happened and the logical display was not created. - Slog.w(TAG, "Rejecting request to create private virtual display " + Slog.w(TAG, "Rejecting request to create virtual display " + "because the logical display was not created."); mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); handleDisplayDeviceRemovedLocked(device); diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java index 475f27b83e29..cb8f3e20d368 100644 --- a/services/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/java/com/android/server/display/LocalDisplayAdapter.java @@ -155,6 +155,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL; } else { mInfo.type = Display.TYPE_HDMI; + mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION; mInfo.name = getContext().getResources().getString( com.android.internal.R.string.display_manager_hdmi_display_name); mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL; diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java index 775ebb235c29..b9839c27c9bd 100644 --- a/services/java/com/android/server/display/LogicalDisplay.java +++ b/services/java/com/android/server/display/LogicalDisplay.java @@ -205,6 +205,9 @@ final class LogicalDisplay { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0) { mBaseDisplayInfo.flags |= Display.FLAG_PRIVATE; } + if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRESENTATION) != 0) { + mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION; + } mBaseDisplayInfo.type = deviceInfo.type; mBaseDisplayInfo.address = deviceInfo.address; mBaseDisplayInfo.name = deviceInfo.name; diff --git a/services/java/com/android/server/display/OverlayDisplayAdapter.java b/services/java/com/android/server/display/OverlayDisplayAdapter.java index 315289730ce6..ce402a521162 100644 --- a/services/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/java/com/android/server/display/OverlayDisplayAdapter.java @@ -245,7 +245,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { mInfo.densityDpi = mDensityDpi; mInfo.xDpi = mDensityDpi; mInfo.yDpi = mDensityDpi; - mInfo.flags = 0; + mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION; if (mSecure) { mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE; } diff --git a/services/java/com/android/server/display/VirtualDisplayAdapter.java b/services/java/com/android/server/display/VirtualDisplayAdapter.java index 634fba7fcf19..3a71361949fe 100644 --- a/services/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/java/com/android/server/display/VirtualDisplayAdapter.java @@ -17,6 +17,7 @@ package com.android.server.display; import android.content.Context; +import android.hardware.display.DisplayManager; import android.os.Handler; import android.os.IBinder; import android.os.IBinder.DeathRecipient; @@ -46,12 +47,13 @@ final class VirtualDisplayAdapter extends DisplayAdapter { super(syncRoot, context, handler, listener, TAG); } - public DisplayDevice createPrivateVirtualDisplayLocked(IBinder appToken, + public DisplayDevice createVirtualDisplayLocked(IBinder appToken, int ownerUid, String ownerPackageName, - String name, int width, int height, int densityDpi, Surface surface) { - IBinder displayToken = SurfaceControl.createDisplay(name, false /*secure*/); + String name, int width, int height, int densityDpi, Surface surface, int flags) { + boolean secure = (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0; + IBinder displayToken = SurfaceControl.createDisplay(name, secure); VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken, - ownerUid, ownerPackageName, name, width, height, densityDpi, surface); + ownerUid, ownerPackageName, name, width, height, densityDpi, surface, flags); try { appToken.linkToDeath(device, 0); @@ -96,6 +98,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter { private final int mWidth; private final int mHeight; private final int mDensityDpi; + private final int mFlags; private boolean mReleased; private Surface mSurface; @@ -103,7 +106,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter { public VirtualDisplayDevice(IBinder displayToken, IBinder appToken, int ownerUid, String ownerPackageName, - String name, int width, int height, int densityDpi, Surface surface) { + String name, int width, int height, int densityDpi, Surface surface, int flags) { super(VirtualDisplayAdapter.this, displayToken); mAppToken = appToken; mOwnerUid = ownerUid; @@ -113,6 +116,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter { mHeight = height; mDensityDpi = densityDpi; mSurface = surface; + mFlags = flags; } @Override @@ -149,7 +153,17 @@ final class VirtualDisplayAdapter extends DisplayAdapter { mInfo.densityDpi = mDensityDpi; mInfo.xDpi = mDensityDpi; mInfo.yDpi = mDensityDpi; - mInfo.flags = DisplayDeviceInfo.FLAG_PRIVATE | DisplayDeviceInfo.FLAG_NEVER_BLANK; + mInfo.flags = 0; + if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) { + mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE | + DisplayDeviceInfo.FLAG_NEVER_BLANK; + } + if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { + mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE; + } + if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION) != 0) { + mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION; + } mInfo.type = Display.TYPE_VIRTUAL; mInfo.touch = DisplayDeviceInfo.TOUCH_NONE; mInfo.ownerUid = mOwnerUid; diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java index 4c80cf5c9fef..11d38190faab 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/java/com/android/server/display/WifiDisplayAdapter.java @@ -352,7 +352,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { } boolean secure = (flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0; - int deviceFlags = 0; + int deviceFlags = DisplayDeviceInfo.FLAG_PRESENTATION; if (secure) { deviceFlags |= DisplayDeviceInfo.FLAG_SECURE; if (mSupportsProtectedBuffers) { diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java index ccead44a6357..256f900ed5a7 100644 --- a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java +++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java @@ -197,8 +197,8 @@ public class DisplaySourceService extends Service { Surface surface = codec.createInputSurface(); codec.start(); - VirtualDisplay virtualDisplay = mDisplayManager.createPrivateVirtualDisplay( - DISPLAY_NAME, mWidth, mHeight, mDensityDpi, surface); + VirtualDisplay virtualDisplay = mDisplayManager.createVirtualDisplay( + DISPLAY_NAME, mWidth, mHeight, mDensityDpi, surface, 0); if (virtualDisplay != null) { mHandler.obtainMessage(MSG_DISPATCH_DISPLAY_ADDED, virtualDisplay.getDisplay()).sendToTarget(); |