summaryrefslogtreecommitdiff
path: root/services/accessibility/java
diff options
context:
space:
mode:
author Daniel Norman <danielnorman@google.com> 2024-12-19 23:57:07 +0000
committer Daniel Norman <danielnorman@google.com> 2025-02-14 15:23:25 -0800
commit22b4f81bf06b603f029a2b3c80ff68db4a1bd229 (patch)
tree5d2ee749360e2aa54eb4e7849f67d2c6f1f63ef3 /services/accessibility/java
parentc42e473bf66d61267b264e86eb94fcbb600b7201 (diff)
Stop blocking preinstalled a11y tools from taking FLAG_SECURE screenshots.
Requires moving the caller of ScreenCapture's screenshot method from the app process to the system_server process since capturing FLAG_SECURE content, even for an app capturing its own content, requires permission CAPTURE_BLACKOUT_CONTENT which is a signature permission. system_server was already used for full-display accessibility screenshots. Bug: 373705911 Test: atest AbstractAccessibilityServiceConnectionTest Test: atest AccessibilityInteractionControllerTest Test: atest AccessibilityTakeScreenshotTest Flag: com.android.server.accessibility.allow_secure_screenshots Change-Id: Ifb711222a42fa18abcabefafdef22daf46402955
Diffstat (limited to 'services/accessibility/java')
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java60
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java7
2 files changed, 65 insertions, 2 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 9ceca5d1dbfe..4b042489f3eb 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -86,11 +86,13 @@ import android.view.MagnificationSpec;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.View;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityCache;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityWindowInfo;
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
+import android.view.accessibility.IWindowSurfaceInfoCallback;
import android.view.inputmethod.EditorInfo;
import android.window.ScreenCapture;
import android.window.ScreenCapture.ScreenshotHardwareBuffer;
@@ -343,6 +345,8 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
SurfaceControl sc,
IAccessibilityInteractionConnectionCallback callback);
+ int performScreenCapture(ScreenCapture.LayerCaptureArgs captureArgs,
+ ScreenCapture.ScreenCaptureListener captureListener);
}
public AbstractAccessibilityServiceConnection(Context context, ComponentName componentName,
@@ -1456,7 +1460,45 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_WINDOW, interactionId);
return;
}
- connection.getRemote().takeScreenshotOfWindow(interactionId, listener, callback);
+ if (Flags.allowSecureScreenshots()) {
+ IWindowSurfaceInfoCallback infoCallback = new IWindowSurfaceInfoCallback.Stub() {
+ @Override
+ public void provideWindowSurfaceInfo(int windowFlags, int processUid,
+ SurfaceControl surfaceControl) {
+ final boolean canCaptureSecureLayers = canCaptureSecureLayers();
+ if (!canCaptureSecureLayers
+ && (windowFlags & WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+ try {
+ callback.sendTakeScreenshotOfWindowError(
+ AccessibilityService.ERROR_TAKE_SCREENSHOT_SECURE_WINDOW,
+ interactionId);
+ } catch (RemoteException e) {
+ // ignore - the other side will time out
+ }
+ return;
+ }
+
+ final ScreenCapture.LayerCaptureArgs captureArgs =
+ new ScreenCapture.LayerCaptureArgs.Builder(surfaceControl)
+ .setChildrenOnly(false)
+ .setUid(processUid)
+ .setCaptureSecureLayers(canCaptureSecureLayers)
+ .build();
+ if (mSystemSupport.performScreenCapture(captureArgs, listener) != 0) {
+ try {
+ callback.sendTakeScreenshotOfWindowError(
+ AccessibilityService.ERROR_TAKE_SCREENSHOT_INTERNAL_ERROR,
+ interactionId);
+ } catch (RemoteException e) {
+ // ignore - the other side will time out
+ }
+ }
+ }
+ };
+ connection.getRemote().getWindowSurfaceInfo(infoCallback);
+ } else {
+ connection.getRemote().takeScreenshotOfWindow(interactionId, listener, callback);
+ }
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1523,7 +1565,14 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
}
}
);
- mWindowManagerService.captureDisplay(displayId, null, screenCaptureListener);
+ if (Flags.allowSecureScreenshots()) {
+ mWindowManagerService.captureDisplay(displayId,
+ new ScreenCapture.CaptureArgs.Builder<>()
+ .setCaptureSecureLayers(canCaptureSecureLayers()).build(),
+ screenCaptureListener);
+ } else {
+ mWindowManagerService.captureDisplay(displayId, null, screenCaptureListener);
+ }
} catch (Exception e) {
sendScreenshotFailure(AccessibilityService.ERROR_TAKE_SCREENSHOT_INVALID_DISPLAY,
callback);
@@ -1564,6 +1613,13 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
}, null).recycleOnUse());
}
+ private boolean canCaptureSecureLayers() {
+ return Flags.allowSecureScreenshots()
+ && mAccessibilityServiceInfo.isAccessibilityTool()
+ && mAccessibilityServiceInfo.getResolveInfo().serviceInfo
+ .applicationInfo.isSystemApp();
+ }
+
@Override
@PermissionManuallyEnforced
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 67fdca446ba4..9eb8442be783 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -173,6 +173,7 @@ import android.view.accessibility.IAccessibilityManagerClient;
import android.view.accessibility.IMagnificationConnection;
import android.view.accessibility.IUserInitializationCompleteCallback;
import android.view.inputmethod.EditorInfo;
+import android.window.ScreenCapture;
import com.android.internal.R;
import com.android.internal.accessibility.AccessibilityShortcutController;
@@ -6725,6 +6726,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
callback));
}
+ @Override
+ public int performScreenCapture(ScreenCapture.LayerCaptureArgs captureArgs,
+ ScreenCapture.ScreenCaptureListener captureListener) {
+ return ScreenCapture.captureLayers(captureArgs, captureListener);
+ }
+
@VisibleForTesting
int getShortcutTypeForGenericShortcutCalls(int userId) {
int navigationMode = Settings.Secure.getIntForUser(