Utilize InputMethodSubtype and additional subtype

* Remove de_QY and fr_CH from supported subtypes
* Add de-qwerty and fr-qwertz predefined additional subtypes instead.

Change-Id: I49e8ba0299529302f2b91b4d018b07304cdd6897
main
Tadashi G. Takaoka 2012-04-11 18:21:10 +09:00
parent f338f8b50d
commit f6972561fc
14 changed files with 305 additions and 201 deletions

View File

@ -134,24 +134,24 @@
<item>5</item> <item>5</item>
</string-array> </string-array>
<!-- Subtype locale name exceptions --> <!-- Subtype locale display name exceptions -->
<string-array name="subtype_locale_exception_keys"> <string-array name="subtype_locale_exception_keys">
<item>en_US</item> <item>en_US</item>
<item>en_GB</item> <item>en_GB</item>
<item>*_QY</item>
<item>QY</item>
</string-array> </string-array>
<string-array name="subtype_locale_exception_values"> <string-array name="subtype_locale_exception_values">
<item>English (US)</item> <item>English (US)</item>
<item>English (UK)</item> <item>English (UK)</item>
<item>@string/subtype_generic_qwerty</item>
<item>QWERTY</item>
</string-array> </string-array>
<!-- Generic subtype label --> <!-- Generic subtype label -->
<string name="subtype_generic">%s</string> <string name="subtype_generic">%s</string>
<!-- Description for generic QWERTY keyboard subtype --> <!-- Description for generic QWERTY keyboard subtype -->
<string name="subtype_generic_qwerty">%s (QWERTY)</string> <string name="subtype_generic_qwerty">%s (QWERTY)</string>
<!-- Description for generic QWERTZ keyboard subtype -->
<string name="subtype_generic_qwertz">%s (QWERTZ)</string>
<!-- Description for generic AZERTY keyboard subtype -->
<string name="subtype_generic_azerty">%s (AZERTY)</string>
<!-- dictionary pack package name /settings activity (for shared prefs and settings) --> <!-- dictionary pack package name /settings activity (for shared prefs and settings) -->
<string name="dictionary_pack_package_name">com.google.android.inputmethod.latin.dictionarypack</string> <string name="dictionary_pack_package_name">com.google.android.inputmethod.latin.dictionarypack</string>

View File

@ -28,7 +28,6 @@
cs: Czech/qwertz cs: Czech/qwertz
da: Danish/nordic da: Danish/nordic
de: German/qwertz de: German/qwertz
de_QY: German (QWERTY)/qwerty
el: Greek/greek el: Greek/greek
en_US: English United States/qwerty en_US: English United States/qwerty
en_GB: English Great Britain/qwerty en_GB: English Great Britain/qwerty
@ -38,7 +37,6 @@
fi: Finnish/nordic fi: Finnish/nordic
fr: French/azerty fr: French/azerty
fr_CA: French Canada/qwerty fr_CA: French Canada/qwerty
fr_CH: French Switzerland/qwertz
hi: Hindi/hindi hi: Hindi/hindi
hr: Croatian/qwertz hr: Croatian/qwertz
hu: Hungarian/qwertz hu: Hungarian/qwertz
@ -64,7 +62,7 @@
tr: Turkish/qwerty tr: Turkish/qwerty
uk: Ukrainian/east_slavic uk: Ukrainian/east_slavic
vi: Vietnamese/qwerty vi: Vietnamese/qwerty
zz_QY: QWERTY/qwerty zz: QWERTY/qwerty
--> -->
<!-- TODO: use <lang>_keyboard icon instead of a common keyboard icon. --> <!-- TODO: use <lang>_keyboard icon instead of a common keyboard icon. -->
<!-- If IME doesn't have an applicable subtype, the first subtype will be used as a default <!-- If IME doesn't have an applicable subtype, the first subtype will be used as a default
@ -120,12 +118,6 @@
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable" android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable"
/> />
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic_qwerty"
android:imeSubtypeLocale="de"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty:de_QY,AsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic" android:label="@string/subtype_generic"
android:imeSubtypeLocale="el" android:imeSubtypeLocale="el"
@ -168,12 +160,6 @@
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable" android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable"
/> />
<subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic"
android:imeSubtypeLocale="fr_CH"
android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwertz,AsciiCapable"
/>
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_generic" android:label="@string/subtype_generic"
android:imeSubtypeLocale="hi" android:imeSubtypeLocale="hi"
@ -327,7 +313,7 @@
/> />
<subtype android:icon="@drawable/ic_subtype_keyboard" <subtype android:icon="@drawable/ic_subtype_keyboard"
android:label="@string/subtype_no_language_qwerty" android:label="@string/subtype_no_language_qwerty"
android:imeSubtypeLocale="zz_QY" android:imeSubtypeLocale="zz"
android:imeSubtypeMode="keyboard" android:imeSubtypeMode="keyboard"
android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable" android:imeSubtypeExtraValue="KeyboardLayoutSet=qwerty,AsciiCapable,EnabledWhenDefaultIsNotAsciiCapable"
/> />

View File

@ -53,6 +53,10 @@ public class InputMethodManagerCompatWrapper {
sInstance.mImm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); sInstance.mImm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
} }
public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {
mImm.setAdditionalInputMethodSubtypes(imiId, subtypes);
}
public InputMethodSubtype getCurrentInputMethodSubtype() { public InputMethodSubtype getCurrentInputMethodSubtype() {
return mImm.getCurrentInputMethodSubtype(); return mImm.getCurrentInputMethodSubtype();
} }

View File

@ -793,7 +793,7 @@ public class Keyboard {
} }
}; };
// Null means the current system locale. // Null means the current system locale.
final Locale locale = language.equals(SubtypeLocale.NO_LANGUAGE) final Locale locale = SubtypeLocale.isNoLanguage(params.mId.mSubtype)
? null : params.mId.mLocale; ? null : params.mId.mLocale;
job.runInLocale(mResources, locale); job.runInLocale(mResources, locale);

View File

