Handle the case where no spell checker is selected.

This follows up to a previous CL [1] that fixed Bug 26685795 that the
Settings app crashes when no spell checker is selected, but introduced
another Bug 26686710 that the user cannot re-select the spell checker
once the device has fallen into that state because the button to select
new spell checker is disabled.

This CL tries to deal with such a case more carefully and gracefully, by
adding more null checking and by showing a meaningful text
("Not selected" for English) to users when no spell checker is currently
selected.

  [1]: I65e6d269572e064aa6897807b6611ef947d90211
       093a6467723208be9c776af7e2b0fdca9841ad20

Bug: 26108333
Bug: 26685795
Bug: 26686710
Change-Id: I0ed71bbb580e3547d97e321799ac2b77b1f284a3
diff --git a/res/values/strings.xml b/res/values/strings.xml
index dfc17a2..b45c1d3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7238,6 +7238,9 @@
     <!-- [CHAR LIMIT=30] Title for dialog for setting to control the default spell checker -->
     <string name="choose_spell_checker">Choose spell checker</string>
 
+    <!-- [CHAR LIMIT=30] Label for the placeholder of the current spell checker name.  Used when no spell checker is currently selected. -->
+    <string name="spell_checker_not_selected">Not selected</string>
+
     <!-- Notification log debug tool: missing title -->
     <string name="notification_log_no_title">(none)</string>
     <!-- Notification log debug tool: delimiter between header and field data -->
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index 1318a1b..fb0a4d5 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -261,12 +261,16 @@
         if (spellChecker != null) {
             final TextServicesManager tsm = (TextServicesManager) getSystemService(
                     Context.TEXT_SERVICES_MANAGER_SERVICE);
-            final SpellCheckerInfo sci = tsm.getCurrentSpellChecker();
-            spellChecker.setEnabled(sci != null);
-            if (tsm.isSpellCheckerEnabled() && sci != null) {
-                spellChecker.setSummary(sci.loadLabel(getPackageManager()));
-            } else {
+            if (!tsm.isSpellCheckerEnabled()) {
+                spellChecker.setEnabled(false);
                 spellChecker.setSummary(R.string.switch_off_text);
+            } else {
+                final SpellCheckerInfo sci = tsm.getCurrentSpellChecker();
+                if (sci != null) {
+                    spellChecker.setSummary(sci.loadLabel(getPackageManager()));
+                } else {
+                    spellChecker.setSummary(R.string.spell_checker_not_selected);
+                }
             }
         }
 
diff --git a/src/com/android/settings/inputmethod/SpellCheckersSettings.java b/src/com/android/settings/inputmethod/SpellCheckersSettings.java
index ad6a17b..bc2a5c0 100644
--- a/src/com/android/settings/inputmethod/SpellCheckersSettings.java
+++ b/src/com/android/settings/inputmethod/SpellCheckersSettings.java
@@ -73,19 +73,17 @@
     }
 
     private void populatePreferenceScreen() {
-        final PreferenceScreen screen = getPreferenceScreen();
-        final Context context = getActivity();
-        final int count = (mEnabledScis == null) ? 0 : mEnabledScis.length;
-
-        for (int index = 0; index < count; ++index) {
-            final SpellCheckerInfo sci = mEnabledScis[index];
-        }
         final SpellCheckerPreference pref = new SpellCheckerPreference(getPrefContext(),
                 mEnabledScis);
         pref.setTitle(R.string.default_spell_checker);
-        pref.setSummary("%s");
+        final int count = (mEnabledScis == null) ? 0 : mEnabledScis.length;
+        if (count > 0) {
+            pref.setSummary("%s");
+        } else {
+            pref.setSummary(R.string.spell_checker_not_selected);
+        }
         pref.setOnPreferenceChangeListener(this);
-        screen.addPreference(pref);
+        getPreferenceScreen().addPreference(pref);
     }
 
     @Override
@@ -114,8 +112,13 @@
         final boolean isSpellCheckerEnabled = mTsm.isSpellCheckerEnabled();
         mSwitchBar.setChecked(isSpellCheckerEnabled);
 
-        final SpellCheckerSubtype currentScs = mTsm.getCurrentSpellCheckerSubtype(
-                false /* allowImplicitlySelectedSubtype */);
+        final SpellCheckerSubtype currentScs;
+        if (mCurrentSci == null) {
+            currentScs = mTsm.getCurrentSpellCheckerSubtype(
+                    false /* allowImplicitlySelectedSubtype */);
+        } else {
+            currentScs = null;
+        }
         mSpellCheckerLanaguagePref.setSummary(getSpellCheckerSubtypeLabel(mCurrentSci, currentScs));
 
         final PreferenceScreen screen = getPreferenceScreen();
@@ -128,12 +131,13 @@
                 pref.setSelected(mCurrentSci);
             }
         }
+        mSpellCheckerLanaguagePref.setEnabled(isSpellCheckerEnabled && mCurrentSci != null);
     }
 
     private CharSequence getSpellCheckerSubtypeLabel(final SpellCheckerInfo sci,
             final SpellCheckerSubtype subtype) {
         if (sci == null) {
-            return null;
+            return getString(R.string.spell_checker_not_selected);
         }
         if (subtype == null) {
             return getString(R.string.use_system_language_to_select_input_method_subtypes);
@@ -173,6 +177,11 @@
             mDialog.dismiss();
         }
         final SpellCheckerInfo currentSci = mTsm.getCurrentSpellChecker();
+        if (currentSci == null) {
+            // This can happen in some situations.  One example is that the package that the current
+            // spell checker belongs to was uninstalled or being in background.
+            return;
+        }
         final SpellCheckerSubtype currentScs = mTsm.getCurrentSpellCheckerSubtype(
                 false /* allowImplicitlySelectedSubtype */);
         final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());