diff options
Diffstat (limited to 'core')
| -rw-r--r-- | core/java/com/android/internal/inputmethod/InputMethodUtils.java | 127 | ||||
| -rw-r--r-- | core/tests/inputmethodtests/src/android/os/InputMethodTest.java | 99 |
2 files changed, 226 insertions, 0 deletions
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java index ac17cbe..742173b 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java +++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java @@ -1302,4 +1302,131 @@ public class InputMethodUtils { return enabledInputMethodAndSubtypes; } } + + // For spell checker service manager. + // TODO: Should we have TextServicesUtils.java? + private static final Locale LOCALE_EN_US = new Locale("en", "US"); + private static final Locale LOCALE_EN_GB = new Locale("en", "GB"); + + /** + * Returns a list of {@link Locale} in the order of appropriateness for the default spell + * checker service. + * + * <p>If the system language is English, and the region is also explicitly specified in the + * system locale, the following fallback order will be applied.</p> + * <ul> + * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li> + * <li>(system-locale-language, system-locale-region)</li> + * <li>("en", "US")</li> + * <li>("en", "GB")</li> + * <li>("en")</li> + * </ul> + * + * <p>If the system language is English, but no region is specified in the system locale, + * the following fallback order will be applied.</p> + * <ul> + * <li>("en")</li> + * <li>("en", "US")</li> + * <li>("en", "GB")</li> + * </ul> + * + * <p>If the system language is not English, the following fallback order will be applied.</p> + * <ul> + * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li> + * <li>(system-locale-language, system-locale-region) (if exists)</li> + * <li>(system-locale-language) (if exists)</li> + * <li>("en", "US")</li> + * <li>("en", "GB")</li> + * <li>("en")</li> + * </ul> + * + * @param systemLocale the current system locale to be taken into consideration. + * @return a list of {@link Locale}. The first one is considered to be most appropriate. + */ + @VisibleForTesting + public static ArrayList<Locale> getSuitableLocalesForSpellChecker( + @Nullable final Locale systemLocale) { + final Locale systemLocaleLanguageCountryVariant; + final Locale systemLocaleLanguageCountry; + final Locale systemLocaleLanguage; + if (systemLocale != null) { + final String language = systemLocale.getLanguage(); + final boolean hasLanguage = !TextUtils.isEmpty(language); + final String country = systemLocale.getCountry(); + final boolean hasCountry = !TextUtils.isEmpty(country); + final String variant = systemLocale.getVariant(); + final boolean hasVariant = !TextUtils.isEmpty(variant); + if (hasLanguage && hasCountry && hasVariant) { + systemLocaleLanguageCountryVariant = new Locale(language, country, variant); + } else { + systemLocaleLanguageCountryVariant = null; + } + if (hasLanguage && hasCountry) { + systemLocaleLanguageCountry = new Locale(language, country); + } else { + systemLocaleLanguageCountry = null; + } + if (hasLanguage) { + systemLocaleLanguage = new Locale(language); + } else { + systemLocaleLanguage = null; + } + } else { + systemLocaleLanguageCountryVariant = null; + systemLocaleLanguageCountry = null; + systemLocaleLanguage = null; + } + + final ArrayList<Locale> locales = new ArrayList<>(); + if (systemLocaleLanguageCountryVariant != null) { + locales.add(systemLocaleLanguageCountryVariant); + } + + if (Locale.ENGLISH.equals(systemLocaleLanguage)) { + if (systemLocaleLanguageCountry != null) { + // If the system language is English, and the region is also explicitly specified, + // following fallback order will be applied. + // - systemLocaleLanguageCountry [if systemLocaleLanguageCountry is non-null] + // - en_US [if systemLocaleLanguageCountry is non-null and not en_US] + // - en_GB [if systemLocaleLanguageCountry is non-null and not en_GB] + // - en + if (systemLocaleLanguageCountry != null) { + locales.add(systemLocaleLanguageCountry); + } + if (!LOCALE_EN_US.equals(systemLocaleLanguageCountry)) { + locales.add(LOCALE_EN_US); + } + if (!LOCALE_EN_GB.equals(systemLocaleLanguageCountry)) { + locales.add(LOCALE_EN_GB); + } + locales.add(Locale.ENGLISH); + } else { + // If the system language is English, but no region is specified, following + // fallback order will be applied. + // - en + // - en_US + // - en_GB + locales.add(Locale.ENGLISH); + locales.add(LOCALE_EN_US); + locales.add(LOCALE_EN_GB); + } + } else { + // If the system language is not English, the fallback order will be + // - systemLocaleLanguageCountry [if non-null] + // - systemLocaleLanguage [if non-null] + // - en_US + // - en_GB + // - en + if (systemLocaleLanguageCountry != null) { + locales.add(systemLocaleLanguageCountry); + } + if (systemLocaleLanguage != null) { + locales.add(systemLocaleLanguage); + } + locales.add(LOCALE_EN_US); + locales.add(LOCALE_EN_GB); + locales.add(Locale.ENGLISH); + } + return locales; + } } diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java index a50fb54..31a4703 100644 --- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java +++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java @@ -51,11 +51,15 @@ public class InputMethodTest extends InstrumentationTestCase { private static final Locale LOCALE_FR = new Locale("fr"); private static final Locale LOCALE_FR_CA = new Locale("fr", "CA"); private static final Locale LOCALE_HI = new Locale("hi"); + private static final Locale LOCALE_JA = new Locale("ja"); private static final Locale LOCALE_JA_JP = new Locale("ja", "JP"); private static final Locale LOCALE_ZH_CN = new Locale("zh", "CN"); private static final Locale LOCALE_ZH_TW = new Locale("zh", "TW"); private static final Locale LOCALE_IN = new Locale("in"); private static final Locale LOCALE_ID = new Locale("id"); + private static final Locale LOCALE_TH = new Locale("ht"); + private static final Locale LOCALE_TH_TH = new Locale("ht", "TH"); + private static final Locale LOCALE_TH_TH_TH = new Locale("ht", "TH", "TH"); private static final String SUBTYPE_MODE_KEYBOARD = "keyboard"; private static final String SUBTYPE_MODE_VOICE = "voice"; private static final String SUBTYPE_MODE_ANY = null; @@ -849,4 +853,99 @@ public class InputMethodTest extends InstrumentationTestCase { return preinstalledImes; } + + @SmallTest + public void testGetSuitableLocalesForSpellChecker() throws Exception { + { + final ArrayList<Locale> locales = + InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_US); + assertEquals(3, locales.size()); + assertEquals(LOCALE_EN_US, locales.get(0)); + assertEquals(LOCALE_EN_GB, locales.get(1)); + assertEquals(LOCALE_EN, locales.get(2)); + } + + { + final ArrayList<Locale> locales = + InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_GB); + assertEquals(3, locales.size()); + assertEquals(LOCALE_EN_GB, locales.get(0)); + assertEquals(LOCALE_EN_US, locales.get(1)); + assertEquals(LOCALE_EN, locales.get(2)); + } + + { + final ArrayList<Locale> locales = + InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN); + assertEquals(3, locales.size()); + assertEquals(LOCALE_EN, locales.get(0)); + assertEquals(LOCALE_EN_US, locales.get(1)); + assertEquals(LOCALE_EN_GB, locales.get(2)); + } + + { + final ArrayList<Locale> locales = + InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_IN); + assertEquals(4, locales.size()); + assertEquals(LOCALE_EN_IN, locales.get(0)); + assertEquals(LOCALE_EN_US, locales.get(1)); + assertEquals(LOCALE_EN_GB, locales.get(2)); + assertEquals(LOCALE_EN, locales.get(3)); + } + + { + final ArrayList<Locale> locales = + InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_JA_JP); + assertEquals(5, locales.size()); + assertEquals(LOCALE_JA_JP, locales.get(0)); + assertEquals(LOCALE_JA, locales.get(1)); + assertEquals(LOCALE_EN_US, locales.get(2)); + assertEquals(LOCALE_EN_GB, locales.get(3)); + assertEquals(Locale.ENGLISH, locales.get(4)); + } + + // Test 3-letter language code. + { + final ArrayList<Locale> locales = + InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_FIL_PH); + assertEquals(5, locales.size()); + assertEquals(LOCALE_FIL_PH, locales.get(0)); + assertEquals(LOCALE_FIL, locales.get(1)); + assertEquals(LOCALE_EN_US, locales.get(2)); + assertEquals(LOCALE_EN_GB, locales.get(3)); + assertEquals(Locale.ENGLISH, locales.get(4)); + } + + // Test variant. + { + final ArrayList<Locale> locales = + InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_TH_TH_TH); + assertEquals(6, locales.size()); + assertEquals(LOCALE_TH_TH_TH, locales.get(0)); + assertEquals(LOCALE_TH_TH, locales.get(1)); + assertEquals(LOCALE_TH, locales.get(2)); + assertEquals(LOCALE_EN_US, locales.get(3)); + assertEquals(LOCALE_EN_GB, locales.get(4)); + assertEquals(Locale.ENGLISH, locales.get(5)); + } + + // Test Locale extension. + { + final Locale localeWithoutVariant = LOCALE_JA_JP; + final Locale localeWithVariant = new Locale.Builder() + .setLocale(LOCALE_JA_JP) + .setExtension('x', "android") + .build(); + assertFalse(localeWithoutVariant.equals(localeWithVariant)); + + final ArrayList<Locale> locales = + InputMethodUtils.getSuitableLocalesForSpellChecker(localeWithVariant); + assertEquals(5, locales.size()); + assertEquals(LOCALE_JA_JP, locales.get(0)); + assertEquals(LOCALE_JA, locales.get(1)); + assertEquals(LOCALE_EN_US, locales.get(2)); + assertEquals(LOCALE_EN_GB, locales.get(3)); + assertEquals(Locale.ENGLISH, locales.get(4)); + } + } } |
