OSDN Git Service

Adding search for dynamic accessibility settings.
authorSvetoslav <svetoslavganov@google.com>
Tue, 15 Apr 2014 00:14:59 +0000 (17:14 -0700)
committerSvetoslav <svetoslavganov@google.com>
Tue, 15 Apr 2014 00:31:23 +0000 (17:31 -0700)
The language and input settings are highly dynamic and this change adds search
support for that. This category depends on installed IMEs, input devices, user
dictionary configuration, etc. We not only compute the right preferences to be
indexed but also track related system state in the settings app to rebuild the
index if needed.

bug:14066763

Change-Id: Ia89d9e35bd79abf8d74614691aedf4ca9b11b6f2

src/com/android/settings/SettingsActivity.java
src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
src/com/android/settings/inputmethod/UserDictionaryList.java
src/com/android/settings/search/SearchIndexableResources.java

index 789ad2a..329e4bf 100644 (file)
@@ -40,6 +40,9 @@ import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.database.ContentObserver;
+import android.hardware.input.InputManager;
+import android.net.Uri;
 import android.nfc.NfcAdapter;
 import android.os.Bundle;
 import android.os.Handler;
@@ -57,7 +60,7 @@ import android.preference.PreferenceScreen;
 import android.print.PrintManager;
 import android.printservice.PrintService;
 import android.printservice.PrintServiceInfo;
-import android.provider.SearchIndexableData;
+import android.provider.UserDictionary;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -69,6 +72,8 @@ import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.Button;
 import android.widget.ListView;
 
@@ -119,7 +124,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 
 import static com.android.settings.dashboard.Header.HEADER_ID_UNDEFINED;
@@ -315,8 +319,8 @@ public class SettingsActivity extends Activity
         }
     };
 
-    private final DynamicIndexablePackageMonitor mDynamicIndexablePackageMonitor =
-            new DynamicIndexablePackageMonitor();
+    private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor =
+            new DynamicIndexableContentMonitor();
 
     private Button mNextButton;
     private ActionBar mActionBar;
@@ -625,7 +629,7 @@ public class SettingsActivity extends Activity
 
         registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
 
-        mDynamicIndexablePackageMonitor.register(this);
+        mDynamicIndexableContentMonitor.register(this);
     }
 
     @Override
@@ -641,7 +645,7 @@ public class SettingsActivity extends Activity
 
         mDevelopmentPreferencesListener = null;
 
-        mDynamicIndexablePackageMonitor.unregister();
+        mDynamicIndexableContentMonitor.unregister();
     }
 
     @Override
@@ -1290,13 +1294,18 @@ public class SettingsActivity extends Activity
         mSearchMenuItem.collapseActionView();
     }
 
-    private static final class DynamicIndexablePackageMonitor extends PackageMonitor {
+    private static final class DynamicIndexableContentMonitor extends PackageMonitor implements
+            InputManager.InputDeviceListener {
+
         private static final Intent ACCESSIBILITY_SERVICE_INTENT =
                 new Intent(AccessibilityService.SERVICE_INTERFACE);
 
         private static final Intent PRINT_SERVICE_INTENT =
                 new Intent(PrintService.SERVICE_INTERFACE);
 
+        private static final Intent IME_SERVICE_INTENT =
+                new Intent("android.view.InputMethod");
+
         private static final long DELAY_PROCESS_PACKAGE_CHANGE = 2000;
 
         private static final int MSG_PACKAGE_AVAILABLE = 1;
@@ -1304,6 +1313,7 @@ public class SettingsActivity extends Activity
 
         private final List<String> mAccessibilityServices = new ArrayList<String>();
         private final List<String> mPrintServices = new ArrayList<String>();
+        private final List<String> mImeServices = new ArrayList<String>();
 
         private final Handler mHandler = new Handler() {
             @Override
@@ -1322,6 +1332,8 @@ public class SettingsActivity extends Activity
             }
         };
 
+        private final ContentObserver mContentObserver = new MyContentObserver(mHandler);
+
         private Context mContext;
 
         public void register(Context context) {
@@ -1350,13 +1362,41 @@ public class SettingsActivity extends Activity
                         .serviceInfo.packageName);
             }
 
