WebView accessibility support - Adding opt-in setting for enabling accessibility script injection from Google

Change-Id: I1676f34c30a0e9414d51060ad4fb2c9c502b09c3
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 84bc6cc..7581275 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2122,10 +2122,21 @@
         </string>
     <!-- Message for the prompt that lets users know that they have no accessibility related apps
          installed and that they can install TalkBack from Market. -->
-    <string name="accessibility_service_no_apps_message">You do not have any accessibility related
+    <string name="accessibility_service_no_apps_message">You do not have any accessibility-related
         applications installed.\n\nYou can download a screen reader for your device from Android
         Market.\n\nClick "OK" to install the screen reader.</string>
 
+    <!-- Accessibility settings: Webpage accessibility scripts category [CHAR LIMIT=25] -->
+    <string name="accessibility_script_injection_category">Accessibility scripts</string>
+    <!-- Accessibility settings: Checkbox title for enabling download of accessibility scripts [CHAR LIMIT=40] -->
+    <string name="accessibility_script_injection_enabled">Download accessibility scripts</string>
+    <!-- Accessibility settings: Checkbox summary for enabling download of accessibility scripts [CHAR LIMIT=65] -->
+    <string name="accessibility_script_injection_enabled_summary">Allow applications to download accessibility scripts from Google</string>
+    <!-- Warning message about security implications of downloading accessibility scripts,
+         displayed as a dialog message when the user selects to enable script downloading. [CHAR LIMIT="NONE"] -->
+    <string name="accessibility_script_injection_security_warning">Some applications can ask Google
+        to download scripts to your phone that make their content more accessible. Are you sure you
+        want to allow Google to install accessibility scripts on your phone?</string>
     <!-- Accessibility settings: Power button category -->
     <string name="accessibility_power_button_category">Power button</string>
     <!-- Accessibility settings: checkbox title for power button behavior -->
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index f82af85..f2efb27 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -26,6 +26,15 @@
     <PreferenceCategory android:key="accessibility_services_category"
             android:title="@string/accessibility_services_category" />
 
+    <PreferenceCategory android:key="accessibility_script_injection_category"
+            android:title="@string/accessibility_script_injection_category">
+        <CheckBoxPreference
+                android:key="toggle_accessibility_script_injection_checkbox"
+                android:title="@string/accessibility_script_injection_enabled"
+                android:summary="@string/accessibility_script_injection_enabled_summary"
+                android:persistent="false" />
+    </PreferenceCategory>
+
     <PreferenceCategory android:key="power_button_category"
             android:title="@string/accessibility_power_button_category">
         <CheckBoxPreference
diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java
index 5737065..104ee9e 100644
--- a/src/com/android/settings/AccessibilitySettings.java
+++ b/src/com/android/settings/AccessibilitySettings.java
@@ -56,6 +56,9 @@
     private static final String ACCESSIBILITY_SERVICES_CATEGORY =
         "accessibility_services_category";
 
+    private static final String TOGGLE_ACCESSIBILITY_SCRIPT_INJECTION_CHECKBOX =
+        "toggle_accessibility_script_injection_checkbox";
+
     private static final String POWER_BUTTON_CATEGORY =
         "power_button_category";
 
@@ -64,6 +67,8 @@
 
     private CheckBoxPreference mToggleCheckBox;
 
+    private CheckBoxPreference mToggleScriptInjectionCheckBox;
+
     private PreferenceCategory mPowerButtonCategory;
     private CheckBoxPreference mPowerButtonEndsCallCheckBox;
 
@@ -81,11 +86,14 @@
         addPreferencesFromResource(R.xml.accessibility_settings);
 
         mToggleCheckBox = (CheckBoxPreference) findPreference(
-            TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX);
+                TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX);
+
+        mToggleScriptInjectionCheckBox = (CheckBoxPreference) findPreference(
+                TOGGLE_ACCESSIBILITY_SCRIPT_INJECTION_CHECKBOX);
 
         mPowerButtonCategory = (PreferenceCategory) findPreference(POWER_BUTTON_CATEGORY);
         mPowerButtonEndsCallCheckBox = (CheckBoxPreference) findPreference(
-            POWER_BUTTON_ENDS_CALL_CHECKBOX);
+                POWER_BUTTON_ENDS_CALL_CHECKBOX);
 
         addAccessibilitServicePreferences();
 
@@ -131,6 +139,12 @@
             displayNoAppsAlert();
         }
 
+        // set the accessibility script injection category
+        boolean scriptInjectionEnabled = (Settings.Secure.getInt(getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1);
+        mToggleScriptInjectionCheckBox.setChecked(scriptInjectionEnabled);
+        mToggleScriptInjectionCheckBox.setEnabled(true);
+
         if (KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_POWER)
                 && Utils.isVoiceCapable(getActivity())) {
             int incallPowerBehavior = Settings.Secure.getInt(getContentResolver(),
@@ -180,7 +194,6 @@
         final String key = preference.getKey();
 
         if (TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX.equals(key)) {
-            boolean isChecked = ((CheckBoxPreference) preference).isChecked();
             handleEnableAccessibilityStateChange((CheckBoxPreference) preference);
         } else if (POWER_BUTTON_ENDS_CALL_CHECKBOX.equals(key)) {
             boolean isChecked = ((CheckBoxPreference) preference).isChecked();
@@ -191,6 +204,8 @@
                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
                     (isChecked ? Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP
                             : Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF));
+        } else if (TOGGLE_ACCESSIBILITY_SCRIPT_INJECTION_CHECKBOX.equals(key)) {
+            handleToggleAccessibilityScriptInjection((CheckBoxPreference) preference);
         } else if (preference instanceof CheckBoxPreference) {
             handleEnableAccessibilityServiceStateChange((CheckBoxPreference) preference);
         }
@@ -237,6 +252,42 @@
     }
 
     /**
+     * Handles the change of the accessibility script injection setting state.
+     *
+     * @param preference The preference for enabling/disabling accessibility script injection.
+     */
+    private void handleToggleAccessibilityScriptInjection(CheckBoxPreference preference) {
+        if (preference.isChecked()) {
+            final CheckBoxPreference checkBoxPreference = preference;
+            // TODO: DialogFragment?
+            AlertDialog dialog = (new AlertDialog.Builder(getActivity()))
+                .setTitle(android.R.string.dialog_alert_title)
+                .setIcon(android.R.drawable.ic_dialog_alert)
+                .setMessage(getActivity().getString(
+                        R.string.accessibility_script_injection_security_warning))
+                .setCancelable(true)
+                .setPositiveButton(android.R.string.ok,
+                    new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            Settings.Secure.putInt(getContentResolver(),
+                            Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 1);
+                        }
+                })
+                .setNegativeButton(android.R.string.cancel,
+                    new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            checkBoxPreference.setChecked(false);
+                        }
+                    })
+                .create();
+                dialog.show();
+        } else {
+            Settings.Secure.putInt(getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0);
+        }
+    }
+
+    /**
      * Handles the change of the preference for enabling/disabling an AccessibilityService.
      *
      * @param preference The preference.