@ -19,9 +19,12 @@ package com.android.inputmethod.keyboard;
import android.text.InputType; import android.text.InputType;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.compat.EditorInfoCompatUtils; import com.android.inputmethod.compat.EditorInfoCompatUtils;
import com.android.inputmethod.latin.InputTypeUtils; import com.android.inputmethod.latin.InputTypeUtils;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.SubtypeLocale;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
@ -53,6 +56,7 @@ public class KeyboardId {
private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1; private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1;
public final InputMethodSubtype mSubtype;
public final Locale mLocale; public final Locale mLocale;
public final int mOrientation; public final int mOrientation;
public final int mWidth; public final int mWidth;
@ -67,10 +71,11 @@ public class KeyboardId {
private final int mHashCode; private final int mHashCode;
public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode, public KeyboardId(int elementId, InputMethodSubtype subtype, int orientation, int width,
EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled, int mode, EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled,
boolean hasShortcutKey, boolean languageSwitchKeyEnabled) { boolean hasShortcutKey, boolean languageSwitchKeyEnabled) {
mLocale = locale; mSubtype = subtype;
mLocale = SubtypeLocale.getSubtypeLocale(subtype);
mOrientation = orientation; mOrientation = orientation;
mWidth = width; mWidth = width;
mMode = mode; mMode = mode;
@ -102,7 +107,7 @@ public class KeyboardId {
id.mCustomActionLabel, id.mCustomActionLabel,
id.navigateNext(), id.navigateNext(),
id.navigatePrevious(), id.navigatePrevious(),
id.mLocale id.mSubtype
}); });
} }
@ -123,7 +128,7 @@ public class KeyboardId {
&& TextUtils.equals(other.mCustomActionLabel, mCustomActionLabel) && TextUtils.equals(other.mCustomActionLabel, mCustomActionLabel)
&& other.navigateNext() == navigateNext() && other.navigateNext() == navigateNext()
&& other.navigatePrevious() == navigatePrevious() && other.navigatePrevious() == navigatePrevious()
&& other.mLocale.equals(mLocale); && other.mSubtype.equals(mSubtype);
} }
public boolean isAlphabetKeyboard() { public boolean isAlphabetKeyboard() {
@ -176,9 +181,10 @@ public class KeyboardId {
@Override @Override
public String toString() { public String toString() {
return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s%s]", return String.format("[%s %s:%s %s%d %s %s %s%s%s%s%s%s%s%s]",
elementIdToName(mElementId), elementIdToName(mElementId),
mLocale, mLocale,
mSubtype.getExtraValueOf(LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET),
(mOrientation == 1 ? "port" : "land"), mWidth, (mOrientation == 1 ? "port" : "land"), mWidth,
modeName(mMode), modeName(mMode),
imeAction(), imeAction(),

View File

@ -44,7 +44,6 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
/** /**
* This class represents a set of keyboard layouts. Each of them represents a different keyboard * This class represents a set of keyboard layouts. Each of them represents a different keyboard
@ -109,7 +108,7 @@ public class KeyboardLayoutSet {
boolean mVoiceKeyOnMain; boolean mVoiceKeyOnMain;
boolean mNoSettingsKey; boolean mNoSettingsKey;
boolean mLanguageSwitchKeyEnabled; boolean mLanguageSwitchKeyEnabled;
Locale mLocale; InputMethodSubtype mSubtype;
int mOrientation; int mOrientation;
int mWidth; int mWidth;
// KeyboardLayoutSet element id to element's parameters map. // KeyboardLayoutSet element id to element's parameters map.
@ -203,10 +202,10 @@ public class KeyboardLayoutSet {
final Params params = mParams; final Params params = mParams;
final boolean isSymbols = (keyboardLayoutSetElementId == KeyboardId.ELEMENT_SYMBOLS final boolean isSymbols = (keyboardLayoutSetElementId == KeyboardId.ELEMENT_SYMBOLS
|| keyboardLayoutSetElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED); || keyboardLayoutSetElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED);
final boolean noLanguage = params.mLocale.getLanguage().equals(SubtypeLocale.NO_LANGUAGE); final boolean noLanguage = SubtypeLocale.isNoLanguage(params.mSubtype);
final boolean voiceKeyEnabled = params.mVoiceKeyEnabled && !noLanguage; final boolean voiceKeyEnabled = params.mVoiceKeyEnabled && !noLanguage;
final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != params.mVoiceKeyOnMain); final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != params.mVoiceKeyOnMain);
return new KeyboardId(keyboardLayoutSetElementId, params.mLocale, params.mOrientation, return new KeyboardId(keyboardLayoutSetElementId, params.mSubtype, params.mOrientation,
params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey, params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey,
voiceKeyEnabled, hasShortcutKey, params.mLanguageSwitchKeyEnabled); voiceKeyEnabled, hasShortcutKey, params.mLanguageSwitchKeyEnabled);
} }
@ -251,7 +250,7 @@ public class KeyboardLayoutSet {
final InputMethodSubtype keyboardSubtype = (forceAscii && !asciiCapable) final InputMethodSubtype keyboardSubtype = (forceAscii && !asciiCapable)
? SubtypeSwitcher.getInstance().getNoLanguageSubtype() ? SubtypeSwitcher.getInstance().getNoLanguageSubtype()
: subtype; : subtype;
mParams.mLocale = SubtypeLocale.getKeyboardLayoutSetLocale(keyboardSubtype); mParams.mSubtype = keyboardSubtype;
mParams.mKeyboardLayoutSetName = KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX mParams.mKeyboardLayoutSetName = KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX
+ SubtypeLocale.getKeyboardLayoutSetName(keyboardSubtype); + SubtypeLocale.getKeyboardLayoutSetName(keyboardSubtype);
return this; return this;
@ -278,7 +277,7 @@ public class KeyboardLayoutSet {
public KeyboardLayoutSet build() { public KeyboardLayoutSet build() {
if (mParams.mOrientation == Configuration.ORIENTATION_UNDEFINED) if (mParams.mOrientation == Configuration.ORIENTATION_UNDEFINED)
throw new RuntimeException("Screen geometry is not specified"); throw new RuntimeException("Screen geometry is not specified");
if (mParams.mLocale == null) if (mParams.mSubtype == null)
throw new RuntimeException("KeyboardLayoutSet subtype is not specified"); throw new RuntimeException("KeyboardLayoutSet subtype is not specified");
final String packageName = mResources.getResourcePackageName( final String packageName = mResources.getResourcePackageName(
R.xml.keyboard_layout_set_qwerty); R.xml.keyboard_layout_set_qwerty);

View File

@ -35,6 +35,7 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.accessibility.AccessibilityUtils;
@ -52,7 +53,6 @@ import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils; import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils;
import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.define.ProductionFlag;
import java.util.Locale;
import java.util.WeakHashMap; import java.util.WeakHashMap;
/** /**
@ -80,7 +80,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
private ObjectAnimator mLanguageOnSpacebarFadeoutAnimator; private ObjectAnimator mLanguageOnSpacebarFadeoutAnimator;
private static final int ALPHA_OPAQUE = 255; private static final int ALPHA_OPAQUE = 255;
private boolean mNeedsToDisplayLanguage; private boolean mNeedsToDisplayLanguage;
private Locale mSpacebarLocale;
private int mLanguageOnSpacebarAnimAlpha = ALPHA_OPAQUE; private int mLanguageOnSpacebarAnimAlpha = ALPHA_OPAQUE;
private final float mSpacebarTextRatio; private final float mSpacebarTextRatio;
private float mSpacebarTextSize; private float mSpacebarTextSize;
@ -468,7 +467,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon(keyboard.mIconsSet) : null; mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon(keyboard.mIconsSet) : null;
final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
mSpacebarTextSize = keyHeight * mSpacebarTextRatio; mSpacebarTextSize = keyHeight * mSpacebarTextRatio;
mSpacebarLocale = keyboard.mId.mLocale;
} }
/** /**
@ -904,12 +902,12 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
} }
// Layout locale language name on spacebar. // Layout locale language name on spacebar.
private String layoutLanguageOnSpacebar(Paint paint, Locale locale, int width, private String layoutLanguageOnSpacebar(Paint paint, InputMethodSubtype subtype, int width,
float origTextSize) { float origTextSize) {
paint.setTextAlign(Align.CENTER); paint.setTextAlign(Align.CENTER);
paint.setTypeface(Typeface.DEFAULT); paint.setTypeface(Typeface.DEFAULT);
// Estimate appropriate language name text size to fit in maxTextWidth. // Estimate appropriate language name text size to fit in maxTextWidth.
String language = SubtypeLocale.getFullDisplayName(locale); String language = SubtypeLocale.getFullDisplayName(subtype);
int textWidth = getTextWidth(paint, language, origTextSize); int textWidth = getTextWidth(paint, language, origTextSize);
// Assuming text width and text size are proportional to each other. // Assuming text width and text size are proportional to each other.
float textSize = origTextSize * Math.min(width / textWidth, 1.0f); float textSize = origTextSize * Math.min(width / textWidth, 1.0f);
@ -921,7 +919,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
final boolean useShortName; final boolean useShortName;
if (useMiddleName) { if (useMiddleName) {
language = SubtypeLocale.getMiddleDisplayName(locale); language = SubtypeLocale.getMiddleDisplayName(subtype);
textWidth = getTextWidth(paint, language, origTextSize); textWidth = getTextWidth(paint, language, origTextSize);
textSize = origTextSize * Math.min(width / textWidth, 1.0f); textSize = origTextSize * Math.min(width / textWidth, 1.0f);
useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME) useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME)
@ -931,7 +929,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
} }
if (useShortName) { if (useShortName) {
language = SubtypeLocale.getShortDisplayName(locale); language = SubtypeLocale.getShortDisplayName(subtype);
textWidth = getTextWidth(paint, language, origTextSize); textWidth = getTextWidth(paint, language, origTextSize);
textSize = origTextSize * Math.min(width / textWidth, 1.0f); textSize = origTextSize * Math.min(width / textWidth, 1.0f);
} }
@ -944,10 +942,10 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
final int width = key.mWidth; final int width = key.mWidth;
final int height = key.mHeight; final int height = key.mHeight;
// If input subtypes are explicitly selected. // If input language are explicitly selected.
if (mNeedsToDisplayLanguage) { if (mNeedsToDisplayLanguage) {
final String language = layoutLanguageOnSpacebar(paint, mSpacebarLocale, width, final String language = layoutLanguageOnSpacebar(
mSpacebarTextSize); paint, getKeyboard().mId.mSubtype, width, mSpacebarTextSize);
// Draw language text with shadow // Draw language text with shadow
// In case there is no space icon, we will place the language text at the center of // In case there is no space icon, we will place the language text at the center of
// spacebar. // spacebar.

View File

@ -0,0 +1,56 @@
/*
* 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 android.view.inputmethod.InputMethodSubtype;
import java.util.HashMap;
import java.util.Locale;
public class AdditionalSubtype {
public static final String QWERTY = "qwerty";
public static final String QWERTZ = "qwertz";
public static final String AZERTY = "azerty";
private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
private static final String SUBTYPE_EXTRA_VALUE_IS_ADDITIONAL_SUBTYPE = "isAdditionalSubtype";
// Keyboard layout to subtype name resource id map.
private static final HashMap<String, Integer> sKeyboardLayoutToNameIdsMap =
new HashMap<String, Integer>();
static {
sKeyboardLayoutToNameIdsMap.put(QWERTY, R.string.subtype_generic_qwerty);
sKeyboardLayoutToNameIdsMap.put(QWERTZ, R.string.subtype_generic_qwertz);
sKeyboardLayoutToNameIdsMap.put(AZERTY, R.string.subtype_generic_azerty);
}
public static boolean isAdditionalSubtype(InputMethodSubtype subtype) {
return subtype.containsExtraValueKey(SUBTYPE_EXTRA_VALUE_IS_ADDITIONAL_SUBTYPE);
}
public static InputMethodSubtype createAddtionalSubtype(
Locale locale, String keyboardLayoutSet) {
final String extraValue = String.format(
"%s=%s,%s", LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET, keyboardLayoutSet,
SUBTYPE_EXTRA_VALUE_IS_ADDITIONAL_SUBTYPE);
Integer nameId = sKeyboardLayoutToNameIdsMap.get(keyboardLayoutSet);
if (nameId == null) nameId = R.string.subtype_generic;
return new InputMethodSubtype(nameId, R.drawable.ic_subtype_keyboard,
locale.toString(), SUBTYPE_MODE_KEYBOARD, extraValue, false, false);
}
}

View File

@ -439,6 +439,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
loadSettings(); loadSettings();
mImm.setAdditionalInputMethodSubtypes(
SubtypeUtils.getInputMethodId(getPackageName()),
mSettingsValues.getPrefefinedAdditionalSubtypes());
// TODO: remove the following when it's not needed by updateCorrectionMode() any more // TODO: remove the following when it's not needed by updateCorrectionMode() any more
mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */); mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
updateCorrectionMode(); updateCorrectionMode();

View File

@ -21,12 +21,14 @@ import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.util.Log; import android.util.Log;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.keyboard.internal.KeySpecParser; import com.android.inputmethod.keyboard.internal.KeySpecParser;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale;
/** /**
* When you call the constructor of this class, you may want to change the current system locale by * When you call the constructor of this class, you may want to change the current system locale by
@ -69,6 +71,7 @@ public class SettingsValues {
private final int mVibrationDurationSettingsRawValue; private final int mVibrationDurationSettingsRawValue;
@SuppressWarnings("unused") // TODO: Use this @SuppressWarnings("unused") // TODO: Use this
private final float mKeypressSoundVolumeRawValue; private final float mKeypressSoundVolumeRawValue;
private final InputMethodSubtype[] mPredefinedAdditionalSubtypes;
// Deduced settings // Deduced settings
public final int mKeypressVibrationDuration; public final int mKeypressVibrationDuration;
@ -145,6 +148,16 @@ public class SettingsValues {
mAutoCorrectionThresholdRawValue); mAutoCorrectionThresholdRawValue);
mVoiceKeyEnabled = mVoiceMode != null && !mVoiceMode.equals(voiceModeOff); mVoiceKeyEnabled = mVoiceMode != null && !mVoiceMode.equals(voiceModeOff);
mVoiceKeyOnMain = mVoiceMode != null && mVoiceMode.equals(voiceModeMain); mVoiceKeyOnMain = mVoiceMode != null && mVoiceMode.equals(voiceModeMain);
// Predefined additional subtypes
final InputMethodSubtype DE_QWERTY = AdditionalSubtype.createAddtionalSubtype(
Locale.GERMAN, AdditionalSubtype.QWERTY);
final InputMethodSubtype FR_QWERTZ = AdditionalSubtype.createAddtionalSubtype(
Locale.FRENCH, AdditionalSubtype.QWERTZ);
mPredefinedAdditionalSubtypes = new InputMethodSubtype[] {
DE_QWERTY,
FR_QWERTZ,
};
} }
// Helper functions to create member values. // Helper functions to create member values.
@ -304,6 +317,11 @@ public class SettingsValues {
return res.getBoolean(R.bool.config_use_fullscreen_mode); return res.getBoolean(R.bool.config_use_fullscreen_mode);
} }
// TODO: Should be able to add/remove/edit.
public InputMethodSubtype[] getPrefefinedAdditionalSubtypes() {
return mPredefinedAdditionalSubtypes;
}
// Accessed from the settings interface, hence public // Accessed from the settings interface, hence public
public static float getCurrentKeypressSoundVolume(final SharedPreferences sp, public static float getCurrentKeypressSoundVolume(final SharedPreferences sp,
final Resources res) { final Resources res) {

View File

@ -20,23 +20,17 @@ import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
public class SubtypeLocale { public class SubtypeLocale {
// Special language code to represent "no language". // Special language code to represent "no language".
public static final String NO_LANGUAGE = "zz"; private static final String NO_LANGUAGE = "zz";
// Special country code to represent "QWERTY". public static final Locale LOCALE_NO_LANGUAGE = new Locale(NO_LANGUAGE);
/* package for test */ static final String QWERTY = "QY";
public static final Locale LOCALE_NO_LANGUAGE_QWERTY = new Locale(NO_LANGUAGE, QWERTY); // Exceptional locales to display name map.
private static final HashMap<String, String> sExceptionalDisplayNamesMap =
private static String[] sExceptionKeys; new HashMap<String, String>();
private static String[] sExceptionValues;
private static final String DEFAULT_KEYBOARD_LAYOUT_SET = "qwerty";
private static final char KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER = ':';
private SubtypeLocale() { private SubtypeLocale() {
// Intentional empty constructor for utility class. // Intentional empty constructor for utility class.
@ -44,72 +38,74 @@ public class SubtypeLocale {
public static void init(Context context) { public static void init(Context context) {
final Resources res = context.getResources(); final Resources res = context.getResources();
sExceptionKeys = res.getStringArray(R.array.subtype_locale_exception_keys); final String[] locales = res.getStringArray(R.array.subtype_locale_exception_keys);
sExceptionValues = res.getStringArray(R.array.subtype_locale_exception_values); final String[] displayNames = res.getStringArray(R.array.subtype_locale_exception_values);
} for (int i = 0; i < locales.length; i++) {
sExceptionalDisplayNamesMap.put(locales[i], displayNames[i]);
private static String lookupExceptionalLocale(String key) {
for (int index = 0; index < sExceptionKeys.length; index++) {
if (sExceptionKeys[index].equals(key)) {
return sExceptionValues[index];
}
}
return null;
}
// Get Locale's full display name in its locale.
// For example:
// "fr_CH" is converted to "Français (Suisse)".
// "de_QY" is converted to "Deutsche (QWERTY)". (Any locale that has country code "QY")
// "zz_QY" is converted to "QWERTY". (The language code "zz" means "No language", thus just
// ends up with the keyboard layout name.)
public static String getFullDisplayName(Locale locale) {
final String key;
if (locale.getLanguage().equals(NO_LANGUAGE)) {
key = locale.getCountry();
} else if (locale.getCountry().equals(QWERTY)) {
key = "*_" + QWERTY;
} else {
key = locale.toString();
}
final String value = lookupExceptionalLocale(key);
if (value == null) {
return StringUtils.toTitleCase(locale.getDisplayName(locale), locale);
}
if (value.indexOf("%s") >= 0) {
final String languageName = StringUtils.toTitleCase(
locale.getDisplayLanguage(locale), locale);
return String.format(value, languageName);
}
return value;
}
// Get Locale's middle display name in its locale.
// For example:
// "fr_CH" is converted to "Français".
// "de_QY" is converted to "Deutsche". (Any locale that has country code "QY")
// "zz_QY" is converted to "QWERTY". (The language code "zz" means "No language", thus just
// ends up with the keyboard layout name.)
public static String getMiddleDisplayName(Locale locale) {
if (NO_LANGUAGE.equals(locale.getLanguage())) {
return lookupExceptionalLocale(locale.getCountry());
} else {
return StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale);
} }
} }
// Get Locale's short display name in its locale. // Get InputMethodSubtype's display name in its locale.
// For example: // isAdditionalSubtype (T=true, F=false)
// "fr_CH" is converted to "Fr". // locale layout | Short Middle Full
// "de_QY" is converted to "De". (Any locale that has country code "QY") // ------ ------ - ---- --------- -----------------
// "zz_QY" is converter to "QY". (The language code "zz" means "No language", thus just ends // en_US qwerty F En English English (US) exception
// up with the keyboard layout name.) // en_GB qwerty F En English English (UK) exception
public static String getShortDisplayName(Locale locale) { // fr azerty F Fr Français Français
if (NO_LANGUAGE.equals(locale.getLanguage())) { // fr_CA qwerty F Fr Français Français (Canada)
return locale.getCountry(); // de qwertz F De Deutsch Deutsch
} else { // zz qwerty F QWERTY QWERTY
return StringUtils.toTitleCase(locale.getLanguage(), locale); // fr qwertz T Fr Français Français (QWERTZ)
// de qwerty T De Deutsch Deutsch (QWERTY)
// en azerty T En English English (AZERTY)
// zz azerty T AZERTY AZERTY
// Get InputMethodSubtype's full display name in its locale.
public static String getFullDisplayName(InputMethodSubtype subtype) {
final String value = sExceptionalDisplayNamesMap.get(subtype.getLocale());
if (value != null) {
return value;
} }
if (isNoLanguage(subtype)) {
return getKeyboardLayoutSetName(subtype).toUpperCase();
}
final Locale locale = getSubtypeLocale(subtype);
final String language = StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale);
if (AdditionalSubtype.isAdditionalSubtype(subtype)) {
return String.format("%s (%s)",
language, getKeyboardLayoutSetName(subtype).toUpperCase());
}
return StringUtils.toTitleCase(locale.getDisplayName(locale), locale);
}
// Get InputMethodSubtype's middle display name in its locale.
public static String getMiddleDisplayName(InputMethodSubtype subtype) {
if (isNoLanguage(subtype)) {
return getKeyboardLayoutSetName(subtype).toUpperCase();
}
final Locale locale = getSubtypeLocale(subtype);
return StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale);
}
// Get InputMethodSubtype's short display name in its locale.
public static String getShortDisplayName(InputMethodSubtype subtype) {
if (isNoLanguage(subtype)) {
return "";
}
final Locale locale = getSubtypeLocale(subtype);
return StringUtils.toTitleCase(locale.getLanguage(), locale);
}
public static boolean isNoLanguage(InputMethodSubtype subtype) {
final String localeString = subtype.getLocale();
return localeString.equals(NO_LANGUAGE);
}
public static Locale getSubtypeLocale(InputMethodSubtype subtype) {
final String localeString = subtype.getLocale();
return LocaleUtils.constructLocaleFromString(localeString);
} }
public static String getKeyboardLayoutSetName(InputMethodSubtype subtype) { public static String getKeyboardLayoutSetName(InputMethodSubtype subtype) {
@ -117,22 +113,7 @@ public class SubtypeLocale {
LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET); LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET);
// TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is // TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is
// fixed. // fixed.
if (keyboardLayoutSet == null) return DEFAULT_KEYBOARD_LAYOUT_SET; if (keyboardLayoutSet == null) return AdditionalSubtype.QWERTY;
final int pos = keyboardLayoutSet.indexOf(KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER); return keyboardLayoutSet;
return (pos > 0) ? keyboardLayoutSet.substring(0, pos) : keyboardLayoutSet;
}
public static String getKeyboardLayoutSetLocaleString(InputMethodSubtype subtype) {
final String keyboardLayoutSet = subtype.getExtraValueOf(
LatinIME.SUBTYPE_EXTRA_VALUE_KEYBOARD_LAYOUT_SET);
// TODO: Remove this null check when InputMethodManager.getCurrentInputMethodSubtype is
// fixed.
if (keyboardLayoutSet == null) return subtype.getLocale();
final int pos = keyboardLayoutSet.indexOf(KEYBOARD_LAYOUT_SET_LOCALE_DELIMITER);
return (pos > 0) ? keyboardLayoutSet.substring(pos + 1) : subtype.getLocale();
}
public static Locale getKeyboardLayoutSetLocale(InputMethodSubtype subtype) {
return LocaleUtils.constructLocaleFromString(getKeyboardLayoutSetLocaleString(subtype));
} }
} }

