Fix bug #16958103 android.content.res.Resources$NotFoundException: String resource ID #0x7f080971

- remove the indexing offending part from InputMethodAndLanguageSettings as the strings
has been changed
- add indexing for VoiceInputSettings

Change-Id: Ib8da55c935e00538ad6fff2f2590b0d525140734
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index b8ae493..c8b86ae 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -673,8 +673,8 @@
         public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
             List<SearchIndexableRaw> indexables = new ArrayList<>();
 
-            Resources resources = context.getResources();
-            String screenTitle = context.getString(R.string.language_keyboard_settings_title);
+            final Resources resources = context.getResources();
+            final String screenTitle = context.getString(R.string.language_keyboard_settings_title);
 
             // Locale picker.
             if (context.getAssets().getLocales().length > 1) {
@@ -836,44 +836,12 @@
                 indexables.add(indexable);
             }
 
-            // Voice recognizers.
-            List<ResolveInfo> recognizers = context.getPackageManager()
-                    .queryIntentServices(new Intent(RecognitionService.SERVICE_INTERFACE),
-                            PackageManager.GET_META_DATA);
-
-            final int recognizerCount = recognizers.size();
-
-            // Recognizer settings.
-            if (recognizerCount > 0) {
-                indexable = new SearchIndexableRaw(context);
-                indexable.key = "recognizer_settings";
-                indexable.title = context.getString(R.string.recognizer_settings_title);
-                indexable.screenTitle = screenTitle;
-                indexables.add(indexable);
-            }
-
-            if (recognizerCount > 1) {
-                // Recognizer chooser.
-                indexable = new SearchIndexableRaw(context);
-                indexable.key = "recognizer_title";
-                indexable.title = context.getString(R.string.recognizer_title);
-                indexable.screenTitle = screenTitle;
-                indexables.add(indexable);
-            }
-
-            for (int i = 0; i < recognizerCount; i++) {
-                ResolveInfo recognizer = recognizers.get(i);
-
-                ServiceInfo serviceInfo = recognizer.serviceInfo;
-                ComponentName componentName = new ComponentName(serviceInfo.packageName,
-                        serviceInfo.name);
-
-                indexable = new SearchIndexableRaw(context);
-                indexable.key = componentName.flattenToString();
-                indexable.title = recognizer.loadLabel(context.getPackageManager()).toString();
-                indexable.screenTitle = screenTitle;
-                indexables.add(indexable);
-            }
+            // Voice input
+            indexable = new SearchIndexableRaw(context);
+            indexable.key = "voice_input_settings";
+            indexable.title = context.getString(R.string.voice_input_settings);
+            indexable.screenTitle = screenTitle;
+            indexables.add(indexable);
 
             // Text-to-speech.
             TtsEngines ttsEngines = new TtsEngines(context);
diff --git a/src/com/android/settings/search/Ranking.java b/src/com/android/settings/search/Ranking.java
index 44717c1..1a08aa2 100644
--- a/src/com/android/settings/search/Ranking.java
+++ b/src/com/android/settings/search/Ranking.java
@@ -43,6 +43,7 @@
 import com.android.settings.print.PrintSettingsFragment;
 import com.android.settings.sim.SimSettings;
 import com.android.settings.users.UserSettings;
+import com.android.settings.voice.VoiceInputSettings;
 import com.android.settings.wifi.AdvancedWifiSettings;
 import com.android.settings.wifi.SavedAccessPointsWifiSettings;
 import com.android.settings.wifi.WifiSettings;
@@ -139,6 +140,7 @@
 
         // IMEs
         sRankMap.put(InputMethodAndLanguageSettings.class.getName(), RANK_IME);
+        sRankMap.put(VoiceInputSettings.class.getName(), RANK_IME);
 
         // Privacy
         sRankMap.put(PrivacySettings.class.getName(), RANK_PRIVACY);
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index e0e09a8..31dac7b 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -46,6 +46,7 @@
 import com.android.settings.print.PrintSettingsFragment;
 import com.android.settings.sim.SimSettings;
 import com.android.settings.users.UserSettings;
+import com.android.settings.voice.VoiceInputSettings;
 import com.android.settings.wifi.AdvancedWifiSettings;
 import com.android.settings.wifi.SavedAccessPointsWifiSettings;
 import com.android.settings.wifi.WifiSettings;
