Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11adf6dc authored by Svetoslav's avatar Svetoslav
Browse files

The touch exploration capability is dynamically granted pre-JellyBeanMR2.

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
parent 4c783066
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -375,23 +375,6 @@ public class AccessibilityServiceInfo implements Parcelable {
        /* do nothing */
    }

    /**
     * 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.
     *
@@ -573,6 +556,23 @@ public class AccessibilityServiceInfo implements Parcelable {
        return mCapabilities;
    }

    /**
     * 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>
+5 −1
Original line number Diff line number Diff line
@@ -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.
+26 −8
Original line number Diff line number Diff line
@@ -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 {