Merge "Remove "enhance web scripts" from settings and make it requested by plug-ins."
diff --git a/api/current.txt b/api/current.txt
index 9cd44ed..8df9c24 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -36,6 +36,8 @@
     field public static final java.lang.String CALL_PHONE = "android.permission.CALL_PHONE";
     field public static final java.lang.String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED";
     field public static final java.lang.String CAMERA = "android.permission.CAMERA";
+    field public static final java.lang.String CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY = "android.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
+    field public static final java.lang.String CAN_REQUEST_TOUCH_EXPLORATION_MODE = "android.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE";
     field public static final java.lang.String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE";
     field public static final java.lang.String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION";
     field public static final java.lang.String CHANGE_NETWORK_STATE = "android.permission.CHANGE_NETWORK_STATE";
@@ -141,6 +143,7 @@
 
   public static final class Manifest.permission_group {
     ctor public Manifest.permission_group();
+    field public static final java.lang.String ACCESSIBILITY_FEATURES = "android.permission-group.ACCESSIBILITY_FEATURES";
     field public static final java.lang.String ACCOUNTS = "android.permission-group.ACCOUNTS";
     field public static final java.lang.String AFFECTS_BATTERY = "android.permission-group.AFFECTS_BATTERY";
     field public static final java.lang.String APP_INFO = "android.permission-group.APP_INFO";
@@ -2104,7 +2107,8 @@
     field public static final int FEEDBACK_SPOKEN = 1; // 0x1
     field public static final int FEEDBACK_VISUAL = 8; // 0x8
     field public static final int FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 2; // 0x2
-    field public static final int FLAG_REPORT_VIEW_IDS = 8; // 0x8
+    field public static final int FLAG_REPORT_VIEW_IDS = 16; // 0x10
+    field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
     field public int eventTypes;
     field public int feedbackType;
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 2006bc7..2dc0501 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -153,13 +153,25 @@
     public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE= 0x0000004;
 
     /**
+     * This flag requests from the system to enable web accessibility enhancing
+     * extensions. Such extensions aim to provide improved accessibility support
+     * for content presented in a {@link android.webkit.WebView}. An example of such
+     * an extension is injecting JavaScript from Google. The system will enable
+     * enhanced web accessibility if there is at least one accessibility service
+     * that has this flag set. Hence, clearing this flag does not guarantee that the
+     * device will not have enhanced web accessibility enabled since there may be
+     * another enabled service that requested it.
+     */
+    public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 0x00000008;
+
+    /**
      * This flag requests that the {@link AccessibilityNodeInfo}s obtained
      * by an {@link AccessibilityService} contain the id of the source view.
      * The source view id will be a fully qualified resource name of the
      * form "package:id/name", for example "foo.bar:id/my_list", and it is
      * useful for UI test automation. This flag is not set by default.
      */
-    public static final int FLAG_REPORT_VIEW_IDS = 0x00000008;
+    public static final int FLAG_REPORT_VIEW_IDS = 0x00000010;
 
     /**
      * The event types an {@link AccessibilityService} is interested in.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3d850cf..be21fb4 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3351,6 +3351,7 @@
          *
          * @hide
          */
+        @Deprecated
         public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES =
             "touch_exploration_granted_accessibility_services";
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 558080c..692c17c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -532,6 +532,31 @@
         android:label="@string/permlab_addVoicemail"
         android:description="@string/permdesc_addVoicemail" />
 
+    <!-- =============================================== -->
+    <!-- Permissions for enabling accessibility features -->
+    <!-- =============================================== -->
+
+    <!-- Used for permissions that allow requesting certain accessibility features. -->
+    <permission-group android:name="android.permission-group.ACCESSIBILITY_FEATURES"
+        android:label="@string/permgrouplab_accessibilityFeatures"
+        android:icon="@drawable/perm_group_accessibility_features"
+        android:description="@string/permgroupdesc_accessibilityFeatures"
+        android:priority="380" />
+
+    <!-- Allows an accessibility service to request touch exploration mode. -->
+    <permission android:name="android.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE"
+        android:permissionGroup="android.permission-group.ACCESSIBILITY_FEATURES"
+        android:label="@string/permlab_canRequestTouchExplorationMode"
+        android:description="@string/permdesc_canRequestTouchExplorationMode"
+        android:protectionLevel="dangerous" />
+
+    <!-- Allows an accessibility service to request enhanced web accessibility. -->
+    <permission android:name="android.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY"
+        android:permissionGroup="android.permission-group.ACCESSIBILITY_FEATURES"
+        android:label="@string/permlab_canRequestEnahncedWebAccessibility"
+        android:description="@string/permdesc_canRequestEnahncedWebAccessibility"
+        android:protectionLevel="dangerous" />
+
     <!-- ======================================= -->
     <!-- Permissions for accessing location info -->
     <!-- ======================================= -->
@@ -1730,7 +1755,7 @@
         android:description="@string/permdesc_bindInputMethod"
         android:protectionLevel="signature" />
 
-        <!-- Must be required by an {@link android.accessibilityservice.AccessibilityService},
+    <!-- Must be required by an {@link android.accessibilityservice.AccessibilityService},
          to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"
         android:label="@string/permlab_bindAccessibilityService"
diff --git a/core/res/res/drawable-hdpi/perm_group_accessibility_features.png b/core/res/res/drawable-hdpi/perm_group_accessibility_features.png
new file mode 100755
index 0000000..849c19c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/perm_group_accessibility_features.png b/core/res/res/drawable-mdpi/perm_group_accessibility_features.png
new file mode 100755
index 0000000..ba86d3d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png b/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png
new file mode 100644
index 0000000..2fec7a3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/perm_group_accessibility_features.png
Binary files differ
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index dc921e6..ab2bd3a 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2510,6 +2510,8 @@
             <flag name="flagIncludeNotImportantViews" value="0x00000002" />
             <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE} -->
             <flag name="flagRequestTouchExplorationMode" value="0x00000004" />
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY} -->
+            <flag name="flagRequestEnhancedWebAccessibility" value="0x00000008" />
         </attr>
         <!-- Component name of an activity that allows the user to modify
              the settings for this service. This setting cannot be changed at runtime. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7f0fc0b..8f8f32d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -535,6 +535,11 @@
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_storage" product="default">Access the SD card.</string>
 
