Loading core/java/com/android/internal/inputmethod/InputMethodUtils.java +25 −4 Original line number Original line Diff line number Diff line Loading @@ -262,6 +262,7 @@ public class InputMethodUtils { final List<InputMethodSubtype> subtypes = InputMethodUtils.getSubtypes(imi); final List<InputMethodSubtype> subtypes = InputMethodUtils.getSubtypes(imi); final String systemLocale = res.getConfiguration().locale.toString(); final String systemLocale = res.getConfiguration().locale.toString(); if (TextUtils.isEmpty(systemLocale)) return new ArrayList<InputMethodSubtype>(); if (TextUtils.isEmpty(systemLocale)) return new ArrayList<InputMethodSubtype>(); final String systemLanguage = res.getConfiguration().locale.getLanguage(); final HashMap<String, InputMethodSubtype> applicableModeAndSubtypesMap = final HashMap<String, InputMethodSubtype> applicableModeAndSubtypesMap = new HashMap<String, InputMethodSubtype>(); new HashMap<String, InputMethodSubtype>(); final int N = subtypes.size(); final int N = subtypes.size(); Loading @@ -282,15 +283,22 @@ public class InputMethodUtils { final InputMethodSubtype subtype = subtypes.get(i); final InputMethodSubtype subtype = subtypes.get(i); final String locale = subtype.getLocale(); final String locale = subtype.getLocale(); final String mode = subtype.getMode(); final String mode = subtype.getMode(); final String language = getLanguageFromLocaleString(locale); // When system locale starts with subtype's locale, that subtype will be applicable // When system locale starts with subtype's locale, that subtype will be applicable // for system locale // for system locale. We need to make sure the languages are the same, to prevent // locales like "fil" (Filipino) being matched by "fi" (Finnish). // // For instance, it's clearly applicable for cases like system locale = en_US and // For instance, it's clearly applicable for cases like system locale = en_US and // subtype = en, but it is not necessarily considered applicable for cases like system // subtype = en, but it is not necessarily considered applicable for cases like system // locale = en and subtype = en_US. // locale = en and subtype = en_US. // // We just call systemLocale.startsWith(locale) in this function because there is no // We just call systemLocale.startsWith(locale) in this function because there is no // need to find applicable subtypes aggressively unlike // need to find applicable subtypes aggressively unlike // findLastResortApplicableSubtypeLocked. // findLastResortApplicableSubtypeLocked. if (systemLocale.startsWith(locale)) { // // TODO: This check is broken. It won't take scripts into account and doesn't // account for the mandatory conversions performed by Locale#toString. if (language.equals(systemLanguage) && systemLocale.startsWith(locale)) { final InputMethodSubtype applicableSubtype = applicableModeAndSubtypesMap.get(mode); final InputMethodSubtype applicableSubtype = applicableModeAndSubtypesMap.get(mode); // If more applicable subtypes are contained, skip. // If more applicable subtypes are contained, skip. if (applicableSubtype != null) { if (applicableSubtype != null) { Loading Loading @@ -334,6 +342,18 @@ public class InputMethodUtils { return InputMethodSubtype.sort(context, 0, imi, enabledSubtypes); return InputMethodSubtype.sort(context, 0, imi, enabledSubtypes); } } /** * Returns the language component of a given locale string. */ private static String getLanguageFromLocaleString(String locale) { final int idx = locale.indexOf('_'); if (idx < 0) { return locale; } else { return locale.substring(0, idx); } } /** /** * If there are no selected subtypes, tries finding the most applicable one according to the * If there are no selected subtypes, tries finding the most applicable one according to the * given locale. * given locale. Loading @@ -353,7 +373,7 @@ public class InputMethodUtils { if (TextUtils.isEmpty(locale)) { if (TextUtils.isEmpty(locale)) { locale = res.getConfiguration().locale.toString(); locale = res.getConfiguration().locale.toString(); } } final String language = locale.substring(0, 2); final String language = getLanguageFromLocaleString(locale); boolean partialMatchFound = false; boolean partialMatchFound = false; InputMethodSubtype applicableSubtype = null; InputMethodSubtype applicableSubtype = null; InputMethodSubtype firstMatchedModeSubtype = null; InputMethodSubtype firstMatchedModeSubtype = null; Loading @@ -361,6 +381,7 @@ public class InputMethodUtils { for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) { InputMethodSubtype subtype = subtypes.get(i); InputMethodSubtype subtype = subtypes.get(i); final String subtypeLocale = subtype.getLocale(); final String subtypeLocale = subtype.getLocale(); final String subtypeLanguage = getLanguageFromLocaleString(subtypeLocale); // An applicable subtype should match "mode". If mode is null, mode will be ignored, // An applicable subtype should match "mode". If mode is null, mode will be ignored, // and all subtypes with all modes can be candidates. // and all subtypes with all modes can be candidates. if (mode == null || subtypes.get(i).getMode().equalsIgnoreCase(mode)) { if (mode == null || subtypes.get(i).getMode().equalsIgnoreCase(mode)) { Loading @@ -371,7 +392,7 @@ public class InputMethodUtils { // Exact match (e.g. system locale is "en_US" and subtype locale is "en_US") // Exact match (e.g. system locale is "en_US" and subtype locale is "en_US") applicableSubtype = subtype; applicableSubtype = subtype; break; break; } else if (!partialMatchFound && subtypeLocale.startsWith(language)) { } else if (!partialMatchFound && language.equals(subtypeLanguage)) { // Partial match (e.g. system locale is "en_US" and subtype locale is "en") // Partial match (e.g. system locale is "en_US" and subtype locale is "en") applicableSubtype = subtype; applicableSubtype = subtype; partialMatchFound = true; partialMatchFound = true; Loading Loading
core/java/com/android/internal/inputmethod/InputMethodUtils.java +25 −4 Original line number Original line Diff line number Diff line Loading @@ -262,6 +262,7 @@ public class InputMethodUtils { final List<InputMethodSubtype> subtypes = InputMethodUtils.getSubtypes(imi); final List<InputMethodSubtype> subtypes = InputMethodUtils.getSubtypes(imi); final String systemLocale = res.getConfiguration().locale.toString(); final String systemLocale = res.getConfiguration().locale.toString(); if (TextUtils.isEmpty(systemLocale)) return new ArrayList<InputMethodSubtype>(); if (TextUtils.isEmpty(systemLocale)) return new ArrayList<InputMethodSubtype>(); final String systemLanguage = res.getConfiguration().locale.getLanguage(); final HashMap<String, InputMethodSubtype> applicableModeAndSubtypesMap = final HashMap<String, InputMethodSubtype> applicableModeAndSubtypesMap = new HashMap<String, InputMethodSubtype>(); new HashMap<String, InputMethodSubtype>(); final int N = subtypes.size(); final int N = subtypes.size(); Loading @@ -282,15 +283,22 @@ public class InputMethodUtils { final InputMethodSubtype subtype = subtypes.get(i); final InputMethodSubtype subtype = subtypes.get(i); final String locale = subtype.getLocale(); final String locale = subtype.getLocale(); final String mode = subtype.getMode(); final String mode = subtype.getMode(); final String language = getLanguageFromLocaleString(locale); // When system locale starts with subtype's locale, that subtype will be applicable // When system locale starts with subtype's locale, that subtype will be applicable // for system locale // for system locale. We need to make sure the languages are the same, to prevent // locales like "fil" (Filipino) being matched by "fi" (Finnish). // // For instance, it's clearly applicable for cases like system locale = en_US and // For instance, it's clearly applicable for cases like system locale = en_US and // subtype = en, but it is not necessarily considered applicable for cases like system // subtype = en, but it is not necessarily considered applicable for cases like system // locale = en and subtype = en_US. // locale = en and subtype = en_US. // // We just call systemLocale.startsWith(locale) in this function because there is no // We just call systemLocale.startsWith(locale) in this function because there is no // need to find applicable subtypes aggressively unlike // need to find applicable subtypes aggressively unlike // findLastResortApplicableSubtypeLocked. // findLastResortApplicableSubtypeLocked. if (systemLocale.startsWith(locale)) { // // TODO: This check is broken. It won't take scripts into account and doesn't // account for the mandatory conversions performed by Locale#toString. if (language.equals(systemLanguage) && systemLocale.startsWith(locale)) { final InputMethodSubtype applicableSubtype = applicableModeAndSubtypesMap.get(mode); final InputMethodSubtype applicableSubtype = applicableModeAndSubtypesMap.get(mode); // If more applicable subtypes are contained, skip. // If more applicable subtypes are contained, skip. if (applicableSubtype != null) { if (applicableSubtype != null) { Loading Loading @@ -334,6 +342,18 @@ public class InputMethodUtils { return InputMethodSubtype.sort(context, 0, imi, enabledSubtypes); return InputMethodSubtype.sort(context, 0, imi, enabledSubtypes); } } /** * Returns the language component of a given locale string. */ private static String getLanguageFromLocaleString(String locale) { final int idx = locale.indexOf('_'); if (idx < 0) { return locale; } else { return locale.substring(0, idx); } } /** /** * If there are no selected subtypes, tries finding the most applicable one according to the * If there are no selected subtypes, tries finding the most applicable one according to the * given locale. * given locale. Loading @@ -353,7 +373,7 @@ public class InputMethodUtils { if (TextUtils.isEmpty(locale)) { if (TextUtils.isEmpty(locale)) { locale = res.getConfiguration().locale.toString(); locale = res.getConfiguration().locale.toString(); } } final String language = locale.substring(0, 2); final String language = getLanguageFromLocaleString(locale); boolean partialMatchFound = false; boolean partialMatchFound = false; InputMethodSubtype applicableSubtype = null; InputMethodSubtype applicableSubtype = null; InputMethodSubtype firstMatchedModeSubtype = null; InputMethodSubtype firstMatchedModeSubtype = null; Loading @@ -361,6 +381,7 @@ public class InputMethodUtils { for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) { InputMethodSubtype subtype = subtypes.get(i); InputMethodSubtype subtype = subtypes.get(i); final String subtypeLocale = subtype.getLocale(); final String subtypeLocale = subtype.getLocale(); final String subtypeLanguage = getLanguageFromLocaleString(subtypeLocale); // An applicable subtype should match "mode". If mode is null, mode will be ignored, // An applicable subtype should match "mode". If mode is null, mode will be ignored, // and all subtypes with all modes can be candidates. // and all subtypes with all modes can be candidates. if (mode == null || subtypes.get(i).getMode().equalsIgnoreCase(mode)) { if (mode == null || subtypes.get(i).getMode().equalsIgnoreCase(mode)) { Loading @@ -371,7 +392,7 @@ public class InputMethodUtils { // Exact match (e.g. system locale is "en_US" and subtype locale is "en_US") // Exact match (e.g. system locale is "en_US" and subtype locale is "en_US") applicableSubtype = subtype; applicableSubtype = subtype; break; break; } else if (!partialMatchFound && subtypeLocale.startsWith(language)) { } else if (!partialMatchFound && language.equals(subtypeLanguage)) { // Partial match (e.g. system locale is "en_US" and subtype locale is "en") // Partial match (e.g. system locale is "en_US" and subtype locale is "en") applicableSubtype = subtype; applicableSubtype = subtype; partialMatchFound = true; partialMatchFound = true; Loading