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 import android.os.CancellationSignal; 23 24 import java.util.function.Consumer; 25 26 /** 27 * A ScrollCaptureCallback is responsible for providing rendered snapshots of scrolling content for 28 * the scroll capture system. A single callback is responsible for providing support to a single 29 * scrolling UI element. At request time, the system will select the best candidate from among all 30 * callbacks registered within the window. 31 * <p> 32 * A callback is assigned to a View using {@link View#setScrollCaptureCallback}, or to the window as 33 * {@link Window#registerScrollCaptureCallback}. The point where the callback is registered defines 34 * the frame of reference for the bounds measurements used. 35 * <p> 36 * <b>Terminology</b> 37 * <dl> 38 * <dt>Containing View</dt> 39 * <dd>The view on which this callback is attached, or the root view of the window if the callback 40 * is assigned directly to a window.</dd> 41 * 42 * <dt>Scroll Bounds</dt> 43 * <dd>A rectangle which describes an area within the containing view where scrolling content 44 * appears. This may be the entire view or any rectangle within. This defines a frame of reference 45 * for requests as well as the width and maximum height of a single request.</dd> 46 * 47 * <dt>Scroll Delta</dt> 48 * <dd>The distance the scroll position has moved since capture started. Implementations are 49 * responsible for tracking changes in vertical scroll position during capture. This is required to 50 * map the capture area to the correct location, given the current scroll position. 51 * 52 * <dt>Capture Area</dt> 53 * <dd>A rectangle which describes the area to capture, relative to scroll bounds. The vertical 54 * position remains relative to the starting scroll position and any movement since ("Scroll Delta") 55 * should be subtracted to locate the correct local position, and scrolled into view as necessary. 56 * </dd> 57 * </dl> 58 * 59 * @see View#setScrollCaptureHint(int) 60 * @see View#setScrollCaptureCallback(ScrollCaptureCallback) 61 * @see Window#registerScrollCaptureCallback(ScrollCaptureCallback) 62 */ 63 @UiThread 64 public interface ScrollCaptureCallback { 65 66 /** 67 * The system is searching for the appropriate scrolling container to capture and would like to 68 * know the size and position of scrolling content handled by this callback. 69 * <p> 70 * To determine scroll bounds, an implementation should inset the visible bounds of the 71 * containing view to cover only the area where scrolling content may be positioned. This 72 * should cover only the content which tracks with scrolling movement. 73 * <p> 74 * Return the updated rectangle to {@link Consumer#accept onReady.accept}. If for any reason the 75 * scrolling content is not available to capture, a empty rectangle may be returned which will 76 * exclude this view from consideration. 77 * <p> 78 * This request may be cancelled via the provided {@link CancellationSignal}. When this happens, 79 * any future call to {@link Consumer#accept onReady.accept} will have no effect and this 80 * content will be omitted from the search results. 81 * 82 * @param signal signal to cancel the operation in progress 83 * @param onReady consumer for the updated rectangle 84 */ onScrollCaptureSearch(@onNull CancellationSignal signal, @NonNull Consumer<Rect> onReady)85 void onScrollCaptureSearch(@NonNull CancellationSignal signal, @NonNull Consumer<Rect> onReady); 86 87 /** 88 * Scroll Capture has selected this callback to provide the scrolling image content. 89 * <p> 90 * {@link Runnable#run onReady.run} should be called when ready to begin handling image 91 * requests. 92 * <p> 93 * This request may be cancelled via the provided {@link CancellationSignal}. When this happens, 94 * any future call to {@link Runnable#run onReady.run} will have no effect and provided session 95 * will not be activated. 96 * 97 * @param session the current session, resources provided by it are valid for use until the 98 * {@link #onScrollCaptureEnd(Runnable) session ends} 99 * @param signal signal to cancel the operation in progress 100 * @param onReady signal used to report completion of the request 101 */ onScrollCaptureStart(@onNull ScrollCaptureSession session, @NonNull CancellationSignal signal, @NonNull Runnable onReady)102 void onScrollCaptureStart(@NonNull ScrollCaptureSession session, 103 @NonNull CancellationSignal signal, @NonNull Runnable onReady); 104 105 /** 106 * An image capture has been requested from the scrolling content. 107 * <p> 108 * The requested rectangle describes an area inside the target view, relative to 109 * <code>scrollBounds</code>. The content may be offscreen, above or below the current visible 110 * portion of the target view. To handle the request, render the available portion of this 111 * rectangle to a buffer and return it via the Surface available from {@link 112 * ScrollCaptureSession#getSurface()}. 113 * <p> 114 * Note: Implementations are only required to render the requested content, and may do so into 115 * off-screen buffers without scrolling if they are able. 116 * <p> 117 * The resulting available portion of the request must be computed as a portion of {@code 118 * captureArea}, and sent to signal the operation is complete, using {@link Consumer#accept 119 * onComplete.accept}. If the requested rectangle is partially or fully out of bounds the 120 * resulting portion should be returned. If no portion is available (outside of available 121 * content), then skip sending any buffer and report an empty Rect as result. 122 * <p> 123 * This request may be cancelled via the provided {@link CancellationSignal}. When this happens, 124 * any future call to {@link Consumer#accept onComplete.accept} will be ignored until the next 125 * request. 126 * 127 * @param session the current session, resources provided by it are valid for use until the 128 * {@link #onScrollCaptureEnd(Runnable) session ends} 129 * @param signal signal to cancel the operation in progress 130 * @param captureArea the area to capture, a rectangle within {@code scrollBounds} 131 * @param onComplete a consumer for the captured area 132 */ onScrollCaptureImageRequest(@onNull ScrollCaptureSession session, @NonNull CancellationSignal signal, @NonNull Rect captureArea, @NonNull Consumer<Rect> onComplete)133 void onScrollCaptureImageRequest(@NonNull ScrollCaptureSession session, 134 @NonNull CancellationSignal signal, @NonNull Rect captureArea, 135 @NonNull Consumer<Rect> onComplete); 136 137 /** 138 * Signals that capture has ended. Implementations should release any temporary resources or 139 * references to objects in use during the capture. Any resources obtained from the session are 140 * now invalid and attempts to use them after this point may throw an exception. 141 * <p> 142 * The window should be returned to its original state when capture started. At a minimum, the 143 * content should be scrolled to its original position. 144 * <p> 145 * {@link Runnable#run onReady.run} should be called as soon as possible after the window is 146 * ready for normal interactive use. After the callback (or after a timeout, if not called) the 147 * screenshot tool will be dismissed and the window may become visible to the user at any time. 148 * 149 * @param onReady a callback to inform the system that the application has completed any 150 * cleanup and is ready to become visible 151 */ onScrollCaptureEnd(@onNull Runnable onReady)152 void onScrollCaptureEnd(@NonNull Runnable onReady); 153 } 154 155