3244931 ANR while in settings attempting to enable Accessibility->Talkabout (IKXEVEREST-1847)

Change-Id: Ifea9324671d0e80a417f4b2fe6dbbe981f8b0679
diff --git a/src/com/android/settings/AccessibilitySettings.java b/src/com/android/settings/AccessibilitySettings.java
index f0c2b02..6cc5508 100644
--- a/src/com/android/settings/AccessibilitySettings.java
+++ b/src/com/android/settings/AccessibilitySettings.java
@@ -21,10 +21,7 @@
 import android.app.Service;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.SystemProperties;
@@ -51,7 +48,7 @@
     private static final String DEFAULT_SCREENREADER_MARKET_LINK =
         "market://search?q=pname:com.google.android.marvin.talkback";
 
-    private final String TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX =
+    private final String TOGGLE_ACCESSIBILITY_CHECKBOX =
         "toggle_accessibility_service_checkbox";
 
     private static final String ACCESSIBILITY_SERVICES_CATEGORY =
@@ -63,9 +60,12 @@
     private static final String POWER_BUTTON_CATEGORY =
         "power_button_category";
 
-    private final String POWER_BUTTON_ENDS_CALL_CHECKBOX =
+    private static final String POWER_BUTTON_ENDS_CALL_CHECKBOX =
         "power_button_ends_call";
 
+    private final String KEY_TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX =
+        "key_toggle_accessibility_service_checkbox";
+
     private static final int DIALOG_ID_DISABLE_ACCESSIBILITY = 1;
     private static final int DIALOG_ID_ENABLE_SCRIPT_INJECTION = 2;
     private static final int DIALOG_ID_ENABLE_ACCESSIBILITY_SERVICE = 3;
@@ -96,7 +96,7 @@
             (PreferenceGroup) findPreference(ACCESSIBILITY_SERVICES_CATEGORY);
 
         mToggleAccessibilityCheckBox = (CheckBoxPreference) findPreference(
-                TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX);
+                TOGGLE_ACCESSIBILITY_CHECKBOX);
 
         mToggleScriptInjectionCheckBox = (CheckBoxPreference) findPreference(
                 TOGGLE_ACCESSIBILITY_SCRIPT_INJECTION_CHECKBOX);
@@ -131,16 +131,7 @@
     }
 
     @Override
-    public void onPause() {
-        super.onPause();
-
-        persistEnabledAccessibilityServices();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
+    public void onActivityCreated(Bundle savedInstanceState) {
         addAccessibilitServicePreferences();
 
         final HashSet<String> enabled = new HashSet<String>();
@@ -169,6 +160,9 @@
         if (!accessibilityServices.isEmpty()) {
             if (serviceState == 1) {
                 mToggleAccessibilityCheckBox.setChecked(true);
+                if (savedInstanceState != null) {
+                    restoreInstanceStrate(savedInstanceState);
+                }
             } else {
                 setAccessibilityServicePreferencesState(false);
             }
@@ -182,7 +176,41 @@
             mToggleAccessibilityCheckBox.setEnabled(false);
             // Notify user that they do not have any accessibility apps
             // installed and direct them to Market to get TalkBack
-            displayNoAppsAlert();
+            showDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES);
+        }
+
+        super.onActivityCreated(savedInstanceState);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+
+        persistEnabledAccessibilityServices();
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        if (mToggleAccessibilityServiceCheckBox != null) {
+            outState.putString(KEY_TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX,
+                    mToggleAccessibilityServiceCheckBox.getKey());
+        }
+    }
+
+    /**
+     * Restores the instance state from <code>savedInstanceState</code>.
+     */
+    private void restoreInstanceStrate(Bundle savedInstanceState) {
+        String key = savedInstanceState.getString(KEY_TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX);
+        if (key != null) {
+            Preference preference = findPreference(key);
+            if (!(preference instanceof CheckBoxPreference)) {
+                throw new IllegalArgumentException(
+                        KEY_TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX
+                                + " must be mapped to an instance of a "
+                                + CheckBoxPreference.class.getName());
+            }
+            mToggleAccessibilityServiceCheckBox = (CheckBoxPreference) preference;
         }
     }
 
