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

Commit 1465cf7f authored by Marvin Ramin's avatar Marvin Ramin
Browse files

Update MediaProjection documentation to mention onStop() reasons

Clearly call out that MediaProjection#Callback#onStop() can be called due to the system and/or the user stopping MediaProjection due to various reasons.

Bug: 352133031
Change-Id: Ifc1c8be955cb7bd46c5aa71335424799c1a5b282
Test: n/a
Flag: DOCS_ONLY
parent 8c3bc196
Loading
Loading
Loading
Loading
+91 −91
Original line number Diff line number Diff line
@@ -91,18 +91,19 @@ public final class MediaProjection {
    }

  /**
     * Register a listener to receive notifications about when the {@link MediaProjection} or
     * captured content changes state.
   * Register a listener to receive notifications about when the {@link MediaProjection} or captured
   * content changes state.
   *
     * <p>The callback must be registered before invoking
     * {@link #createVirtualDisplay(String, int, int, int, int, Surface, VirtualDisplay.Callback,
     * Handler)} to ensure that any notifications on the callback are not missed. The client must
     * implement {@link Callback#onStop()} and clean up any resources it is holding, e.g. the
     * {@link VirtualDisplay} and {@link Surface}.
   * <p>The callback must be registered before invoking {@link #createVirtualDisplay(String, int,
   * int, int, int, Surface, VirtualDisplay.Callback, Handler)} to ensure that any notifications on
   * the callback are not missed. The client must implement {@link Callback#onStop()} and clean up
   * any resources it is holding, e.g. the {@link VirtualDisplay} and {@link Surface}. This should
   * also update any application UI indicating the MediaProjection status as MediaProjection has
   * stopped.
   *
   * @param callback The callback to call.
     * @param handler  The handler on which the callback should be invoked, or
     *                 null if the callback should be invoked on the calling thread's looper.
   * @param handler The handler on which the callback should be invoked, or null if the callback
   *     should be invoked on the calling thread's looper.
   * @throws NullPointerException If the given callback is null.
   * @see #unregisterCallback
   */
