OSDN Git Service

The touch exploration capability is dynamically granted pre-JellyBeanMR2.
authorSvetoslav <svetoslavganov@google.com>
Wed, 24 Apr 2013 21:51:29 +0000 (14:51 -0700)
committerSvetoslav <svetoslavganov@google.com>
Wed, 24 Apr 2013 21:59:04 +0000 (14:59 -0700)
Since the enable touch exploration capability is dynamically granted by
the user for apps targeting pre-JellybeanMR2 API level, we have to properly
update the accessibility service info for that service and also avoid
caching copies of the service info.

bug:8633951

Change-Id: I83dd1c852706ec55d40cda7209ad842889fb970a

core/java/android/accessibilityservice/AccessibilityServiceInfo.java
core/java/android/app/UiAutomationConnection.java
services/java/com/android/server/accessibility/AccessibilityManagerService.java

index 7e21db3..de58a33 100644 (file)
@@ -378,23 +378,6 @@ public class AccessibilityServiceInfo implements Parcelable {
     /**
      * Creates a new instance.
      *
-     * @param isAutomation Whether this is a test automation service.
-     *
-     * @hide
-     */
-    public AccessibilityServiceInfo(boolean isAutomation) {
-        // Automation service can do anything.
-        if (isAutomation) {
-            mCapabilities |= CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
-                    | CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
-                    | CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
-                    | CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS;
-        }
-    }
-
-    /**
-     * Creates a new instance.
-     *
      * @param resolveInfo The service resolve info.
      * @param context Context for accessing resources.
      * @throws XmlPullParserException If a XML parsing error occurs.
@@ -461,8 +444,8 @@ public class AccessibilityServiceInfo implements Parcelable {
                 mCapabilities |= CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION;
             }
             if (asAttributes.getBoolean(com.android.internal.R.styleable
-                    .AccessibilityService_canRequestEnhancedWebAccessibility, false)) {
-                mCapabilities |= CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY;
+                        .AccessibilityService_canRequestEnhancedWebAccessibility, false)) {
+                    mCapabilities |= CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY;
             }
             if (asAttributes.getBoolean(com.android.internal.R.styleable
                     .AccessibilityService_canRequestFilterKeyEvents, false)) {
@@ -574,6 +557,23 @@ public class AccessibilityServiceInfo implements Parcelable {
     }
 
     /**
+     * Sets the bit mask of capabilities this accessibility service has such as
+     * being able to retrieve the active window content, etc.
+     *
+     * @param capabilities The capability bit mask.
+     *
+     * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
+     * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
+     * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
+     * @see #CAPABILITY_FILTER_KEY_EVENTS
+     *
+     * @hide
+     */
+    public void setCapabilities(int capabilities) {
+        mCapabilities = capabilities;
+    }
+
+    /**
      * Gets the non-localized description of the accessibility service.
      * <p>
      *    <strong>Statically set from
index 5bc17fa..607930c 100644 (file)
@@ -158,11 +158,15 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
     private void registerUiTestAutomationServiceLocked(IAccessibilityServiceClient client) {
         IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
                 ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
-        AccessibilityServiceInfo info = new AccessibilityServiceInfo(true);
+        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
         info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
         info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
         info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
                 | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS;
+        info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
+                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
+                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
+                | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS);
         try {
             // Calling out with a lock held is fine since if the system
             // process is gone the client calling in will be killed.
index 64dfd67..3fd534e 100644 (file)
@@ -1261,6 +1261,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
     }
 
     private void onUserStateChangedLocked(UserState userState) {
+        updateLegacyCapabilities(userState);
         updateServicesLocked(userState);
         updateTouchExplorationLocked(userState);
         updateEnhancedWebAccessibilityLocked(userState);
@@ -1268,6 +1269,28 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
         scheduleUpdateClientsIfNeededLocked(userState);
     }
 
+    private void updateLegacyCapabilities(UserState userState) {
+        // Up to JB-MR1 we had a white list with services that can enable touch
+        // exploration. When a service is first started we show a dialog to the
+        // use to get a permission to white list the service.
+        final int installedServiceCount = userState.mInstalledServices.size();
+        for (int i = 0; i < installedServiceCount; i++) {
+            AccessibilityServiceInfo serviceInfo = userState.mInstalledServices.get(i);
+            ResolveInfo resolveInfo = serviceInfo.getResolveInfo();
+            if ((serviceInfo.getCapabilities()
+                        & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) == 0
+                    && resolveInfo.serviceInfo.applicationInfo.targetSdkVersion
+                        <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+                ComponentName componentName = new ComponentName(
+                        resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
+                if (userState.mTouchExplorationGrantedServices.contains(componentName)) {
+                    serviceInfo.setCapabilities(serviceInfo.getCapabilities()
+                            | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION);
+                }
+            }
+        }
+    }
+
     private void updateServicesLocked(UserState userState) {
         if (userState.mIsAccessibilityEnabled) {
             manageServicesLocked(userState);
@@ -1658,8 +1681,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
 
         Intent mIntent;
 
-        boolean mCanRetrieveScreenContent;
-
         boolean mIsAutomation;
 
         final Rect mTempBounds = new Rect();
@@ -1695,15 +1716,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
             mAccessibilityServiceInfo = accessibilityServiceInfo;
             mIsAutomation = (sFakeAccessibilityServiceComponentName.equals(componentName));
             if (!mIsAutomation) {
-                mCanRetrieveScreenContent = (accessibilityServiceInfo.getCapabilities()
-                        & AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION) != 0;
                 mIntent = new Intent().setComponent(mComponentName);
                 mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                         com.android.internal.R.string.accessibility_binding_label);
                 mIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
                         mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
-            } else {
-                mCanRetrieveScreenContent = true;
             }
             setDynamicallyConfigurableProperties(accessibilityServiceInfo);
         }
@@ -2152,7 +2169,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
                         .loadLabel(mContext.getPackageManager()));
                 pw.append(", feedbackType"
                         + AccessibilityServiceInfo.feedbackTypeToString(mFeedbackType));
-                pw.append(", canRetrieveScreenContent=" + mCanRetrieveScreenContent);
+                pw.append(", capabilities=" + mAccessibilityServiceInfo.getCapabilities());
                 pw.append(", eventTypes="
                         + AccessibilityEvent.eventTypeToString(mEventTypes));
                 pw.append(", notificationTimeout=" + mNotificationTimeout);
@@ -2742,7 +2759,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
         }
 
         public boolean canRetrieveWindowContent(Service service) {
-            return service.mCanRetrieveScreenContent;
+            return (service.mAccessibilityServiceInfo.getCapabilities()
+                    & AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0;
         }
 
         public void enforceCanRetrieveWindowContent(Service service) throws RemoteException {