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

Commit 8f1b73e1 authored by Mark Renouf's avatar Mark Renouf
Browse files

Long screenshots framework update and API unhide

This change includes a series of API review changes. The most
significant update is the addition of cancellation signals to
API methods where needed.

Renames some internal classes and interfaces to support the
API changes and to simplify tests and improve quality.

Test: numerous presubmits
Bug: 175830670
CTS-Coverage-Bug: 180419562
Change-Id: I9b1b950a2779fc902ecf4d6394e3c35171926700
parent 05944984
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -48037,6 +48037,32 @@ package android.view {
    method public void onScaleEnd(android.view.ScaleGestureDetector);
  }
  @UiThread public interface ScrollCaptureCallback {
    method public void onScrollCaptureEnd(@NonNull Runnable);
    method public void onScrollCaptureImageRequest(@NonNull android.view.ScrollCaptureSession, @NonNull android.os.CancellationSignal, @NonNull android.graphics.Rect, @NonNull java.util.function.Consumer<android.graphics.Rect>);
    method public void onScrollCaptureSearch(@NonNull android.os.CancellationSignal, @NonNull java.util.function.Consumer<android.graphics.Rect>);
    method public void onScrollCaptureStart(@NonNull android.view.ScrollCaptureSession, @NonNull android.os.CancellationSignal, @NonNull Runnable);
  }
  public class ScrollCaptureSession {
    ctor public ScrollCaptureSession(@NonNull android.view.Surface, @NonNull android.graphics.Rect, @NonNull android.graphics.Point);
    method @NonNull public android.graphics.Point getPositionInWindow();
    method @NonNull public android.graphics.Rect getScrollBounds();
    method @NonNull public android.view.Surface getSurface();
  }
  public final class ScrollCaptureTarget {
    ctor public ScrollCaptureTarget(@NonNull android.view.View, @NonNull android.graphics.Rect, @NonNull android.graphics.Point, @NonNull android.view.ScrollCaptureCallback);
    method @NonNull public android.view.ScrollCaptureCallback getCallback();
    method @NonNull public android.view.View getContainingView();
    method public int getHint();
    method @NonNull public android.graphics.Rect getLocalVisibleRect();
    method @NonNull public android.graphics.Point getPositionInWindow();
    method @Nullable public android.graphics.Rect getScrollBounds();
    method public void setScrollBounds(@Nullable android.graphics.Rect);
    method @UiThread public void updatePositionInWindow();
  }
  public class SearchEvent {
    ctor public SearchEvent(android.view.InputDevice);
    method public android.view.InputDevice getInputDevice();
@@ -48363,6 +48389,7 @@ package android.view {
    method public void dispatchProvideStructure(android.view.ViewStructure);
    method protected void dispatchRestoreInstanceState(android.util.SparseArray<android.os.Parcelable>);
    method protected void dispatchSaveInstanceState(android.util.SparseArray<android.os.Parcelable>);
    method public void dispatchScrollCaptureSearch(@NonNull android.graphics.Rect, @NonNull android.graphics.Point, @NonNull java.util.function.Consumer<android.view.ScrollCaptureTarget>);
    method protected void dispatchSetActivated(boolean);
    method protected void dispatchSetPressed(boolean);
    method protected void dispatchSetSelected(boolean);
@@ -48522,6 +48549,7 @@ package android.view {
    method public int getScrollBarFadeDuration();
    method public int getScrollBarSize();
    method public int getScrollBarStyle();
    method public int getScrollCaptureHint();
    method public int getScrollIndicators();
    method public final int getScrollX();
    method public final int getScrollY();
@@ -48690,6 +48718,7 @@ package android.view {
    method public void onRtlPropertiesChanged(int);
    method @CallSuper @Nullable protected android.os.Parcelable onSaveInstanceState();
    method public void onScreenStateChanged(int);
    method public void onScrollCaptureSearch(@NonNull android.graphics.Rect, @NonNull android.graphics.Point, @NonNull java.util.function.Consumer<android.view.ScrollCaptureTarget>);
    method protected void onScrollChanged(int, int, int, int);
    method protected boolean onSetAlpha(int);
    method protected void onSizeChanged(int, int, int, int);
@@ -48872,6 +48901,8 @@ package android.view {
    method public void setScrollBarFadeDuration(int);
    method public void setScrollBarSize(int);
    method public void setScrollBarStyle(int);
    method public final void setScrollCaptureCallback(@Nullable android.view.ScrollCaptureCallback);
    method public void setScrollCaptureHint(int);
    method public void setScrollContainer(boolean);
    method public void setScrollIndicators(int);
    method public void setScrollIndicators(int, int);
@@ -49050,6 +49081,10 @@ package android.view {
    field public static final int SCROLL_AXIS_HORIZONTAL = 1; // 0x1
    field public static final int SCROLL_AXIS_NONE = 0; // 0x0
    field public static final int SCROLL_AXIS_VERTICAL = 2; // 0x2
    field public static final int SCROLL_CAPTURE_HINT_AUTO = 0; // 0x0
    field public static final int SCROLL_CAPTURE_HINT_EXCLUDE = 1; // 0x1
    field public static final int SCROLL_CAPTURE_HINT_EXCLUDE_DESCENDANTS = 4; // 0x4
    field public static final int SCROLL_CAPTURE_HINT_INCLUDE = 2; // 0x2
    field public static final int SCROLL_INDICATOR_BOTTOM = 2; // 0x2
    field public static final int SCROLL_INDICATOR_END = 32; // 0x20
    field public static final int SCROLL_INDICATOR_LEFT = 4; // 0x4
@@ -49834,6 +49869,7 @@ package android.view {
    method public abstract boolean performContextMenuIdentifierAction(int, int);
    method public abstract boolean performPanelIdentifierAction(int, int, int);
    method public abstract boolean performPanelShortcut(int, int, android.view.KeyEvent, int);
    method public void registerScrollCaptureCallback(@NonNull android.view.ScrollCaptureCallback);
    method public final void removeOnFrameMetricsAvailableListener(android.view.Window.OnFrameMetricsAvailableListener);
    method public boolean requestFeature(int);
    method @NonNull public final <T extends android.view.View> T requireViewById(@IdRes int);
@@ -49913,6 +49949,7 @@ package android.view {
    method public abstract void takeKeyEvents(boolean);
    method public abstract void takeSurface(android.view.SurfaceHolder.Callback2);
    method public abstract void togglePanel(int, android.view.KeyEvent);
    method public void unregisterScrollCaptureCallback(@NonNull android.view.ScrollCaptureCallback);
    field public static final int DECOR_CAPTION_SHADE_AUTO = 0; // 0x0
    field public static final int DECOR_CAPTION_SHADE_DARK = 2; // 0x2
    field public static final int DECOR_CAPTION_SHADE_LIGHT = 1; // 0x1
+15 −21
Original line number Diff line number Diff line
@@ -16,12 +16,10 @@

package android.view;

import android.graphics.Point;
import android.graphics.Rect;
import android.view.ScrollCaptureResponse;
import android.view.Surface;

import android.view.IScrollCaptureConnection;

/**
 * Asynchronous callback channel for responses to scroll capture requests.
 *
@@ -29,34 +27,30 @@ import android.view.IScrollCaptureConnection;
 */
interface IScrollCaptureCallbacks {
    /**
     * Scroll capture is available, and a connection has been provided.
     * Provides the result of WindowManagerService#requestScrollCapture
     *
     * @param connection a connection to a window process and scrollable content
     * @param scrollAreaInWindow the location of scrolling in global (window) coordinate space
     * @param response the response which describes the result
     */
    oneway void onConnected(in IScrollCaptureConnection connection, in Rect scrollBounds,
            in Point positionInWindow);
    oneway void onScrollCaptureResponse(in ScrollCaptureResponse response);

    /**
     * The window does not support scroll capture.
     */
    oneway void onUnavailable();

    /**
     * Called when the remote end has confirmed the request and is ready to begin providing image
     * requests.
     * Called in reply to IScrollCaptureConnection#startCapture, when the remote end has confirmed
     * the request and is ready to begin capturing images.
     */
    oneway void onCaptureStarted();

    /**
     * Received a response from a capture request.
     * Received a response from a capture request. The provided rectangle indicates the portion
     * of the requested rectangle which was captured. An empty rectangle indicates that the request
     * could not be satisfied (most commonly due to the available scrolling range).
     *
     * @param flags flags describing additional status of the result
     * @param capturedArea the actual area of the image captured
     */
    oneway void onCaptureBufferSent(long frameNumber, in Rect capturedArea);
    oneway void onImageRequestCompleted(int flags, in Rect capturedArea);

    /**
     * Signals that the capture session has completed and the target window may be returned to
     * normal interactive use. This may be due to normal shutdown, or after a timeout or other
     * unrecoverable state change such as activity lifecycle, window visibility or focus.
     * Signals that the capture session has completed and the target window is ready for normal use.
     */
    oneway void onConnectionClosed();
    oneway void onCaptureEnded();
}
+23 −11
Original line number Diff line number Diff line
@@ -17,33 +17,45 @@
package android.view;

import android.graphics.Rect;
import android.os.ICancellationSignal;
import android.view.Surface;


 /**
   * Interface implemented by a client of the Scroll Capture framework to receive requests
   * to start, capture images and end the session.
   * A remote connection to a scroll capture target.
   *
   * {@hide}
   */
interface IScrollCaptureConnection {

    /**
     * Informs the client that it has been selected for scroll capture and should prepare to
     * to begin handling capture requests.
     * Informs the target that it has been selected for scroll capture.
     *
     * @param surface a return channel for image buffers
     *
     * @return a cancallation signal which is used cancel the request
     */
    ICancellationSignal startCapture(in Surface surface);

    /**
     * Request the target capture an image within the provided rectangle.
     *
     * @param surface a return channel for image buffers
     * @param signal a cancallation signal which can interrupt the request
     *
     * @return a cancallation signal which is used cancel the request
     */
    oneway void startCapture(in Surface surface);
    ICancellationSignal requestImage(in Rect captureArea);

    /**
     * Request the client capture an image within the provided rectangle.
     * Inform the target that capture has ended.
     *
     * @see android.view.ScrollCaptureCallback#onScrollCaptureRequest
     * @return a cancallation signal which is used cancel the request
     */
    oneway void requestImage(in Rect captureArea);
    ICancellationSignal endCapture();

    /**
     * Inform the client that capture has ended. The client should shut down and release all
     * local resources in use and prepare for return to normal interactive usage.
     * Closes the connection.
     */
    oneway void endCapture();
    oneway void close();
}
+53 −50
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.view;
import android.annotation.NonNull;
import android.annotation.UiThread;
import android.graphics.Rect;
import android.os.CancellationSignal;

import java.util.function.Consumer;

@@ -58,8 +59,6 @@ import java.util.function.Consumer;
 * @see View#setScrollCaptureHint(int)
 * @see View#setScrollCaptureCallback(ScrollCaptureCallback)
 * @see Window#registerScrollCaptureCallback(ScrollCaptureCallback)
 *
 * @hide
 */
@UiThread
public interface ScrollCaptureCallback {
@@ -68,80 +67,84 @@ public interface ScrollCaptureCallback {
     * The system is searching for the appropriate scrolling container to capture and would like to
     * know the size and position of scrolling content handled by this callback.
     * <p>
     * Implementations should inset {@code containingViewBounds} to cover only the area within the
     * containing view where scrolling content may be positioned. This should cover only the content
     * which tracks with scrolling movement.
     * <p>
     * Return the updated rectangle to {@code resultConsumer}. If for any reason the scrolling
     * content is not available to capture, a {@code null} rectangle may be returned, and this view
     * will be excluded as the target for this request.
     * To determine scroll bounds, an implementation should inset the visible bounds of the
     * containing view to cover only the area where scrolling content may be positioned. This
     * should cover only the content which tracks with scrolling movement.
     * <p>
     * Responses received after XXXms will be discarded.
     * Return the updated rectangle to {@link Consumer#accept onReady.accept}. If for any reason the
     * scrolling content is not available to capture, a empty rectangle may be returned which will
     * exclude this view from consideration.
     * <p>
     * TODO: finalize timeout
     * This request may be cancelled via the provided {@link CancellationSignal}. When this happens,
     * any future call to {@link Consumer#accept onReady.accept} will have no effect and this
     * content will be omitted from the search results.
     *
     * @param signal  signal to cancel the operation in progress
     * @param onReady consumer for the updated rectangle
     */
    void onScrollCaptureSearch(@NonNull Consumer<Rect> onReady);
    void onScrollCaptureSearch(@NonNull CancellationSignal signal, @NonNull Consumer<Rect> onReady);

    /**
     * Scroll Capture has selected this callback to provide the scrolling image content.
     * <p>
     * The onReady signal should be called when ready to begin handling image requests.
     * {@link Runnable#run onReady.run} should be called when ready to begin handling image
     * requests.
     * <p>
     * This request may be cancelled via the provided {@link CancellationSignal}. When this happens,
     * any future call to {@link Runnable#run onReady.run} will have no effect and provided session
     * will not be activated.
     *
     * @param session the current session, resources provided by it are valid for use until the
     *                {@link #onScrollCaptureEnd(Runnable) session ends}
     * @param signal  signal to cancel the operation in progress
     * @param onReady signal used to report completion of the request
     */
    void onScrollCaptureStart(@NonNull ScrollCaptureSession session, @NonNull Runnable onReady);
    void onScrollCaptureStart(@NonNull ScrollCaptureSession session,
            @NonNull CancellationSignal signal, @NonNull Runnable onReady);

    /**
     * An image capture has been requested from the scrolling content.
     * <p>
     * <code>captureArea</code> contains the bounds of the image requested, relative to the
     * rectangle provided by {@link ScrollCaptureCallback#onScrollCaptureSearch}, referred to as
     * {@code scrollBounds}.
     * here.
     * <p>
     * A series of requests will step by a constant vertical amount relative to {@code
     * scrollBounds}, moving through the scrolling range of content, above and below the current
     * visible area. The rectangle's vertical position will not account for any scrolling movement
     * since capture started. Implementations therefore must track any scroll position changes and
     * subtract this distance from requests.
     * The requested rectangle describes an area inside the target view, relative to
     * <code>scrollBounds</code>. The content may be offscreen, above or below the current visible
     * portion of the target view. To handle the request, render the available portion of this
     * rectangle to a buffer and return it via the Surface available from {@link
     * ScrollCaptureSession#getSurface()}.
     * <p>
     * To handle a request, the content should be scrolled to maximize the visible area of the
     * requested rectangle. Offset {@code captureArea} again to account for any further scrolling.
     * Note: Implementations are only required to render the requested content, and may do so into
     * off-screen buffers without scrolling if they are able.
     * <p>
     * Finally, clip this rectangle against scrollBounds to determine what portion, if any is
     * visible content to capture. If the rectangle is completely clipped, set it to {@link
     * Rect#setEmpty() empty} and skip the next step.
     * <p>
     * Make a copy of {@code captureArea}, transform to window coordinates and draw the window,
     * clipped to this rectangle, into the {@link ScrollCaptureSession#getSurface() surface} at
     * offset (0,0).
     * <p>
     * Finally, return the resulting {@code captureArea} using
     * {@link ScrollCaptureSession#notifyBufferSent}.
     * <p>
     * If the response is not supplied within XXXms, the session will end with a call to {@link
     * #onScrollCaptureEnd}, after which {@code session} is invalid and should be discarded.
     * <p>
     * TODO: finalize timeout
     * The resulting available portion of the request must be computed as a portion of {@code
     * captureArea}, and sent to signal the operation is complete, using  {@link Consumer#accept
     * onComplete.accept}. If the requested rectangle is  partially or fully out of bounds the
     * resulting portion should be returned. If no portion is available (outside of available
     * content), then skip sending any buffer and report an empty Rect as result.
     * <p>
     * This request may be cancelled via the provided {@link CancellationSignal}. When this happens,
     * any future call to {@link Consumer#accept onComplete.accept} will be ignored until the next
     * request.
     *
     * @param session the current session, resources provided by it are valid for use until the
     *                {@link #onScrollCaptureEnd(Runnable) session ends}
     * @param signal      signal to cancel the operation in progress
     * @param captureArea the area to capture, a rectangle within {@code scrollBounds}
     * @param onComplete  a consumer for the captured area
     */
    void onScrollCaptureImageRequest(
            @NonNull ScrollCaptureSession session, @NonNull Rect captureArea);
    void onScrollCaptureImageRequest(@NonNull ScrollCaptureSession session,
            @NonNull CancellationSignal signal, @NonNull Rect captureArea,
            @NonNull Consumer<Rect> onComplete);

    /**
     * Signals that capture has ended. Implementations should release any temporary resources or
     * references to objects in use during the capture. Any resources obtained from the session are
     * now invalid and attempts to use them after this point may throw an exception.
     * <p>
     * The window should be returned as much as possible to its original state when capture started.
     * At a minimum, the content should be scrolled to its original position.
     * <p>
     * <code>onReady</code> should be called when the window should be made visible and
     * interactive. The system will wait up to XXXms for this call before proceeding.
     * The window should be returned to its original state when capture started. At a minimum, the
     * content should be scrolled to its original position.
     * <p>
     * TODO: finalize timeout
     * {@link Runnable#run onReady.run} should be called as soon as possible after the window is
     * ready for normal interactive use. After the callback (or after a timeout, if not called) the
     * screenshot tool will be dismissed and the window may become visible to the user at any time.
     *
     * @param onReady a callback to inform the system that the application has completed any
     *                cleanup and is ready to become visible
+192 −181

File changed.

Preview size limit exceeded, changes collapsed.

Loading