diff options
author | 2020-03-03 01:06:40 +0000 | |
---|---|---|
committer | 2020-03-03 01:06:40 +0000 | |
commit | 78afcedf9fefcd651802183f7844d3660e3e67df (patch) | |
tree | a18eb2a1485d8d1e7b6056acc247372b8f6bfcdf | |
parent | d212fd103fa3d290c69449d526fc0d9553f4820b (diff) | |
parent | 979600dce1789ac905f5dec5039c7e9c317959cc (diff) |
Merge "Add a rate limitation of takeScreenshot() API" into rvc-dev
6 files changed, 52 insertions, 40 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index 9050833cbb47..1169c91b6cd7 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -48,6 +48,10 @@ package android.accessibilityservice { ctor public AccessibilityGestureEvent(int, int); } + public abstract class AccessibilityService extends android.app.Service { + field public static final int ACCESSIBILITY_TAKE_SCREENSHOT_REQUEST_INTERVAL_TIMES_MS = 1000; // 0x3e8 + } + } package android.animation { diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 0a138cf81a4c..23cbdcdad00a 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -22,6 +22,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.TestApi; import android.app.Service; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; @@ -572,6 +573,26 @@ public abstract class AccessibilityService extends Service { */ public static final int SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN = 0x40000000; + /** + * The interval time of calling + * {@link AccessibilityService#takeScreenshot(int, Executor, Consumer)} API. + * @hide + */ + @TestApi + public static final int ACCESSIBILITY_TAKE_SCREENSHOT_REQUEST_INTERVAL_TIMES_MS = 1000; + + /** @hide */ + public static final String KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER = + "screenshot_hardwareBuffer"; + + /** @hide */ + public static final String KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE = + "screenshot_colorSpace"; + + /** @hide */ + public static final String KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP = + "screenshot_timestamp"; + private int mConnectionId = AccessibilityInteractionClient.NO_ID; @UnsupportedAppUsage @@ -597,17 +618,6 @@ public abstract class AccessibilityService extends Service { private FingerprintGestureController mFingerprintGestureController; - /** @hide */ - public static final String KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER = - "screenshot_hardwareBuffer"; - - /** @hide */ - public static final String KEY_ACCESSIBILITY_SCREENSHOT_COLORSPACE = - "screenshot_colorSpace"; - - /** @hide */ - public static final String KEY_ACCESSIBILITY_SCREENSHOT_TIMESTAMP = - "screenshot_timestamp"; /** * Callback for {@link android.view.accessibility.AccessibilityEvent}s. @@ -1926,10 +1936,9 @@ public abstract class AccessibilityService extends Service { * default display. * @param executor Executor on which to run the callback. * @param callback The callback invoked when the taking screenshot is done. - * The {@link AccessibilityService.ScreenshotResult} will be null for an - * invalid display. * - * @return {@code true} if the taking screenshot accepted, {@code false} if not. + * @return {@code true} if the taking screenshot accepted, {@code false} if too little time + * has elapsed since the last screenshot, invalid display or internal errors. */ public boolean takeScreenshot(int displayId, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<ScreenshotResult> callback) { @@ -1942,11 +1951,7 @@ public abstract class AccessibilityService extends Service { return false; } try { - connection.takeScreenshot(displayId, new RemoteCallback((result) -> { - if (result == null) { - sendScreenshotResult(executor, callback, null); - return; - } + return connection.takeScreenshot(displayId, new RemoteCallback((result) -> { final HardwareBuffer hardwareBuffer = result.getParcelable(KEY_ACCESSIBILITY_SCREENSHOT_HARDWAREBUFFER); final ParcelableColorSpace colorSpace = @@ -1959,7 +1964,6 @@ public abstract class AccessibilityService extends Service { } catch (RemoteException re) { throw new RuntimeException(re); } - return true; } /** diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl index 0b3b9b2ecae1..1b7b4af34a94 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl @@ -110,7 +110,7 @@ interface IAccessibilityServiceConnection { int getWindowIdForLeashToken(IBinder token); - void takeScreenshot(int displayId, in RemoteCallback callback); + boolean takeScreenshot(int displayId, in RemoteCallback callback); void setGestureDetectionPassthroughRegion(int displayId, in Region region); diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java index 75a7504cac2f..12f67a65920e 100644 --- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java +++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java @@ -156,7 +156,9 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon return -1; } - public void takeScreenshot(int displayId, RemoteCallback callback) {} + public boolean takeScreenshot(int displayId, RemoteCallback callback) { + return false; + } public void setTouchExplorationPassthroughRegion(int displayId, Region region) {} diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index 0a527d420c15..b905a39d1594 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -27,6 +27,7 @@ import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; import android.accessibilityservice.AccessibilityGestureEvent; +import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.accessibilityservice.IAccessibilityServiceConnection; @@ -177,6 +178,8 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ final SparseArray<IBinder> mOverlayWindowTokens = new SparseArray(); + /** The timestamp of requesting to take screenshot in milliseconds */ + private long mRequestTakeScreenshotTimestampMs; public interface SystemSupport { /** @@ -974,44 +977,39 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } @Override - public void takeScreenshot(int displayId, RemoteCallback callback) { + public boolean takeScreenshot(int displayId, RemoteCallback callback) { + final long currentTimestamp = SystemClock.uptimeMillis(); + if (mRequestTakeScreenshotTimestampMs != 0 + && (currentTimestamp - mRequestTakeScreenshotTimestampMs) + <= AccessibilityService.ACCESSIBILITY_TAKE_SCREENSHOT_REQUEST_INTERVAL_TIMES_MS) { + return false; + } + mRequestTakeScreenshotTimestampMs = currentTimestamp; + synchronized (mLock) { if (!hasRightsToCurrentUserLocked()) { - sendScreenshotResult(true, null, callback); - return; + return false; } if (!mSecurityPolicy.canTakeScreenshotLocked(this)) { - sendScreenshotResult(true, null, callback); throw new SecurityException("Services don't have the capability of taking" + " the screenshot."); } } if (!mSecurityPolicy.checkAccessibilityAccess(this)) { - sendScreenshotResult(true, null, callback); - return; + return false; } final Display display = DisplayManagerGlobal.getInstance() .getRealDisplay(displayId); if (display == null) { - sendScreenshotResult(true, null, callback); - return; + return false; } - sendScreenshotResult(false, display, callback); - } - - private void sendScreenshotResult(boolean noResult, Display display, RemoteCallback callback) { - final boolean noScreenshot = noResult; final long identity = Binder.clearCallingIdentity(); try { mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { - if (noScreenshot) { - callback.sendResult(null); - return; - } final Point displaySize = new Point(); // TODO (b/145893483): calling new API with the display as a parameter // when surface control supported. @@ -1041,6 +1039,8 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } finally { Binder.restoreCallingIdentity(identity); } + + return true; } @Override diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java index d1c3a02c6761..4f5b9ed00ee2 100644 --- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java +++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java @@ -328,6 +328,8 @@ class UiAutomationManager { public void onFingerprintGesture(int gesture) {} @Override - public void takeScreenshot(int displayId, RemoteCallback callback) {} + public boolean takeScreenshot(int displayId, RemoteCallback callback) { + return false; + } } } |