+            // Cache IME service packages to know when they go away.
+            InputMethodManager imeManager = (InputMethodManager)
+                    mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
+            List<InputMethodInfo> inputMethods = imeManager.getInputMethodList();
+            final int inputMethodCount = inputMethods.size();
+            for (int i = 0; i < inputMethodCount; i++) {
+                InputMethodInfo inputMethod = inputMethods.get(i);
+                mImeServices.add(inputMethod.getServiceInfo().packageName);
+            }
+
+            // Watch for related content URIs.
+            mContext.getContentResolver().registerContentObserver(
+                    UserDictionary.Words.CONTENT_URI, true, mContentObserver);
+
+            // Watch for input device changes.
+            InputManager inputManager = (InputManager) context.getSystemService(
+                    Context.INPUT_SERVICE);
+            inputManager.registerInputDeviceListener(this, mHandler);
+
+            // Start tracking packages.
             register(context, Looper.getMainLooper(), UserHandle.CURRENT, false);
         }
 
         public void unregister() {
             super.unregister();
+
+            InputManager inputManager = (InputManager) mContext.getSystemService(
+                    Context.INPUT_SERVICE);
+            inputManager.unregisterInputDeviceListener(this);
+
+            mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+
             mAccessibilityServices.clear();
             mPrintServices.clear();
+            mImeServices.clear();
         }
 
         // Covers installed, appeared external storage with the package, upgraded.
@@ -1385,6 +1425,23 @@ public class SettingsActivity extends Activity
             }
         }
 
+        @Override
+        public void onInputDeviceAdded(int deviceId) {
+            Index.getInstance(mContext).updateFromClassNameResource(
+                    InputMethodAndLanguageSettings.class.getName(), false, true);
+        }
+
+        @Override
+        public void onInputDeviceRemoved(int deviceId) {
+            onInputDeviceChanged(deviceId);
+        }
+
+        @Override
+        public void onInputDeviceChanged(int deviceId) {
+            Index.getInstance(mContext).updateFromClassNameResource(
+                    InputMethodAndLanguageSettings.class.getName(), true, true);
+        }
+
         private void postMessage(int what, String packageName) {
             Message message = mHandler.obtainMessage(what, packageName);
             mHandler.sendMessageDelayed(message, DELAY_PROCESS_PACKAGE_CHANGE);
@@ -1412,6 +1469,17 @@ public class SettingsActivity extends Activity
                 }
                 intent.setPackage(null);
             }
+
+            if (!mImeServices.contains(packageName)) {
+                Intent intent = IME_SERVICE_INTENT;
+                intent.setPackage(packageName);
+                if (!mContext.getPackageManager().queryIntentServices(intent, 0).isEmpty()) {
+                    mImeServices.add(packageName);
+                    Index.getInstance(mContext).updateFromClassNameResource(
+                            InputMethodAndLanguageSettings.class.getName(), false, true);
+                }
+                intent.setPackage(null);
+            }
         }
 
         private void handlePackageUnavailable(String packageName) {
@@ -1429,5 +1497,20 @@ public class SettingsActivity extends Activity
                         PrintSettingsFragment.class.getName(), true, true);
             }
         }
+
+        private final class MyContentObserver extends ContentObserver {
+
+            public MyContentObserver(Handler handler) {
+                super(handler);
+            }
+
+            @Override
+            public void onChange(boolean selfChange, Uri uri) {
+                if (UserDictionary.Words.CONTENT_URI.equals(uri)) {
+                    Index.getInstance(mContext).updateFromClassNameResource(
+                            InputMethodAndLanguageSettings.class.getName(), true, true);
+                }
+            };
+        }
     }
 }
