Show subtype locales in the personal dictionary

...and change the destination of the intent

Bug: 9117704
Bug: 8856930

Change-Id: I39e55d2c5ca9a602f9a586625dcf25d5fb065a0a
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 39279d4..e29f04c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -522,7 +522,7 @@
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
             </intent-filter>
             <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
-                android:value="com.android.settings.UserDictionarySettings" />
+                android:value="com.android.settings.inputmethod.UserDictionaryList" />
             <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
                 android:resource="@id/language_settings" />
             <meta-data android:name="com.android.settings.PARENT_FRAGMENT_TITLE"
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index acb0c22..48acac8 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -193,24 +193,11 @@
 
     private void updateUserDictionaryPreference(Preference userDictionaryPreference) {
         final Activity activity = getActivity();
-        final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity);
-        if (null == localeList) {
+        final TreeSet<String> localeSet = UserDictionaryList.getUserDictionaryLocalesSet(activity);
+        if (null == localeSet) {
             // The locale list is null if and only if the user dictionary service is
             // not present or disabled. In this case we need to remove the preference.
             getPreferenceScreen().removePreference(userDictionaryPreference);
-        } else if (localeList.size() <= 1) {
-            userDictionaryPreference.setFragment(
-                    com.android.settings.UserDictionarySettings.class.getName());
-            // If the size of localeList is 0, we don't set the locale parameter in the
-            // extras. This will be interpreted by the UserDictionarySettings class as
-            // meaning "the current locale".
-            // Note that with the current code for UserDictionaryList#getUserDictionaryLocalesSet()
-            // the locale list always has at least one element, since it always includes the current
-            // locale explicitly. @see UserDictionaryList.getUserDictionaryLocalesSet().
-            if (localeList.size() == 1) {
-                final String locale = (String)localeList.toArray()[0];
-                userDictionaryPreference.getExtras().putString("locale", locale);
-            }
         } else {
             userDictionaryPreference.setFragment(UserDictionaryList.class.getName());
         }
diff --git a/src/com/android/settings/inputmethod/UserDictionaryList.java b/src/com/android/settings/inputmethod/UserDictionaryList.java
index 5390be6..b6e6f93 100644
--- a/src/com/android/settings/inputmethod/UserDictionaryList.java
+++ b/src/com/android/settings/inputmethod/UserDictionaryList.java
@@ -21,25 +21,60 @@
 import com.android.settings.Utils;
 
 import android.app.Activity;
+import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
 import android.os.Bundle;
 import android.preference.Preference;
+import android.preference.PreferenceActivity;
 import android.preference.PreferenceGroup;
 import android.provider.UserDictionary;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.TreeSet;
 
 public class UserDictionaryList extends SettingsPreferenceFragment {
-
     public static final String USER_DICTIONARY_SETTINGS_INTENT_ACTION =
             "android.settings.USER_DICTIONARY_SETTINGS";
+    private String mLocale;
 
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity()));
+        getActivity().getActionBar().setTitle(R.string.user_dict_settings_title);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        final Intent intent = getActivity().getIntent();
+        final String localeFromIntent =
+                null == intent ? null : intent.getStringExtra("locale");
+
+        final Bundle arguments = getArguments();
+        final String localeFromArguments =
+                null == arguments ? null : arguments.getString("locale");
+
+        final String locale;
+        if (null != localeFromArguments) {
+            locale = localeFromArguments;
+        } else if (null != localeFromIntent) {
+            locale = localeFromIntent;
+        } else {
+            locale = null;
+        }
+        mLocale = locale;
     }
 
     static TreeSet<String> getUserDictionaryLocalesSet(Activity activity) {
@@ -47,7 +82,7 @@
         final Cursor cursor = activity.managedQuery(UserDictionary.Words.CONTENT_URI,
                 new String[] { UserDictionary.Words.LOCALE },
                 null, null, null);
-        final TreeSet<String> localeList = new TreeSet<String>();
+        final TreeSet<String> localeSet = new TreeSet<String>();
         if (null == cursor) {
             // The user dictionary service is not present or disabled. Return null.
             return null;
@@ -55,30 +90,51 @@
             final int columnIndex = cursor.getColumnIndex(UserDictionary.Words.LOCALE);
             do {
                 String locale = cursor.getString(columnIndex);
-                localeList.add(null != locale ? locale : "");
+                localeSet.add(null != locale ? locale : "");
             } while (cursor.moveToNext());
         }
-        localeList.add(Locale.getDefault().toString());
-        return localeList;
+        localeSet.add(Locale.getDefault().toString());
+        final InputMethodManager imm =
+                (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
+        final List<InputMethodInfo> imis = imm.getEnabledInputMethodList();
+        for (InputMethodInfo imi : imis) {
+            final List<InputMethodSubtype> subtypes =
+                    imm.getEnabledInputMethodSubtypeList(
+                            imi, true /* allowsImplicitlySelectedSubtypes */);
+            for (InputMethodSubtype subtype : subtypes) {
+                final String locale = subtype.getLocale();
+                if (!TextUtils.isEmpty(locale)) {
+                    localeSet.add(locale);
+                }
+            }
+        }
+        return localeSet;
     }
 
     /**
      * Creates the entries that allow the user to go into the user dictionary for each locale.
      * @param userDictGroup The group to put the settings in.
+     * @return the shown language set
      */
-    protected void createUserDictSettings(PreferenceGroup userDictGroup) {
+    protected TreeSet<String> createUserDictSettingsAndReturnSet(PreferenceGroup userDictGroup) {
         final Activity activity = getActivity();
         userDictGroup.removeAll();
-        final TreeSet<String> localeList =
+        final TreeSet<String> localeSet =
                 UserDictionaryList.getUserDictionaryLocalesSet(activity);
+        if (mLocale != null) {
+            // If the caller explicitly specify empty string as a locale, we'll show "all languages"
+            // in the list.
+            localeSet.add(mLocale);
+        }
 
-        if (localeList.isEmpty()) {
+        if (localeSet.isEmpty()) {
             userDictGroup.addPreference(createUserDictionaryPreference(null, activity));
         } else {
-            for (String locale : localeList) {
+            for (String locale : localeSet) {
                 userDictGroup.addPreference(createUserDictionaryPreference(locale, activity));
             }
         }
+        return localeSet;
     }
 
     /**
@@ -107,6 +163,25 @@
     @Override
     public void onResume() {
         super.onResume();
-        createUserDictSettings(getPreferenceScreen());
+        final TreeSet<String> localeSet = createUserDictSettingsAndReturnSet(getPreferenceScreen());
+        if (localeSet.size() <= 1) {
+            // Redirect to UserDictionarySettings if the user needs only one language.
+            final Bundle extras = new Bundle();
+            if (!localeSet.isEmpty()) {
+                // If the size of localeList is 0, we don't set the locale parameter in the
+                // extras. This will be interpreted by the UserDictionarySettings class as
+                // meaning "the current locale".
+                // Note that with the current code for
+                // UserDictionaryList#getUserDictionaryLocalesSet()
+                // the locale list always has at least one element, since it always includes
+                // the current locale explicitly.
+                // @see UserDictionaryList.getUserDictionaryLocalesSet().
+                extras.putString("locale", localeSet.first());
+            }
+            startFragment(this,
+                    com.android.settings.UserDictionarySettings.class.getCanonicalName(), -1,
+                    extras);
+            finish();
+        }
     }
 }