136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani/*
28632bff2d5a8e1160989008dea6eff4b94b065ddTadashi G. Takaoka * Copyright (C) 2008-2009 The Android Open Source Project
315a0ba6d74feed57124938336f951ae14aa47ad9satok *
436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * Licensed under the Apache License, Version 2.0 (the "License"); you may not
536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * use this file except in compliance with the License. You may obtain a copy of
636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * the License at
715a0ba6d74feed57124938336f951ae14aa47ad9satok *
836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * http://www.apache.org/licenses/LICENSE-2.0
915a0ba6d74feed57124938336f951ae14aa47ad9satok *
1036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * Unless required by applicable law or agreed to in writing, software
1136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * License for the specific language governing permissions and limitations under
1436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani * the License.
1536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani */
1636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
1715a0ba6d74feed57124938336f951ae14aa47ad9satokpackage com.android.inputmethod.deprecated.languageswitcher;
1815a0ba6d74feed57124938336f951ae14aa47ad9satok
1962c7e25e11f021f6640f9170e53b7e86ed537fd8satokimport com.android.inputmethod.compat.SharedPreferencesCompat;
201be29abab2e112f0253a8a5da3478740bb866d27Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.KeyboardBuilder;
214250eb27f54f8fedc388fe4825b0646a88778744Jean Chalardimport com.android.inputmethod.latin.DictionaryFactory;
22ef35cb631c45c8b106fe7ed9e0d1178c3e5fb963Jean Chalardimport com.android.inputmethod.latin.LocaleUtils;
2315a0ba6d74feed57124938336f951ae14aa47ad9satokimport com.android.inputmethod.latin.R;
2415a0ba6d74feed57124938336f951ae14aa47ad9satokimport com.android.inputmethod.latin.Settings;
2515a0ba6d74feed57124938336f951ae14aa47ad9satokimport com.android.inputmethod.latin.Utils;
2615a0ba6d74feed57124938336f951ae14aa47ad9satok
2715a0ba6d74feed57124938336f951ae14aa47ad9satokimport org.xmlpull.v1.XmlPullParserException;
2836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
2936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.SharedPreferences;
3036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.SharedPreferences.Editor;
311e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasaniimport android.content.res.Resources;
3236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.os.Bundle;
3336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.preference.CheckBoxPreference;
3436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.preference.PreferenceActivity;
3536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.preference.PreferenceGroup;
3636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.preference.PreferenceManager;
376516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasaniimport android.text.TextUtils;
389ee51db95bdfec4a99bbbc5c78af00b06b426979satokimport android.util.Pair;
3936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
4015a0ba6d74feed57124938336f951ae14aa47ad9satokimport java.io.IOException;
41fa086c90760bc2bedf0b74eacb0fed3bf7ebc2b7Tadashi G. Takaokaimport java.text.Collator;
42fa086c90760bc2bedf0b74eacb0fed3bf7ebc2b7Tadashi G. Takaokaimport java.util.ArrayList;
43fa086c90760bc2bedf0b74eacb0fed3bf7ebc2b7Tadashi G. Takaokaimport java.util.Arrays;
441b9eecb521862b4e75b0a34623efdc98087d75basatokimport java.util.HashMap;
45fa086c90760bc2bedf0b74eacb0fed3bf7ebc2b7Tadashi G. Takaokaimport java.util.Locale;
46f733074aaecdfd6e89cfee2daff8a9c1233b60f1satokimport java.util.Map.Entry;
47f733074aaecdfd6e89cfee2daff8a9c1233b60f1satokimport java.util.TreeMap;
48fa086c90760bc2bedf0b74eacb0fed3bf7ebc2b7Tadashi G. Takaoka
4936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasanipublic class InputLanguageSelection extends PreferenceActivity {
5036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
5127d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa    private SharedPreferences mPrefs;
5236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    private String mSelectedLanguages;
531b9eecb521862b4e75b0a34623efdc98087d75basatok    private HashMap<CheckBoxPreference, Locale> mLocaleMap =
541b9eecb521862b4e75b0a34623efdc98087d75basatok            new HashMap<CheckBoxPreference, Locale>();
5536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
56f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok    private static class LocaleEntry implements Comparable<Object> {
57e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka        private static Collator sCollator = Collator.getInstance();
5836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
59e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka        private String mLabel;
60e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka        public final Locale mLocale;
6136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
62f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        public LocaleEntry(String label, Locale locale) {
63e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka            this.mLabel = label;
64e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka            this.mLocale = locale;
65e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka        }
66e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka
6736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        @Override
6836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        public String toString() {
69e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka            return this.mLabel;
7036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        }
7136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
725a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka        @Override
7336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        public int compareTo(Object o) {
74f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            return sCollator.compare(this.mLabel, ((LocaleEntry) o).mLabel);
7536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        }
7636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    }
7736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
7836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    @Override
7936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    protected void onCreate(Bundle icicle) {
8036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        super.onCreate(icicle);
8136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        addPreferencesFromResource(R.xml.language_prefs);
8236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        // Get the settings preferences
8327d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
849502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka        mSelectedLanguages = mPrefs.getString(Settings.PREF_SELECTED_LANGUAGES, "");
8536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        String[] languageList = mSelectedLanguages.split(",");
86f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        ArrayList<LocaleEntry> availableLanguages = getUniqueLocales();
8736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        PreferenceGroup parent = getPreferenceScreen();
88f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        final HashMap<Long, LocaleEntry> dictionaryIdLocaleMap = new HashMap<Long, LocaleEntry>();
89f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        final TreeMap<LocaleEntry, Boolean> localeHasDictionaryMap =
90f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                new TreeMap<LocaleEntry, Boolean>();
911b9eecb521862b4e75b0a34623efdc98087d75basatok        for (int i = 0; i < availableLanguages.size(); i++) {
92f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            LocaleEntry loc = availableLanguages.get(i);
93f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            Locale locale = loc.mLocale;
94f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            final Pair<Long, Boolean> hasDictionaryOrLayout = hasDictionaryOrLayout(locale);
95f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            final Long dictionaryId = hasDictionaryOrLayout.first;
969ee51db95bdfec4a99bbbc5c78af00b06b426979satok            final boolean hasLayout = hasDictionaryOrLayout.second;
97f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            final boolean hasDictionary = dictionaryId != null;
981b9eecb521862b4e75b0a34623efdc98087d75basatok            // Add this locale to the supported list if:
99f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            // 1) this locale has a layout/ 2) this locale has a dictionary
100f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            // If some locales have no layout but have a same dictionary, the shortest locale
101f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            // will be added to the supported list.
102f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            if (!hasLayout && !hasDictionary) {
10315a0ba6d74feed57124938336f951ae14aa47ad9satok                continue;
10415a0ba6d74feed57124938336f951ae14aa47ad9satok            }
105f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            if (hasLayout) {
106f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                localeHasDictionaryMap.put(loc, hasDictionary);
107f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            }
108f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            if (!hasDictionary) {
109f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                continue;
110f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            }
111f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            if (dictionaryIdLocaleMap.containsKey(dictionaryId)) {
112f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                final String newLocale = locale.toString();
113f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                final String oldLocale =
114f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                        dictionaryIdLocaleMap.get(dictionaryId).mLocale.toString();
115f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                // Check if this locale is more appropriate to be the candidate of the input locale.
116f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                if (oldLocale.length() <= newLocale.length() && !hasLayout) {
117f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                    // Don't add this new locale to the map<dictionary id, locale> if:
118f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                    // 1) the new locale's name is longer than the existing one, and
119f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                    // 2) the new locale doesn't have its layout
120f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                    continue;
121f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                }
122f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            }
123f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            dictionaryIdLocaleMap.put(dictionaryId, loc);
124f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        }
125f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok
126f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        for (LocaleEntry localeEntry : dictionaryIdLocaleMap.values()) {
127f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            if (!localeHasDictionaryMap.containsKey(localeEntry)) {
128f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                localeHasDictionaryMap.put(localeEntry, true);
129f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            }
130f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        }
131f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok
132f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        for (Entry<LocaleEntry, Boolean> entry : localeHasDictionaryMap.entrySet()) {
133f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            final LocaleEntry localeEntry = entry.getKey();
134f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            final Locale locale = localeEntry.mLocale;
135f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            final Boolean hasDictionary = entry.getValue();
13615a0ba6d74feed57124938336f951ae14aa47ad9satok            CheckBoxPreference pref = new CheckBoxPreference(this);
137f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok            pref.setTitle(localeEntry.mLabel);
13836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            boolean checked = isLocaleIn(locale, languageList);
13936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            pref.setChecked(checked);
1409ee51db95bdfec4a99bbbc5c78af00b06b426979satok            if (hasDictionary) {
1411e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani                pref.setSummary(R.string.has_dictionary);
1421e5374e98b2707aecd774f495350a74be55ec5dcAmith Yamasani            }
1431b9eecb521862b4e75b0a34623efdc98087d75basatok            mLocaleMap.put(pref, locale);
14436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            parent.addPreference(pref);
14536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        }
14636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    }
14736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
14836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    private boolean isLocaleIn(Locale locale, String[] list) {
14936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        String lang = get5Code(locale);
15036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        for (int i = 0; i < list.length; i++) {
15136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            if (lang.equalsIgnoreCase(list[i])) return true;
15236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        }
15336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        return false;
15436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    }
15536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
156f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok    private Pair<Long, Boolean> hasDictionaryOrLayout(Locale locale) {
157f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        if (locale == null) return new Pair<Long, Boolean>(null, false);
158458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa        final Resources res = getResources();
159ef35cb631c45c8b106fe7ed9e0d1178c3e5fb963Jean Chalard        final Locale saveLocale = LocaleUtils.setSystemLocale(res, locale);
160f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        final Long dictionaryId = DictionaryFactory.getDictionaryId(this, locale);
1619ee51db95bdfec4a99bbbc5c78af00b06b426979satok        boolean hasLayout = false;
162979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
1639ee51db95bdfec4a99bbbc5c78af00b06b426979satok        try {
1641b9eecb521862b4e75b0a34623efdc98087d75basatok            final String localeStr = locale.toString();
1651be29abab2e112f0253a8a5da3478740bb866d27Tadashi G. Takaoka            final String[] layoutCountryCodes = KeyboardBuilder.parseKeyboardLocale(
1661b9eecb521862b4e75b0a34623efdc98087d75basatok                    this, R.xml.kbd_qwerty).split(",", -1);
1671b9eecb521862b4e75b0a34623efdc98087d75basatok            if (!TextUtils.isEmpty(localeStr) && layoutCountryCodes.length > 0) {
1681b9eecb521862b4e75b0a34623efdc98087d75basatok                for (String s : layoutCountryCodes) {
1691b9eecb521862b4e75b0a34623efdc98087d75basatok                    if (s.equals(localeStr)) {
1701b9eecb521862b4e75b0a34623efdc98087d75basatok                        hasLayout = true;
1711b9eecb521862b4e75b0a34623efdc98087d75basatok                        break;
1721b9eecb521862b4e75b0a34623efdc98087d75basatok                    }
1731b9eecb521862b4e75b0a34623efdc98087d75basatok                }
17415a0ba6d74feed57124938336f951ae14aa47ad9satok            }
17515a0ba6d74feed57124938336f951ae14aa47ad9satok        } catch (XmlPullParserException e) {
17615a0ba6d74feed57124938336f951ae14aa47ad9satok        } catch (IOException e) {
17715a0ba6d74feed57124938336f951ae14aa47ad9satok        }
178ef35cb631c45c8b106fe7ed9e0d1178c3e5fb963Jean Chalard        LocaleUtils.setSystemLocale(res, saveLocale);
179f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        return new Pair<Long, Boolean>(dictionaryId, hasLayout);
18015a0ba6d74feed57124938336f951ae14aa47ad9satok    }
18115a0ba6d74feed57124938336f951ae14aa47ad9satok
18236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    private String get5Code(Locale locale) {
1836516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani        String country = locale.getCountry();
1846516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani        return locale.getLanguage()
1856516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani                + (TextUtils.isEmpty(country) ? "" : "_" + country);
18636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    }
18736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
18836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    @Override
18936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    protected void onResume() {
19036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        super.onResume();
19136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    }
19236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
19336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    @Override
19436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    protected void onPause() {
19536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        super.onPause();
19636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        // Save the selected languages
19736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        String checkedLanguages = "";
19836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        PreferenceGroup parent = getPreferenceScreen();
19936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        int count = parent.getPreferenceCount();
20036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        for (int i = 0; i < count; i++) {
20136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            CheckBoxPreference pref = (CheckBoxPreference) parent.getPreference(i);
20236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            if (pref.isChecked()) {
2031b9eecb521862b4e75b0a34623efdc98087d75basatok                checkedLanguages += get5Code(mLocaleMap.get(pref)) + ",";
20436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            }
20536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        }
20636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        if (checkedLanguages.length() < 1) checkedLanguages = null; // Save null
20727d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa        Editor editor = mPrefs.edit();
2089502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka        editor.putString(Settings.PREF_SELECTED_LANGUAGES, checkedLanguages);
2090ea6270ffbe75eba2a754f8107487f3e0c1485a3Ken Wakasa        SharedPreferencesCompat.apply(editor);
21036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    }
21136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
212f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok    public ArrayList<LocaleEntry> getUniqueLocales() {
21336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        String[] locales = getAssets().getLocales();
21436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        Arrays.sort(locales);
215f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        ArrayList<LocaleEntry> uniqueLocales = new ArrayList<LocaleEntry>();
21636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
21736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        final int origSize = locales.length;
218f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok        LocaleEntry[] preprocess = new LocaleEntry[origSize];
21936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        int finalSize = 0;
22036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        for (int i = 0 ; i < origSize; i++ ) {
22136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            String s = locales[i];
22236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            int len = s.length();
22388808fcdd41c901072f3d224fa109182b26af22dsatok            String language = "";
22488808fcdd41c901072f3d224fa109182b26af22dsatok            String country = "";
22536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            if (len == 5) {
22688808fcdd41c901072f3d224fa109182b26af22dsatok                language = s.substring(0, 2);
22788808fcdd41c901072f3d224fa109182b26af22dsatok                country = s.substring(3, 5);
22888808fcdd41c901072f3d224fa109182b26af22dsatok            } else if (len < 5) {
22988808fcdd41c901072f3d224fa109182b26af22dsatok                language = s;
23088808fcdd41c901072f3d224fa109182b26af22dsatok            }
23188808fcdd41c901072f3d224fa109182b26af22dsatok            Locale l = new Locale(language, country);
23236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
23388808fcdd41c901072f3d224fa109182b26af22dsatok            // Exclude languages that are not relevant to LatinIME
23415a0ba6d74feed57124938336f951ae14aa47ad9satok            if (TextUtils.isEmpty(language)) {
23588808fcdd41c901072f3d224fa109182b26af22dsatok                continue;
23688808fcdd41c901072f3d224fa109182b26af22dsatok            }
2370a2df340e5bb3f7df4b5a1ddb3e611f08d195948Amith Yamasani
23888808fcdd41c901072f3d224fa109182b26af22dsatok            if (finalSize == 0) {
23988808fcdd41c901072f3d224fa109182b26af22dsatok                preprocess[finalSize++] =
24057f05f44123fd458203a6f776f2ff904889d2616Tadashi G. Takaoka                        new LocaleEntry(Utils.getFullDisplayName(l, false), l);
24188808fcdd41c901072f3d224fa109182b26af22dsatok            } else {
242f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                if (s.equals("zz_ZZ")) {
243f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                    // ignore this locale
24436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani                } else {
24557f05f44123fd458203a6f776f2ff904889d2616Tadashi G. Takaoka                    final String displayName = Utils.getFullDisplayName(l, false);
246f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok                    preprocess[finalSize++] = new LocaleEntry(displayName, l);
24736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani                }
24836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            }
24936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        }
25036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        for (int i = 0; i < finalSize ; i++) {
25136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            uniqueLocales.add(preprocess[i]);
25236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        }
25336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        return uniqueLocales;
25436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    }
25536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani}
256