From 8dc791e678c5c000414f38c4939e9e34dcd4e5c7 Mon Sep 17 00:00:00 2001 From: Jackal Guo Date: Mon, 14 Jan 2019 10:26:42 +0800 Subject: [PATCH] Adding AppOps data for Accessibility Support to expose the apps accessing accessibility features in the permission hub. Start logging each time any data goes to services. Bug: 122615167 Test: a11y CTS & unit test Change-Id: I21f92dad8b3ec2e59a8ad6d180dc466357347784 --- core/java/android/app/AppOpsManager.java | 14 ++++++++- ...bstractAccessibilityServiceConnection.java | 30 +++++++++++++++++++ .../AccessibilityManagerService.java | 25 ++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index ab2430c7a4908..9559158290454 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -554,9 +554,11 @@ public class AppOpsManager { public static final int OP_WRITE_MEDIA_IMAGES = 86; /** @hide Has a legacy (non-isolated) view of storage. */ public static final int OP_LEGACY_STORAGE = 87; + /** @hide Accessing accessibility features */ + public static final int OP_ACCESS_ACCESSIBILITY = 88; /** @hide */ @UnsupportedAppUsage - public static final int _NUM_OP = 88; + public static final int _NUM_OP = 89; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -825,6 +827,8 @@ public class AppOpsManager { public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images"; /** @hide Has a legacy (non-isolated) view of storage. */ public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage"; + /** @hide Interact with accessibility. */ + public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility"; // Warning: If an permission is added here it also has to be added to // com.android.packageinstaller.permission.utils.EventLogger @@ -984,6 +988,7 @@ public class AppOpsManager { OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES OP_LEGACY_STORAGE, // LEGACY_STORAGE + OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY }; /** @@ -1078,6 +1083,7 @@ public class AppOpsManager { OPSTR_READ_MEDIA_IMAGES, OPSTR_WRITE_MEDIA_IMAGES, OPSTR_LEGACY_STORAGE, + OPSTR_ACCESS_ACCESSIBILITY, }; /** @@ -1173,6 +1179,7 @@ public class AppOpsManager { "READ_MEDIA_IMAGES", "WRITE_MEDIA_IMAGES", "LEGACY_STORAGE", + "ACCESS_ACCESSIBILITY", }; /** @@ -1269,6 +1276,7 @@ public class AppOpsManager { Manifest.permission.READ_MEDIA_IMAGES, null, // no permission for OP_WRITE_MEDIA_IMAGES null, // no permission for OP_LEGACY_STORAGE + null, // no permission for OP_ACCESS_ACCESSIBILITY }; /** @@ -1365,6 +1373,7 @@ public class AppOpsManager { null, // READ_MEDIA_IMAGES null, // WRITE_MEDIA_IMAGES null, // LEGACY_STORAGE + null, // ACCESS_ACCESSIBILITY }; /** @@ -1460,6 +1469,7 @@ public class AppOpsManager { false, // READ_MEDIA_IMAGES false, // WRITE_MEDIA_IMAGES false, // LEGACY_STORAGE + false, // ACCESS_ACCESSIBILITY }; /** @@ -1554,6 +1564,7 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE + AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY }; /** @@ -1652,6 +1663,7 @@ public class AppOpsManager { false, // READ_MEDIA_IMAGES false, // WRITE_MEDIA_IMAGES false, // LEGACY_STORAGE + false, // ACCESS_ACCESSIBILITY }; /** diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java index 2c075dc809d03..f4ac130749038 100644 --- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java +++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java @@ -275,6 +275,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS) == 0) { return false; } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return false; + } try { mServiceInterface.onKeyEvent(keyEvent, sequenceNumber); } catch (RemoteException e) { @@ -388,6 +391,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ if (mSecurityPolicy.mWindows == null) { return null; } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return null; + } List windows = new ArrayList<>(); final int windowCount = mSecurityPolicy.mWindows.size(); for (int i = 0; i < windowCount; i++) { @@ -413,6 +419,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ if (!permissionGranted) { return null; } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return null; + } AccessibilityWindowInfo window = mSecurityPolicy.findA11yWindowInfoById(windowId); if (window != null) { AccessibilityWindowInfo windowClone = AccessibilityWindowInfo.obtain(window); @@ -455,6 +464,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId); } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return null; + } final int interrogatingPid = Binder.getCallingPid(); callback = mSystemSupport.replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, interrogatingPid, interrogatingTid); @@ -511,6 +523,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId); } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return null; + } final int interrogatingPid = Binder.getCallingPid(); callback = mSystemSupport.replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, interrogatingPid, interrogatingTid); @@ -567,6 +582,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId); } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return null; + } final int interrogatingPid = Binder.getCallingPid(); callback = mSystemSupport.replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, interrogatingPid, interrogatingTid); @@ -623,6 +641,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId); } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return null; + } final int interrogatingPid = Binder.getCallingPid(); callback = mSystemSupport.replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, interrogatingPid, interrogatingTid); @@ -678,6 +699,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ } spec = mSystemSupport.getCompatibleMagnificationSpecLocked(resolvedWindowId); } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return null; + } final int interrogatingPid = Binder.getCallingPid(); callback = mSystemSupport.replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId, interrogatingPid, interrogatingTid); @@ -722,6 +746,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ return false; } } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return false; + } boolean returnValue = mSystemSupport.performAccessibilityAction(resolvedWindowId, accessibilityNodeId, action, arguments, interactionId, callback, mFetchFlags, interrogatingTid); @@ -974,6 +1001,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ return; } + if (!mSecurityPolicy.checkAccessibilityAccess(this)) { + return; + } // Make a copy since during dispatch it is possible the event to // be modified to remove its source if the receiving service does // not have permission to access the window content. diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 305c53e1e26a3..f88d5217ab2f6 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -3787,6 +3787,31 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub return findWindowIdLocked(token); } } + + public boolean checkAccessibilityAccess(AbstractAccessibilityServiceConnection service) { + final String packageName = service.getComponentName().getPackageName(); + final ResolveInfo resolveInfo = service.getServiceInfo().getResolveInfo(); + + if (resolveInfo == null) { + // For InteractionBridge and UiAutomation + return true; + } + + final int uid = resolveInfo.serviceInfo.applicationInfo.uid; + final long identityToken = Binder.clearCallingIdentity(); + try { + // For the caller is system, just block the data to a11y services. + if (OWN_PROCESS_ID == Binder.getCallingPid()) { + return mAppOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_ACCESS_ACCESSIBILITY, + uid, packageName) == AppOpsManager.MODE_ALLOWED; + } + + return mAppOpsManager.noteOp(AppOpsManager.OPSTR_ACCESS_ACCESSIBILITY, + uid, packageName) == AppOpsManager.MODE_ALLOWED; + } finally { + Binder.restoreCallingIdentity(identityToken); + } + } } /**