1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.view;
18 
19 import android.annotation.NonNull;
20 import android.annotation.UiThread;
21 import android.graphics.Rect;
22 
23 import java.util.function.Consumer;
24 
25 /**
26  * A ScrollCaptureCallback is responsible for providing rendered snapshots of scrolling content for
27  * the scroll capture system. A single callback is responsible for providing support to a single
28  * scrolling UI element. At request time, the system will select the best candidate from among all
29  * callbacks registered within the window.
30  * <p>
31  * A callback is assigned to a View using {@link View#setScrollCaptureCallback}, or to the window as
32  * {@link Window#addScrollCaptureCallback}. The point where the callback is registered defines the
33  * frame of reference for the bounds measurements used.
34  * <p>
35  * <b>Terminology</b>
36  * <dl>
37  * <dt>Containing View</dt>
38  * <dd>The view on which this callback is attached, or the root view of the window if the callback
39  * is assigned  directly to a window.</dd>
40  *
41  * <dt>Scroll Bounds</dt>
42  * <dd>A rectangle which describes an area within the containing view where scrolling content may
43  * be positioned. This may be the Containing View bounds itself, or any rectangle within.
44  * Requested by {@link #onScrollCaptureSearch}.</dd>
45  *
46  * <dt>Scroll Delta</dt>
47  * <dd>The distance the scroll position has moved since capture started. Implementations are
48  * responsible for tracking changes in vertical scroll position during capture. This is required to
49  * map the capture area to the correct location, given the current scroll position.
50  *
51  * <dt>Capture Area</dt>
52  * <dd>A rectangle which describes the area to capture, relative to scroll bounds. The vertical
53  * position remains relative to the starting scroll position and any movement since ("Scroll Delta")
54  * should be subtracted to locate the correct local position, and scrolled into view as necessary.
55  * </dd>
56  * </dl>
57  *
58  * @see View#setScrollCaptureHint(int)
59  * @see View#setScrollCaptureCallback(ScrollCaptureCallback)
60  * @see Window#addScrollCaptureCallback(ScrollCaptureCallback)
61  *
62  * @hide
63  */
64 @UiThread
65 public interface ScrollCaptureCallback {
66 
67     /**
68      * The system is searching for the appropriate scrolling container to capture and would like to
69      * know the size and position of scrolling content handled by this callback.
70      * <p>
71      * Implementations should inset {@code containingViewBounds} to cover only the area within the
72      * containing view where scrolling content may be positioned. This should cover only the content
73      * which tracks with scrolling movement.
74      * <p>
75      * Return the updated rectangle to {@code resultConsumer}. If for any reason the scrolling
76      * content is not available to capture, a {@code null} rectangle may be returned, and this view
77      * will be excluded as the target for this request.
78      * <p>
79      * Responses received after XXXms will be discarded.
80      * <p>
81      * TODO: finalize timeout
82      *
83      * @param onReady              consumer for the updated rectangle
84      */
onScrollCaptureSearch(@onNull Consumer<Rect> onReady)85     void onScrollCaptureSearch(@NonNull Consumer<Rect> onReady);
86 
87     /**
88      * Scroll Capture has selected this callback to provide the scrolling image content.
89      * <p>
90      * The onReady signal should be called when ready to begin handling image requests.
91      */
onScrollCaptureStart(@onNull ScrollCaptureSession session, @NonNull Runnable onReady)92     void onScrollCaptureStart(@NonNull ScrollCaptureSession session, @NonNull Runnable onReady);
93 
94     /**
95      * An image capture has been requested from the scrolling content.
96      * <p>
97      * <code>captureArea</code> contains the bounds of the image requested, relative to the
98      * rectangle provided by {@link ScrollCaptureCallback#onScrollCaptureSearch}, referred to as
99      * {@code scrollBounds}.
100      * here.
101      * <p>
102      * A series of requests will step by a constant vertical amount relative to {@code
103      * scrollBounds}, moving through the scrolling range of content, above and below the current
104      * visible area. The rectangle's vertical position will not account for any scrolling movement
105      * since capture started. Implementations therefore must track any scroll position changes and
106      * subtract this distance from requests.
107      * <p>
108      * To handle a request, the content should be scrolled to maximize the visible area of the
109      * requested rectangle. Offset {@code captureArea} again to account for any further scrolling.
110      * <p>
111      * Finally, clip this rectangle against scrollBounds to determine what portion, if any is
112      * visible content to capture. If the rectangle is completely clipped, set it to {@link
113      * Rect#setEmpty() empty} and skip the next step.
114      * <p>
115      * Make a copy of {@code captureArea}, transform to window coordinates and draw the window,
116      * clipped to this rectangle, into the {@link ScrollCaptureSession#getSurface() surface} at
117      * offset (0,0).
118      * <p>
119      * Finally, return the resulting {@code captureArea} using
120      * {@link ScrollCaptureSession#notifyBufferSent}.
121      * <p>
122      * If the response is not supplied within XXXms, the session will end with a call to {@link
123      * #onScrollCaptureEnd}, after which {@code session} is invalid and should be discarded.
124      * <p>
125      * TODO: finalize timeout
126      * <p>
127      *
128      * @param captureArea the area to capture, a rectangle within {@code scrollBounds}
129      */
onScrollCaptureImageRequest( @onNull ScrollCaptureSession session, @NonNull Rect captureArea)130     void onScrollCaptureImageRequest(
131             @NonNull ScrollCaptureSession session, @NonNull Rect captureArea);
132 
133     /**
134      * Signals that capture has ended. Implementations should release any temporary resources or
135      * references to objects in use during the capture. Any resources obtained from the session are
136      * now invalid and attempts to use them after this point may throw an exception.
137      * <p>
138      * The window should be returned as much as possible to its original state when capture started.
139      * At a minimum, the content should be scrolled to its original position.
140      * <p>
141      * <code>onReady</code> should be called when the window should be made visible and
142      * interactive. The system will wait up to XXXms for this call before proceeding.
143      * <p>
144      * TODO: finalize timeout
145      *
146      * @param onReady a callback to inform the system that the application has completed any
147      *                cleanup and is ready to become visible
148      */
onScrollCaptureEnd(@onNull Runnable onReady)149     void onScrollCaptureEnd(@NonNull Runnable onReady);
150 }
151 
152