@@ -230,6 +231,13 @@
                         InputMethodAndLanguageSettings.class.getName(),
                         R.drawable.ic_settings_language));
 
+        sResMap.put(VoiceInputSettings.class.getName(),
+                new SearchIndexableResource(
+                        Ranking.getRankForClassName(VoiceInputSettings.class.getName()),
+                        NO_DATA_RES_ID,
+                        VoiceInputSettings.class.getName(),
+                        R.drawable.ic_settings_language));
+
         sResMap.put(PrivacySettings.class.getName(),
                 new SearchIndexableResource(
                         Ranking.getRankForClassName(PrivacySettings.class.getName()),
diff --git a/src/com/android/settings/voice/VoiceInputSettings.java b/src/com/android/settings/voice/VoiceInputSettings.java
index 309c6e9..aa85024 100644
--- a/src/com/android/settings/voice/VoiceInputSettings.java
+++ b/src/com/android/settings/voice/VoiceInputSettings.java
@@ -16,18 +16,33 @@
 
 package com.android.settings.voice;
 
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
 import android.preference.Preference;
 import android.provider.Settings;
+import android.service.voice.VoiceInteractionService;
+import android.service.voice.VoiceInteractionServiceInfo;
+import android.speech.RecognitionService;
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settings.search.SearchIndexableRaw;
 import com.android.settings.voice.VoiceInputPreference.RadioButtonGroupState;
 
 import android.os.Bundle;
 import android.preference.PreferenceCategory;
 import android.widget.Checkable;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class VoiceInputSettings extends SettingsPreferenceFragment implements
-        Preference.OnPreferenceClickListener, RadioButtonGroupState {
+        Preference.OnPreferenceClickListener, RadioButtonGroupState, Indexable {
 
     private static final String TAG = "VoiceInputSettings";
     private static final boolean DBG = false;
@@ -160,4 +175,68 @@
         }
         return true;
     }
+
+    // For Search
+    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+        new BaseSearchIndexProvider() {
+
+            @Override
+            public List<SearchIndexableRaw> getRawDataToIndex(Context context,
+                    boolean enabled) {
+
+                List<SearchIndexableRaw> indexables = new ArrayList<>();
+
+                final String screenTitle = context.getString(R.string.voice_input_settings_title);
+
+                SearchIndexableRaw indexable = new SearchIndexableRaw(context);
+                indexable.key = "voice_service_preference_section_title";
+                indexable.title = context.getString(R.string.voice_service_preference_section_title);
+                indexable.screenTitle = screenTitle;
+                indexables.add(indexable);
+
+                final List<ResolveInfo> voiceInteractions =
+                        context.getPackageManager().queryIntentServices(
+                                new Intent(VoiceInteractionService.SERVICE_INTERFACE),
+                                PackageManager.GET_META_DATA);
+
+                final int countInteractions = voiceInteractions.size();
+                for (int i = 0; i < countInteractions; i++) {
+                    ResolveInfo info = voiceInteractions.get(i);
+                    VoiceInteractionServiceInfo visInfo = new VoiceInteractionServiceInfo(
+                            context.getPackageManager(), info.serviceInfo);
+                    if (visInfo.getParseError() != null) {
+                        continue;
+                    }
+                    indexables.add(getSearchIndexableRaw(context, info, screenTitle));
+                }
+
+                final List<ResolveInfo> recognitions =
+                        context.getPackageManager().queryIntentServices(
+                                new Intent(RecognitionService.SERVICE_INTERFACE),
+                                PackageManager.GET_META_DATA);
+
+                final int countRecognitions = recognitions.size();
+                for (int i = 0; i < countRecognitions; i++) {
+                    ResolveInfo info = recognitions.get(i);
+                    indexables.add(getSearchIndexableRaw(context, info, screenTitle));
+                }
+
+                return indexables;
+            }
+
+            private SearchIndexableRaw getSearchIndexableRaw(Context context,
+                    ResolveInfo info, String screenTitle) {
+
+                ServiceInfo serviceInfo = info.serviceInfo;
+                ComponentName componentName = new ComponentName(serviceInfo.packageName,
+                        serviceInfo.name);
+
+                SearchIndexableRaw indexable = new SearchIndexableRaw(context);
+                indexable.key = componentName.flattenToString();
+                indexable.title = info.loadLabel(context.getPackageManager()).toString();
+                indexable.screenTitle = screenTitle;
+
+                return indexable;
+            }
+        };
 }