mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
am 3895d7f8: Additional subtype ID should be independent of OS-version
* commit '3895d7f8dc2e4999947f61220b86fa148f433413': Additional subtype ID should be independent of OS-version
This commit is contained in:
commit
177e952933
@ -19,6 +19,7 @@ package com.android.inputmethod.compat;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.view.inputmethod.InputMethodSubtype;
|
import android.view.inputmethod.InputMethodSubtype;
|
||||||
|
|
||||||
|
import com.android.inputmethod.annotations.UsedForTesting;
|
||||||
import com.android.inputmethod.latin.Constants;
|
import com.android.inputmethod.latin.Constants;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
@ -64,7 +65,12 @@ public final class InputMethodSubtypeCompatUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isAsciiCapable(final InputMethodSubtype subtype) {
|
public static boolean isAsciiCapable(final InputMethodSubtype subtype) {
|
||||||
return (Boolean)CompatUtils.invoke(subtype, false, METHOD_isAsciiCapable)
|
return isAsciiCapableWithAPI(subtype)
|
||||||
|| subtype.containsExtraValueKey(Constants.Subtype.ExtraValue.ASCII_CAPABLE);
|
|| subtype.containsExtraValueKey(Constants.Subtype.ExtraValue.ASCII_CAPABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UsedForTesting
|
||||||
|
public static boolean isAsciiCapableWithAPI(final InputMethodSubtype subtype) {
|
||||||
|
return (Boolean)CompatUtils.invoke(subtype, false, METHOD_isAsciiCapable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,8 +150,9 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment {
|
|||||||
// TODO: Should filter out already existing combinations of locale and layout.
|
// TODO: Should filter out already existing combinations of locale and layout.
|
||||||
for (final String layout : SubtypeLocaleUtils.getPredefinedKeyboardLayoutSet()) {
|
for (final String layout : SubtypeLocaleUtils.getPredefinedKeyboardLayoutSet()) {
|
||||||
// This is a dummy subtype with NO_LANGUAGE, only for display.
|
// This is a dummy subtype with NO_LANGUAGE, only for display.
|
||||||
final InputMethodSubtype subtype = AdditionalSubtypeUtils.createAdditionalSubtype(
|
final InputMethodSubtype subtype =
|
||||||
SubtypeLocaleUtils.NO_LANGUAGE, layout, null);
|
AdditionalSubtypeUtils.createDummyAdditionalSubtype(
|
||||||
|
SubtypeLocaleUtils.NO_LANGUAGE, layout);
|
||||||
add(new KeyboardLayoutSetItem(subtype));
|
add(new KeyboardLayoutSetItem(subtype));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,8 +287,9 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment {
|
|||||||
(SubtypeLocaleItem) mSubtypeLocaleSpinner.getSelectedItem();
|
(SubtypeLocaleItem) mSubtypeLocaleSpinner.getSelectedItem();
|
||||||
final KeyboardLayoutSetItem layout =
|
final KeyboardLayoutSetItem layout =
|
||||||
(KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem();
|
(KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem();
|
||||||
final InputMethodSubtype subtype = AdditionalSubtypeUtils.createAdditionalSubtype(
|
final InputMethodSubtype subtype =
|
||||||
locale.first, layout.first, Constants.Subtype.ExtraValue.ASCII_CAPABLE);
|
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
|
locale.first, layout.first);
|
||||||
setSubtype(subtype);
|
setSubtype(subtype);
|
||||||
notifyChanged();
|
notifyChanged();
|
||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
|
@ -374,8 +374,8 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
|
|||||||
public DictAndKeyboard createDictAndKeyboard(final Locale locale) {
|
public DictAndKeyboard createDictAndKeyboard(final Locale locale) {
|
||||||
final int script = ScriptUtils.getScriptFromSpellCheckerLocale(locale);
|
final int script = ScriptUtils.getScriptFromSpellCheckerLocale(locale);
|
||||||
final String keyboardLayoutName = getKeyboardLayoutNameForScript(script);
|
final String keyboardLayoutName = getKeyboardLayoutNameForScript(script);
|
||||||
final InputMethodSubtype subtype = AdditionalSubtypeUtils.createAdditionalSubtype(
|
final InputMethodSubtype subtype = AdditionalSubtypeUtils.createDummyAdditionalSubtype(
|
||||||
locale.toString(), keyboardLayoutName, null);
|
locale.toString(), keyboardLayoutName);
|
||||||
final KeyboardLayoutSet keyboardLayoutSet = createKeyboardSetForSpellChecker(subtype);
|
final KeyboardLayoutSet keyboardLayoutSet = createKeyboardSetForSpellChecker(subtype);
|
||||||
|
|
||||||
final DictionaryCollection dictionaryCollection =
|
final DictionaryCollection dictionaryCollection =
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package com.android.inputmethod.latin.utils;
|
package com.android.inputmethod.latin.utils;
|
||||||
|
|
||||||
import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE;
|
import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE;
|
||||||
|
import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.ASCII_CAPABLE;
|
||||||
import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
|
import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
|
||||||
import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.IS_ADDITIONAL_SUBTYPE;
|
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.KEYBOARD_LAYOUT_SET;
|
||||||
@ -56,25 +57,33 @@ public final class AdditionalSubtypeUtils {
|
|||||||
private static final int LENGTH_WITH_EXTRA_VALUE = (INDEX_OF_EXTRA_VALUE + 1);
|
private static final int LENGTH_WITH_EXTRA_VALUE = (INDEX_OF_EXTRA_VALUE + 1);
|
||||||
private static final String PREF_SUBTYPE_SEPARATOR = ";";
|
private static final String PREF_SUBTYPE_SEPARATOR = ";";
|
||||||
|
|
||||||
public static InputMethodSubtype createAdditionalSubtype(final String localeString,
|
private static InputMethodSubtype createAdditionalSubtypeInternal(
|
||||||
final String keyboardLayoutSetName, final String extraValue) {
|
final String localeString, final String keyboardLayoutSetName,
|
||||||
final String layoutExtraValue = KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName;
|
final boolean isAsciiCapable, final boolean isEmojiCapable) {
|
||||||
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);
|
final int nameId = SubtypeLocaleUtils.getSubtypeNameId(localeString, keyboardLayoutSetName);
|
||||||
return buildInputMethodSubtype(
|
final String platformVersionDependentExtraValues = getPlatformVersionDependentExtraValue(
|
||||||
nameId, localeString, layoutExtraValue, additionalSubtypeExtraValue);
|
localeString, keyboardLayoutSetName, isAsciiCapable, isEmojiCapable);
|
||||||
|
final int platformVersionIndependentSubtypeId =
|
||||||
|
getPlatformVersionIndependentSubtypeId(localeString, keyboardLayoutSetName);
|
||||||
|
// NOTE: In KitKat and later, InputMethodSubtypeBuilder#setIsAsciiCapable is also available.
|
||||||
|
// TODO: Use InputMethodSubtypeBuilder#setIsAsciiCapable when appropriate.
|
||||||
|
return InputMethodSubtypeCompatUtils.newInputMethodSubtype(nameId,
|
||||||
|
R.drawable.ic_ime_switcher_dark, localeString, KEYBOARD_MODE,
|
||||||
|
platformVersionDependentExtraValues,
|
||||||
|
false /* isAuxiliary */, false /* overrideImplicitlyEnabledSubtype */,
|
||||||
|
platformVersionIndependentSubtypeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputMethodSubtype createDummyAdditionalSubtype(
|
||||||
|
final String localeString, final String keyboardLayoutSetName) {
|
||||||
|
return createAdditionalSubtypeInternal(localeString, keyboardLayoutSetName,
|
||||||
|
false /* isAsciiCapable */, false /* isEmojiCapable */);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputMethodSubtype createAsciiEmojiCapableAdditionalSubtype(
|
||||||
|
final String localeString, final String keyboardLayoutSetName) {
|
||||||
|
return createAdditionalSubtypeInternal(localeString, keyboardLayoutSetName,
|
||||||
|
true /* isAsciiCapable */, true /* isEmojiCapable */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPrefSubtype(final InputMethodSubtype subtype) {
|
public static String getPrefSubtype(final InputMethodSubtype subtype) {
|
||||||
@ -106,10 +115,10 @@ public final class AdditionalSubtypeUtils {
|
|||||||
}
|
}
|
||||||
final String localeString = elems[INDEX_OF_LOCALE];
|
final String localeString = elems[INDEX_OF_LOCALE];
|
||||||
final String keyboardLayoutSetName = elems[INDEX_OF_KEYBOARD_LAYOUT];
|
final String keyboardLayoutSetName = elems[INDEX_OF_KEYBOARD_LAYOUT];
|
||||||
final String extraValue = (elems.length == LENGTH_WITH_EXTRA_VALUE)
|
// Here we assume that all the additional subtypes have AsciiCapable and EmojiCapable.
|
||||||
? elems[INDEX_OF_EXTRA_VALUE] : null;
|
// This is actually what the setting dialog for additional subtype is doing.
|
||||||
final InputMethodSubtype subtype = createAdditionalSubtype(
|
final InputMethodSubtype subtype = createAsciiEmojiCapableAdditionalSubtype(
|
||||||
localeString, keyboardLayoutSetName, extraValue);
|
localeString, keyboardLayoutSetName);
|
||||||
if (subtype.getNameResId() == SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT) {
|
if (subtype.getNameResId() == SubtypeLocaleUtils.UNKNOWN_KEYBOARD_LAYOUT) {
|
||||||
// Skip unknown keyboard layout subtype. This may happen when predefined keyboard
|
// Skip unknown keyboard layout subtype. This may happen when predefined keyboard
|
||||||
// layout has been removed.
|
// layout has been removed.
|
||||||
@ -148,35 +157,80 @@ public final class AdditionalSubtypeUtils {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InputMethodSubtype buildInputMethodSubtype(final int nameId,
|
/**
|
||||||
final String localeString, final String layoutExtraValue,
|
* Returns the extra value that is optimized for the running OS.
|
||||||
final String additionalSubtypeExtraValue) {
|
* <p>
|
||||||
// To preserve additional subtype settings and user's selection across OS updates, subtype
|
* Historically the extra value has been used as the last resort to annotate various kinds of
|
||||||
// id shouldn't be changed. New attributes, such as emojiCapable, are carefully excluded
|
* attributes. Some of these attributes are valid only on some platform versions. Thus we cannot
|
||||||
// from the calculation of subtype id.
|
* assume that the extra values stored in a persistent storage are always valid. We need to
|
||||||
final String compatibleExtraValue = StringUtils.joinCommaSplittableText(
|
* regenerate the extra value on the fly instead.
|
||||||
layoutExtraValue, additionalSubtypeExtraValue);
|
* </p>
|
||||||
final int compatibleSubtypeId = getInputMethodSubtypeId(localeString, compatibleExtraValue);
|
* @param localeString the locale string (e.g., "en_US").
|
||||||
final String extraValue;
|
* @param keyboardLayoutSetName the keyboard layout set name (e.g., "dvorak").
|
||||||
// Color Emoji is supported from KitKat.
|
* @param isAsciiCapable true when ASCII characters are supported with this layout.
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
* @param isEmojiCapable true when Unicode Emoji characters are supported with this layout.
|
||||||
extraValue = StringUtils.appendToCommaSplittableTextIfNotExists(
|
* @return extra value that is optimized for the running OS.
|
||||||
EMOJI_CAPABLE, compatibleExtraValue);
|
* @see #getPlatformVersionIndependentSubtypeId(String, String)
|
||||||
} else {
|
*/
|
||||||
extraValue = compatibleExtraValue;
|
private static String getPlatformVersionDependentExtraValue(final String localeString,
|
||||||
|
final String keyboardLayoutSetName, final boolean isAsciiCapable,
|
||||||
|
final boolean isEmojiCapable) {
|
||||||
|
final ArrayList<String> extraValueItems = new ArrayList<>();
|
||||||
|
extraValueItems.add(KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName);
|
||||||
|
if (isAsciiCapable) {
|
||||||
|
extraValueItems.add(ASCII_CAPABLE);
|
||||||
}
|
}
|
||||||
return InputMethodSubtypeCompatUtils.newInputMethodSubtype(nameId,
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &&
|
||||||
R.drawable.ic_ime_switcher_dark, localeString, KEYBOARD_MODE, extraValue,
|
SubtypeLocaleUtils.isExceptionalLocale(localeString)) {
|
||||||
false, false, compatibleSubtypeId);
|
extraValueItems.add(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" +
|
||||||
|
SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(keyboardLayoutSetName));
|
||||||
|
}
|
||||||
|
if (isEmojiCapable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
extraValueItems.add(EMOJI_CAPABLE);
|
||||||
|
}
|
||||||
|
extraValueItems.add(IS_ADDITIONAL_SUBTYPE);
|
||||||
|
return TextUtils.join(",", extraValueItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getInputMethodSubtypeId(final String localeString, final String extraValue) {
|
/**
|
||||||
// From the compatibility point of view, the calculation of subtype id has been copied from
|
* Returns the subtype ID that is supposed to be compatible between different version of OSes.
|
||||||
// {@link InputMethodSubtype} of JellyBean MR2.
|
* <p>
|
||||||
|
* From the compatibility point of view, it is important to keep subtype id predictable and
|
||||||
|
* stable between different OSes. For this purpose, the calculation code in this method is
|
||||||
|
* carefully chosen and then fixed. Treat the following code as no more or less than a
|
||||||
|
* hash function. Each component to be hashed can be different from the corresponding value
|
||||||
|
* that is used to instantiate {@link InputMethodSubtype} actually.
|
||||||
|
* For example, you don't need to update <code>compatibilityExtraValueItems</code> in this
|
||||||
|
* method even when we need to add some new extra values for the actual instance of
|
||||||
|
* {@link InputMethodSubtype}.
|
||||||
|
* </p>
|
||||||
|
* @param localeString the locale string (e.g., "en_US").
|
||||||
|
* @param keyboardLayoutSetName the keyboard layout set name (e.g., "dvorak").
|
||||||
|
* @return a platform-version independent subtype ID.
|
||||||
|
* @see #getPlatformVersionDependentExtraValue(String, String, boolean, boolean)
|
||||||
|
*/
|
||||||
|
private static int getPlatformVersionIndependentSubtypeId(final String localeString,
|
||||||
|
final String keyboardLayoutSetName) {
|
||||||
|
// For compatibility reasons, we concatenate the extra values in the following order.
|
||||||
|
// - KeyboardLayoutSet
|
||||||
|
// - AsciiCapable
|
||||||
|
// - UntranslatableReplacementStringInSubtypeName
|
||||||
|
// - EmojiCapable
|
||||||
|
// - isAdditionalSubtype
|
||||||
|
final ArrayList<String> compatibilityExtraValueItems = new ArrayList<>();
|
||||||
|
compatibilityExtraValueItems.add(KEYBOARD_LAYOUT_SET + "=" + keyboardLayoutSetName);
|
||||||
|
compatibilityExtraValueItems.add(ASCII_CAPABLE);
|
||||||
|
if (SubtypeLocaleUtils.isExceptionalLocale(localeString)) {
|
||||||
|
compatibilityExtraValueItems.add(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME + "=" +
|
||||||
|
SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(keyboardLayoutSetName));
|
||||||
|
}
|
||||||
|
compatibilityExtraValueItems.add(EMOJI_CAPABLE);
|
||||||
|
compatibilityExtraValueItems.add(IS_ADDITIONAL_SUBTYPE);
|
||||||
|
final String compatibilityExtraValues = TextUtils.join(",", compatibilityExtraValueItems);
|
||||||
return Arrays.hashCode(new Object[] {
|
return Arrays.hashCode(new Object[] {
|
||||||
localeString,
|
localeString,
|
||||||
KEYBOARD_MODE,
|
KEYBOARD_MODE,
|
||||||
extraValue,
|
compatibilityExtraValues,
|
||||||
false /* isAuxiliary */,
|
false /* isAuxiliary */,
|
||||||
false /* overrideImplicitlyEnabledSubtype */ });
|
false /* overrideImplicitlyEnabledSubtype */ });
|
||||||
}
|
}
|
||||||
|
@ -104,8 +104,8 @@ public abstract class KeyboardLayoutSetTestsBase extends AndroidTestCase {
|
|||||||
final Locale subtypeLocale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
|
final Locale subtypeLocale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
|
||||||
if (locale.equals(subtypeLocale)) {
|
if (locale.equals(subtypeLocale)) {
|
||||||
// Create additional subtype.
|
// Create additional subtype.
|
||||||
return AdditionalSubtypeUtils.createAdditionalSubtype(
|
return AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
locale.toString(), keyboardLayout, null /* extraValue */);
|
locale.toString(), keyboardLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
|
@ -67,10 +67,10 @@ public class LanguageOnSpacebarHelperTests extends AndroidTestCase {
|
|||||||
Locale.CANADA_FRENCH.toString(), "qwerty");
|
Locale.CANADA_FRENCH.toString(), "qwerty");
|
||||||
FR_CH_SWISS = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
FR_CH_SWISS = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||||
"fr_CH", "swiss");
|
"fr_CH", "swiss");
|
||||||
FR_CH_QWERTZ = AdditionalSubtypeUtils.createAdditionalSubtype(
|
FR_CH_QWERTZ = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
"fr_CH", "qwertz", null);
|
"fr_CH", "qwertz");
|
||||||
FR_CH_QWERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
|
FR_CH_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
"fr_CH", "qwerty", null);
|
"fr_CH", "qwerty");
|
||||||
ZZ_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
ZZ_QWERTY = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||||
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
|
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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 android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
|
import android.view.inputmethod.InputMethodSubtype;
|
||||||
|
|
||||||
|
import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE;
|
||||||
|
import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.ASCII_CAPABLE;
|
||||||
|
import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.EMOJI_CAPABLE;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
public class AdditionalSubtypeUtilsTests extends AndroidTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predictable subtype ID for en_US dvorak layout. This is actually a hash code calculated as
|
||||||
|
* follows.
|
||||||
|
* <code>
|
||||||
|
* final boolean isAuxiliary = false;
|
||||||
|
* final boolean overrideImplicitlyEnabledSubtype = false;
|
||||||
|
* final int SUBTYPE_ID_EN_US_DVORAK = Arrays.hashCode(new Object[] {
|
||||||
|
* "en_US",
|
||||||
|
* "keyboard",
|
||||||
|
* "KeyboardLayoutSet=dvorak"
|
||||||
|
* + ",AsciiCapable"
|
||||||
|
* + ",UntranslatableReplacementStringInSubtypeName=Dvorak"
|
||||||
|
* + ",EmojiCapable"
|
||||||
|
* + ",isAdditionalSubtype",
|
||||||
|
* isAuxiliary,
|
||||||
|
* overrideImplicitlyEnabledSubtype });
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
private static int SUBTYPE_ID_EN_US_DVORAK = 0xb3c0cc56;
|
||||||
|
private static String EXTRA_VALUE_EN_US_DVORAK_ICS =
|
||||||
|
"KeyboardLayoutSet=dvorak" +
|
||||||
|
",AsciiCapable" +
|
||||||
|
",isAdditionalSubtype";
|
||||||
|
private static String EXTRA_VALUE_EN_US_DVORAK_JELLY_BEAN =
|
||||||
|
"KeyboardLayoutSet=dvorak" +
|
||||||
|
",AsciiCapable" +
|
||||||
|
",UntranslatableReplacementStringInSubtypeName=Dvorak" +
|
||||||
|
",isAdditionalSubtype";
|
||||||
|
private static String EXTRA_VALUE_EN_US_DVORAK_KITKAT =
|
||||||
|
"KeyboardLayoutSet=dvorak" +
|
||||||
|
",AsciiCapable" +
|
||||||
|
",UntranslatableReplacementStringInSubtypeName=Dvorak" +
|
||||||
|
",EmojiCapable" +
|
||||||
|
",isAdditionalSubtype";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predictable subtype ID for azerty layout. This is actually a hash code calculated as follows.
|
||||||
|
* <code>
|
||||||
|
* final boolean isAuxiliary = false;
|
||||||
|
* final boolean overrideImplicitlyEnabledSubtype = false;
|
||||||
|
* final int SUBTYPE_ID_ZZ_AZERTY = Arrays.hashCode(new Object[] {
|
||||||
|
* "zz",
|
||||||
|
* "keyboard",
|
||||||
|
* "KeyboardLayoutSet=azerty"
|
||||||
|
* + ",AsciiCapable"
|
||||||
|
* + ",EmojiCapable"
|
||||||
|
* + ",isAdditionalSubtype",
|
||||||
|
* isAuxiliary,
|
||||||
|
* overrideImplicitlyEnabledSubtype });
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
private static int SUBTYPE_ID_ZZ_AZERTY = 0x5b6be697;
|
||||||
|
private static String EXTRA_VALUE_ZZ_AZERTY_ICS =
|
||||||
|
"KeyboardLayoutSet=azerty" +
|
||||||
|
",AsciiCapable" +
|
||||||
|
",isAdditionalSubtype";
|
||||||
|
private static String EXTRA_VALUE_ZZ_AZERTY_KITKAT =
|
||||||
|
"KeyboardLayoutSet=azerty" +
|
||||||
|
",AsciiCapable" +
|
||||||
|
",EmojiCapable" +
|
||||||
|
",isAdditionalSubtype";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
final Context context = getContext();
|
||||||
|
SubtypeLocaleUtils.init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertEnUsDvorak(InputMethodSubtype subtype) {
|
||||||
|
assertEquals("en_US", subtype.getLocale());
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
assertEquals(EXTRA_VALUE_EN_US_DVORAK_KITKAT, subtype.getExtraValue());
|
||||||
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||||
|
assertEquals(EXTRA_VALUE_EN_US_DVORAK_JELLY_BEAN, subtype.getExtraValue());
|
||||||
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||||
|
assertEquals(EXTRA_VALUE_EN_US_DVORAK_ICS, subtype.getExtraValue());
|
||||||
|
}
|
||||||
|
assertTrue(subtype.containsExtraValueKey(ASCII_CAPABLE));
|
||||||
|
assertTrue(InputMethodSubtypeCompatUtils.isAsciiCapable(subtype));
|
||||||
|
// TODO: Enable following test
|
||||||
|
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
// assertTrue(InputMethodSubtypeCompatUtils.isAsciiCapableWithAPI(subtype));
|
||||||
|
// }
|
||||||
|
assertTrue(subtype.containsExtraValueKey(EMOJI_CAPABLE));
|
||||||
|
assertTrue(subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE));
|
||||||
|
assertEquals("dvorak", subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET));
|
||||||
|
assertEquals("Dvorak", subtype.getExtraValueOf(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME));
|
||||||
|
assertEquals(KEYBOARD_MODE, subtype.getMode());
|
||||||
|
assertEquals(SUBTYPE_ID_EN_US_DVORAK, subtype.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertAzerty(InputMethodSubtype subtype) {
|
||||||
|
assertEquals("zz", subtype.getLocale());
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
assertEquals(EXTRA_VALUE_ZZ_AZERTY_KITKAT, subtype.getExtraValue());
|
||||||
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||||
|
assertEquals(EXTRA_VALUE_ZZ_AZERTY_ICS, subtype.getExtraValue());
|
||||||
|
}
|
||||||
|
assertTrue(subtype.containsExtraValueKey(ASCII_CAPABLE));
|
||||||
|
assertTrue(InputMethodSubtypeCompatUtils.isAsciiCapable(subtype));
|
||||||
|
// TODO: Enable following test
|
||||||
|
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
// assertTrue(InputMethodSubtypeCompatUtils.isAsciiCapableWithAPI(subtype));
|
||||||
|
// }
|
||||||
|
assertTrue(subtype.containsExtraValueKey(EMOJI_CAPABLE));
|
||||||
|
assertTrue(subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE));
|
||||||
|
assertEquals("azerty", subtype.getExtraValueOf(KEYBOARD_LAYOUT_SET));
|
||||||
|
assertFalse(subtype.containsExtraValueKey(UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME));
|
||||||
|
assertEquals(KEYBOARD_MODE, subtype.getMode());
|
||||||
|
assertEquals(SUBTYPE_ID_ZZ_AZERTY, subtype.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRestorable() {
|
||||||
|
final InputMethodSubtype EN_UK_DVORAK =
|
||||||
|
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
|
Locale.US.toString(), "dvorak");
|
||||||
|
final InputMethodSubtype ZZ_AZERTY =
|
||||||
|
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
|
SubtypeLocaleUtils.NO_LANGUAGE, "azerty");
|
||||||
|
assertEnUsDvorak(EN_UK_DVORAK);
|
||||||
|
assertAzerty(ZZ_AZERTY);
|
||||||
|
|
||||||
|
// Make sure the subtype can be stored and restored in a deterministic manner.
|
||||||
|
final InputMethodSubtype[] subtypes = { EN_UK_DVORAK, ZZ_AZERTY };
|
||||||
|
final String prefSubtype = AdditionalSubtypeUtils.createPrefSubtypes(subtypes);
|
||||||
|
final InputMethodSubtype[] restoredSubtypes =
|
||||||
|
AdditionalSubtypeUtils.createAdditionalSubtypesArray(prefSubtype);
|
||||||
|
assertEquals(2, restoredSubtypes.length);
|
||||||
|
final InputMethodSubtype restored_EN_UK_DVORAK = restoredSubtypes[0];
|
||||||
|
final InputMethodSubtype restored_ZZ_AZERTY = restoredSubtypes[1];
|
||||||
|
|
||||||
|
assertEnUsDvorak(restored_EN_UK_DVORAK);
|
||||||
|
assertAzerty(restored_ZZ_AZERTY);
|
||||||
|
}
|
||||||
|
}
|
@ -87,20 +87,20 @@ public class SpacebarLanguagetUtilsTests extends AndroidTestCase {
|
|||||||
"de_CH", "swiss");
|
"de_CH", "swiss");
|
||||||
ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||||
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
|
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
|
||||||
DE_QWERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
|
DE_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
Locale.GERMAN.toString(), "qwerty", null);
|
Locale.GERMAN.toString(), "qwerty");
|
||||||
FR_QWERTZ = AdditionalSubtypeUtils.createAdditionalSubtype(
|
FR_QWERTZ = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
Locale.FRENCH.toString(), "qwertz", null);
|
Locale.FRENCH.toString(), "qwertz");
|
||||||
EN_US_AZERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
|
EN_US_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
Locale.US.toString(), "azerty", null);
|
Locale.US.toString(), "azerty");
|
||||||
EN_UK_DVORAK = AdditionalSubtypeUtils.createAdditionalSubtype(
|
EN_UK_DVORAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
Locale.UK.toString(), "dvorak", null);
|
Locale.UK.toString(), "dvorak");
|
||||||
ES_US_COLEMAK = AdditionalSubtypeUtils.createAdditionalSubtype(
|
ES_US_COLEMAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
"es_US", "colemak", null);
|
"es_US", "colemak");
|
||||||
ZZ_AZERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
|
ZZ_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
SubtypeLocaleUtils.NO_LANGUAGE, "azerty", null);
|
SubtypeLocaleUtils.NO_LANGUAGE, "azerty");
|
||||||
ZZ_PC = AdditionalSubtypeUtils.createAdditionalSubtype(
|
ZZ_PC = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty", null);
|
SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAllFullDisplayNameForSpacebar() {
|
public void testAllFullDisplayNameForSpacebar() {
|
||||||
|
@ -87,20 +87,20 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
|
|||||||
"de_CH", "swiss");
|
"de_CH", "swiss");
|
||||||
ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
|
||||||
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
|
SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
|
||||||
DE_QWERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
|
DE_QWERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
Locale.GERMAN.toString(), "qwerty", null);
|
Locale.GERMAN.toString(), "qwerty");
|
||||||
FR_QWERTZ = AdditionalSubtypeUtils.createAdditionalSubtype(
|
FR_QWERTZ = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
Locale.FRENCH.toString(), "qwertz", null);
|
Locale.FRENCH.toString(), "qwertz");
|
||||||
EN_US_AZERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
|
EN_US_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
Locale.US.toString(), "azerty", null);
|
Locale.US.toString(), "azerty");
|
||||||
EN_UK_DVORAK = AdditionalSubtypeUtils.createAdditionalSubtype(
|
EN_UK_DVORAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
Locale.UK.toString(), "dvorak", null);
|
Locale.UK.toString(), "dvorak");
|
||||||
ES_US_COLEMAK = AdditionalSubtypeUtils.createAdditionalSubtype(
|
ES_US_COLEMAK = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
"es_US", "colemak", null);
|
"es_US", "colemak");
|
||||||
ZZ_AZERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
|
ZZ_AZERTY = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
SubtypeLocaleUtils.NO_LANGUAGE, "azerty", null);
|
SubtypeLocaleUtils.NO_LANGUAGE, "azerty");
|
||||||
ZZ_PC = AdditionalSubtypeUtils.createAdditionalSubtype(
|
ZZ_PC = AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
|
||||||
SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty", null);
|
SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAllFullDisplayName() {
|
public void testAllFullDisplayName() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user