summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jacky Kao <jackykao@google.com> 2020-03-03 01:06:40 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-03-03 01:06:40 +0000
commit78afcedf9fefcd651802183f7844d3660e3e67df (patch)
treea18eb2a1485d8d1e7b6056acc247372b8f6bfcdf
parentd212fd103fa3d290c69449d526fc0d9553f4820b (diff)
parent979600dce1789ac905f5dec5039c7e9c317959cc (diff)
Merge "Add a rate limitation of takeScreenshot() API" into rvc-dev
-rw-r--r--api/test-current.txt4
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java44
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl2
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java4
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java34
-rw-r--r--services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java4
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;
+ }
}
}