index dbfa1bc..c0e930e 100644 (file)
@@ -23,6 +23,9 @@ import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.UserDictionarySettings;
 import com.android.settings.Utils;
 import com.android.settings.VoiceInputOutputSettings;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settings.search.SearchIndexableRaw;
 
 import android.app.Activity;
 import android.app.Fragment;
@@ -30,6 +33,7 @@ import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
@@ -47,10 +51,13 @@ import android.preference.PreferenceCategory;
 import android.preference.PreferenceScreen;
 import android.provider.Settings;
 import android.provider.Settings.System;
+import android.speech.RecognitionService;
+import android.speech.tts.TtsEngines;
 import android.text.TextUtils;
 import android.view.InputDevice;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
 import android.widget.BaseAdapter;
 
 import java.util.ArrayList;
@@ -60,7 +67,7 @@ import java.util.TreeSet;
 
 public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
         implements Preference.OnPreferenceChangeListener, InputManager.InputDeviceListener,
-        KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener {
+        KeyboardLayoutDialogFragment.OnSetupKeyboardLayoutsListener, Indexable {
 
     private static final String KEY_PHONE_LANGUAGE = "phone_language";
     private static final String KEY_CURRENT_INPUT_METHOD = "current_input_method";
@@ -242,34 +249,8 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
 
         if (!mIsOnlyImeSettings) {
             if (mLanguagePref != null) {
-                Configuration conf = getResources().getConfiguration();
-                String language = conf.locale.getLanguage();
-                String localeString;
-                // TODO: This is not an accurate way to display the locale, as it is
-                // just working around the fact that we support limited dialects
-                // and want to pretend that the language is valid for all locales.
-                // We need a way to support languages that aren't tied to a particular
-                // locale instead of hiding the locale qualifier.
-                if (language.equals("zz")) {
-                    String country = conf.locale.getCountry();
-                    if (country.equals("ZZ")) {
-                        localeString = "[Developer] Accented English (zz_ZZ)";
-                    } else if (country.equals("ZY")) {
-                        localeString = "[Developer] Fake Bi-Directional (zz_ZY)";
-                    } else {
-                        localeString = "";
-                    }
-                } else if (hasOnlyOneLanguageInstance(language,
-                        Resources.getSystem().getAssets().getLocales())) {
-                    localeString = conf.locale.getDisplayLanguage(conf.locale);
-                } else {
-                    localeString = conf.locale.getDisplayName(conf.locale);
-                }
-                if (localeString.length() > 1) {
-                    localeString = Character.toUpperCase(localeString.charAt(0))
-                            + localeString.substring(1);
-                    mLanguagePref.setSummary(localeString);
-                }
+                String localeName = getLocaleName(getResources());
+                mLanguagePref.setSummary(localeName);
             }
 
             updateUserDictionaryPreference(findPreference(KEY_USER_DICTIONARY_SETTINGS));
@@ -361,7 +342,40 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
         return super.onPreferenceTreeClick(preferenceScreen, preference);
     }
 
-    private boolean hasOnlyOneLanguageInstance(String languageCode, String[] locales) {
+    private static String getLocaleName(Resources resources) {
+        Configuration conf = resources.getConfiguration();
+        String language = conf.locale.getLanguage();
+        String localeName;
+        // TODO: This is not an accurate way to display the locale, as it is
+        // just working around the fact that we support limited dialects
+        // and want to pretend that the language is valid for all locales.
+        // We need a way to support languages that aren't tied to a particular
+        // locale instead of hiding the locale qualifier.
+        if (language.equals("zz")) {
+            String country = conf.locale.getCountry();
+            if (country.equals("ZZ")) {
+                localeName = "[Developer] Accented English (zz_ZZ)";
+            } else if (country.equals("ZY")) {
+                localeName = "[Developer] Fake Bi-Directional (zz_ZY)";
+            } else {
+                localeName = "";
+            }
+        } else if (hasOnlyOneLanguageInstance(language,
+                Resources.getSystem().getAssets().getLocales())) {
+            localeName = conf.locale.getDisplayLanguage(conf.locale);
+        } else {
+            localeName = conf.locale.getDisplayName(conf.locale);
+        }
+
+        if (localeName.length() > 1) {
+            localeName = Character.toUpperCase(localeName.charAt(0))
+                    + localeName.substring(1);
+        }
+
+        return localeName;
+    }
+
+    private static boolean hasOnlyOneLanguageInstance(String languageCode, String[] locales) {
         int count = 0;
         for (String localeCode : locales) {
             if (localeCode.length() > 2
@@ -582,7 +596,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
         }
     }
 
-    private boolean haveInputDeviceWithVibrator() {
+    private static boolean haveInputDeviceWithVibrator() {
         final int[] devices = InputDevice.getDeviceIds();
         for (int i = 0; i < devices.length; i++) {
             InputDevice device = InputDevice.getDevice(devices[i]);
@@ -617,4 +631,225 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
             mContext.getContentResolver().unregisterContentObserver(this);
         }
     }
+
+    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<SearchIndexableRaw>();
+
+            Resources resources = context.getResources();
+            String screenTitle = context.getString(R.string.language_keyboard_settings_title);
+
+            // Locale picker.
+            if (context.getAssets().getLocales().length > 1) {
+                String localeName = getLocaleName(resources);
+                SearchIndexableRaw indexable = new SearchIndexableRaw(context);
+                indexable.title = context.getString(R.string.phone_language);
+                indexable.summaryOn = localeName;
+                indexable.summaryOff = localeName;
+                indexable.screenTitle = screenTitle;
+                indexables.add(indexable);
+            }
+
+            // Spell checker.
+            SearchIndexableRaw indexable = new SearchIndexableRaw(context);
+            indexable.title = context.getString(R.string.spellcheckers_settings_title);
+            indexable.screenTitle = screenTitle;
+            indexables.add(indexable);
+
+            // User dictionary.
+            if (UserDictionaryList.getUserDictionaryLocalesSet(context) != null) {
+                indexable = new SearchIndexableRaw(context);
+                indexable.title = context.getString(R.string.user_dict_settings_title);
+                indexable.screenTitle = screenTitle;
+                indexables.add(indexable);
+            }
+
+            // Keyboard settings.
+            indexable = new SearchIndexableRaw(context);
+            indexable.title = context.getString(R.string.keyboard_settings_category);
+            indexable.screenTitle = screenTitle;
+            indexables.add(indexable);
+
+            InputMethodSettingValuesWrapper immValues = InputMethodSettingValuesWrapper
+                    .getInstance(context);
+            immValues.refreshAllInputMethodAndSubtypes();
+
+            // Current IME.
+            String currImeName = immValues.getCurrentInputMethodName(context).toString();
+            indexable = new SearchIndexableRaw(context);
+            indexable.title = context.getString(R.string.current_input_method);
+            indexable.summaryOn = currImeName;
+            indexable.summaryOff = currImeName;
+            indexable.screenTitle = screenTitle;
+            indexables.add(indexable);
+
+            InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(
+                    Context.INPUT_METHOD_SERVICE);
+
+            // All other IMEs.
+            List<InputMethodInfo> inputMethods = immValues.getInputMethodList();
+            final int inputMethodCount = (inputMethods == null ? 0 : inputMethods.size());
+            for (int i = 0; i < inputMethodCount; ++i) {
+                InputMethodInfo inputMethod = inputMethods.get(i);
+
+                StringBuilder builder = new StringBuilder();
+                List<InputMethodSubtype> subtypes = inputMethodManager
+                        .getEnabledInputMethodSubtypeList(inputMethod, true);
+                final int subtypeCount = subtypes.size();
+                for (int j = 0; j < subtypeCount; j++) {
+                    InputMethodSubtype subtype = subtypes.get(j);
+                    if (builder.length() > 0) {
+                        builder.append(',');
+                    }
+                    CharSequence subtypeLabel = subtype.getDisplayName(context,
+                            inputMethod.getPackageName(), inputMethod.getServiceInfo()
+                                    .applicationInfo);
+                    builder.append(subtypeLabel);
+                }
+                String summary = builder.toString();
+
+                indexable = new SearchIndexableRaw(context);
+                indexable.title = inputMethod.loadLabel(context.getPackageManager()).toString();
+                indexable.summaryOn = summary;
+                indexable.summaryOff = summary;
+                indexable.screenTitle = screenTitle;
+                indexables.add(indexable);
+            }
+
+            // Hard keyboards
+            InputManager inputManager = (InputManager) context.getSystemService(
+                    Context.INPUT_SERVICE);
+            if (resources.getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY) {
+                boolean hasHardKeyboards = false;
+
+                final int[] devices = InputDevice.getDeviceIds();
+                for (int i = 0; i < devices.length; i++) {
+                    InputDevice device = InputDevice.getDevice(devices[i]);
+                    if (device == null || device.isVirtual() || !device.isFullKeyboard()) {
+                        continue;
+                    }
+
+                    hasHardKeyboards = true;
+
+                    InputDeviceIdentifier identifier = device.getIdentifier();
+                    String keyboardLayoutDescriptor =
+                            inputManager.getCurrentKeyboardLayoutForInputDevice(identifier);
+                    KeyboardLayout keyboardLayout = keyboardLayoutDescriptor != null ?
+                            inputManager.getKeyboardLayout(keyboardLayoutDescriptor) : null;
+
+                    String summary;
+                    if (keyboardLayout != null) {
+                        summary = keyboardLayout.toString();
+                    } else {
+                        summary = context.getString(R.string.keyboard_layout_default_label);
+                    }
+
+                    indexable = new SearchIndexableRaw(context);
+                    indexable.title = device.getName();
+                    indexable.summaryOn = summary;
+                    indexable.summaryOff = summary;
+                    indexable.screenTitle = screenTitle;
+                    indexables.add(indexable);
+                }
+
+                if (hasHardKeyboards) {
+                    // Hard keyboard category.
+                    indexable = new SearchIndexableRaw(context);
+                    indexable.title = context.getString(
+                            R.string.builtin_keyboard_settings_title);
+                    indexable.screenTitle = screenTitle;
+                    indexables.add(indexable);
+
+                    // Auto replace.
+                    indexable = new SearchIndexableRaw(context);
+                    indexable.title = context.getString(R.string.auto_replace);
+                    indexable.summaryOn = context.getString(R.string.auto_replace_summary);
+                    indexable.summaryOff = context.getString(R.string.auto_replace_summary);
+                    indexable.screenTitle = screenTitle;
+                    indexables.add(indexable);
+
+                    // Auto caps.
+                    indexable = new SearchIndexableRaw(context);
+                    indexable.title = context.getString(R.string.auto_caps);
+                    indexable.summaryOn = context.getString(R.string.auto_caps_summary);
+                    indexable.summaryOff = context.getString(R.string.auto_caps_summary);
+                    indexable.screenTitle = screenTitle;
+                    indexables.add(indexable);
+
+                    // Auto punctuate.
+                    indexable = new SearchIndexableRaw(context);
+                    indexable.title = context.getString(R.string.auto_punctuate);
+                    indexable.summaryOn = context.getString(R.string.auto_punctuate_summary);
+                    indexable.summaryOff = context.getString(R.string.auto_punctuate_summary);
+                    indexable.screenTitle = screenTitle;
+                    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.title = context.getString(R.string.recognizer_settings_title);
+                indexable.screenTitle = screenTitle;
+                indexables.add(indexable);
+            }
+
+            if (recognizerCount > 1) {
+                // Recognizer chooser.
+                indexable = new SearchIndexableRaw(context);
+                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);
+                indexable = new SearchIndexableRaw(context);
+                indexable.title = recognizer.loadLabel(context.getPackageManager()).toString();
+                indexable.screenTitle = screenTitle;
+                indexables.add(indexable);
+            }
+
+            // Text-to-speech.
+            TtsEngines ttsEngines = new TtsEngines(context);
+            if (!ttsEngines.getEngines().isEmpty()) {
+                indexable = new SearchIndexableRaw(context);
+                indexable.title = context.getString(R.string.tts_settings_title);
+                indexable.screenTitle = screenTitle;
+                indexables.add(indexable);
+            }
+
+            // Pointer settings.
+            indexable = new SearchIndexableRaw(context);
+            indexable.title = context.getString(R.string.pointer_settings_category);
+            indexable.screenTitle = screenTitle;
+            indexables.add(indexable);
+
+            indexable = new SearchIndexableRaw(context);
+            indexable.title = context.getString(R.string.pointer_speed);
+            indexable.screenTitle = screenTitle;
+            indexables.add(indexable);
+
+            // Game controllers.
+            if (haveInputDeviceWithVibrator()) {
+                indexable = new SearchIndexableRaw(context);
+                indexable.title = context.getString(R.string.vibrate_input_devices);
+                indexable.summaryOn = context.getString(R.string.vibrate_input_devices_summary);
+                indexable.summaryOff = context.getString(R.string.vibrate_input_devices_summary);
+                indexable.screenTitle = screenTitle;
+                indexables.add(indexable);
+            }
+
+            return indexables;
+        }
+    };
 }
index 24acb4a..7439001 100644 (file)
@@ -72,22 +72,27 @@ public class UserDictionaryList extends SettingsPreferenceFragment {
         mLocale = locale;
     }
 
-    public static TreeSet<String> getUserDictionaryLocalesSet(Activity activity) {
-        @SuppressWarnings("deprecation")
-        final Cursor cursor = activity.managedQuery(UserDictionary.Words.CONTENT_URI,
-                new String[] { UserDictionary.Words.LOCALE },
+    public static TreeSet<String> getUserDictionaryLocalesSet(Context context) {
+        final Cursor cursor = context.getContentResolver().query(
+                UserDictionary.Words.CONTENT_URI, new String[] { UserDictionary.Words.LOCALE },
                 null, null, null);
         final TreeSet<String> localeSet = new TreeSet<String>();
         if (null == cursor) {
             // The user dictionary service is not present or disabled. Return null.
             return null;
-        } else if (cursor.moveToFirst()) {
-            final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE);
-            do {
-                final String locale = cursor.getString(columnIndex);
-                localeSet.add(null != locale ? locale : "");
-            } while (cursor.moveToNext());
         }
+        try {
+            if (cursor.moveToFirst()) {
+                final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE);
+                do {
+                    final String locale = cursor.getString(columnIndex);
+                    localeSet.add(null != locale ? locale : "");
+                } while (cursor.moveToNext());
+            }
+        } finally {
+            cursor.close();
+        }
+
         // CAVEAT: Keep this for consistency of the implementation between Keyboard and Settings
         // if (!UserDictionarySettings.IS_SHORTCUT_API_SUPPORTED) {
         //     // For ICS, we need to show "For all languages" in case that the keyboard locale
@@ -96,7 +101,7 @@ public class UserDictionaryList extends SettingsPreferenceFragment {
         // }
 
         final InputMethodManager imm =
-                (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
+                (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
         final List<InputMethodInfo> imis = imm.getEnabledInputMethodList();
         for (final InputMethodInfo imi : imis) {
             final List<InputMethodSubtype> subtypes =
index cfc90c6..6f8efce 100644 (file)
@@ -168,7 +168,7 @@ public final class SearchIndexableResources {
 
         sResMap.put(InputMethodAndLanguageSettings.class.getName(),
                 new SearchIndexableResource(RANK_IME,
-                        R.xml.language_settings,
+                        NO_DATA_RES_ID,
                         InputMethodAndLanguageSettings.class.getName(),
                         R.drawable.ic_settings_language));