+    <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permgrouplab_accessibilityFeatures">Accessibility features</string>
+    <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permgroupdesc_accessibilityFeatures">Features that assistive technology can request.</string>
+
     <!--  Permissions -->
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -935,6 +940,20 @@
         interface of an accessibility service. Should never be needed for normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_canRequestTouchExplorationMode">request explore by touch</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_canRequestTouchExplorationMode">Allows the hoder to request an
+        interaction mode in which touched items are spoken aloud and the UI can be explored
+        via gestures.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_canRequestEnahncedWebAccessibility">request enhanced web accessibility</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_canRequestEnahncedWebAccessibility">Allows the hoder to request
+        enabling of web accessibility enhancements. For example, installing scripts from
+        Google to make app content more accessible.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_bindTextService">bind to a text service</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_bindTextService">Allows the holder to bind to the top-level
@@ -2695,25 +2714,6 @@
     <!-- SearchView accessibility description for voice button [CHAR LIMIT=NONE] -->
     <string name="searchview_description_voice">Voice search</string>
 
-    <!-- Title for a warning message about the interaction model changes after allowing an accessibility
-         service to put the device into explore by touch mode, displayed as a dialog message when
-         the user selects to enables the service. (default). [CHAR LIMIT=45] -->
-    <string name="enable_explore_by_touch_warning_title">Enable Explore by Touch?</string>
-    <!-- Summary for a warning message about the interaction model changes after allowing an accessibility
-         service to put the device into explore by touch mode, displayed as a dialog message when
-         the user selects to enables the service. (tablet). [CHAR LIMIT=NONE] -->
-    <string name="enable_explore_by_touch_warning_message" product="tablet">
-            <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch.
-            When Explore by Touch is turned on, you can hear or see descriptions of what\'s under
-            your finger or perform gestures to interact with the tablet.</string>
-    <!-- Summary for a warning message about the interaction model changes after allowing an accessibility
-         service to put the device into explore by touch mode, displayed as a dialog message when
-         the user selects to enables the service. (default). [CHAR LIMIT=NONE] -->
-    <string name="enable_explore_by_touch_warning_message" product="default">
-            <xliff:g id="accessibility_service_name">%1$s</xliff:g> wants to enable Explore by Touch.
-            When Explore by Touch is turned on, you can hear or see descriptions of what\'s under
-            your finger or perform gestures to interact with the phone.</string>
-
     <!-- String used to display the date. This is the string to say something happened 1 month ago. -->
     <string name="oneMonthDurationPast">1 month ago</string>
     <!-- String used to display the date. This is the string to say something happened more than 1 month ago. -->
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index fc0ff55..695c2aa 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 96;
+    private static final int DATABASE_VERSION = 97;
 
     private Context mContext;
     private int mUserHandle;