View File

@ -105,7 +105,7 @@ public class SubtypeSwitcher {
mCurrentSubtype = mImm.getCurrentInputMethodSubtype(); mCurrentSubtype = mImm.getCurrentInputMethodSubtype();
mAllEnabledSubtypesOfCurrentInputMethod = null; mAllEnabledSubtypesOfCurrentInputMethod = null;
mNoLanguageSubtype = SubtypeUtils.findSubtypeByLocaleAndKeyboardLayoutSet( mNoLanguageSubtype = SubtypeUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
service, SubtypeLocale.LOCALE_NO_LANGUAGE_QWERTY, "qwerty"); service, SubtypeLocale.LOCALE_NO_LANGUAGE, AdditionalSubtype.QWERTY);
final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
mIsNetworkConnected = (info != null && info.isConnected()); mIsNetworkConnected = (info != null && info.isConnected());
@ -135,7 +135,7 @@ public class SubtypeSwitcher {
mEnabledLanguagesOfCurrentInputMethod.clear(); mEnabledLanguagesOfCurrentInputMethod.clear();
mEnabledKeyboardSubtypesOfCurrentInputMethod.clear(); mEnabledKeyboardSubtypesOfCurrentInputMethod.clear();
for (InputMethodSubtype ims : mAllEnabledSubtypesOfCurrentInputMethod) { for (InputMethodSubtype ims : mAllEnabledSubtypesOfCurrentInputMethod) {
final String locale = SubtypeLocale.getKeyboardLayoutSetLocaleString(ims); final String locale = ims.getLocale();
final String mode = ims.getMode(); final String mode = ims.getMode();
mLocaleSplitter.setString(locale); mLocaleSplitter.setString(locale);
if (mLocaleSplitter.hasNext()) { if (mLocaleSplitter.hasNext()) {
@ -165,8 +165,7 @@ public class SubtypeSwitcher {
+ (mShortcutInputMethodInfo == null + (mShortcutInputMethodInfo == null
? "<null>" : mShortcutInputMethodInfo.getId()) + ", " ? "<null>" : mShortcutInputMethodInfo.getId()) + ", "
+ (mShortcutSubtype == null ? "<null>" : ( + (mShortcutSubtype == null ? "<null>" : (
SubtypeLocale.getKeyboardLayoutSetLocaleString(mShortcutSubtype) mShortcutSubtype.getLocale() + ", " + mShortcutSubtype.getMode())));
+ ", " + mShortcutSubtype.getMode())));
} }
// TODO: Update an icon for shortcut IME // TODO: Update an icon for shortcut IME
final Map<InputMethodInfo, List<InputMethodSubtype>> shortcuts = final Map<InputMethodInfo, List<InputMethodSubtype>> shortcuts =
@ -188,14 +187,13 @@ public class SubtypeSwitcher {
+ (mShortcutInputMethodInfo == null + (mShortcutInputMethodInfo == null
? "<null>" : mShortcutInputMethodInfo.getId()) + ", " ? "<null>" : mShortcutInputMethodInfo.getId()) + ", "
+ (mShortcutSubtype == null ? "<null>" : ( + (mShortcutSubtype == null ? "<null>" : (
SubtypeLocale.getKeyboardLayoutSetLocaleString(mShortcutSubtype) mShortcutSubtype.getLocale() + ", " + mShortcutSubtype.getMode())));
+ ", " + mShortcutSubtype.getMode())));
} }
} }
// Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function. // Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function.
public void updateSubtype(InputMethodSubtype newSubtype) { public void updateSubtype(InputMethodSubtype newSubtype) {
final String newLocale = SubtypeLocale.getKeyboardLayoutSetLocaleString(newSubtype); final String newLocale = newSubtype.getLocale();
final String newMode = newSubtype.getMode(); final String newMode = newSubtype.getMode();
final String oldMode = mCurrentSubtype.getMode(); final String oldMode = mCurrentSubtype.getMode();
if (DBG) { if (DBG) {
@ -335,7 +333,7 @@ public class SubtypeSwitcher {
} }
public boolean needsToDisplayLanguage(Locale keyboardLocale) { public boolean needsToDisplayLanguage(Locale keyboardLocale) {
if (keyboardLocale.equals(SubtypeLocale.LOCALE_NO_LANGUAGE_QWERTY)) { if (keyboardLocale.equals(SubtypeLocale.LOCALE_NO_LANGUAGE)) {
return true; return true;
} }
if (!keyboardLocale.equals(mInputLocale)) { if (!keyboardLocale.equals(mInputLocale)) {

View File

@ -143,6 +143,7 @@ public class SubtypeUtils {
return subtype; return subtype;
} }
} }
throw new RuntimeException("Can not find subtype of locale " + localeString); throw new RuntimeException("Can't find subtype for locale " + localeString
+ " and keyboard layout " + keyoardLayoutSet);
} }
} }

