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

Commit 73c26d74 authored by Mark Renouf's avatar Mark Renouf Committed by Automerger Merge Worker
Browse files

Merge "Scroll Capture Framework" into rvc-dev am: 03f9a814 am: d32e93a8

Change-Id: Ie03a91b91785a75bfdce8c6af9fa3824727d7490
parents d7cc8265 d32e93a8
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

import android.graphics.Rect;
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.
   *
   * {@hide}
   */
interface IScrollCaptureClient {

    /**
     * Informs the client that it has been selected for scroll capture and should prepare to
     * to begin handling capture requests.
     */
    oneway void startCapture(in Surface surface);

    /**
     * Request the client capture an image within the provided rectangle.
     *
     * @see android.view.ScrollCaptureCallback#onScrollCaptureRequest
     */
    oneway void requestImage(in Rect captureArea);

    /**
     * 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.
     */
    oneway void endCapture();
}
+63 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

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

import android.view.IScrollCaptureClient;

/**
 * Interface to a controller passed to the {@link IScrollCaptureClient} which provides the client an
 * asynchronous callback channel for responses.
 *
 * {@hide}
 */
interface IScrollCaptureController {
    /**
     * Scroll capture is available, and a client connect has been returned.
     *
     * @param client interface to a ScrollCaptureCallback in the window process
     * @param scrollAreaInWindow the location of scrolling in global (window) coordinate space
     */
    oneway void onClientConnected(in IScrollCaptureClient client, in Rect scrollBounds,
            in Point positionInWindow);

    /**
     * Nothing in the window can be scrolled, scroll capture not offered.
     */
    oneway void onClientUnavailable();

    /**
     * Notifies the system that the client has confirmed the request and is ready to begin providing
     * image requests.
     */
    oneway void onCaptureStarted();

    /**
     * Received a response from a capture request.
     */
    oneway void onCaptureBufferSent(long frameNumber, 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.
     */
    oneway void onConnectionClosed();
}
+12 −4
Original line number Diff line number Diff line
@@ -21,15 +21,16 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.MergedConfiguration;
import android.view.DisplayCutout;
import android.view.DragEvent;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.IScrollCaptureController;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.DisplayCutout;
import android.view.InsetsState;
import android.view.InsetsSourceControl;

import com.android.internal.os.IResultReceiver;
import android.util.MergedConfiguration;

/**
 * API back to a client window that the Window Manager uses to inform it of
@@ -139,4 +140,11 @@ oneway interface IWindow {
     * Tell the window that it is either gaining or losing pointer capture.
     */
    void dispatchPointerCaptureChanged(boolean hasCapture);

    /**
     * Called when Scroll Capture support is requested for a window.
     *
     * @param controller the controller to receive responses
     */
    void requestScrollCapture(in IScrollCaptureController controller);
}
+15 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import android.view.IDisplayFoldListener;
import android.view.IDisplayWindowRotationController;
import android.view.IOnKeyguardExitResult;
import android.view.IPinnedStackListener;
import android.view.IScrollCaptureController;
import android.view.RemoteAnimationAdapter;
import android.view.IRotationWatcher;
import android.view.ISystemGestureExclusionListener;
@@ -749,4 +750,18 @@ interface IWindowManager
     * @param flags see definition in SurfaceTracing.cpp
     */
    void setLayerTracingFlags(int flags);

    /**
     * Forwards a scroll capture request to the appropriate window, if available.
     *
     * @param displayId the id of the display to target
     * @param behindClient token for a window, used to filter the search to windows behind it, or
     *                     {@code null} to accept a window at any zOrder
     * @param taskId specifies the id of a task the result must belong to, or -1 to ignore task ids
     * @param controller the controller to receive results, a call to either
     *      {@link IScrollCaptureController#onClientConnected} or
     *      {@link IScrollCaptureController#onClientUnavailable}.
     */
    void requestScrollCapture(int displayId, IBinder behindClient, int taskId,
            IScrollCaptureController controller);
}
+151 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

import android.annotation.NonNull;
import android.annotation.UiThread;
import android.graphics.Rect;

import java.util.function.Consumer;

/**
 * A ScrollCaptureCallback is responsible for providing rendered snapshots of scrolling content for
 * the scroll capture system. A single callback is responsible for providing support to a single
 * scrolling UI element. At request time, the system will select the best candidate from among all
 * callbacks registered within the window.
 * <p>
 * A callback is assigned to a View using {@link View#setScrollCaptureCallback}, or to the window as
 * {@link Window#addScrollCaptureCallback}. The point where the callback is registered defines the
 * frame of reference for the bounds measurements used.
 * <p>
 * <b>Terminology</b>
 * <dl>
 * <dt>Containing View</dt>
 * <dd>The view on which this callback is attached, or the root view of the window if the callback
 * is assigned  directly to a window.</dd>
 *
 * <dt>Scroll Bounds</dt>
 * <dd>A rectangle which describes an area within the containing view where scrolling content may
 * be positioned. This may be the Containing View bounds itself, or any rectangle within.
 * Requested by {@link #onScrollCaptureSearch}.</dd>
 *
 * <dt>Scroll Delta</dt>
 * <dd>The distance the scroll position has moved since capture started. Implementations are
 * responsible for tracking changes in vertical scroll position during capture. This is required to
 * map the capture area to the correct location, given the current scroll position.
 *
 * <dt>Capture Area</dt>
 * <dd>A rectangle which describes the area to capture, relative to scroll bounds. The vertical
 * position remains relative to the starting scroll position and any movement since ("Scroll Delta")
 * should be subtracted to locate the correct local position, and scrolled into view as necessary.
 * </dd>
 * </dl>
 *
 * @see View#setScrollCaptureHint(int)
 * @see View#setScrollCaptureCallback(ScrollCaptureCallback)
 * @see Window#addScrollCaptureCallback(ScrollCaptureCallback)
 *
 * @hide
 */
@UiThread
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.
     * <p>
     * Responses received after XXXms will be discarded.
     * <p>
     * TODO: finalize timeout
     *
     * @param onReady              consumer for the updated rectangle
     */
    void onScrollCaptureSearch(@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.
     */
    void onScrollCaptureStart(@NonNull ScrollCaptureSession session, @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.
     * <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.
     * <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
     * <p>
     *
     * @param captureArea the area to capture, a rectangle within {@code scrollBounds}
     */
    void onScrollCaptureImageRequest(
            @NonNull ScrollCaptureSession session, @NonNull Rect captureArea);

    /**
     * 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.
     * <p>
     * TODO: finalize timeout
     *
     * @param onReady a callback to inform the system that the application has completed any
     *                cleanup and is ready to become visible
     */
    void onScrollCaptureEnd(@NonNull Runnable onReady);
}
Loading