@@ -1536,6 +1536,22 @@
             upgradeVersion = 96;
         }
 
+        if (upgradeVersion == 96) {
+            // Remove Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                try {
+                    db.execSQL("DELETE FROM system WHERE name='"
+                            + Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES
+                            + "'");
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
+            upgradeVersion = 97;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index b7c3450..93187c10 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -23,15 +23,12 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.IAccessibilityServiceClient;
 import android.accessibilityservice.IAccessibilityServiceConnection;
-import android.app.AlertDialog;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
@@ -70,7 +67,6 @@
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
-import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityManager;
@@ -161,8 +157,6 @@
 
     private Service mQueryBridge;
 
-    private AlertDialog mEnableTouchExplorationDialog;
-
     private AccessibilityInputFilter mInputFilter;
 
     private boolean mHasInputFilter;
@@ -250,12 +244,6 @@
                             persistComponentNamesToSettingLocked(
                                     Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
                                     state.mEnabledServices, userId);
-                            // Update the touch exploration granted services setting.
-                            state.mTouchExplorationGrantedServices.remove(comp);
-                            persistComponentNamesToSettingLocked(
-                                    Settings.Secure.
-                                            TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
-                                    state.mEnabledServices, userId);
                             return;
                         }
                     }
@@ -534,6 +522,9 @@
             // No touch exploration.
             userState.mIsTouchExplorationEnabled = false;
 
+            // No touch enhanced web accessibility.
+            userState.mIsEnhancedWebAccessibilityEnabled = false;
+
             // Hook the automation service up.
             mUiAutomationService = new Service(mCurrentUserId, componentName,
                     accessibilityServiceInfo, true);
@@ -559,16 +550,14 @@
         synchronized (mLock) {
             UserState userState = getCurrentUserStateLocked();
             // Stash the old state so we can restore it when the keyguard is gone.
-            mTempStateChangeForCurrentUserMemento.initialize(mCurrentUserId,
-                    getCurrentUserStateLocked());
+            mTempStateChangeForCurrentUserMemento.initialize(getCurrentUserStateLocked());
             // Set the temporary state.
             userState.mIsAccessibilityEnabled = true;
-            userState.mIsTouchExplorationEnabled= touchExplorationEnabled;
+            userState.mIsTouchExplorationEnabled = touchExplorationEnabled;
+            userState.mIsEnhancedWebAccessibilityEnabled = false;
             userState.mIsDisplayMagnificationEnabled = false;
             userState.mEnabledServices.clear();
             userState.mEnabledServices.add(service);
-            userState.mTouchExplorationGrantedServices.clear();
-            userState.mTouchExplorationGrantedServices.add(service);
             // Update the internal state.
             performServiceManagementLocked(userState);
             scheduleUpdateInputFilter(userState);
@@ -842,14 +831,6 @@
                 userState.mEnabledServices);
     }
 
-    private void populateTouchExplorationGrantedAccessibilityServicesLocked(
-            UserState userState) {
-        populateComponentNamesFromSettingLocked(
-                Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
-                userState.mUserId,
-                userState.mTouchExplorationGrantedServices);
-    }
-
     /**
      * Performs {@link AccessibilityService}s delayed notification. The delay is configurable
      * and denotes the period after the last event before notifying the service.
@@ -896,6 +877,7 @@
             userState.mComponentNameToServiceMap.put(service.mComponentName, service);
             scheduleUpdateInputFilter(userState);
             tryEnableTouchExplorationLocked(service);
+            tryEnableEnhancedWebAccessibilityLocked(service);
         } catch (RemoteException e) {
             /* do nothing */
         }