@@ -159,72 +160,65 @@ public final class MediaProjection {
    }

  /**
     * Creates a {@link android.hardware.display.VirtualDisplay} to capture the
     * contents of the screen.
   * Creates a {@link android.hardware.display.VirtualDisplay} to capture the contents of the
   * screen.
   *
   * <p>To correctly clean up resources associated with a capture, the application must register a
     * {@link Callback} before invocation. The app must override {@link Callback#onStop()} to clean
     * up (by invoking{@link VirtualDisplay#release()}, {@link Surface#release()} and related
     * resources).
   * {@link Callback} before invocation. The app must override {@link Callback#onStop()} to clean up
   * resources (by invoking{@link VirtualDisplay#release()}, {@link Surface#release()} and related
   * resources) and to update any available UI regarding the MediaProjection status.
   *
   * @param name The name of the virtual display, must be non-empty.
   * @param width The width of the virtual display in pixels. Must be greater than 0.
   * @param height The height of the virtual display in pixels. Must be greater than 0.
   * @param dpi 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,
     *                 or null if there is none initially.
     * @param flags    A combination of virtual display flags. See {@link DisplayManager} for the
     *                 full list of flags. Note that
     *                 {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PRESENTATION}
     *                 is always enabled. The following flags may be overridden, depending on how
     *                 the component with {android.Manifest.permission.MANAGE_MEDIA_PROJECTION}
     *                 handles the user's consent:
     *                 {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY},
     *                 {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR},
     *                 {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC}.
   * @param surface The surface to which the content of the virtual display should be rendered, or
   *     null if there is none initially.
   * @param flags A combination of virtual display flags. See {@link DisplayManager} for the full
   *     list of flags. Note that {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PRESENTATION} is always
   *     enabled. The following flags may be overridden, depending on how the component with
   *     {android.Manifest.permission.MANAGE_MEDIA_PROJECTION} handles the user's consent: {@link
   *     DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}, {@link
   *     DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR}, {@link
   *     DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC}.
   * @param callback Callback invoked when the virtual display's state changes, or null.
     * @param handler  The {@link android.os.Handler} on which the callback should be invoked, or
     *                 null if the callback should be invoked on the calling thread's main
     *                 {@link android.os.Looper}.
   * @param handler The {@link android.os.Handler} on which the callback should be invoked, or null
   *     if the callback should be invoked on the calling thread's main {@link android.os.Looper}.
   * @throws IllegalStateException If the target SDK is {@link
     *                               android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and up, and
     *                               if no {@link Callback} is registered.
   *     android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and up, and if no {@link Callback} is
   *     registered.
   * @throws SecurityException In any of the following scenarios:
   *     <ol>
     *                                 <li>If attempting to create a new virtual display
     *                                 associated with this MediaProjection instance after it has
     *                                 been stopped by invoking {@link #stop()}.
     *                                 <li>If attempting to create a new virtual display
     *                                 associated with this MediaProjection instance after a
     *                                 {@link MediaProjection.Callback#onStop()} callback has been
     *                                 received due to the user or the system stopping the
     *                                 MediaProjection session.
     *                                 <li>If the target SDK is {@link
     *                                 android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and up,
     *                                 and if this instance has already taken a recording through
     *                                 {@code #createVirtualDisplay}, but {@link #stop()} wasn't
     *                                 invoked to end the recording.
     *                                 <li>If the target SDK is {@link
     *                                 android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and up,
     *                                 and if {@link MediaProjectionManager#getMediaProjection}
     *                                 was invoked more than once to get this
     *                                 {@code MediaProjection} instance.
   *       <li>If attempting to create a new virtual display associated with this MediaProjection
   *           instance after it has been stopped by invoking {@link #stop()}.
   *       <li>If attempting to create a new virtual display associated with this MediaProjection
   *           instance after a {@link MediaProjection.Callback#onStop()} callback has been received
   *           due to the user or the system stopping the MediaProjection session.
   *       <li>If the target SDK is {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and
   *           up, and if this instance has already taken a recording through {@code
   *           #createVirtualDisplay}, but {@link #stop()} wasn't invoked to end the recording.
   *       <li>If the target SDK is {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U} and
   *           up, and if {@link MediaProjectionManager#getMediaProjection} was invoked more than
   *           once to get this {@code MediaProjection} instance.
   *     </ol>
     *                               In cases 2 & 3, no exception is thrown if the target SDK is
     *                               less than
     *                               {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U}.
     *                               Instead, recording doesn't begin until the user re-grants
     *                               consent in the dialog.
     * @return The created {@link VirtualDisplay}, or {@code null} if no {@link VirtualDisplay}
     * could be created.
   *     In cases 2 & 3, no exception is thrown if the target SDK is less than {@link
   *     android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U}. Instead, recording doesn't begin until
   *     the user re-grants consent in the dialog.
   * @return The created {@link VirtualDisplay}, or {@code null} if no {@link VirtualDisplay} could
   *     be created.
   * @see VirtualDisplay
   * @see VirtualDisplay.Callback
   */
  @SuppressWarnings("RequiresPermission")
  @Nullable
    public VirtualDisplay createVirtualDisplay(@NonNull String name,
            int width, int height, int dpi, @VirtualDisplayFlag int flags,
            @Nullable Surface surface, @Nullable VirtualDisplay.Callback callback,
  public VirtualDisplay createVirtualDisplay(
      @NonNull String name,
      int width,
      int height,
      int dpi,
      @VirtualDisplayFlag int flags,
      @Nullable Surface surface,
      @Nullable VirtualDisplay.Callback callback,
      @Nullable Handler handler) {
        if (shouldMediaProjectionRequireCallback()) {
            if (mCallbacks.isEmpty()) {
@@ -322,12 +316,18 @@ public final class MediaProjection {
         * Called when the MediaProjection session is no longer valid.
         *
         * <p>Once a MediaProjection has been stopped, it's up to the application to release any
         * resources it may be holding (e.g. releasing the {@link VirtualDisplay} and
         * {@link Surface}).
         * resources it may be holding (e.g. releasing the {@link VirtualDisplay} and {@link
         * Surface}). If the application is displaying any UI indicating the MediaProjection state
         * it should be updated to indicate that MediaProjection is no longer active.
         *
         * <p>MediaProjection stopping can be a result of the system stopping the ongoing
         * MediaProjection due to various reasons, such as another MediaProjection session starting.
         * MediaProjection may also stop due to the user explicitly stopping ongoing MediaProjection
         * via any available system-level UI.
         *
         * <p>After this callback any call to
         * {@link MediaProjection#createVirtualDisplay} will fail, even if no such
         * {@link VirtualDisplay} was ever created for this MediaProjection session.
         * <p>After this callback any call to {@link MediaProjection#createVirtualDisplay} will
         * fail, even if no such {@link VirtualDisplay} was ever created for this MediaProjection
         * session.
         */
        public void onStop() {}

+3 −1
Original line number Diff line number Diff line
@@ -64,7 +64,9 @@ import java.util.Map;
 *       holding, e.g. the {@link VirtualDisplay} and {@link Surface}. The MediaProjection may
 *       further no longer create any new {@link VirtualDisplay}s via {@link
 *       MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface,
 *       VirtualDisplay.Callback, Handler)}.
 *       VirtualDisplay.Callback, Handler)}. Note that the `onStop()` callback can be a result of
 *       the system stopping MediaProjection due to various reasons or the user stopping the
 *       MediaProjection via UI affordances in system-level UI.
 *   <li>Start the screen capture session for media projection by calling {@link
 *       MediaProjection#createVirtualDisplay(String, int, int, int, int, Surface,
 *       android.hardware.display.VirtualDisplay.Callback, Handler)}.