From a410cb48eab0cd75aa27e20f60e47a29a59fb9ff Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Wed, 24 Jul 2013 10:37:07 +0900 Subject: Move subtype related utility class to utils package Change-Id: I3564796531ea85f2ebafde40cd822b806b8741df --- .../android/inputmethod/keyboard/KeyboardId.java | 4 +- .../inputmethod/keyboard/KeyboardLayoutSet.java | 8 +- .../inputmethod/keyboard/MainKeyboardView.java | 8 +- .../keyboard/internal/KeyboardBuilder.java | 4 +- .../inputmethod/latin/AdditionalSubtype.java | 139 --------- .../inputmethod/latin/RichInputMethodManager.java | 10 +- .../android/inputmethod/latin/SubtypeLocale.java | 335 --------------------- .../android/inputmethod/latin/SubtypeSwitcher.java | 14 +- .../inputmethod/latin/UserBinaryDictionary.java | 3 +- .../latin/settings/AdditionalSubtypeSettings.java | 34 +-- .../inputmethod/latin/settings/Settings.java | 4 +- .../latin/settings/SettingsFragment.java | 10 +- .../latin/utils/AdditionalSubtypeUtils.java | 138 +++++++++ .../latin/utils/SubtypeLocaleUtils.java | 333 ++++++++++++++++++++ 14 files changed, 523 insertions(+), 521 deletions(-) delete mode 100644 java/src/com/android/inputmethod/latin/AdditionalSubtype.java delete mode 100644 java/src/com/android/inputmethod/latin/SubtypeLocale.java create mode 100644 java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java create mode 100644 java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java (limited to 'java/src') diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java index d00521c58..8864b7603 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java @@ -25,8 +25,8 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.EditorInfoCompatUtils; -import com.android.inputmethod.latin.SubtypeLocale; import com.android.inputmethod.latin.utils.InputTypeUtils; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Arrays; import java.util.Locale; @@ -76,7 +76,7 @@ public final class KeyboardId { public KeyboardId(final int elementId, final KeyboardLayoutSet.Params params) { mSubtype = params.mSubtype; - mLocale = SubtypeLocale.getSubtypeLocale(mSubtype); + mLocale = SubtypeLocaleUtils.getSubtypeLocale(mSubtype); mOrientation = params.mOrientation; mWidth = params.mKeyboardWidth; mHeight = params.mKeyboardHeight; diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java index c4f5eb035..6a900b45f 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java @@ -41,15 +41,15 @@ import com.android.inputmethod.compat.EditorInfoCompatUtils; import com.android.inputmethod.keyboard.internal.KeyboardBuilder; import com.android.inputmethod.keyboard.internal.KeyboardParams; import com.android.inputmethod.keyboard.internal.KeysCache; -import com.android.inputmethod.latin.AdditionalSubtype; import com.android.inputmethod.latin.InputAttributes; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.SubtypeLocale; import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.InputTypeUtils; import com.android.inputmethod.latin.utils.ResourceUtils; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import com.android.inputmethod.latin.utils.XmlParseUtils; import org.xmlpull.v1.XmlPullParser; @@ -288,7 +288,7 @@ public final class KeyboardLayoutSet { : subtype; mParams.mSubtype = keyboardSubtype; mParams.mKeyboardLayoutSetName = KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX - + SubtypeLocale.getKeyboardLayoutSetName(keyboardSubtype); + + SubtypeLocaleUtils.getKeyboardLayoutSetName(keyboardSubtype); return this; } @@ -445,7 +445,7 @@ public final class KeyboardLayoutSet { public static KeyboardLayoutSet createKeyboardSetForSpellChecker(final Context context, final String locale, final String layout) { final InputMethodSubtype subtype = - AdditionalSubtype.createAdditionalSubtype(locale, layout, null); + AdditionalSubtypeUtils.createAdditionalSubtype(locale, layout, null); return createKeyboardSet(context, subtype, SPELLCHECKER_DUMMY_KEYBOARD_WIDTH, SPELLCHECKER_DUMMY_KEYBOARD_HEIGHT, false /* testCasesHaveTouchCoordinates */, true /* isSpellChecker */); diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 834ff0a42..a45133c3f 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -59,7 +59,6 @@ import com.android.inputmethod.keyboard.internal.TouchScreenRegulator; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.SubtypeLocale; import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.settings.DebugSettings; @@ -67,6 +66,7 @@ import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CoordinateUtils; import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import com.android.inputmethod.latin.utils.TypefaceUtils; import com.android.inputmethod.latin.utils.UsabilityStudyLogUtils; import com.android.inputmethod.latin.utils.ViewLayoutUtils; @@ -1342,17 +1342,17 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack private static String layoutLanguageOnSpacebar(final Paint paint, final InputMethodSubtype subtype, final int width) { // Choose appropriate language name to fit into the width. - final String fullText = SubtypeLocale.getFullDisplayName(subtype); + final String fullText = SubtypeLocaleUtils.getFullDisplayName(subtype); if (fitsTextIntoWidth(width, fullText, paint)) { return fullText; } - final String middleText = SubtypeLocale.getMiddleDisplayName(subtype); + final String middleText = SubtypeLocaleUtils.getMiddleDisplayName(subtype); if (fitsTextIntoWidth(width, middleText, paint)) { return middleText; } - final String shortText = SubtypeLocale.getShortDisplayName(subtype); + final String shortText = SubtypeLocaleUtils.getShortDisplayName(subtype); if (fitsTextIntoWidth(width, shortText, paint)) { return shortText; } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java index 26bbd7de9..e438e6d86 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java @@ -30,10 +30,10 @@ import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardId; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.SubtypeLocale; import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale; import com.android.inputmethod.latin.utils.ResourceUtils; import com.android.inputmethod.latin.utils.StringUtils; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import com.android.inputmethod.latin.utils.XmlParseUtils; import org.xmlpull.v1.XmlPullParser; @@ -285,7 +285,7 @@ public class KeyboardBuilder { } }; // Null means the current system locale. - final Locale locale = SubtypeLocale.isNoLanguage(params.mId.mSubtype) + final Locale locale = SubtypeLocaleUtils.isNoLanguage(params.mId.mSubtype) ? null : params.mId.mLocale; job.runInLocale(mResources, locale); diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java b/java/src/com/android/inputmethod/latin/AdditionalSubtype.java deleted file mode 100644 index 0bddeb5ce..000000000 --- a/java/src/com/android/inputmethod/latin/AdditionalSubtype.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.latin; - -import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE; -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.IS_ADDITIONAL_SUBTYPE; -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME; - -import android.os.Build; -import android.text.TextUtils; -import android.view.inputmethod.InputMethodSubtype; - -import com.android.inputmethod.latin.utils.CollectionUtils; -import com.android.inputmethod.latin.utils.StringUtils; - -import java.util.ArrayList; - -public final class AdditionalSubtype { - private static final InputMethodSubtype[] EMPTY_SUBTYPE_ARRAY = new InputMethodSubtype[0]; - - private AdditionalSubtype() { - // This utility class is not publicly instantiable. - } - - public static boolean isAdditionalSubtype(final InputMethodSubtype subtype) { - return subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE); - } - - private static final String LOCALE_AND_LAYOUT_SEPARATOR = ":"; - private static final String PREF_SUBTYPE_SEPARATOR = ";"; - - public static InputMethodSubtype createAdditionalSubtype(final String localeString, - final String keyboardLayoutSetName, final String extraValue) { - final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName; - final String layoutDisplayNameExtraValue; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN - && SubtypeLocale.isExceptionalLocale(localeString)) { - final String layoutDisplayName = SubtypeLocale.getKeyboardLayoutSetDisplayName( - keyboardLayoutSetName); - layoutDisplayNameExtraValue = StringUtils.appendToCommaSplittableTextIfNotExists( - UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" + layoutDisplayName, extraValue); - } else { - layoutDisplayNameExtraValue = extraValue; - } - final String additionalSubtypeExtraValue = - StringUtils.appendToCommaSplittableTextIfNotExists( - IS_ADDITIONAL_SUBTYPE, layoutDisplayNameExtraValue); - final int nameId = SubtypeLocale.getSubtypeNameId(localeString, keyboardLayoutSetName); - return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard, - localeString, KEYBOARD_MODE, - layoutExtraValue + "," + additionalSubtypeExtraValue, false, false); - } - - public static String getPrefSubtype(final InputMethodSubtype subtype) { - final String localeString = subtype.getLocale(); - final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype); - final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName; - final String extraValue = StringUtils.removeFromCommaSplittableTextIfExists( - layoutExtraValue, StringUtils.removeFromCommaSplittableTextIfExists( - IS_ADDITIONAL_SUBTYPE, subtype.getExtraValue())); - final String basePrefSubtype = localeString + LOCALE_AND_LAYOUT_SEPARATOR - + keyboardLayoutSetName; - return extraValue.isEmpty() ? basePrefSubtype - : basePrefSubtype + LOCALE_AND_LAYOUT_SEPARATOR + extraValue; - } - - public static InputMethodSubtype createAdditionalSubtype(final String prefSubtype) { - final String elems[] = prefSubtype.split(LOCALE_AND_LAYOUT_SEPARATOR); - if (elems.length < 2 || elems.length > 3) { - throw new RuntimeException("Unknown additional subtype specified: " + prefSubtype); - } - final String localeString = elems[0]; - final String keyboardLayoutSetName = elems[1]; - final String extraValue = (elems.length == 3) ? elems[2] : null; - return createAdditionalSubtype(localeString, keyboardLayoutSetName, extraValue); - } - - public static InputMethodSubtype[] createAdditionalSubtypesArray(final String prefSubtypes) { - if (TextUtils.isEmpty(prefSubtypes)) { - return EMPTY_SUBTYPE_ARRAY; - } - final String[] prefSubtypeArray = prefSubtypes.split(PREF_SUBTYPE_SEPARATOR); - final ArrayList subtypesList = - CollectionUtils.newArrayList(prefSubtypeArray.length); - for (final String prefSubtype : prefSubtypeArray) { - final InputMethodSubtype subtype = createAdditionalSubtype(prefSubtype); - if (subtype.getNameResId() == SubtypeLocale.UNKNOWN_KEYBOARD_LAYOUT) { - // Skip unknown keyboard layout subtype. This may happen when predefined keyboard - // layout has been removed. - continue; - } - subtypesList.add(subtype); - } - return subtypesList.toArray(new InputMethodSubtype[subtypesList.size()]); - } - - public static String createPrefSubtypes(final InputMethodSubtype[] subtypes) { - if (subtypes == null || subtypes.length == 0) { - return ""; - } - final StringBuilder sb = new StringBuilder(); - for (final InputMethodSubtype subtype : subtypes) { - if (sb.length() > 0) { - sb.append(PREF_SUBTYPE_SEPARATOR); - } - sb.append(getPrefSubtype(subtype)); - } - return sb.toString(); - } - - public static String createPrefSubtypes(final String[] prefSubtypes) { - if (prefSubtypes == null || prefSubtypes.length == 0) { - return ""; - } - final StringBuilder sb = new StringBuilder(); - for (final String prefSubtype : prefSubtypes) { - if (sb.length() > 0) { - sb.append(PREF_SUBTYPE_SEPARATOR); - } - sb.append(prefSubtype); - } - return sb.toString(); - } -} diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java index 56b1e3f61..6b6bbf3a7 100644 --- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java +++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java @@ -29,7 +29,9 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; import com.android.inputmethod.latin.settings.Settings; +import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Collections; import java.util.HashMap; @@ -84,11 +86,11 @@ public final class RichInputMethodManager { mInputMethodInfoOfThisIme = getInputMethodInfoOfThisIme(context); // Initialize additional subtypes. - SubtypeLocale.init(context); + SubtypeLocaleUtils.init(context); final String prefAdditionalSubtypes = Settings.readPrefAdditionalSubtypes( prefs, context.getResources()); final InputMethodSubtype[] additionalSubtypes = - AdditionalSubtype.createAdditionalSubtypesArray(prefAdditionalSubtypes); + AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefAdditionalSubtypes); setAdditionalInputMethodSubtypes(additionalSubtypes); } @@ -134,7 +136,7 @@ public final class RichInputMethodManager { final int currentIndex = getSubtypeIndexInList(currentSubtype, enabledSubtypes); if (currentIndex == INDEX_NOT_FOUND) { Log.w(TAG, "Can't find current subtype in enabled subtypes: subtype=" - + SubtypeLocale.getSubtypeNameForLogging(currentSubtype)); + + SubtypeLocaleUtils.getSubtypeNameForLogging(currentSubtype)); return false; } final int nextIndex = (currentIndex + 1) % enabledSubtypes.size(); @@ -342,7 +344,7 @@ public final class RichInputMethodManager { final int count = myImi.getSubtypeCount(); for (int i = 0; i < count; i++) { final InputMethodSubtype subtype = myImi.getSubtypeAt(i); - final String layoutName = SubtypeLocale.getKeyboardLayoutSetName(subtype); + final String layoutName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype); if (localeString.equals(subtype.getLocale()) && keyboardLayoutSetName.equals(layoutName)) { return subtype; diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java deleted file mode 100644 index 683211c93..000000000 --- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.latin; - -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; -import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME; - -import android.content.Context; -import android.content.res.Resources; -import android.os.Build; -import android.util.Log; -import android.view.inputmethod.InputMethodSubtype; - -import com.android.inputmethod.latin.utils.CollectionUtils; -import com.android.inputmethod.latin.utils.DebugLogUtils; -import com.android.inputmethod.latin.utils.LocaleUtils; -import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale; -import com.android.inputmethod.latin.utils.StringUtils; - -import java.util.HashMap; -import java.util.Locale; - -public final class SubtypeLocale { - static final String TAG = SubtypeLocale.class.getSimpleName(); - // This class must be located in the same package as LatinIME.java. - private static final String RESOURCE_PACKAGE_NAME = - DictionaryFactory.class.getPackage().getName(); - - // Special language code to represent "no language". - public static final String NO_LANGUAGE = "zz"; - public static final String QWERTY = "qwerty"; - public static final int UNKNOWN_KEYBOARD_LAYOUT = R.string.subtype_generic; - - private static boolean sInitialized = false; - private static Resources sResources; - private static String[] sPredefinedKeyboardLayoutSet; - // Keyboard layout to its display name map. - private static final HashMap sKeyboardLayoutToDisplayNameMap = - CollectionUtils.newHashMap(); - // Keyboard layout to subtype name resource id map. - private static final HashMap sKeyboardLayoutToNameIdsMap = - CollectionUtils.newHashMap(); - // Exceptional locale to subtype name resource id map. - private static final HashMap sExceptionalLocaleToNameIdsMap = - CollectionUtils.newHashMap(); - // Exceptional locale to subtype name with layout resource id map. - private static final HashMap sExceptionalLocaleToWithLayoutNameIdsMap = - CollectionUtils.newHashMap(); - private static final String SUBTYPE_NAME_RESOURCE_PREFIX = - "string/subtype_"; - private static final String SUBTYPE_NAME_RESOURCE_GENERIC_PREFIX = - "string/subtype_generic_"; - private static final String SUBTYPE_NAME_RESOURCE_WITH_LAYOUT_PREFIX = - "string/subtype_with_layout_"; - private static final String SUBTYPE_NAME_RESOURCE_NO_LANGUAGE_PREFIX = - "string/subtype_no_language_"; - // Keyboard layout set name for the subtypes that don't have a keyboardLayoutSet extra value. - // This is for compatibility to keep the same subtype ids as pre-JellyBean. - private static final HashMap sLocaleAndExtraValueToKeyboardLayoutSetMap = - CollectionUtils.newHashMap(); - - private SubtypeLocale() { - // Intentional empty constructor for utility class. - } - - // Note that this initialization method can be called multiple times. - public static synchronized void init(final Context context) { - if (sInitialized) return; - - final Resources res = context.getResources(); - sResources = res; - - final String[] predefinedLayoutSet = res.getStringArray(R.array.predefined_layouts); - sPredefinedKeyboardLayoutSet = predefinedLayoutSet; - final String[] layoutDisplayNames = res.getStringArray( - R.array.predefined_layout_display_names); - for (int i = 0; i < predefinedLayoutSet.length; i++) { - final String layoutName = predefinedLayoutSet[i]; - sKeyboardLayoutToDisplayNameMap.put(layoutName, layoutDisplayNames[i]); - final String resourceName = SUBTYPE_NAME_RESOURCE_GENERIC_PREFIX + layoutName; - final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME); - sKeyboardLayoutToNameIdsMap.put(layoutName, resId); - // Register subtype name resource id of "No language" with key "zz_" - final String noLanguageResName = SUBTYPE_NAME_RESOURCE_NO_LANGUAGE_PREFIX + layoutName; - final int noLanguageResId = res.getIdentifier( - noLanguageResName, null, RESOURCE_PACKAGE_NAME); - final String key = getNoLanguageLayoutKey(layoutName); - sKeyboardLayoutToNameIdsMap.put(key, noLanguageResId); - } - - final String[] exceptionalLocales = res.getStringArray( - R.array.subtype_locale_exception_keys); - for (int i = 0; i < exceptionalLocales.length; i++) { - final String localeString = exceptionalLocales[i]; - final String resourceName = SUBTYPE_NAME_RESOURCE_PREFIX + localeString; - final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME); - sExceptionalLocaleToNameIdsMap.put(localeString, resId); - final String resourceNameWithLayout = - SUBTYPE_NAME_RESOURCE_WITH_LAYOUT_PREFIX + localeString; - final int resIdWithLayout = res.getIdentifier( - resourceNameWithLayout, null, RESOURCE_PACKAGE_NAME); - sExceptionalLocaleToWithLayoutNameIdsMap.put(localeString, resIdWithLayout); - } - - final String[] keyboardLayoutSetMap = res.getStringArray( - R.array.locale_and_extra_value_to_keyboard_layout_set_map); - for (int i = 0; i + 1 < keyboardLayoutSetMap.length; i += 2) { - final String key = keyboardLayoutSetMap[i]; - final String keyboardLayoutSet = keyboardLayoutSetMap[i + 1]; - sLocaleAndExtraValueToKeyboardLayoutSetMap.put(key, keyboardLayoutSet); - } - - sInitialized = true; - } - - public static String[] getPredefinedKeyboardLayoutSet() { - return sPredefinedKeyboardLayoutSet; - } - - public static boolean isExceptionalLocale(final String localeString) { - return sExceptionalLocaleToNameIdsMap.containsKey(localeString); - } - - private static final String getNoLanguageLayoutKey(final String keyboardLayoutName) { - return NO_LANGUAGE + "_" + keyboardLayoutName; - } - - public static int getSubtypeNameId(final String localeString, final String keyboardLayoutName) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN - && isExceptionalLocale(localeString)) { - return sExceptionalLocaleToWithLayoutNameIdsMap.get(localeString); - } - final String key = NO_LANGUAGE.equals(localeString) - ? getNoLanguageLayoutKey(keyboardLayoutName) - : keyboardLayoutName; - final Integer nameId = sKeyboardLayoutToNameIdsMap.get(key); - return nameId == null ? UNKNOWN_KEYBOARD_LAYOUT : nameId; - } - - private static Locale getDisplayLocaleOfSubtypeLocale(final String localeString) { - if (NO_LANGUAGE.equals(localeString)) { - return sResources.getConfiguration().locale; - } - return LocaleUtils.constructLocaleFromString(localeString); - } - - public static String getSubtypeLocaleDisplayNameInSystemLocale(final String localeString) { - final Locale displayLocale = sResources.getConfiguration().locale; - return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale); - } - - public static String getSubtypeLocaleDisplayName(final String localeString) { - final Locale displayLocale = getDisplayLocaleOfSubtypeLocale(localeString); - return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale); - } - - private static String getSubtypeLocaleDisplayNameInternal(final String localeString, - final Locale displayLocale) { - final Integer exceptionalNameResId = sExceptionalLocaleToNameIdsMap.get(localeString); - final String displayName; - if (exceptionalNameResId != null) { - final RunInLocale getExceptionalName = new RunInLocale() { - @Override - protected String job(final Resources res) { - return res.getString(exceptionalNameResId); - } - }; - displayName = getExceptionalName.runInLocale(sResources, displayLocale); - } else if (NO_LANGUAGE.equals(localeString)) { - // No language subtype should be displayed in system locale. - return sResources.getString(R.string.subtype_no_language); - } else { - final Locale locale = LocaleUtils.constructLocaleFromString(localeString); - displayName = locale.getDisplayName(displayLocale); - } - return StringUtils.capitalizeFirstCodePoint(displayName, displayLocale); - } - - // InputMethodSubtype's display name in its locale. - // isAdditionalSubtype (T=true, F=false) - // locale layout | display name - // ------ ------- - ---------------------- - // en_US qwerty F English (US) exception - // en_GB qwerty F English (UK) exception - // es_US spanish F Español (EE.UU.) exception - // fr azerty F Français - // fr_CA qwerty F Français (Canada) - // de qwertz F Deutsch - // zz qwerty F No language (QWERTY) in system locale - // fr qwertz T Français (QWERTZ) - // de qwerty T Deutsch (QWERTY) - // en_US azerty T English (US) (AZERTY) exception - // zz azerty T No language (AZERTY) in system locale - - private static String getReplacementString(final InputMethodSubtype subtype, - final Locale displayLocale) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN - && subtype.containsExtraValueKey(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)) { - return subtype.getExtraValueOf(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME); - } else { - return getSubtypeLocaleDisplayNameInternal(subtype.getLocale(), displayLocale); - } - } - - public static String getSubtypeDisplayNameInSystemLocale(final InputMethodSubtype subtype) { - final Locale displayLocale = sResources.getConfiguration().locale; - return getSubtypeDisplayNameInternal(subtype, displayLocale); - } - - public static String getSubtypeNameForLogging(final InputMethodSubtype subtype) { - if (subtype == null) { - return ""; - } - return getSubtypeLocale(subtype) + "/" + getKeyboardLayoutSetName(subtype); - } - - private static String getSubtypeDisplayNameInternal(final InputMethodSubtype subtype, - final Locale displayLocale) { - final String replacementString = getReplacementString(subtype, displayLocale); - final int nameResId = subtype.getNameResId(); - final RunInLocale getSubtypeName = new RunInLocale() { - @Override - protected String job(final Resources res) { - try { - return res.getString(nameResId, replacementString); - } catch (Resources.NotFoundException e) { - // TODO: Remove this catch when InputMethodManager.getCurrentInputMethodSubtype - // is fixed. - Log.w(TAG, "Unknown subtype: mode=" + subtype.getMode() - + " nameResId=" + subtype.getNameResId() - + " locale=" + subtype.getLocale() - + " extra=" + subtype.getExtraValue() - + "\n" + DebugLogUtils.getStackTrace()); - return ""; - } - } - }; - return StringUtils.capitalizeFirstCodePoint( - getSubtypeName.runInLocale(sResources, displayLocale), displayLocale); - } - - public static boolean isNoLanguage(final InputMethodSubtype subtype) { - final String localeString = subtype.getLocale(); - return NO_LANGUAGE.equals(localeString); - } - - public static Locale getSubtypeLocale(final InputMethodSubtype subtype) { - final String localeString = subtype.getLocale(); - return LocaleUtils.constructLocaleFromString(localeString); - } - - public static String getKeyboardLayoutSetDisplayName(final InputMethodSubtype subtype) { - final String layoutName = getKeyboardLayoutSetName(subtype); - return getKeyboardLayoutSetDisplayName(layoutName); - } - - public static String getKeyboardLayoutSetDisplayName(final String layoutName) { - return sKeyboardLayoutToDisplayNameMap.get(layoutName); - } - - public static String getKeyboardLayoutSetName(final InputMethodSubtype subtype) { - String keyboardLayoutSet = subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET); - if (keyboardLayoutSet == null) { - // This subtype doesn't have a keyboardLayoutSet extra value, so lookup its keyboard - // layout set in sLocaleAndExtraValueToKeyboardLayoutSetMap to keep it compatible with - // pre-JellyBean. - final String key = subtype.getLocale() + ":" + subtype.getExtraValue(); - keyboardLayoutSet = sLocaleAndExtraValueToKeyboardLayoutSetMap.get(key); - } - // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is - // fixed. - if (keyboardLayoutSet == null) { - android.util.Log.w(TAG, "KeyboardLayoutSet not found, use QWERTY: " + - "locale=" + subtype.getLocale() + " extraValue=" + subtype.getExtraValue()); - return QWERTY; - } - return keyboardLayoutSet; - } - - // InputMethodSubtype's display name for spacebar text in its locale. - // isAdditionalSubtype (T=true, F=false) - // locale layout | Short Middle Full - // ------ ------- - ---- --------- ---------------------- - // en_US qwerty F En English English (US) exception - // en_GB qwerty F En English English (UK) exception - // es_US spanish F Es Español Español (EE.UU.) exception - // fr azerty F Fr Français Français - // fr_CA qwerty F Fr Français Français (Canada) - // de qwertz F De Deutsch Deutsch - // zz qwerty F QWERTY QWERTY - // fr qwertz T Fr Français Français - // de qwerty T De Deutsch Deutsch - // en_US azerty T En English English (US) - // zz azerty T AZERTY AZERTY - - // Get InputMethodSubtype's full display name in its locale. - public static String getFullDisplayName(final InputMethodSubtype subtype) { - if (isNoLanguage(subtype)) { - return getKeyboardLayoutSetDisplayName(subtype); - } - return getSubtypeLocaleDisplayName(subtype.getLocale()); - } - - // Get InputMethodSubtype's middle display name in its locale. - public static String getMiddleDisplayName(final InputMethodSubtype subtype) { - if (isNoLanguage(subtype)) { - return getKeyboardLayoutSetDisplayName(subtype); - } - final Locale locale = getSubtypeLocale(subtype); - return getSubtypeLocaleDisplayName(locale.getLanguage()); - } - - // Get InputMethodSubtype's short display name in its locale. - public static String getShortDisplayName(final InputMethodSubtype subtype) { - if (isNoLanguage(subtype)) { - return ""; - } - final Locale locale = getSubtypeLocale(subtype); - return StringUtils.capitalizeFirstCodePoint(locale.getLanguage(), locale); - } -} diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index dfa4a8693..be03d4ae5 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -33,6 +33,7 @@ import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.keyboard.KeyboardSwitcher; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.List; import java.util.Locale; @@ -82,7 +83,7 @@ public final class SubtypeSwitcher { } public static void init(final Context context) { - SubtypeLocale.init(context); + SubtypeLocaleUtils.init(context); RichInputMethodManager.init(context); sInstance.initialize(context); } @@ -153,10 +154,11 @@ public final class SubtypeSwitcher { // Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function. public void onSubtypeChanged(final InputMethodSubtype newSubtype) { if (DBG) { - Log.w(TAG, "onSubtypeChanged: " + SubtypeLocale.getSubtypeNameForLogging(newSubtype)); + Log.w(TAG, "onSubtypeChanged: " + + SubtypeLocaleUtils.getSubtypeNameForLogging(newSubtype)); } - final Locale newLocale = SubtypeLocale.getSubtypeLocale(newSubtype); + final Locale newLocale = SubtypeLocaleUtils.getSubtypeLocale(newSubtype); final Locale systemLocale = mResources.getConfiguration().locale; final boolean sameLocale = systemLocale.equals(newLocale); final boolean sameLanguage = systemLocale.getLanguage().equals(newLocale.getLanguage()); @@ -232,7 +234,7 @@ public final class SubtypeSwitcher { ////////////////////////////////// public boolean needsToDisplayLanguage(final Locale keyboardLocale) { - if (keyboardLocale.toString().equals(SubtypeLocale.NO_LANGUAGE)) { + if (keyboardLocale.toString().equals(SubtypeLocaleUtils.NO_LANGUAGE)) { return true; } if (!keyboardLocale.equals(getCurrentSubtypeLocale())) { @@ -249,7 +251,7 @@ public final class SubtypeSwitcher { public Locale getCurrentSubtypeLocale() { if (null != sForcedLocaleForTesting) return sForcedLocaleForTesting; - return SubtypeLocale.getSubtypeLocale(getCurrentSubtype()); + return SubtypeLocaleUtils.getSubtypeLocale(getCurrentSubtype()); } public InputMethodSubtype getCurrentSubtype() { @@ -259,7 +261,7 @@ public final class SubtypeSwitcher { public InputMethodSubtype getNoLanguageSubtype() { if (mNoLanguageSubtype == null) { mNoLanguageSubtype = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( - SubtypeLocale.NO_LANGUAGE, SubtypeLocale.QWERTY); + SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.QWERTY); } if (mNoLanguageSubtype != null) { return mNoLanguageSubtype; diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java index ab8f34893..ed6fefae4 100644 --- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java @@ -29,6 +29,7 @@ import android.text.TextUtils; import com.android.inputmethod.compat.UserDictionaryCompatUtils; import com.android.inputmethod.latin.utils.LocaleUtils; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.Arrays; import java.util.Locale; @@ -76,7 +77,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { final boolean alsoUseMoreRestrictiveLocales) { super(context, getFilenameWithLocale(NAME, locale), Dictionary.TYPE_USER); if (null == locale) throw new NullPointerException(); // Catch the error earlier - if (SubtypeLocale.NO_LANGUAGE.equals(locale)) { + if (SubtypeLocaleUtils.NO_LANGUAGE.equals(locale)) { // If we don't have a locale, insert into the "all locales" user dictionary. mLocale = USER_DICTIONARY_ALL_LANGUAGES; } else { diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java index 2ef555e95..4bf524cbb 100644 --- a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java +++ b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java @@ -44,12 +44,12 @@ import android.widget.Spinner; import android.widget.SpinnerAdapter; import android.widget.Toast; -import com.android.inputmethod.latin.AdditionalSubtype; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.RichInputMethodManager; -import com.android.inputmethod.latin.SubtypeLocale; +import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.IntentUtils; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import java.util.ArrayList; import java.util.TreeSet; @@ -78,7 +78,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { public SubtypeLocaleItem(final String localeString) { this(localeString, - SubtypeLocale.getSubtypeLocaleDisplayNameInSystemLocale(localeString)); + SubtypeLocaleUtils.getSubtypeLocaleDisplayNameInSystemLocale(localeString)); } @Override @@ -109,7 +109,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { if (DEBUG_SUBTYPE_ID) { android.util.Log.d(TAG, String.format("%-6s 0x%08x %11d %s", subtype.getLocale(), subtype.hashCode(), subtype.hashCode(), - SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype))); + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype))); } if (subtype.containsExtraValueKey(ASCII_CAPABLE)) { items.add(createItem(context, subtype.getLocale())); @@ -121,7 +121,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { public static SubtypeLocaleItem createItem(final Context context, final String localeString) { - if (localeString.equals(SubtypeLocale.NO_LANGUAGE)) { + if (localeString.equals(SubtypeLocaleUtils.NO_LANGUAGE)) { final String displayName = context.getString(R.string.subtype_no_language); return new SubtypeLocaleItem(localeString, displayName); } else { @@ -132,8 +132,8 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { static final class KeyboardLayoutSetItem extends Pair { public KeyboardLayoutSetItem(final InputMethodSubtype subtype) { - super(SubtypeLocale.getKeyboardLayoutSetName(subtype), - SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype)); + super(SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype), + SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype)); } @Override @@ -148,10 +148,10 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // TODO: Should filter out already existing combinations of locale and layout. - for (final String layout : SubtypeLocale.getPredefinedKeyboardLayoutSet()) { + for (final String layout : SubtypeLocaleUtils.getPredefinedKeyboardLayoutSet()) { // This is a dummy subtype with NO_LANGUAGE, only for display. - final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype( - SubtypeLocale.NO_LANGUAGE, layout, null); + final InputMethodSubtype subtype = AdditionalSubtypeUtils.createAdditionalSubtype( + SubtypeLocaleUtils.NO_LANGUAGE, layout, null); add(new KeyboardLayoutSetItem(subtype)); } } @@ -212,11 +212,11 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { setKey(KEY_NEW_SUBTYPE); } else { final String displayName = - SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype); + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype); setTitle(displayName); setDialogTitle(displayName); setKey(KEY_PREFIX + subtype.getLocale() + "_" - + SubtypeLocale.getKeyboardLayoutSetName(subtype)); + + SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype)); } } @@ -286,7 +286,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { (SubtypeLocaleItem) mSubtypeLocaleSpinner.getSelectedItem(); final KeyboardLayoutSetItem layout = (KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem(); - final InputMethodSubtype subtype = AdditionalSubtype.createAdditionalSubtype( + final InputMethodSubtype subtype = AdditionalSubtypeUtils.createAdditionalSubtype( locale.first, layout.first, ASCII_CAPABLE); setSubtype(subtype); notifyChanged(); @@ -504,13 +504,13 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { final Context context = getActivity(); final Resources res = context.getResources(); final String message = res.getString(R.string.custom_input_style_already_exists, - SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype)); + SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype)); Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); } private InputMethodSubtype findDuplicatedSubtype(final InputMethodSubtype subtype) { final String localeString = subtype.getLocale(); - final String keyboardLayoutSetName = SubtypeLocale.getKeyboardLayoutSetName(subtype); + final String keyboardLayoutSetName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype); return mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet( localeString, keyboardLayoutSetName); } @@ -543,7 +543,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { final PreferenceGroup group = getPreferenceScreen(); group.removeAll(); final InputMethodSubtype[] subtypesArray = - AdditionalSubtype.createAdditionalSubtypesArray(prefSubtypes); + AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefSubtypes); for (final InputMethodSubtype subtype : subtypesArray) { final SubtypePreference pref = new SubtypePreference( context, subtype, mSubtypeProxy); @@ -572,7 +572,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment { super.onPause(); final String oldSubtypes = Settings.readPrefAdditionalSubtypes(mPrefs, getResources()); final InputMethodSubtype[] subtypes = getSubtypes(); - final String prefSubtypes = AdditionalSubtype.createPrefSubtypes(subtypes); + final String prefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(subtypes); if (prefSubtypes.equals(oldSubtypes)) { return; } diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index 674263dee..bfaf2caf1 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -24,9 +24,9 @@ import android.preference.PreferenceManager; import android.util.Log; import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; -import com.android.inputmethod.latin.AdditionalSubtype; import com.android.inputmethod.latin.InputAttributes; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; import com.android.inputmethod.latin.utils.LocaleUtils; import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale; import com.android.inputmethod.latin.utils.ResourceUtils; @@ -241,7 +241,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static String readPrefAdditionalSubtypes(final SharedPreferences prefs, final Resources res) { - final String predefinedPrefSubtypes = AdditionalSubtype.createPrefSubtypes( + final String predefinedPrefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes( res.getStringArray(R.array.predefined_subtypes)); return prefs.getString(PREF_CUSTOM_INPUT_STYLES, predefinedPrefSubtypes); } diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java index 4b62a5389..446777704 100644 --- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java +++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java @@ -37,17 +37,17 @@ import android.util.Log; import android.view.inputmethod.InputMethodSubtype; import com.android.inputmethod.dictionarypack.DictionarySettingsActivity; -import com.android.inputmethod.latin.AdditionalSubtype; import com.android.inputmethod.latin.AudioAndHapticFeedbackManager; import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.SubtypeLocale; import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.setup.LauncherIconVisibilityManager; import com.android.inputmethod.latin.userdictionary.UserDictionaryList; import com.android.inputmethod.latin.userdictionary.UserDictionarySettings; +import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils; import com.android.inputmethod.latin.utils.ApplicationUtils; import com.android.inputmethod.latin.utils.FeedbackUtils; +import com.android.inputmethod.latin.utils.SubtypeLocaleUtils; import com.android.inputmethod.research.ResearchLogger; import com.android.inputmethodcommon.InputMethodSettingsFragment; @@ -104,7 +104,7 @@ public final class SettingsFragment extends InputMethodSettingsFragment // singleton and utility classes may not have been initialized. We have to call // initialization method of these classes here. See {@link LatinIME#onCreate()}. SubtypeSwitcher.init(context); - SubtypeLocale.init(context); + SubtypeLocaleUtils.init(context); AudioAndHapticFeedbackManager.init(context); mVoicePreference = (ListPreference) findPreference(Settings.PREF_VOICE_MODE); @@ -314,11 +314,11 @@ public final class SettingsFragment extends InputMethodSettingsFragment final Resources res = getResources(); final String prefSubtype = Settings.readPrefAdditionalSubtypes(prefs, res); final InputMethodSubtype[] subtypes = - AdditionalSubtype.createAdditionalSubtypesArray(prefSubtype); + AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefSubtype); final StringBuilder styles = new StringBuilder(); for (final InputMethodSubtype subtype : subtypes) { if (styles.length() > 0) styles.append(", "); - styles.append(SubtypeLocale.getSubtypeDisplayNameInSystemLocale(subtype)); + styles.append(SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype)); } customInputStyles.setSummary(styles); } diff --git a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java new file mode 100644 index 000000000..215faa0c7 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.utils; + +import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE; +import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.IS_ADDITIONAL_SUBTYPE; +import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; +import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME; + +import android.os.Build; +import android.text.TextUtils; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.R; + +import java.util.ArrayList; + +public final class AdditionalSubtypeUtils { + private static final InputMethodSubtype[] EMPTY_SUBTYPE_ARRAY = new InputMethodSubtype[0]; + + private AdditionalSubtypeUtils() { + // This utility class is not publicly instantiable. + } + + public static boolean isAdditionalSubtype(final InputMethodSubtype subtype) { + return subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE); + } + + private static final String LOCALE_AND_LAYOUT_SEPARATOR = ":"; + private static final String PREF_SUBTYPE_SEPARATOR = ";"; + + public static InputMethodSubtype createAdditionalSubtype(final String localeString, + final String keyboardLayoutSetName, final String extraValue) { + final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName; + final String layoutDisplayNameExtraValue; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN + && SubtypeLocaleUtils.isExceptionalLocale(localeString)) { + final String layoutDisplayName = SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName( + keyboardLayoutSetName); + layoutDisplayNameExtraValue = StringUtils.appendToCommaSplittableTextIfNotExists( + UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" + layoutDisplayName, extraValue); + } else { + layoutDisplayNameExtraValue = extraValue; + } + final String additionalSubtypeExtraValue = + StringUtils.appendToCommaSplittableTextIfNotExists( + IS_ADDITIONAL_SUBTYPE, layoutDisplayNameExtraValue); + final int nameId = SubtypeLocaleUtils.getSubtypeNameId(localeString, keyboardLayoutSetName); + return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard, + localeString, KEYBOARD_MODE, + layoutExtraValue + "," + additionalSubtypeExtraValue, false, false); + } + + public static String getPrefSubtype(final InputMethodSubtype subtype) { + final String localeString = subtype.getLocale(); + final String keyboardLayoutSetName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype); + final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName; + final String extraValue = StringUtils.removeFromCommaSplittableTextIfExists( + layoutExtraValue, StringUtils.removeFromCommaSplittableTextIfExists( + IS_ADDITIONAL_SUBTYPE, subtype.getExtraValue())); + final String basePrefSubtype = localeString + LOCALE_AND_LAYOUT_SEPARATOR + + keyboardLayoutSetName; + return extraValue.isEmpty() ? basePrefSubtype + : basePrefSubtype + LOCALE_AND_LAYOUT_SEPARATOR + extraValue; + } + + public static InputMethodSubtype createAdditionalSubtype(final String prefSubtype) { + final String elems[] = prefSubtype.split(LOCALE_AND_LAYOUT_SEPARATOR); + if (elems.length < 2 || elems.length > 3) { + throw new RuntimeException("Unknown additional subtype specified: " + prefSubtype); + } + final String localeString = elems[0]; + final String keyboardLayoutSetName = elems[1]; + final String extraValue = (elems.length == 3) ? elems[2] : null; + return createAdditionalSubtype(localeString, keyboardLayoutSetName, extraValue); + } + + public static InputMethodSubtype[] createAdditionalSubtypesArray(final String prefSubtypes) { + if (TextUtils.isEmpty(prefSubtypes)) { + return EMPTY_SUBTYPE_ARRAY; + } + final String[] prefSubtypeArray = prefSubtypes.split(PREF_SUBTYPE_SEPARATOR); + final ArrayList subtypesList = + CollectionUtils.newArrayList(prefSubtypeArray.length); + for (final String prefSubtype : prefSubtypeArray) { + final InputMethodSubtype subtype = createAdditionalSubtype(prefSubtype); + if (subtype.getNameResId() == SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT) { + // Skip unknown keyboard layout subtype. This may happen when predefined keyboard + // layout has been removed. + continue; + } + subtypesList.add(subtype); + } + return subtypesList.toArray(new InputMethodSubtype[subtypesList.size()]); + } + + public static String createPrefSubtypes(final InputMethodSubtype[] subtypes) { + if (subtypes == null || subtypes.length == 0) { + return ""; + } + final StringBuilder sb = new StringBuilder(); + for (final InputMethodSubtype subtype : subtypes) { + if (sb.length() > 0) { + sb.append(PREF_SUBTYPE_SEPARATOR); + } + sb.append(getPrefSubtype(subtype)); + } + return sb.toString(); + } + + public static String createPrefSubtypes(final String[] prefSubtypes) { + if (prefSubtypes == null || prefSubtypes.length == 0) { + return ""; + } + final StringBuilder sb = new StringBuilder(); + for (final String prefSubtype : prefSubtypes) { + if (sb.length() > 0) { + sb.append(PREF_SUBTYPE_SEPARATOR); + } + sb.append(prefSubtype); + } + return sb.toString(); + } +} diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java new file mode 100644 index 000000000..4cfa2897d --- /dev/null +++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin.utils; + +import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; +import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME; + +import android.content.Context; +import android.content.res.Resources; +import android.os.Build; +import android.util.Log; +import android.view.inputmethod.InputMethodSubtype; + +import com.android.inputmethod.latin.DictionaryFactory; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.utils.LocaleUtils.RunInLocale; + +import java.util.HashMap; +import java.util.Locale; + +public final class SubtypeLocaleUtils { + static final String TAG = SubtypeLocaleUtils.class.getSimpleName(); + // This class must be located in the same package as LatinIME.java. + private static final String RESOURCE_PACKAGE_NAME = + DictionaryFactory.class.getPackage().getName(); + + // Special language code to represent "no language". + public static final String NO_LANGUAGE = "zz"; + public static final String QWERTY = "qwerty"; + public static final int UNKNOWN_KEYBOARD_LAYOUT = R.string.subtype_generic; + + private static boolean sInitialized = false; + private static Resources sResources; + private static String[] sPredefinedKeyboardLayoutSet; + // Keyboard layout to its display name map. + private static final HashMap sKeyboardLayoutToDisplayNameMap = + CollectionUtils.newHashMap(); + // Keyboard layout to subtype name resource id map. + private static final HashMap sKeyboardLayoutToNameIdsMap = + CollectionUtils.newHashMap(); + // Exceptional locale to subtype name resource id map. + private static final HashMap sExceptionalLocaleToNameIdsMap = + CollectionUtils.newHashMap(); + // Exceptional locale to subtype name with layout resource id map. + private static final HashMap sExceptionalLocaleToWithLayoutNameIdsMap = + CollectionUtils.newHashMap(); + private static final String SUBTYPE_NAME_RESOURCE_PREFIX = + "string/subtype_"; + private static final String SUBTYPE_NAME_RESOURCE_GENERIC_PREFIX = + "string/subtype_generic_"; + private static final String SUBTYPE_NAME_RESOURCE_WITH_LAYOUT_PREFIX = + "string/subtype_with_layout_"; + private static final String SUBTYPE_NAME_RESOURCE_NO_LANGUAGE_PREFIX = + "string/subtype_no_language_"; + // Keyboard layout set name for the subtypes that don't have a keyboardLayoutSet extra value. + // This is for compatibility to keep the same subtype ids as pre-JellyBean. + private static final HashMap sLocaleAndExtraValueToKeyboardLayoutSetMap = + CollectionUtils.newHashMap(); + + private SubtypeLocaleUtils() { + // Intentional empty constructor for utility class. + } + + // Note that this initialization method can be called multiple times. + public static synchronized void init(final Context context) { + if (sInitialized) return; + + final Resources res = context.getResources(); + sResources = res; + + final String[] predefinedLayoutSet = res.getStringArray(R.array.predefined_layouts); + sPredefinedKeyboardLayoutSet = predefinedLayoutSet; + final String[] layoutDisplayNames = res.getStringArray( + R.array.predefined_layout_display_names); + for (int i = 0; i < predefinedLayoutSet.length; i++) { + final String layoutName = predefinedLayoutSet[i]; + sKeyboardLayoutToDisplayNameMap.put(layoutName, layoutDisplayNames[i]); + final String resourceName = SUBTYPE_NAME_RESOURCE_GENERIC_PREFIX + layoutName; + final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME); + sKeyboardLayoutToNameIdsMap.put(layoutName, resId); + // Register subtype name resource id of "No language" with key "zz_" + final String noLanguageResName = SUBTYPE_NAME_RESOURCE_NO_LANGUAGE_PREFIX + layoutName; + final int noLanguageResId = res.getIdentifier( + noLanguageResName, null, RESOURCE_PACKAGE_NAME); + final String key = getNoLanguageLayoutKey(layoutName); + sKeyboardLayoutToNameIdsMap.put(key, noLanguageResId); + } + + final String[] exceptionalLocales = res.getStringArray( + R.array.subtype_locale_exception_keys); + for (int i = 0; i < exceptionalLocales.length; i++) { + final String localeString = exceptionalLocales[i]; + final String resourceName = SUBTYPE_NAME_RESOURCE_PREFIX + localeString; + final int resId = res.getIdentifier(resourceName, null, RESOURCE_PACKAGE_NAME); + sExceptionalLocaleToNameIdsMap.put(localeString, resId); + final String resourceNameWithLayout = + SUBTYPE_NAME_RESOURCE_WITH_LAYOUT_PREFIX + localeString; + final int resIdWithLayout = res.getIdentifier( + resourceNameWithLayout, null, RESOURCE_PACKAGE_NAME); + sExceptionalLocaleToWithLayoutNameIdsMap.put(localeString, resIdWithLayout); + } + + final String[] keyboardLayoutSetMap = res.getStringArray( + R.array.locale_and_extra_value_to_keyboard_layout_set_map); + for (int i = 0; i + 1 < keyboardLayoutSetMap.length; i += 2) { + final String key = keyboardLayoutSetMap[i]; + final String keyboardLayoutSet = keyboardLayoutSetMap[i + 1]; + sLocaleAndExtraValueToKeyboardLayoutSetMap.put(key, keyboardLayoutSet); + } + + sInitialized = true; + } + + public static String[] getPredefinedKeyboardLayoutSet() { + return sPredefinedKeyboardLayoutSet; + } + + public static boolean isExceptionalLocale(final String localeString) { + return sExceptionalLocaleToNameIdsMap.containsKey(localeString); + } + + private static final String getNoLanguageLayoutKey(final String keyboardLayoutName) { + return NO_LANGUAGE + "_" + keyboardLayoutName; + } + + public static int getSubtypeNameId(final String localeString, final String keyboardLayoutName) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN + && isExceptionalLocale(localeString)) { + return sExceptionalLocaleToWithLayoutNameIdsMap.get(localeString); + } + final String key = NO_LANGUAGE.equals(localeString) + ? getNoLanguageLayoutKey(keyboardLayoutName) + : keyboardLayoutName; + final Integer nameId = sKeyboardLayoutToNameIdsMap.get(key); + return nameId == null ? UNKNOWN_KEYBOARD_LAYOUT : nameId; + } + + private static Locale getDisplayLocaleOfSubtypeLocale(final String localeString) { + if (NO_LANGUAGE.equals(localeString)) { + return sResources.getConfiguration().locale; + } + return LocaleUtils.constructLocaleFromString(localeString); + } + + public static String getSubtypeLocaleDisplayNameInSystemLocale(final String localeString) { + final Locale displayLocale = sResources.getConfiguration().locale; + return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale); + } + + public static String getSubtypeLocaleDisplayName(final String localeString) { + final Locale displayLocale = getDisplayLocaleOfSubtypeLocale(localeString); + return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale); + } + + private static String getSubtypeLocaleDisplayNameInternal(final String localeString, + final Locale displayLocale) { + final Integer exceptionalNameResId = sExceptionalLocaleToNameIdsMap.get(localeString); + final String displayName; + if (exceptionalNameResId != null) { + final RunInLocale getExceptionalName = new RunInLocale() { + @Override + protected String job(final Resources res) { + return res.getString(exceptionalNameResId); + } + }; + displayName = getExceptionalName.runInLocale(sResources, displayLocale); + } else if (NO_LANGUAGE.equals(localeString)) { + // No language subtype should be displayed in system locale. + return sResources.getString(R.string.subtype_no_language); + } else { + final Locale locale = LocaleUtils.constructLocaleFromString(localeString); + displayName = locale.getDisplayName(displayLocale); + } + return StringUtils.capitalizeFirstCodePoint(displayName, displayLocale); + } + + // InputMethodSubtype's display name in its locale. + // isAdditionalSubtype (T=true, F=false) + // locale layout | display name + // ------ ------- - ---------------------- + // en_US qwerty F English (US) exception + // en_GB qwerty F English (UK) exception + // es_US spanish F Español (EE.UU.) exception + // fr azerty F Français + // fr_CA qwerty F Français (Canada) + // de qwertz F Deutsch + // zz qwerty F No language (QWERTY) in system locale + // fr qwertz T Français (QWERTZ) + // de qwerty T Deutsch (QWERTY) + // en_US azerty T English (US) (AZERTY) exception + // zz azerty T No language (AZERTY) in system locale + + private static String getReplacementString(final InputMethodSubtype subtype, + final Locale displayLocale) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN + && subtype.containsExtraValueKey(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME)) { + return subtype.getExtraValueOf(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME); + } else { + return getSubtypeLocaleDisplayNameInternal(subtype.getLocale(), displayLocale); + } + } + + public static String getSubtypeDisplayNameInSystemLocale(final InputMethodSubtype subtype) { + final Locale displayLocale = sResources.getConfiguration().locale; + return getSubtypeDisplayNameInternal(subtype, displayLocale); + } + + public static String getSubtypeNameForLogging(final InputMethodSubtype subtype) { + if (subtype == null) { + return ""; + } + return getSubtypeLocale(subtype) + "/" + getKeyboardLayoutSetName(subtype); + } + + private static String getSubtypeDisplayNameInternal(final InputMethodSubtype subtype, + final Locale displayLocale) { + final String replacementString = getReplacementString(subtype, displayLocale); + final int nameResId = subtype.getNameResId(); + final RunInLocale getSubtypeName = new RunInLocale() { + @Override + protected String job(final Resources res) { + try { + return res.getString(nameResId, replacementString); + } catch (Resources.NotFoundException e) { + // TODO: Remove this catch when InputMethodManager.getCurrentInputMethodSubtype + // is fixed. + Log.w(TAG, "Unknown subtype: mode=" + subtype.getMode() + + " nameResId=" + subtype.getNameResId() + + " locale=" + subtype.getLocale() + + " extra=" + subtype.getExtraValue() + + "\n" + DebugLogUtils.getStackTrace()); + return ""; + } + } + }; + return StringUtils.capitalizeFirstCodePoint( + getSubtypeName.runInLocale(sResources, displayLocale), displayLocale); + } + + public static boolean isNoLanguage(final InputMethodSubtype subtype) { + final String localeString = subtype.getLocale(); + return NO_LANGUAGE.equals(localeString); + } + + public static Locale getSubtypeLocale(final InputMethodSubtype subtype) { + final String localeString = subtype.getLocale(); + return LocaleUtils.constructLocaleFromString(localeString); + } + + public static String getKeyboardLayoutSetDisplayName(final InputMethodSubtype subtype) { + final String layoutName = getKeyboardLayoutSetName(subtype); + return getKeyboardLayoutSetDisplayName(layoutName); + } + + public static String getKeyboardLayoutSetDisplayName(final String layoutName) { + return sKeyboardLayoutToDisplayNameMap.get(layoutName); + } + + public static String getKeyboardLayoutSetName(final InputMethodSubtype subtype) { + String keyboardLayoutSet = subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET); + if (keyboardLayoutSet == null) { + // This subtype doesn't have a keyboardLayoutSet extra value, so lookup its keyboard + // layout set in sLocaleAndExtraValueToKeyboardLayoutSetMap to keep it compatible with + // pre-JellyBean. + final String key = subtype.getLocale() + ":" + subtype.getExtraValue(); + keyboardLayoutSet = sLocaleAndExtraValueToKeyboardLayoutSetMap.get(key); + } + // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is + // fixed. + if (keyboardLayoutSet == null) { + android.util.Log.w(TAG, "KeyboardLayoutSet not found, use QWERTY: " + + "locale=" + subtype.getLocale() + " extraValue=" + subtype.getExtraValue()); + return QWERTY; + } + return keyboardLayoutSet; + } + + // InputMethodSubtype's display name for spacebar text in its locale. + // isAdditionalSubtype (T=true, F=false) + // locale layout | Short Middle Full + // ------ ------- - ---- --------- ---------------------- + // en_US qwerty F En English English (US) exception + // en_GB qwerty F En English English (UK) exception + // es_US spanish F Es Español Español (EE.UU.) exception + // fr azerty F Fr Français Français + // fr_CA qwerty F Fr Français Français (Canada) + // de qwertz F De Deutsch Deutsch + // zz qwerty F QWERTY QWERTY + // fr qwertz T Fr Français Français + // de qwerty T De Deutsch Deutsch + // en_US azerty T En English English (US) + // zz azerty T AZERTY AZERTY + + // Get InputMethodSubtype's full display name in its locale. + public static String getFullDisplayName(final InputMethodSubtype subtype) { + if (isNoLanguage(subtype)) { + return getKeyboardLayoutSetDisplayName(subtype); + } + return getSubtypeLocaleDisplayName(subtype.getLocale()); + } + + // Get InputMethodSubtype's middle display name in its locale. + public static String getMiddleDisplayName(final InputMethodSubtype subtype) { + if (isNoLanguage(subtype)) { + return getKeyboardLayoutSetDisplayName(subtype); + } + final Locale locale = getSubtypeLocale(subtype); + return getSubtypeLocaleDisplayName(locale.getLanguage()); + } + + // Get InputMethodSubtype's short display name in its locale. + public static String getShortDisplayName(final InputMethodSubtype subtype) { + if (isNoLanguage(subtype)) { + return ""; + } + final Locale locale = getSubtypeLocale(subtype); + return StringUtils.capitalizeFirstCodePoint(locale.getLanguage(), locale); + } +} -- cgit v1.2.3-83-g751a