@@ -918,6 +900,7 @@
         service.dispose();
         scheduleUpdateInputFilter(userState);
         tryDisableTouchExplorationLocked(service);
+        tryDisableEnhancedWebAccessibilityLocked(service);
         return removed;
     }
 
@@ -937,7 +920,7 @@
     private boolean canDispathEventLocked(Service service, AccessibilityEvent event,
             int handledFeedbackTypes) {
 
-        if (!service.canReceiveEvents()) {
+        if (!service.canReceiveEventsLocked()) {
             return false;
         }
 
@@ -1140,53 +1123,6 @@
         }
     }
 
-    private void showEnableTouchExplorationDialog(final Service service) {
-        String label = service.mResolveInfo.loadLabel(
-                mContext.getPackageManager()).toString();
-        synchronized (mLock) {
-            final UserState state = getCurrentUserStateLocked();
-            if (state.mIsTouchExplorationEnabled) {
-                return;
-            }
-            if (mEnableTouchExplorationDialog != null
-                    && mEnableTouchExplorationDialog.isShowing()) {
-                return;
-            }
-            mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext)
-                .setIconAttribute(android.R.attr.alertDialogIcon)
-                .setPositiveButton(android.R.string.ok, new OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        // The user allowed the service to toggle touch exploration.
-                        state.mTouchExplorationGrantedServices.add(service.mComponentName);
-                        persistComponentNamesToSettingLocked(
-                                Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
-                                       state.mTouchExplorationGrantedServices, state.mUserId);
-                        // Enable touch exploration.
-                        Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                                Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1,
-                                service.mUserId);
-                    }
-                })
-                .setNegativeButton(android.R.string.cancel, new OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        dialog.dismiss();
-                    }
-                })
-                .setTitle(R.string.enable_explore_by_touch_warning_title)
-                .setMessage(mContext.getString(
-                        R.string.enable_explore_by_touch_warning_message, label))
-                .create();
-            mEnableTouchExplorationDialog.getWindow().setType(
-                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-            mEnableTouchExplorationDialog.getWindow().getAttributes().privateFlags
-                    |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-            mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true);
-            mEnableTouchExplorationDialog.show();
-        }
-    }
-
     private int getClientState(UserState userState) {
         int clientState = 0;
         if (userState.mIsAccessibilityEnabled) {
@@ -1202,7 +1138,6 @@
     private void recreateInternalStateLocked(UserState userState) {
         populateInstalledAccessibilityServiceLocked(userState);
         populateEnabledAccessibilityServicesLocked(userState);
-        populateTouchExplorationGrantedAccessibilityServicesLocked(userState);
 
         handleTouchExplorationEnabledSettingChangedLocked(userState);
         handleDisplayMagnificationEnabledSettingChangedLocked(userState);
@@ -1240,40 +1175,21 @@
                 0, userState.mUserId) == 1;
     }
 
-    private void handleTouchExplorationGrantedAccessibilityServicesChangedLocked(
-            UserState userState) {
-        final int serviceCount = userState.mServices.size();
-        for (int i = 0; i < serviceCount; i++) {
-            Service service = userState.mServices.get(i);
-            if (service.mRequestTouchExplorationMode
-                    && userState.mTouchExplorationGrantedServices.contains(
-                            service.mComponentName)) {
-                tryEnableTouchExplorationLocked(service);
-                return;
-            }
+    private void tryEnableTouchExplorationLocked(Service service) {
+        if (!service.mRequestTouchExplorationMode || !service.canReceiveEventsLocked()) {
+            return;
         }
-        if (userState.mIsTouchExplorationEnabled) {
-            Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0, userState.mUserId);
-        }
-    }
-
-    private void tryEnableTouchExplorationLocked(final Service service) {
         UserState userState = getUserStateLocked(service.mUserId);
-        if (!userState.mIsTouchExplorationEnabled && service.mRequestTouchExplorationMode
-                && service.canReceiveEvents()) {
-            final boolean canToggleTouchExploration =
-                    userState.mTouchExplorationGrantedServices.contains(service.mComponentName);
-            if (!service.mIsAutomation && !canToggleTouchExploration) {
-                showEnableTouchExplorationDialog(service);
-            } else {
-                Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                        Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, userState.mUserId);
-            }
+        if (!userState.mIsTouchExplorationEnabled) {
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1, userState.mUserId);
         }
     }
 
     private void tryDisableTouchExplorationLocked(Service service) {
+        if (!service.mRequestTouchExplorationMode) {
+            return;
+        }
         UserState userState = getUserStateLocked(service.mUserId);
         if (userState.mIsTouchExplorationEnabled) {
             final int serviceCount = userState.mServices.size();
@@ -1288,6 +1204,35 @@
         }
     }
 
+    private void tryEnableEnhancedWebAccessibilityLocked(Service service) {
+        if (!service.mRequestEnhancedWebAccessibility || !service.canReceiveEventsLocked()) {
+            return;
+        }
+        UserState userState = getUserStateLocked(service.mUserId);
+        if (!userState.mIsEnhancedWebAccessibilityEnabled) {
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1, userState.mUserId);
+        }
+    }
+
+    private void tryDisableEnhancedWebAccessibilityLocked(Service service) {
+        if (!service.mRequestEnhancedWebAccessibility) {
+            return;
+        }
+        UserState userState = getUserStateLocked(service.mUserId);
+        if (userState.mIsEnhancedWebAccessibilityEnabled) {
+            final int serviceCount = userState.mServices.size();
+            for (int i = 0; i < serviceCount; i++) {
+                Service other = userState.mServices.get(i);
+                if (other != service && other.mRequestEnhancedWebAccessibility) {
+                    return;
+                }
+            }
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0, userState.mUserId);
+        }
+    }
+
     @Override
     public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
         mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
