summaryrefslogtreecommitdiff
path: root/core/java/android/view/ScrollCaptureClient.java
diff options
context:
space:
mode:
authorMark Renouf <mrenouf@google.com>2020-10-02 16:14:12 -0400
committerMark Renouf <mrenouf@google.com>2020-10-19 14:48:32 -0400
commit749b6360a15d3b4c215163cc1237b2c75b7410bf (patch)
tree78ea3f282689f46fed8224ce85028dbb774b9193 /core/java/android/view/ScrollCaptureClient.java
parentc1a295c62b7ba92e9dd592d4c7b4c3cc27361124 (diff)
Refactor names of internal scrollcapture interfaces
Renames to better align with use and existing naming patterns. Using 'connection' to avoid confusion as to control flow or roles. (A connection is direct from SystemUI --> App process) IScrollCaptureClient -> IScrollCaptureConnection IScrollCaptureController -> IScrollCaptureCallbacks Test: atest FrameworksCoreTests:ScrollCaptureConnectionTest \ FrameworksCoreTests:ScrollCaptureTargetResolverTest \ ScrollCaptureTest Change-Id: I9afd33109f6718b61d172ce3e4b3bb5d71a2897e
Diffstat (limited to 'core/java/android/view/ScrollCaptureClient.java')
-rw-r--r--core/java/android/view/ScrollCaptureClient.java312
1 files changed, 0 insertions, 312 deletions
diff --git a/core/java/android/view/ScrollCaptureClient.java b/core/java/android/view/ScrollCaptureClient.java
deleted file mode 100644
index f163124f3a98..000000000000
--- a/core/java/android/view/ScrollCaptureClient.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * 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 static java.util.Objects.requireNonNull;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UiThread;
-import android.annotation.WorkerThread;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.util.CloseGuard;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * A client of the system providing Scroll Capture capability on behalf of a Window.
- * <p>
- * An instance is created to wrap the selected {@link ScrollCaptureCallback}.
- *
- * @hide
- */
-public class ScrollCaptureClient extends IScrollCaptureClient.Stub {
-
- private static final String TAG = "ScrollCaptureClient";
- private static final int DEFAULT_TIMEOUT = 1000;
-
- private final Handler mHandler;
- private ScrollCaptureTarget mSelectedTarget;
- private int mTimeoutMillis = DEFAULT_TIMEOUT;
-
- protected Surface mSurface;
- private IScrollCaptureController mController;
-
- private final Rect mScrollBounds;
- private final Point mPositionInWindow;
- private final CloseGuard mCloseGuard;
-
- // The current session instance in use by the callback.
- private ScrollCaptureSession mSession;
-
- // Helps manage timeout callbacks registered to handler and aids testing.
- private DelayedAction mTimeoutAction;
-
- /**
- * Constructs a ScrollCaptureClient.
- *
- * @param selectedTarget the target the client is controlling
- * @param controller the callbacks to reply to system requests
- *
- * @hide
- */
- public ScrollCaptureClient(
- @NonNull ScrollCaptureTarget selectedTarget,
- @NonNull IScrollCaptureController controller) {
- requireNonNull(selectedTarget, "<selectedTarget> must non-null");
- requireNonNull(controller, "<controller> must non-null");
- final Rect scrollBounds = requireNonNull(selectedTarget.getScrollBounds(),
- "target.getScrollBounds() must be non-null to construct a client");
-
- mSelectedTarget = selectedTarget;
- mHandler = selectedTarget.getContainingView().getHandler();
- mScrollBounds = new Rect(scrollBounds);
- mPositionInWindow = new Point(selectedTarget.getPositionInWindow());
-
- mController = controller;
- mCloseGuard = new CloseGuard();
- mCloseGuard.open("close");
-
- selectedTarget.getContainingView().addOnAttachStateChangeListener(
- new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
-
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- selectedTarget.getContainingView().removeOnAttachStateChangeListener(this);
- endCapture();
- }
- });
- }
-
- @VisibleForTesting
- public void setTimeoutMillis(int timeoutMillis) {
- mTimeoutMillis = timeoutMillis;
- }
-
- @Nullable
- @VisibleForTesting
- public DelayedAction getTimeoutAction() {
- return mTimeoutAction;
- }
-
- private void checkConnected() {
- if (mSelectedTarget == null || mController == null) {
- throw new IllegalStateException("This client has been disconnected.");
- }
- }
-
- private void checkStarted() {
- if (mSession == null) {
- throw new IllegalStateException("Capture session has not been started!");
- }
- }
-
- @WorkerThread // IScrollCaptureClient
- @Override
- public void startCapture(Surface surface) throws RemoteException {
- checkConnected();
- mSurface = surface;
- scheduleTimeout(mTimeoutMillis, this::onStartCaptureTimeout);
- mSession = new ScrollCaptureSession(mSurface, mScrollBounds, mPositionInWindow, this);
- mHandler.post(() -> mSelectedTarget.getCallback().onScrollCaptureStart(mSession,
- this::onStartCaptureCompleted));
- }
-
- @UiThread
- private void onStartCaptureCompleted() {
- if (cancelTimeout()) {
- mHandler.post(() -> {
- try {
- mController.onCaptureStarted();
- } catch (RemoteException e) {
- doShutdown();
- }
- });
- }
- }
-
- @UiThread
- private void onStartCaptureTimeout() {
- endCapture();
- }
-
- @WorkerThread // IScrollCaptureClient
- @Override
- public void requestImage(Rect requestRect) {
- checkConnected();
- checkStarted();
- scheduleTimeout(mTimeoutMillis, this::onRequestImageTimeout);
- // Response is dispatched via ScrollCaptureSession, to onRequestImageCompleted
- mHandler.post(() -> mSelectedTarget.getCallback().onScrollCaptureImageRequest(
- mSession, new Rect(requestRect)));
- }
-
- @UiThread
- void onRequestImageCompleted(long frameNumber, Rect capturedArea) {
- final Rect finalCapturedArea = new Rect(capturedArea);
- if (cancelTimeout()) {
- mHandler.post(() -> {
- try {
- mController.onCaptureBufferSent(frameNumber, finalCapturedArea);
- } catch (RemoteException e) {
- doShutdown();
- }
- });
- }
- }
-
- @UiThread
- private void onRequestImageTimeout() {
- endCapture();
- }
-
- @WorkerThread // IScrollCaptureClient
- @Override
- public void endCapture() {
- if (isStarted()) {
- scheduleTimeout(mTimeoutMillis, this::onEndCaptureTimeout);
- mHandler.post(() ->
- mSelectedTarget.getCallback().onScrollCaptureEnd(this::onEndCaptureCompleted));
- } else {
- disconnect();
- }
- }
-
- private boolean isStarted() {
- return mController != null && mSelectedTarget != null;
- }
-
- @UiThread
- private void onEndCaptureCompleted() { // onEndCaptureCompleted
- if (cancelTimeout()) {
- doShutdown();
- }
- }
-
- @UiThread
- private void onEndCaptureTimeout() {
- doShutdown();
- }
-
-
- private void doShutdown() {
- try {
- if (mController != null) {
- mController.onConnectionClosed();
- }
- } catch (RemoteException e) {
- // Ignore
- } finally {
- disconnect();
- }
- }
-
- /**
- * Shuts down this client and releases references to dependent objects. No attempt is made
- * to notify the controller, use with caution!
- */
- public void disconnect() {
- if (mSession != null) {
- mSession.disconnect();
- mSession = null;
- }
-
- mSelectedTarget = null;
- mController = null;
- }
-
- /** @return a string representation of the state of this client */
- public String toString() {
- return "ScrollCaptureClient{"
- + ", session=" + mSession
- + ", selectedTarget=" + mSelectedTarget
- + ", clientCallbacks=" + mController
- + "}";
- }
-
- private boolean cancelTimeout() {
- if (mTimeoutAction != null) {
- return mTimeoutAction.cancel();
- }
- return false;
- }
-
- private void scheduleTimeout(long timeoutMillis, Runnable action) {
- if (mTimeoutAction != null) {
- mTimeoutAction.cancel();
- }
- mTimeoutAction = new DelayedAction(mHandler, timeoutMillis, action);
- }
-
- /** @hide */
- @VisibleForTesting
- public static class DelayedAction {
- private final AtomicBoolean mCompleted = new AtomicBoolean();
- private final Object mToken = new Object();
- private final Handler mHandler;
- private final Runnable mAction;
-
- @VisibleForTesting
- public DelayedAction(Handler handler, long timeoutMillis, Runnable action) {
- mHandler = handler;
- mAction = action;
- mHandler.postDelayed(this::onTimeout, mToken, timeoutMillis);
- }
-
- private boolean onTimeout() {
- if (mCompleted.compareAndSet(false, true)) {
- mAction.run();
- return true;
- }
- return false;
- }
-
- /**
- * Cause the timeout action to run immediately and mark as timed out.
- *
- * @return true if the timeout was run, false if the timeout had already been canceled
- */
- @VisibleForTesting
- public boolean timeoutNow() {
- return onTimeout();
- }
-
- /**
- * Attempt to cancel the timeout action (such as after a callback is made)
- *
- * @return true if the timeout was canceled and will not run, false if time has expired and
- * the timeout action has or will run momentarily
- */
- public boolean cancel() {
- if (!mCompleted.compareAndSet(false, true)) {
- // Whoops, too late!
- return false;
- }
- mHandler.removeCallbacksAndMessages(mToken);
- return true;
- }
- }
-}