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