Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd4750dd authored by Michael Wright's avatar Michael Wright Committed by Android Git Automerger
Browse files

am 97b2b671: Allow media projections to create public presentations.

* commit '97b2b67155910079d122ecb1d2bc69c42d8e24c4':
  Allow media projections to create public presentations.
parents af3dec5e 6720be4e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -13236,10 +13236,10 @@ package android.hardware.display {
    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_AUTO_MIRROR = 16; // 0x10
    field public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 8; // 0x8
    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_SCREEN_SHARE = 16; // 0x10
    field public static final int VIRTUAL_DISPLAY_FLAG_SECURE = 4; // 0x4
  }
@@ -16401,7 +16401,7 @@ package android.media.projection {
  public final class MediaProjection {
    method public void addCallback(android.media.projection.MediaProjection.Callback, android.os.Handler);
    method public android.media.AudioRecord createAudioRecord(int, int, int, int);
    method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, boolean, android.view.Surface, android.hardware.display.VirtualDisplay.Callbacks, android.os.Handler);
    method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, int, android.view.Surface, android.hardware.display.VirtualDisplay.Callbacks, android.os.Handler);
    method public void removeCallback(android.media.projection.MediaProjection.Callback);
    method public void stop();
  }
+38 −15
Original line number Diff line number Diff line
@@ -96,11 +96,9 @@ public final class DisplayManager {
     * 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.
     * Creating a public virtual display that isn't restricted to own-content only implicitly
     * creates an auto-mirroring display. See {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR} for
     * restrictions on who is allowed to create an auto-mirroring display.
     * </p>
     *
     * <h3>Private virtual displays</h3>
@@ -108,6 +106,8 @@ public final class DisplayManager {
     * When this flag is not set, the virtual display is private as defined by the
     * {@link Display#FLAG_PRIVATE} display flag.
     * </p>
     *
     * <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
@@ -119,6 +119,7 @@ public final class DisplayManager {
     *
     * @see #createVirtualDisplay
     * @see #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
     * @see #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
     */
    public static final int VIRTUAL_DISPLAY_FLAG_PUBLIC = 1 << 0;

@@ -187,29 +188,51 @@ public final class DisplayManager {
     * will be blanked instead if it has no windows.
     * </p>
     *
     * <p>
     * This flag is mutually exclusive with {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}.  If both
     * flags are specified then the own-content only behavior will be applied.
     * </p>
     *
     * <p>
     * This behavior of this flag is implied whenever neither {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}
     * nor {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR} have been set.  This flag is only required to
     * override the default behavior when creating a public display.
     * </p>
     *
     * @see #createVirtualDisplay
     */
    public static final int VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY = 1 << 3;


    /**
     * Virtual display flag: Indicates that the display is being created for
     * the purpose of screen sharing.  This implies
     * VIRTUAL_DISPLAY_FLAG_PRIVATE.  Other flags are not allowed (especially
     * not VIRTUAL_DISPLAY_FLAG_PUBLIC or PRESENTATION).
     * Virtual display flag: Allows content to be mirrored on private displays when no content is
     * being shown.
     *
     * <p>
     * This flag is mutually exclusive with {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}.
     * If both flags are specified then the own-content only behavior will be applied.
     * </p>
     *
     * <p>
     * Requires screen share permission for use.
     * The behavior of this flag is implied whenever {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC} is set
     * and {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY} has not been set.   This flag is only
     * required to override the default behavior when creating a private display.
     * </p>
     *
     * <p>
     * While a display of this type exists, the system will show some sort of
     * notification to the user indicating that the screen is being shared.
     * Creating an auto-mirroing 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.
     *
     * Alternatively, an appropriate {@link MediaProjection} may be used to create an
     * auto-mirroring virtual display.
     * </p>
     *
     * @see #createVirtualDisplay
     */
    public static final int VIRTUAL_DISPLAY_FLAG_SCREEN_SHARE = 1 << 4;
    public static final int VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR = 1 << 4;

    /** @hide */
    public DisplayManager(Context context) {
@@ -489,7 +512,7 @@ public final class DisplayManager {
     * @param flags A combination of virtual display flags:
     * {@link #VIRTUAL_DISPLAY_FLAG_PUBLIC}, {@link #VIRTUAL_DISPLAY_FLAG_PRESENTATION},
     * {@link #VIRTUAL_DISPLAY_FLAG_SECURE}, {@link #VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY},
     * or {@link #VIRTUAL_DISPLAY_FLAG_SCREEN_SHARE}.
     * or {@link #VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}.
     * @param callbacks Callbacks to call when the state of the {@link VirtualDisplay} changes
     * @param handler The handler on which the listener should be invoked, or null
     * if the listener should be invoked on the calling thread's looper.
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ interface IMediaProjection {
    boolean canProjectAudio();
    boolean canProjectVideo();
    boolean canProjectSecureVideo();
    int getVirtualDisplayFlags();
    int applyVirtualDisplayFlags(int flags);
    void addCallback(IMediaProjectionCallback callback);
    void removeCallback(IMediaProjectionCallback callback);
}
+16 −5
Original line number Diff line number Diff line
@@ -92,6 +92,19 @@ public final class MediaProjection {
        mCallbacks.remove(callback);
    }

    /**
     * @hide
     */
    public VirtualDisplay createVirtualDisplay(@NonNull String name,
            int width, int height, int dpi, boolean isSecure, @Nullable Surface surface,
            @Nullable VirtualDisplay.Callbacks callbacks, @Nullable Handler handler) {
        DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
        int flags = isSecure ? DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE : 0;
        return dm.createVirtualDisplay(this, name, width, height, dpi, surface,
                    flags | DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR |
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION, callbacks, handler);
    }

    /**
     * Creates a {@link android.hardware.display.VirtualDisplay} to capture the
     * contents of the screen.
@@ -105,9 +118,8 @@ public final class MediaProjection {
     * than 0.
     * @param surface The surface to which the content of the virtual display
     * should be rendered, or null if there is none initially.
     * @param isSecure Whether the display should be considered a secure
     * display. This typically requires special permissions not available to
     * third party applications.
     * @param flags A combination of virtual display flags. See {@link DisplayManager} for the full
     * list of flags.
     * @param callbacks Callbacks to call when the virtual display's state
     * changes, or null if none.
     * @param handler The {@link android.os.Handler} on which the callback should be
@@ -118,10 +130,9 @@ public final class MediaProjection {
     * String, int, int, int, int, Surface, VirtualDisplay.Callbacks, Handler)
     */
    public VirtualDisplay createVirtualDisplay(@NonNull String name,
            int width, int height, int dpi, boolean isSecure, @Nullable Surface surface,
            int width, int height, int dpi, int flags, @Nullable Surface surface,
            @Nullable VirtualDisplay.Callbacks callbacks, @Nullable Handler handler) {
        DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
        int flags = isSecure ? DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE : 0;
        return dm.createVirtualDisplay(
                    this, name, width, height, dpi, surface, flags, callbacks, handler);
    }
+11 −23
Original line number Diff line number Diff line
@@ -1269,28 +1269,26 @@ public final class DisplayManagerService extends SystemService {
                        + "greater than 0");
            }

            if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
                flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
            }
            if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) {
                flags &= ~DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
            }

            if (projection != null) {
                try {
                    if (!getProjectionService().isValidMediaProjection(projection)) {
                        throw new SecurityException("Invalid media projection");
                    }
                    flags = projection.applyVirtualDisplayFlags(flags);
                } catch (RemoteException e) {
                    throw new SecurityException("unable to validate media projection");
                }
                flags &= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
                try {
                    flags |= projection.getVirtualDisplayFlags();
                } catch (RemoteException e) {
                    throw new RuntimeException("unable to retrieve media projection flags");
                    throw new SecurityException("unable to validate media projection or flags");
                }
            }

            if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SCREEN_SHARE) != 0) {
                if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0 ||
                        (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION) != 0) {
                    throw new IllegalArgumentException("screen sharing virtual displays must not "
                            + "be public or presentation displays");
                }
            if (callingUid != Process.SYSTEM_UID &&
                    (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) {
                if (!canProjectVideo(projection)) {
                    throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
                            + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
@@ -1298,16 +1296,6 @@ public final class DisplayManagerService extends SystemService {
                            + "display.");
                }
            }


            if (callingUid != Process.SYSTEM_UID &&
                    (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) {
                if (!canProjectVideo(projection)) {
                    throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or "
                            + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate "
                            + "MediaProjection token to create a public virtual display.");
                }
            }
            if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) {
                if (!canProjectSecureVideo(projection)) {
                    throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT "
Loading