@@ -1494,6 +1439,8 @@
 
         boolean mRequestTouchExplorationMode;
 
+        boolean mRequestEnhancedWebAccessibility;
+
         int mFetchFlags;
 
         long mNotificationTimeout;
@@ -1547,9 +1494,6 @@
             mIsAutomation = isAutomation;
             if (!isAutomation) {
                 mCanRetrieveScreenContent = accessibilityServiceInfo.getCanRetrieveWindowContent();
-                mRequestTouchExplorationMode =
-                    (accessibilityServiceInfo.flags
-                            & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
                 mIntent = new Intent().setComponent(mComponentName);
                 mIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                         com.android.internal.R.string.accessibility_binding_label);
@@ -1582,18 +1526,39 @@
                     & AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS) != 0 ?
                             AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS : 0;
 
-            mRequestTouchExplorationMode = (info.flags
-                    & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
+            if (mResolveInfo != null) {
+                String packageName = mResolveInfo.serviceInfo.packageName;
+
+                if (mContext.getPackageManager().checkPermission(
+                        android.Manifest.permission.CAN_REQUEST_TOUCH_EXPLORATION_MODE,
+                        packageName) == PackageManager.PERMISSION_GRANTED) {
+                    mRequestTouchExplorationMode = (info.flags
+                            & AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
+                }
+
+                if (mContext.getPackageManager().checkPermission(
+                        android.Manifest.permission.CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY,
+                        packageName) == PackageManager.PERMISSION_GRANTED) {
+                    mRequestEnhancedWebAccessibility = (info.flags
+                           & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
+                }
+            }
 
             // If this service is up and running we may have to enable touch
-            // exploration, otherwise this will happen when the service connects.
+            // exploration or enhanced web accessibility, otherwise this will
+            // happen when the service connects.
             synchronized (mLock) {
-                if (canReceiveEvents()) {
+                if (canReceiveEventsLocked()) {
                     if (mRequestTouchExplorationMode) {
                         tryEnableTouchExplorationLocked(this);
                     } else {
                         tryDisableTouchExplorationLocked(this);
                     }
+                    if (mRequestEnhancedWebAccessibility) {
+                        tryEnableEnhancedWebAccessibilityLocked(this);
+                    } else {
+                        tryDisableEnhancedWebAccessibilityLocked(this);
+                    }
                 }
             }
         }
@@ -1630,7 +1595,7 @@
             return false;
         }
 
-        public boolean canReceiveEvents() {
+        public boolean canReceiveEventsLocked() {
             return (mEventTypes != 0 && mFeedbackType != 0 && mService != null);
         }
 
@@ -2484,9 +2449,6 @@
 
         public final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
 
-        public final Set<ComponentName> mTouchExplorationGrantedServices =
-                new HashSet<ComponentName>();
-
         public final SparseArray<AccessibilityConnectionWrapper>
                 mInteractionConnections =
                 new SparseArray<AccessibilityConnectionWrapper>();
@@ -2497,6 +2459,7 @@
 
         public boolean mIsAccessibilityEnabled;
         public boolean mIsTouchExplorationEnabled;
+        public boolean mIsEnhancedWebAccessibilityEnabled;
         public boolean mIsDisplayMagnificationEnabled;
 
         public UserState(int userId) {
@@ -2508,36 +2471,37 @@
         public int mUserId = UserHandle.USER_NULL;
         public boolean mIsAccessibilityEnabled;
         public boolean mIsTouchExplorationEnabled;
+        public boolean mIsEnhancedWebAccessibilityEnabled;
         public boolean mIsDisplayMagnificationEnabled;
         public final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
         public final Set<ComponentName> mTouchExplorationGrantedServices =
                 new HashSet<ComponentName>();
 
-        public void initialize(int userId, UserState userState) {
-            mUserId = userId;
+        public void initialize(UserState userState) {
+            mUserId = userState.mUserId;
             mIsAccessibilityEnabled = userState.mIsAccessibilityEnabled;
             mIsTouchExplorationEnabled = userState.mIsTouchExplorationEnabled;
+            mIsEnhancedWebAccessibilityEnabled = userState.mIsEnhancedWebAccessibilityEnabled;
             mIsDisplayMagnificationEnabled = userState.mIsDisplayMagnificationEnabled;
             mEnabledServices.clear();
             mEnabledServices.addAll(userState.mEnabledServices);
             mTouchExplorationGrantedServices.clear();
-            mTouchExplorationGrantedServices.addAll(userState.mTouchExplorationGrantedServices);
         }
 
         public void applyTo(UserState userState) {
             userState.mIsAccessibilityEnabled = mIsAccessibilityEnabled;
             userState.mIsTouchExplorationEnabled = mIsTouchExplorationEnabled;
+            userState.mIsEnhancedWebAccessibilityEnabled = mIsEnhancedWebAccessibilityEnabled;
             userState.mIsDisplayMagnificationEnabled = mIsDisplayMagnificationEnabled;
             userState.mEnabledServices.clear();
             userState.mEnabledServices.addAll(mEnabledServices);
-            userState.mTouchExplorationGrantedServices.clear();
-            userState.mTouchExplorationGrantedServices.addAll(mTouchExplorationGrantedServices);
         }
 
         public void clear() {
             mUserId = UserHandle.USER_NULL;
             mIsAccessibilityEnabled = false;
             mIsTouchExplorationEnabled = false;
+            mIsEnhancedWebAccessibilityEnabled = false;
             mIsDisplayMagnificationEnabled = false;
             mEnabledServices.clear();
             mTouchExplorationGrantedServices.clear();
@@ -2558,9 +2522,6 @@
         private final Uri mEnabledAccessibilityServicesUri = Settings.Secure.getUriFor(
                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
 
-        private final Uri mTouchExplorationGrantedAccessibilityServicesUri = Settings.Secure
-                .getUriFor(Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
-
         public AccessibilityContentObserver(Handler handler) {
             super(handler);
         }
@@ -2574,9 +2535,6 @@
                     false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(mEnabledAccessibilityServicesUri,
                     false, this, UserHandle.USER_ALL);
-            contentResolver.registerContentObserver(
-                    mTouchExplorationGrantedAccessibilityServicesUri,
-                    false, this, UserHandle.USER_ALL);
         }
 
         @Override
@@ -2621,15 +2579,6 @@
                         manageServicesLocked(userState);
                     }
                 }
-            } else if (mTouchExplorationGrantedAccessibilityServicesUri.equals(uri)) {
-                synchronized (mLock) {
-                    // We will update when the automation service dies.
-                    if (mUiAutomationService == null) {
-                        UserState userState = getCurrentUserStateLocked();
-                        populateTouchExplorationGrantedAccessibilityServicesLocked(userState);
-                        handleTouchExplorationGrantedAccessibilityServicesChangedLocked(userState);
-                    }
-                }
             }
         }
     }