View File

@ -18,56 +18,35 @@ package com.android.inputmethod.latin;
import android.content.Context; import android.content.Context;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
public class SubtypeLocaleTests extends AndroidTestCase { public class SubtypeLocaleTests extends AndroidTestCase {
private static final Locale LOCALE_zz_QY = SubtypeLocale.LOCALE_NO_LANGUAGE_QWERTY; // Locale to subtypes list.
private static final Locale LOCALE_de_QY = private final ArrayList<InputMethodSubtype> mSubtypesList = new ArrayList<InputMethodSubtype>();
new Locale(Locale.GERMAN.getLanguage(), SubtypeLocale.QWERTY);
private ArrayList<InputMethodSubtype> mSubtypesList;
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
final Context context = getContext(); final Context context = getContext();
final String packageName = context.getApplicationInfo().packageName; InputMethodManagerCompatWrapper.init(context);
SubtypeLocale.init(context); SubtypeLocale.init(context);
final InputMethodManager imm = (InputMethodManager) context.getSystemService(
Context.INPUT_METHOD_SERVICE);
for (final InputMethodInfo imi : imm.getInputMethodList()) {
if (imi.getPackageName().equals(packageName)) {
mSubtypesList = new ArrayList<InputMethodSubtype>();
final int subtypeCount = imi.getSubtypeCount();
for (int i = 0; i < subtypeCount; i++) {
final InputMethodSubtype ims = imi.getSubtypeAt(i);
mSubtypesList.add(ims);
}
break;
}
}
assertNotNull("Can not find input method " + packageName, mSubtypesList);
assertTrue("Can not find keyboard subtype", mSubtypesList.size() > 0);
} }
public void testFullDisplayName() { public void testAllFullDisplayName() {
final StringBuilder messages = new StringBuilder(); final StringBuilder messages = new StringBuilder();
int failedCount = 0; int failedCount = 0;
for (final InputMethodSubtype subtype : mSubtypesList) { for (final InputMethodSubtype subtype : mSubtypesList) {
final Locale locale = SubtypeLocale.getKeyboardLayoutSetLocale(subtype); final Locale locale = SubtypeLocale.getSubtypeLocale(subtype);
if (locale.getLanguage().equals(SubtypeLocale.NO_LANGUAGE)) { if (SubtypeLocale.isNoLanguage(subtype)) {
// This is special language name for language agnostic usage. // This is special language name for language agnostic usage.
continue; continue;
} }
final String keyboardName = SubtypeLocale.getFullDisplayName(locale); final String keyboardName = SubtypeLocale.getFullDisplayName(subtype);
final String languageName = StringUtils.toTitleCase( final String languageName = StringUtils.toTitleCase(
locale.getDisplayLanguage(locale), locale); locale.getDisplayLanguage(locale), locale);
if (!keyboardName.contains(languageName)) { if (!keyboardName.contains(languageName)) {
@ -80,24 +59,16 @@ public class SubtypeLocaleTests extends AndroidTestCase {
assertEquals(messages.toString(), 0, failedCount); assertEquals(messages.toString(), 0, failedCount);
} }
public void testFullDisplayNameNoLanguage() { public void testAllMiddleDisplayName() {
assertEquals("zz_QY", "QWERTY", SubtypeLocale.getFullDisplayName(LOCALE_zz_QY));
final String de_QY = SubtypeLocale.getFullDisplayName(LOCALE_de_QY);
assertTrue("de_QY", de_QY.contains("(QWERTY"));
assertTrue("de_QY", de_QY.contains(Locale.GERMAN.getDisplayLanguage(Locale.GERMAN)));
}
public void testMiddleDisplayName() {
final StringBuilder messages = new StringBuilder(); final StringBuilder messages = new StringBuilder();
int failedCount = 0; int failedCount = 0;
for (final InputMethodSubtype subtype : mSubtypesList) { for (final InputMethodSubtype subtype : mSubtypesList) {
final Locale locale = SubtypeLocale.getKeyboardLayoutSetLocale(subtype); final Locale locale = SubtypeLocale.getSubtypeLocale(subtype);
if (locale.getLanguage().equals(SubtypeLocale.NO_LANGUAGE)) { if (SubtypeLocale.isNoLanguage(subtype)) {
// This is special language name for language agnostic usage. // This is special language name for language agnostic usage.
continue; continue;
} }
final String keyboardName = SubtypeLocale.getMiddleDisplayName(locale); final String keyboardName = SubtypeLocale.getMiddleDisplayName(subtype);
final String languageName = StringUtils.toTitleCase( final String languageName = StringUtils.toTitleCase(
locale.getDisplayLanguage(locale), locale); locale.getDisplayLanguage(locale), locale);
if (!keyboardName.equals(languageName)) { if (!keyboardName.equals(languageName)) {
@ -110,21 +81,12 @@ public class SubtypeLocaleTests extends AndroidTestCase {
assertEquals(messages.toString(), 0, failedCount); assertEquals(messages.toString(), 0, failedCount);
} }
public void testMiddleDisplayNameNoLanguage() { public void testAllShortDisplayName() {
assertEquals("zz_QY", "QWERTY", SubtypeLocale.getMiddleDisplayName(LOCALE_zz_QY));
assertEquals("de_QY", "Deutsch", SubtypeLocale.getMiddleDisplayName(LOCALE_de_QY));
}
public void testShortDisplayName() {
final StringBuilder messages = new StringBuilder(); final StringBuilder messages = new StringBuilder();
int failedCount = 0; int failedCount = 0;
for (final InputMethodSubtype subtype : mSubtypesList) { for (final InputMethodSubtype subtype : mSubtypesList) {
final Locale locale = SubtypeLocale.getKeyboardLayoutSetLocale(subtype); final Locale locale = SubtypeLocale.getSubtypeLocale(subtype);
if (locale.getCountry().equals(SubtypeLocale.QWERTY)) { final String keyboardName = SubtypeLocale.getShortDisplayName(subtype);
// This is special country code for QWERTY keyboard.
continue;
}
final String keyboardName = SubtypeLocale.getShortDisplayName(locale);
final String languageCode = StringUtils.toTitleCase(locale.getLanguage(), locale); final String languageCode = StringUtils.toTitleCase(locale.getLanguage(), locale);
if (!keyboardName.equals(languageCode)) { if (!keyboardName.equals(languageCode)) {
failedCount++; failedCount++;
@ -136,8 +98,99 @@ public class SubtypeLocaleTests extends AndroidTestCase {
assertEquals(messages.toString(), 0, failedCount); assertEquals(messages.toString(), 0, failedCount);
} }
public void testShortDisplayNameNoLanguage() { // Get InputMethodSubtype's display name in its locale.
assertEquals("zz_QY", "QY", SubtypeLocale.getShortDisplayName(LOCALE_zz_QY)); // additional
assertEquals("de_QY", "De", SubtypeLocale.getShortDisplayName(LOCALE_de_QY)); // locale layout Short Middle Full
// ------ ------ - ---- --------- -----------------
// en_US qwerty F En English English (US) exception
// en_GB qwerty F En English English (UK) 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 (QWERTZ)
// de qwerty T De Deutsch Deutsch (QWERTY)
// zz azerty T AZERTY AZERTY
public void testSampleSubtypes() {
final Context context = getContext();
final InputMethodSubtype EN_US = SubtypeUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
context, Locale.US, AdditionalSubtype.QWERTY);
final InputMethodSubtype EN_GB = SubtypeUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
context, Locale.UK, AdditionalSubtype.QWERTY);
final InputMethodSubtype FR = SubtypeUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
context, Locale.FRENCH, AdditionalSubtype.AZERTY);
final InputMethodSubtype FR_CA = SubtypeUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
context, Locale.CANADA_FRENCH, AdditionalSubtype.QWERTY);
final InputMethodSubtype DE = SubtypeUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
context, Locale.GERMAN, AdditionalSubtype.QWERTZ);
final InputMethodSubtype ZZ = SubtypeUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
context, SubtypeLocale.LOCALE_NO_LANGUAGE, AdditionalSubtype.QWERTY);
assertFalse(AdditionalSubtype.isAdditionalSubtype(EN_US));
assertFalse(AdditionalSubtype.isAdditionalSubtype(EN_GB));
assertFalse(AdditionalSubtype.isAdditionalSubtype(FR));
assertFalse(AdditionalSubtype.isAdditionalSubtype(FR_CA));
assertFalse(AdditionalSubtype.isAdditionalSubtype(DE));
assertFalse(AdditionalSubtype.isAdditionalSubtype(ZZ));
assertEquals("en_US", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(EN_US));
assertEquals("en_GB", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(EN_GB));
assertEquals("fr ", "azerty", SubtypeLocale.getKeyboardLayoutSetName(FR));
assertEquals("fr_CA", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(FR_CA));
assertEquals("de ", "qwertz", SubtypeLocale.getKeyboardLayoutSetName(DE));
assertEquals("zz ", "qwerty", SubtypeLocale.getKeyboardLayoutSetName(ZZ));
assertEquals("en_US", "English (US)", SubtypeLocale.getFullDisplayName(EN_US));
assertEquals("en_GB", "English (UK)", SubtypeLocale.getFullDisplayName(EN_GB));
assertEquals("fr ", "Français", SubtypeLocale.getFullDisplayName(FR));
assertEquals("fr_CA", "Français (Canada)", SubtypeLocale.getFullDisplayName(FR_CA));
assertEquals("de ", "Deutsch", SubtypeLocale.getFullDisplayName(DE));
assertEquals("zz ", "QWERTY", SubtypeLocale.getFullDisplayName(ZZ));
assertEquals("en_US", "English", SubtypeLocale.getMiddleDisplayName(EN_US));
assertEquals("en_GB", "English", SubtypeLocale.getMiddleDisplayName(EN_GB));
assertEquals("fr ", "Français", SubtypeLocale.getMiddleDisplayName(FR));
assertEquals("fr_CA", "Français", SubtypeLocale.getMiddleDisplayName(FR_CA));
assertEquals("de ", "Deutsch", SubtypeLocale.getMiddleDisplayName(DE));
assertEquals("zz ", "QWERTY", SubtypeLocale.getMiddleDisplayName(ZZ));
assertEquals("en_US", "En", SubtypeLocale.getShortDisplayName(EN_US));
assertEquals("en_GB", "En", SubtypeLocale.getShortDisplayName(EN_GB));
assertEquals("fr ", "Fr", SubtypeLocale.getShortDisplayName(FR));
assertEquals("fr_CA", "Fr", SubtypeLocale.getShortDisplayName(FR_CA));
assertEquals("de ", "De", SubtypeLocale.getShortDisplayName(DE));
assertEquals("zz ", "", SubtypeLocale.getShortDisplayName(ZZ));
}
public void testAdditionalSubtype() {
final InputMethodSubtype DE_QWERTY = AdditionalSubtype.createAddtionalSubtype(
Locale.GERMAN, AdditionalSubtype.QWERTY);
final InputMethodSubtype FR_QWERTZ = AdditionalSubtype.createAddtionalSubtype(
Locale.FRENCH, AdditionalSubtype.QWERTZ);
final InputMethodSubtype EN_AZERTY = AdditionalSubtype.createAddtionalSubtype(
Locale.ENGLISH, AdditionalSubtype.AZERTY);
final InputMethodSubtype ZZ_AZERTY = AdditionalSubtype.createAddtionalSubtype(
SubtypeLocale.LOCALE_NO_LANGUAGE, AdditionalSubtype.AZERTY);
assertTrue(AdditionalSubtype.isAdditionalSubtype(FR_QWERTZ));
assertTrue(AdditionalSubtype.isAdditionalSubtype(DE_QWERTY));
assertTrue(AdditionalSubtype.isAdditionalSubtype(EN_AZERTY));
assertTrue(AdditionalSubtype.isAdditionalSubtype(ZZ_AZERTY));
assertEquals("fr qwertz", "Français (QWERTZ)", SubtypeLocale.getFullDisplayName(FR_QWERTZ));
assertEquals("de qwerty", "Deutsch (QWERTY)", SubtypeLocale.getFullDisplayName(DE_QWERTY));
assertEquals("en azerty", "English (AZERTY)", SubtypeLocale.getFullDisplayName(EN_AZERTY));
assertEquals("zz azerty", "AZERTY", SubtypeLocale.getFullDisplayName(ZZ_AZERTY));
assertEquals("fr qwertz", "Français", SubtypeLocale.getMiddleDisplayName(FR_QWERTZ));
assertEquals("de qwerty", "Deutsch", SubtypeLocale.getMiddleDisplayName(DE_QWERTY));
assertEquals("en azerty", "English", SubtypeLocale.getMiddleDisplayName(EN_AZERTY));
assertEquals("zz azerty", "AZERTY", SubtypeLocale.getMiddleDisplayName(ZZ_AZERTY));
assertEquals("fr qwertz", "Fr", SubtypeLocale.getShortDisplayName(FR_QWERTZ));
assertEquals("de qwerty", "De", SubtypeLocale.getShortDisplayName(DE_QWERTY));
assertEquals("en azerty", "En", SubtypeLocale.getShortDisplayName(EN_AZERTY));
assertEquals("zz azerty", "", SubtypeLocale.getShortDisplayName(ZZ_AZERTY));
} }
} }