@@ -208,7 +236,7 @@
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
         final String key = preference.getKey();
 
-        if (TOGGLE_ACCESSIBILITY_SERVICE_CHECKBOX.equals(key)) {
+        if (TOGGLE_ACCESSIBILITY_CHECKBOX.equals(key)) {
             handleEnableAccessibilityStateChange((CheckBoxPreference) preference);
         } else if (POWER_BUTTON_ENDS_CALL_CHECKBOX.equals(key)) {
             boolean isChecked = ((CheckBoxPreference) preference).isChecked();
@@ -327,22 +355,6 @@
         }
     }
 
-    /**
-     * Displays a message telling the user that they do not have any accessibility
-     * related apps installed and that they can get TalkBack (Google's free screen
-     * reader) from Market.
-     */
-    private void displayNoAppsAlert() {
-        try {
-            PackageManager pm = getActivity().getPackageManager();
-            ApplicationInfo info = pm.getApplicationInfo("com.android.vending", 0);
-            showDialog(DIALOG_ID_NO_ACCESSIBILITY_SERVICES);
-        } catch (NameNotFoundException e) {
-            // This is a no-op if the user does not have Android Market
-            return;
-        }
-    }
-
     @Override
     public Dialog onCreateDialog(int dialogId) {
         switch (dialogId) {
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index a2f701d..6f0c91f 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -23,7 +23,6 @@
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.content.res.Resources;
 import android.os.Bundle;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceFragment;
@@ -49,9 +48,6 @@
 
     private SettingsDialogFragment mDialogFragment;
 
-    private int mResultCode = Activity.RESULT_CANCELED;
-    private Intent mResultData;
-
     private Button mNextButton;
 
     @Override
@@ -114,18 +110,55 @@
     }
 
     public static class SettingsDialogFragment extends DialogFragment {
+        private static final String KEY_DIALOG_ID = "key_dialog_id";
+        private static final String KEY_PARENT_FRAGMENT_ID = "key_parent_fragment_id";
+
         private int mDialogId;
 
-        private DialogCreatable mFragment;
+        private Fragment mParentFragment;
+
+        public SettingsDialogFragment() {
+            /* do nothing */
+        }
 
         public SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
             mDialogId = dialogId;
-            mFragment = fragment;
+            if (!(fragment instanceof Fragment)) {
+                throw new IllegalArgumentException("fragment argument must be an instance of "
+                        + Fragment.class.getName());
+            }
+            mParentFragment = (Fragment) fragment;
+        }
+
+        @Override
+        public void onActivityCreated(Bundle savedInstanceState) {
+            if (savedInstanceState != null) {
+                mDialogId = savedInstanceState.getInt(KEY_DIALOG_ID, 0);
+                int mParentFragmentId = savedInstanceState.getInt(KEY_PARENT_FRAGMENT_ID, -1);
+                if (mParentFragmentId > -1) {
+                    mParentFragment = getFragmentManager().findFragmentById(mParentFragmentId);
+                    if (!(mParentFragment instanceof DialogCreatable)) {
+                        throw new IllegalArgumentException(
+                                KEY_PARENT_FRAGMENT_ID + " must implement "
+                                        + DialogCreatable.class.getName());
+                    }
+                }
+            }
+            super.onActivityCreated(savedInstanceState);
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+            if (mParentFragment != null) {
+                outState.putInt(KEY_DIALOG_ID, mDialogId);
+                outState.putInt(KEY_PARENT_FRAGMENT_ID, mParentFragment.getId());
+            }
         }
 
         @Override
         public Dialog onCreateDialog(Bundle savedInstanceState) {
-            return mFragment.onCreateDialog(mDialogId);
+            return ((DialogCreatable) mParentFragment).onCreateDialog(mDialogId);
         }
 
         public int getDialogId() {