1e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka/* 2e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * Copyright (C) 2011 The Android Open Source Project 3e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * 4e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 5e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * you may not use this file except in compliance with the License. 6e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * You may obtain a copy of the License at 7e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * 8e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 9e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * 10e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 11e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 12e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * See the License for the specific language governing permissions and 14e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka * limitations under the License. 15e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka */ 16e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka 17e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaokapackage com.android.inputmethod.latin; 18e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka 191cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaokaimport static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; 208e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaokaimport static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME; 211cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaoka 22e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaokaimport android.content.Context; 23e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaokaimport android.content.res.Resources; 248e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaokaimport android.os.Build; 25ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaokaimport android.util.Log; 268abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaokaimport android.view.inputmethod.InputMethodSubtype; 278abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka 28757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaokaimport com.android.inputmethod.latin.LocaleUtils.RunInLocale; 29757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka 30f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaokaimport java.util.HashMap; 31e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaokaimport java.util.Locale; 32e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka 33a28a05e971cc242b338331a3b78276fa95188d19Tadashi G. Takaokapublic final class SubtypeLocale { 34ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka static final String TAG = SubtypeLocale.class.getSimpleName(); 3538026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka // This class must be located in the same package as LatinIME.java. 3638026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka private static final String RESOURCE_PACKAGE_NAME = 3738026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka DictionaryFactory.class.getPackage().getName(); 38c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka 393bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka // Special language code to represent "no language". 40a58ebc73ae3eb2783713c471d8abb348c7dfc8daTadashi G. Takaoka public static final String NO_LANGUAGE = "zz"; 4138026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka public static final String QWERTY = "qwerty"; 4296e404310deca42a6696abdcb3111d355815b547Tadashi G. Takaoka public static final int UNKNOWN_KEYBOARD_LAYOUT = R.string.subtype_generic; 4396e404310deca42a6696abdcb3111d355815b547Tadashi G. Takaoka 44d6ac0443f0250281872fd889c81d8cbd71e72736Tadashi G. Takaoka private static boolean sInitialized = false; 4538026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka private static String[] sPredefinedKeyboardLayoutSet; 4638026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka // Keyboard layout to its display name map. 478e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka private static final HashMap<String, String> sKeyboardLayoutToDisplayNameMap = 485f282ea9e4a4590fcbab6e27d5fca7dacbb40a6aTadashi G. Takaoka CollectionUtils.newHashMap(); 4938026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka // Keyboard layout to subtype name resource id map. 5038026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka private static final HashMap<String, Integer> sKeyboardLayoutToNameIdsMap = 515f282ea9e4a4590fcbab6e27d5fca7dacbb40a6aTadashi G. Takaoka CollectionUtils.newHashMap(); 528e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka // Exceptional locale to subtype name resource id map. 538e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka private static final HashMap<String, Integer> sExceptionalLocaleToWithLayoutNameIdsMap = 545f282ea9e4a4590fcbab6e27d5fca7dacbb40a6aTadashi G. Takaoka CollectionUtils.newHashMap(); 5527b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka private static final String SUBTYPE_NAME_RESOURCE_GENERIC_PREFIX = 5627b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka "string/subtype_generic_"; 578e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka private static final String SUBTYPE_NAME_RESOURCE_WITH_LAYOUT_PREFIX = 588e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka "string/subtype_with_layout_"; 5927b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka private static final String SUBTYPE_NAME_RESOURCE_NO_LANGUAGE_PREFIX = 6027b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka "string/subtype_no_language_"; 61f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka // Exceptional locales to display name map. 62f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka private static final HashMap<String, String> sExceptionalDisplayNamesMap = 635f282ea9e4a4590fcbab6e27d5fca7dacbb40a6aTadashi G. Takaoka CollectionUtils.newHashMap(); 647f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka // Keyboard layout set name for the subtypes that don't have a keyboardLayoutSet extra value. 657f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka // This is for compatibility to keep the same subtype ids as pre-JellyBean. 667f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka private static final HashMap<String,String> sLocaleAndExtraValueToKeyboardLayoutSetMap = 675f282ea9e4a4590fcbab6e27d5fca7dacbb40a6aTadashi G. Takaoka CollectionUtils.newHashMap(); 688abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka 69e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka private SubtypeLocale() { 70e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka // Intentional empty constructor for utility class. 71e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka } 72e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka 73d6ac0443f0250281872fd889c81d8cbd71e72736Tadashi G. Takaoka // Note that this initialization method can be called multiple times. 74d6ac0443f0250281872fd889c81d8cbd71e72736Tadashi G. Takaoka public static synchronized void init(Context context) { 75d6ac0443f0250281872fd889c81d8cbd71e72736Tadashi G. Takaoka if (sInitialized) return; 76d6ac0443f0250281872fd889c81d8cbd71e72736Tadashi G. Takaoka 77e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka final Resources res = context.getResources(); 7838026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka 7938026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka final String[] predefinedLayoutSet = res.getStringArray(R.array.predefined_layouts); 8038026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka sPredefinedKeyboardLayoutSet = predefinedLayoutSet; 8138026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka final String[] layoutDisplayNames = res.getStringArray( 8238026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka R.array.predefined_layout_display_names); 8338026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka for (int i = 0; i < predefinedLayoutSet.length; i++) { 8438026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka final String layoutName = predefinedLayoutSet[i]; 858e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka sKeyboardLayoutToDisplayNameMap.put(layoutName, layoutDisplayNames[i]); 8627b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka final String resourceName = SUBTYPE_NAME_RESOURCE_GENERIC_PREFIX + layoutName; 8738026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME); 8838026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka sKeyboardLayoutToNameIdsMap.put(layoutName, resId); 8927b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // Register subtype name resource id of "No language" with key "zz_<layout>" 9027b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka final String noLanguageResName = SUBTYPE_NAME_RESOURCE_NO_LANGUAGE_PREFIX + layoutName; 9127b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka final int noLanguageResId = res.getIdentifier( 9227b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka noLanguageResName, null, RESOURCE_PACKAGE_NAME); 9327b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka final String key = getNoLanguageLayoutKey(layoutName); 9427b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka sKeyboardLayoutToNameIdsMap.put(key, noLanguageResId); 9538026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka } 9638026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka 9738026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka final String[] exceptionalLocales = res.getStringArray( 9838026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka R.array.subtype_locale_exception_keys); 9938026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka final String[] exceptionalDisplayNames = res.getStringArray( 10038026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka R.array.subtype_locale_exception_values); 10138026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka for (int i = 0; i < exceptionalLocales.length; i++) { 1028e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka final String localeString = exceptionalLocales[i]; 1038e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka sExceptionalDisplayNamesMap.put(localeString, exceptionalDisplayNames[i]); 1048e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka final String resourceName = SUBTYPE_NAME_RESOURCE_WITH_LAYOUT_PREFIX + localeString; 1058e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME); 1068e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka sExceptionalLocaleToWithLayoutNameIdsMap.put(localeString, resId); 107e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka } 1087f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka 1097f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka final String[] keyboardLayoutSetMap = res.getStringArray( 1107f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka R.array.locale_and_extra_value_to_keyboard_layout_set_map); 1117f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka for (int i = 0; i < keyboardLayoutSetMap.length; i += 2) { 1127f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka final String key = keyboardLayoutSetMap[i]; 1137f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka final String keyboardLayoutSet = keyboardLayoutSetMap[i + 1]; 1147f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka sLocaleAndExtraValueToKeyboardLayoutSetMap.put(key, keyboardLayoutSet); 1157f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka } 116d6ac0443f0250281872fd889c81d8cbd71e72736Tadashi G. Takaoka 117d6ac0443f0250281872fd889c81d8cbd71e72736Tadashi G. Takaoka sInitialized = true; 1183bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka } 1193bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka 12038026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka public static String[] getPredefinedKeyboardLayoutSet() { 12138026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka return sPredefinedKeyboardLayoutSet; 12238026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka } 12338026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka 1248e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka public static boolean isExceptionalLocale(String localeString) { 1258e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka return sExceptionalLocaleToWithLayoutNameIdsMap.containsKey(localeString); 1268e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka } 1278e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka 12827b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka private static final String getNoLanguageLayoutKey(String keyboardLayoutName) { 12927b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka return NO_LANGUAGE + "_" + keyboardLayoutName; 13038026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka } 13138026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka 13227b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka public static int getSubtypeNameId(String localeString, String keyboardLayoutName) { 133165725aba8a179440af9c93869b35f206b2e133fTadashi G. Takaoka if (Build.VERSION.SDK_INT >= /* JELLY_BEAN */ 15 && isExceptionalLocale(localeString)) { 1348e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka return sExceptionalLocaleToWithLayoutNameIdsMap.get(localeString); 1358e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka } 13627b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka final String key = localeString.equals(NO_LANGUAGE) 13727b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka ? getNoLanguageLayoutKey(keyboardLayoutName) 13827b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka : keyboardLayoutName; 13927b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka final Integer nameId = sKeyboardLayoutToNameIdsMap.get(key); 14027b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka return nameId == null ? UNKNOWN_KEYBOARD_LAYOUT : nameId; 14127b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka } 142c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka 14327b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka public static String getSubtypeLocaleDisplayName(String localeString) { 14427b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka final String exceptionalValue = sExceptionalDisplayNamesMap.get(localeString); 145c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka if (exceptionalValue != null) { 146c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka return exceptionalValue; 147c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka } 14827b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka final Locale locale = LocaleUtils.constructLocaleFromString(localeString); 149f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka return StringUtils.toTitleCase(locale.getDisplayName(locale), locale); 1503bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka } 1513bf57a5624679a20db26df912077a53b9f90ad36Tadashi G. Takaoka 15227b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // InputMethodSubtype's display name in its locale. 15327b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // isAdditionalSubtype (T=true, F=false) 15427b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // locale layout | display name 15527b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // ------ ------ - ---------------------- 15627b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // en_US qwerty F English (US) exception 15727b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // en_GB qwerty F English (UK) exception 15827b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // fr azerty F Français 15927b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // fr_CA qwerty F Français (Canada) 16027b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // de qwertz F Deutsch 161757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka // zz qwerty F No language (QWERTY) in system locale 16227b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // fr qwertz T Français (QWERTZ) 16327b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // de qwerty T Deutsch (QWERTY) 16427b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka // en_US azerty T English (US) (AZERTY) 165757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka // zz azerty T No language (AZERTY) in system locale 16627b42ced86e1c85de3d59d91a9e5c577fa552569Tadashi G. Takaoka 167ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka public static String getSubtypeDisplayName(final InputMethodSubtype subtype, Resources res) { 168165725aba8a179440af9c93869b35f206b2e133fTadashi G. Takaoka final String replacementString = (Build.VERSION.SDK_INT >= /* JELLY_BEAN */ 15 169165725aba8a179440af9c93869b35f206b2e133fTadashi G. Takaoka && subtype.containsExtraValueKey(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)) 1708e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka ? subtype.getExtraValueOf(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME) 1718e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka : getSubtypeLocaleDisplayName(subtype.getLocale()); 172757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka final int nameResId = subtype.getNameResId(); 173757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka final RunInLocale<String> getSubtypeName = new RunInLocale<String>() { 174757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka @Override 175757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka protected String job(Resources res) { 176ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka try { 1778e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka return res.getString(nameResId, replacementString); 178ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka } catch (Resources.NotFoundException e) { 179ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka // TODO: Remove this catch when InputMethodManager.getCurrentInputMethodSubtype 180ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka // is fixed. 181ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka Log.w(TAG, "Unknown subtype: mode=" + subtype.getMode() 182ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka + " locale=" + subtype.getLocale() 183ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka + " extra=" + subtype.getExtraValue() 184ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka + "\n" + Utils.getStackTrace()); 185ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka return ""; 186ca934420269e18c843181c0dc98cd61cce67dd19Tadashi G. Takaoka } 187757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka } 188757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka }; 189757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka final Locale locale = isNoLanguage(subtype) 190757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka ? res.getConfiguration().locale : getSubtypeLocale(subtype); 191757c12556b5336cce4962b18967a0da20c871329Tadashi G. Takaoka return getSubtypeName.runInLocale(res, locale); 192cb389ef0d6e6eec737c249e1729c2a2cdc30f341Tadashi G. Takaoka } 1938abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka 194f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka public static boolean isNoLanguage(InputMethodSubtype subtype) { 195f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka final String localeString = subtype.getLocale(); 196f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka return localeString.equals(NO_LANGUAGE); 1978abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka } 1988abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka 199f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka public static Locale getSubtypeLocale(InputMethodSubtype subtype) { 200f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka final String localeString = subtype.getLocale(); 201f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka return LocaleUtils.constructLocaleFromString(localeString); 202f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka } 203f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka 204bb17bafac3db7f54559e3d774069f0a915753cc3Tadashi G. Takaoka public static String getKeyboardLayoutSetDisplayName(InputMethodSubtype subtype) { 20578173bdf535e38a4f9c3bcc8038151de86071728Tadashi G. Takaoka final String layoutName = getKeyboardLayoutSetName(subtype); 2068e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka return getKeyboardLayoutSetDisplayName(layoutName); 2078e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka } 2088e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka 2098e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka public static String getKeyboardLayoutSetDisplayName(String layoutName) { 2108e50c5d198f65beb6679a9a1e0102e5fc52d7707Tadashi G. Takaoka return sKeyboardLayoutToDisplayNameMap.get(layoutName); 211bb17bafac3db7f54559e3d774069f0a915753cc3Tadashi G. Takaoka } 212bb17bafac3db7f54559e3d774069f0a915753cc3Tadashi G. Takaoka 213f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka public static String getKeyboardLayoutSetName(InputMethodSubtype subtype) { 2147f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka String keyboardLayoutSet = subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET); 2157f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka if (keyboardLayoutSet == null) { 2167f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka // This subtype doesn't have a keyboardLayoutSet extra value, so lookup its keyboard 2177f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka // layout set in sLocaleAndExtraValueToKeyboardLayoutSetMap to keep it compatible with 2187f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka // pre-JellyBean. 2197f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka final String key = subtype.getLocale() + ":" + subtype.getExtraValue(); 2207f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka keyboardLayoutSet = sLocaleAndExtraValueToKeyboardLayoutSetMap.get(key); 2217f7947c97b141cbb338c5164e9e19d1ac9ff3d1cTadashi G. Takaoka } 2228abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is 2238abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka // fixed. 224c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka if (keyboardLayoutSet == null) { 225c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka android.util.Log.w(TAG, "KeyboardLayoutSet not found, use QWERTY: " + 226b9fca7a192f3e448220fe79ea89d307f47b0d6b8Tadashi G. Takaoka "locale=" + subtype.getLocale() + " extraValue=" + subtype.getExtraValue()); 22738026b4f03fb4d846b8613d889d68c439f6e30cbTadashi G. Takaoka return QWERTY; 228c27fe6253c1d8b3ad3c2f891a48ec5c54d77a3f1Tadashi G. Takaoka } 229f6972561fcb45310f18230ce217f0c6bb57e7eeeTadashi G. Takaoka return keyboardLayoutSet; 2308abde7db6bacbd5726a87e924ec8aea7fbb10d9aTadashi G. Takaoka } 231e276d8ddaaff91d5940a71cefb5ecd94fd48ba98Tadashi G. Takaoka} 232