1ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok/* 2ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * Copyright (C) 2010 The Android Open Source Project 3ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * 4ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * Licensed under the Apache License, Version 2.0 (the "License"); 5ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * you may not use this file except in compliance with the License. 6ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * You may obtain a copy of the License at 7ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * 8ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * http://www.apache.org/licenses/LICENSE-2.0 9ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * 10ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * Unless required by applicable law or agreed to in writing, software 11ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * distributed under the License is distributed on an "AS IS" BASIS, 12ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * See the License for the specific language governing permissions and 14ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * limitations under the License. 15ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 16ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 17ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokpackage android.view.inputmethod; 18ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 197265d9bd6d80c5bedaa6de2b80f6619a301a07c8satokimport android.content.Context; 204f31353cb3b00c77c9420ef27ec949fd570ede3bsatokimport android.content.pm.ApplicationInfo; 21ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.os.Parcel; 22ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.os.Parcelable; 234f31353cb3b00c77c9420ef27ec949fd570ede3bsatokimport android.text.TextUtils; 249c4cc03a354922df08efacfc486ef0e80144d3easatokimport android.util.Slog; 25ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 267265d9bd6d80c5bedaa6de2b80f6619a301a07c8satokimport java.util.ArrayList; 27ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport java.util.Arrays; 289c4cc03a354922df08efacfc486ef0e80144d3easatokimport java.util.HashMap; 297265d9bd6d80c5bedaa6de2b80f6619a301a07c8satokimport java.util.HashSet; 3083e675f5ecf9f5615f3179ac102176faa3ae2596satokimport java.util.IllegalFormatException; 317265d9bd6d80c5bedaa6de2b80f6619a301a07c8satokimport java.util.List; 32a9778d4d442db65344e32318b1fd43ab54898389satokimport java.util.Locale; 33ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 34ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok/** 359a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * This class is used to specify meta information of a subtype contained in an input method editor 369a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * (IME). Subtype can describe locale (e.g. en_US, fr_FR...) and mode (e.g. voice, keyboard...), 379a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * and is used for IME switch and settings. The input method subtype allows the system to bring up 389a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * the specified subtype of the designated IME directly. 3944b75030931d9c65c9e495a86d11d71da59b4429satok * 409a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * <p>It should be defined in an XML resource file of the input method with the 415df0631003392c416c9617458dc2814f9eaec317Scott Main * <code><subtype></code> element, which resides within an {@code <input-method>} element. 425df0631003392c416c9617458dc2814f9eaec317Scott Main * For more information, see the guide to 435df0631003392c416c9617458dc2814f9eaec317Scott Main * <a href="{@docRoot}guide/topics/text/creating-input-method.html"> 4444b75030931d9c65c9e495a86d11d71da59b4429satok * Creating an Input Method</a>.</p> 455df0631003392c416c9617458dc2814f9eaec317Scott Main * 465df0631003392c416c9617458dc2814f9eaec317Scott Main * @see InputMethodInfo 475df0631003392c416c9617458dc2814f9eaec317Scott Main * 485df0631003392c416c9617458dc2814f9eaec317Scott Main * @attr ref android.R.styleable#InputMethod_Subtype_label 495df0631003392c416c9617458dc2814f9eaec317Scott Main * @attr ref android.R.styleable#InputMethod_Subtype_icon 505df0631003392c416c9617458dc2814f9eaec317Scott Main * @attr ref android.R.styleable#InputMethod_Subtype_imeSubtypeLocale 515df0631003392c416c9617458dc2814f9eaec317Scott Main * @attr ref android.R.styleable#InputMethod_Subtype_imeSubtypeMode 525df0631003392c416c9617458dc2814f9eaec317Scott Main * @attr ref android.R.styleable#InputMethod_Subtype_imeSubtypeExtraValue 535df0631003392c416c9617458dc2814f9eaec317Scott Main * @attr ref android.R.styleable#InputMethod_Subtype_isAuxiliary 545df0631003392c416c9617458dc2814f9eaec317Scott Main * @attr ref android.R.styleable#InputMethod_Subtype_overridesImplicitlyEnabledSubtype 555df0631003392c416c9617458dc2814f9eaec317Scott Main * @attr ref android.R.styleable#InputMethod_Subtype_subtypeId 565df0631003392c416c9617458dc2814f9eaec317Scott Main * @attr ref android.R.styleable#InputMethod_Subtype_isAsciiCapable 57ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 58ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokpublic final class InputMethodSubtype implements Parcelable { 599c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String TAG = InputMethodSubtype.class.getSimpleName(); 609c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String EXTRA_VALUE_PAIR_SEPARATOR = ","; 619c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String EXTRA_VALUE_KEY_VALUE_SEPARATOR = "="; 6283e675f5ecf9f5615f3179ac102176faa3ae2596satok // TODO: remove this 6383e675f5ecf9f5615f3179ac102176faa3ae2596satok private static final String EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME = 6483e675f5ecf9f5615f3179ac102176faa3ae2596satok "UntranslatableReplacementStringInSubtypeName"; 659c4cc03a354922df08efacfc486ef0e80144d3easatok 669aabb95781bee6a44684a6f6feb155e115d24983satok private final boolean mIsAuxiliary; 67a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok private final boolean mOverridesImplicitlyEnabledSubtype; 68dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private final boolean mIsAsciiCapable; 699aabb95781bee6a44684a6f6feb155e115d24983satok private final int mSubtypeHashCode; 70ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final int mSubtypeIconResId; 719aabb95781bee6a44684a6f6feb155e115d24983satok private final int mSubtypeNameResId; 72e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka private final int mSubtypeId; 73ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final String mSubtypeLocale; 749ef0283bdcd9534cc09ae37eb2b78771b95247b5satok private final String mSubtypeMode; 75ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final String mSubtypeExtraValue; 76e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok private volatile HashMap<String, String> mExtraValueHashMapCache; 77ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 78ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 79dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * InputMethodSubtypeBuilder is a builder class of InputMethodSubtype. 80dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * This class is designed to be used with 81dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * {@link android.view.inputmethod.InputMethodManager#setAdditionalInputMethodSubtypes}. 82dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * The developer needs to be aware of what each parameter means. 83dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 84dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public static class InputMethodSubtypeBuilder { 85dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 86dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param isAuxiliary should true when this subtype is auxiliary, false otherwise. 87dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * An auxiliary subtype has the following differences with a regular subtype: 88dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * - An auxiliary subtype cannot be chosen as the default IME in Settings. 89dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * - The framework will never switch to this subtype through 90dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}. 91dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * Note that the subtype will still be available in the IME switcher. 92dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * The intent is to allow for IMEs to specify they are meant to be invoked temporarily 93dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * in a one-shot way, and to return to the previous IME once finished (e.g. voice input). 94dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 95dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtypeBuilder setIsAuxiliary(boolean isAuxiliary) { 96dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mIsAuxiliary = isAuxiliary; 97dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return this; 98dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 99dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private boolean mIsAuxiliary = false; 100dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 101dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 102dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param overridesImplicitlyEnabledSubtype should be true if this subtype should be 103dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * enabled by default if no other subtypes in the IME are enabled explicitly. Note that a 104dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * subtype with this parameter set will not be shown in the list of subtypes in each IME's 105dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * subtype enabler. A canonical use of this would be for an IME to supply an "automatic" 106dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * subtype that adapts to the current system language. 107dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 108dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtypeBuilder setOverridesImplicitlyEnabledSubtype( 109dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka boolean overridesImplicitlyEnabledSubtype) { 110dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mOverridesImplicitlyEnabledSubtype = overridesImplicitlyEnabledSubtype; 111dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return this; 112dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 113dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private boolean mOverridesImplicitlyEnabledSubtype = false; 114dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 115dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 116dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param isAsciiCapable should be true if this subtype is ASCII capable. If the subtype 117dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * is ASCII capable, it should guarantee that the user can input ASCII characters with 118dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * this subtype. This is important because many password fields only allow 119dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * ASCII-characters. 120dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 121dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtypeBuilder setIsAsciiCapable(boolean isAsciiCapable) { 122dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mIsAsciiCapable = isAsciiCapable; 123dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return this; 124dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 125dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private boolean mIsAsciiCapable = false; 126dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 127dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 128dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param subtypeIconResId is a resource ID of the subtype icon drawable. 129dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 130dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtypeBuilder setSubtypeIconResId(int subtypeIconResId) { 131dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeIconResId = subtypeIconResId; 132dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return this; 133dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 134dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private int mSubtypeIconResId = 0; 135dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 136dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 137dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param subtypeNameResId is the resource ID of the subtype name string. 138dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * The string resource may have exactly one %s in it. If present, 139dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * the %s part will be replaced with the locale's display name by 140dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * the formatter. Please refer to {@link #getDisplayName} for details. 141dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 142dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtypeBuilder setSubtypeNameResId(int subtypeNameResId) { 143dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeNameResId = subtypeNameResId; 144dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return this; 145dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 146dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private int mSubtypeNameResId = 0; 147dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 148dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 149dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param subtypeId is the unique ID for this subtype. The input method framework keeps 150dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * track of enabled subtypes by ID. When the IME package gets upgraded, enabled IDs will 151dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * stay enabled even if other attributes are different. If the ID is unspecified or 0, 152dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * Arrays.hashCode(new Object[] {locale, mode, extraValue, 153dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * isAuxiliary, overridesImplicitlyEnabledSubtype}) will be used instead. 154dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 155dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtypeBuilder setSubtypeId(int subtypeId) { 156dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeId = subtypeId; 157dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return this; 158dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 159dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private int mSubtypeId = 0; 160dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 161dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 162dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param subtypeLocale is the locale supported by this subtype. 163dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 164dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtypeBuilder setSubtypeLocale(String subtypeLocale) { 165dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeLocale = subtypeLocale == null ? "" : subtypeLocale; 166dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return this; 167dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 168dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private String mSubtypeLocale = ""; 169dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 170dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 171dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param subtypeMode is the mode supported by this subtype. 172dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 173dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtypeBuilder setSubtypeMode(String subtypeMode) { 174dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeMode = subtypeMode == null ? "" : subtypeMode; 175dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return this; 176dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 177dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private String mSubtypeMode = ""; 178dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 179dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param subtypeExtraValue is the extra value of the subtype. This string is free-form, 180dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * but the API supplies tools to deal with a key-value comma-separated list; see 181dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * {@link #containsExtraValueKey} and {@link #getExtraValueOf}. 182dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 183dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtypeBuilder setSubtypeExtraValue(String subtypeExtraValue) { 184dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeExtraValue = subtypeExtraValue == null ? "" : subtypeExtraValue; 185dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return this; 186dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 187dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private String mSubtypeExtraValue = ""; 188dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 189dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 190dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @return InputMethodSubtype using parameters in this InputMethodSubtypeBuilder. 191dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 192dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public InputMethodSubtype build() { 193dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return new InputMethodSubtype(this); 194dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 195dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 196dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 197dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private static InputMethodSubtypeBuilder getBuilder(int nameId, int iconId, String locale, 198dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka String mode, String extraValue, boolean isAuxiliary, 199dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka boolean overridesImplicitlyEnabledSubtype, int id, boolean isAsciiCapable) { 200dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka final InputMethodSubtypeBuilder builder = new InputMethodSubtypeBuilder(); 201dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka builder.mSubtypeNameResId = nameId; 202dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka builder.mSubtypeIconResId = iconId; 203dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka builder.mSubtypeLocale = locale; 204dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka builder.mSubtypeMode = mode; 205dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka builder.mSubtypeExtraValue = extraValue; 206dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka builder.mIsAuxiliary = isAuxiliary; 207dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka builder.mOverridesImplicitlyEnabledSubtype = overridesImplicitlyEnabledSubtype; 208dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka builder.mSubtypeId = id; 209dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka builder.mIsAsciiCapable = isAsciiCapable; 210dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return builder; 211dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 212dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 213dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 214e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * Constructor with no subtype ID specified. 215dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @deprecated use {@link InputMethodSubtypeBuilder} instead. 216dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * Arguments for this constructor have the same meanings as 217dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * {@link InputMethodSubtype#InputMethodSubtype(int, int, String, String, String, boolean, 218dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * boolean, int)} except "id". 2199aabb95781bee6a44684a6f6feb155e115d24983satok */ 220a9778d4d442db65344e32318b1fd43ab54898389satok public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, 221a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) { 222e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka this(nameId, iconId, locale, mode, extraValue, isAuxiliary, 223e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka overridesImplicitlyEnabledSubtype, 0); 224e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka } 225e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka 226e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka /** 227e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * Constructor. 228dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @deprecated use {@link InputMethodSubtypeBuilder} instead. 229dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * "isAsciiCapable" is "false" in this constructor. 230e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param nameId Resource ID of the subtype name string. The string resource may have exactly 231e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * one %s in it. If there is, the %s part will be replaced with the locale's display name by 232e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * the formatter. Please refer to {@link #getDisplayName} for details. 233e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param iconId Resource ID of the subtype icon drawable. 234e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param locale The locale supported by the subtype 235e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param mode The mode supported by the subtype 236e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param extraValue The extra value of the subtype. This string is free-form, but the API 237e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * supplies tools to deal with a key-value comma-separated list; see 238e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * {@link #containsExtraValueKey} and {@link #getExtraValueOf}. 239e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param isAuxiliary true when this subtype is auxiliary, false otherwise. An auxiliary 240e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * subtype will not be shown in the list of enabled IMEs for choosing the current IME in 241e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * the Settings even when this subtype is enabled. Please note that this subtype will still 242e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * be shown in the list of IMEs in the IME switcher to allow the user to tentatively switch 243e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * to this subtype while an IME is shown. The framework will never switch the current IME to 244e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * this subtype by {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}. 245e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * The intent of having this flag is to allow for IMEs that are invoked in a one-shot way as 246e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * auxiliary input mode, and return to the previous IME once it is finished (e.g. voice input). 247e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param overridesImplicitlyEnabledSubtype true when this subtype should be enabled by default 248e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * if no other subtypes in the IME are enabled explicitly. Note that a subtype with this 249e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * parameter being true will not be shown in the list of subtypes in each IME's subtype enabler. 250e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * Having an "automatic" subtype is an example use of this flag. 251e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param id The unique ID for the subtype. The input method framework keeps track of enabled 252e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * subtypes by ID. When the IME package gets upgraded, enabled IDs will stay enabled even if 253e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * other attributes are different. If the ID is unspecified or 0, 254e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * Arrays.hashCode(new Object[] {locale, mode, extraValue, 255e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * isAuxiliary, overridesImplicitlyEnabledSubtype}) will be used instead. 256e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka */ 257e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, 258e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype, int id) { 259dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka this(getBuilder(nameId, iconId, locale, mode, extraValue, isAuxiliary, 260dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka overridesImplicitlyEnabledSubtype, id, false)); 261dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 262dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 263dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 264dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * Constructor. 265dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @param builder Builder for InputMethodSubtype 266dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 267dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka private InputMethodSubtype(InputMethodSubtypeBuilder builder) { 268dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeNameResId = builder.mSubtypeNameResId; 269dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeIconResId = builder.mSubtypeIconResId; 270dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeLocale = builder.mSubtypeLocale; 271dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeMode = builder.mSubtypeMode; 272dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeExtraValue = builder.mSubtypeExtraValue; 273dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mIsAuxiliary = builder.mIsAuxiliary; 274dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mOverridesImplicitlyEnabledSubtype = builder.mOverridesImplicitlyEnabledSubtype; 275dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeId = builder.mSubtypeId; 276dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mIsAsciiCapable = builder.mIsAsciiCapable; 277e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka // If hashCode() of this subtype is 0 and you want to specify it as an id of this subtype, 278e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka // just specify 0 as this subtype's id. Then, this subtype's id is treated as 0. 279dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeHashCode = mSubtypeId != 0 ? mSubtypeId : hashCodeInternal(mSubtypeLocale, 280dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mSubtypeMode, mSubtypeExtraValue, mIsAuxiliary, mOverridesImplicitlyEnabledSubtype, 281dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mIsAsciiCapable); 282ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 283ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 284ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodSubtype(Parcel source) { 285af4bf400abab86baee44dacbcdf13444d06ee46esatok String s; 286ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeNameResId = source.readInt(); 287ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeIconResId = source.readInt(); 288af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 289af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeLocale = s != null ? s : ""; 290af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 291af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeMode = s != null ? s : ""; 292af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 293af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeExtraValue = s != null ? s : ""; 2949aabb95781bee6a44684a6f6feb155e115d24983satok mIsAuxiliary = (source.readInt() == 1); 295a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok mOverridesImplicitlyEnabledSubtype = (source.readInt() == 1); 296e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka mSubtypeHashCode = source.readInt(); 297e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka mSubtypeId = source.readInt(); 298dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka mIsAsciiCapable = (source.readInt() == 1); 299ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 300ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 301ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 3029a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return Resource ID of the subtype name string. 303ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 304ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int getNameResId() { 305ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeNameResId; 306ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 307ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 308ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 3099a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return Resource ID of the subtype icon drawable. 310ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 311ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int getIconResId() { 312ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeIconResId; 313ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 314ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 315ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 3169a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The locale of the subtype. This method returns the "locale" string parameter passed 3179a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * to the constructor. 318ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 319ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public String getLocale() { 320ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeLocale; 321ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 322ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 323ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 3249a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The mode of the subtype. 325ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 3269ef0283bdcd9534cc09ae37eb2b78771b95247b5satok public String getMode() { 3279ef0283bdcd9534cc09ae37eb2b78771b95247b5satok return mSubtypeMode; 328ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 329ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 330ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 3319a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The extra value of the subtype. 332ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 333ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public String getExtraValue() { 334ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeExtraValue; 335ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 336ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 3379aabb95781bee6a44684a6f6feb155e115d24983satok /** 3389a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return true if this subtype is auxiliary, false otherwise. An auxiliary subtype will not be 3399a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * shown in the list of enabled IMEs for choosing the current IME in the Settings even when this 3409a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * subtype is enabled. Please note that this subtype will still be shown in the list of IMEs in 3419a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * the IME switcher to allow the user to tentatively switch to this subtype while an IME is 3429a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * shown. The framework will never switch the current IME to this subtype by 3439a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}. 3449a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * The intent of having this flag is to allow for IMEs that are invoked in a one-shot way as 3459a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * auxiliary input mode, and return to the previous IME once it is finished (e.g. voice input). 3469aabb95781bee6a44684a6f6feb155e115d24983satok */ 3479aabb95781bee6a44684a6f6feb155e115d24983satok public boolean isAuxiliary() { 3489aabb95781bee6a44684a6f6feb155e115d24983satok return mIsAuxiliary; 3499aabb95781bee6a44684a6f6feb155e115d24983satok } 3509aabb95781bee6a44684a6f6feb155e115d24983satok 3514f31353cb3b00c77c9420ef27ec949fd570ede3bsatok /** 3529a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return true when this subtype will be enabled by default if no other subtypes in the IME 3539a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * are enabled explicitly, false otherwise. Note that a subtype with this method returning true 3549a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * will not be shown in the list of subtypes in each IME's subtype enabler. Having an 3559a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * "automatic" subtype is an example use of this flag. 356a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok */ 357a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok public boolean overridesImplicitlyEnabledSubtype() { 358a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok return mOverridesImplicitlyEnabledSubtype; 359a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok } 360a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok 361a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok /** 362dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * @return true if this subtype is Ascii capable, false otherwise. If the subtype is ASCII 363dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * capable, it should guarantee that the user can input ASCII characters with this subtype. 364dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka * This is important because many password fields only allow ASCII-characters. 365dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka */ 366dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka public boolean isAsciiCapable() { 367dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka return mIsAsciiCapable; 368dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka } 369dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka 370dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka /** 3714f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @param context Context will be used for getting Locale and PackageManager. 3724f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @param packageName The package name of the IME 3734f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @param appInfo The application info of the IME 3744f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @return a display name for this subtype. The string resource of the label (mSubtypeNameResId) 3759a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * may have exactly one %s in it. If there is, the %s part will be replaced with the locale's 3769a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * display name by the formatter. If there is not, this method returns the string specified by 3779a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * mSubtypeNameResId. If mSubtypeNameResId is not specified (== 0), it's up to the framework to 3789a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * generate an appropriate display name. 3794f31353cb3b00c77c9420ef27ec949fd570ede3bsatok */ 3804f31353cb3b00c77c9420ef27ec949fd570ede3bsatok public CharSequence getDisplayName( 3814f31353cb3b00c77c9420ef27ec949fd570ede3bsatok Context context, String packageName, ApplicationInfo appInfo) { 382a9778d4d442db65344e32318b1fd43ab54898389satok final Locale locale = constructLocaleFromString(mSubtypeLocale); 383a9778d4d442db65344e32318b1fd43ab54898389satok final String localeStr = locale != null ? locale.getDisplayName() : mSubtypeLocale; 3844f31353cb3b00c77c9420ef27ec949fd570ede3bsatok if (mSubtypeNameResId == 0) { 385a9778d4d442db65344e32318b1fd43ab54898389satok return localeStr; 3864f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } 38735412d63ee59b99a43725e466c5deef52b2324dfsatok final CharSequence subtypeName = context.getPackageManager().getText( 38835412d63ee59b99a43725e466c5deef52b2324dfsatok packageName, mSubtypeNameResId, appInfo); 3894f31353cb3b00c77c9420ef27ec949fd570ede3bsatok if (!TextUtils.isEmpty(subtypeName)) { 39083e675f5ecf9f5615f3179ac102176faa3ae2596satok final String replacementString = 39183e675f5ecf9f5615f3179ac102176faa3ae2596satok containsExtraValueKey(EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME) 39283e675f5ecf9f5615f3179ac102176faa3ae2596satok ? getExtraValueOf(EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME) 39383e675f5ecf9f5615f3179ac102176faa3ae2596satok : localeStr; 39483e675f5ecf9f5615f3179ac102176faa3ae2596satok try { 39583e675f5ecf9f5615f3179ac102176faa3ae2596satok return String.format( 39683e675f5ecf9f5615f3179ac102176faa3ae2596satok subtypeName.toString(), replacementString != null ? replacementString : ""); 39783e675f5ecf9f5615f3179ac102176faa3ae2596satok } catch (IllegalFormatException e) { 39883e675f5ecf9f5615f3179ac102176faa3ae2596satok Slog.w(TAG, "Found illegal format in subtype name("+ subtypeName + "): " + e); 39983e675f5ecf9f5615f3179ac102176faa3ae2596satok return ""; 40083e675f5ecf9f5615f3179ac102176faa3ae2596satok } 4014f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } else { 402a9778d4d442db65344e32318b1fd43ab54898389satok return localeStr; 4034f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } 4044f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } 4054f31353cb3b00c77c9420ef27ec949fd570ede3bsatok 4069c4cc03a354922df08efacfc486ef0e80144d3easatok private HashMap<String, String> getExtraValueHashMap() { 4079c4cc03a354922df08efacfc486ef0e80144d3easatok if (mExtraValueHashMapCache == null) { 408e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok synchronized(this) { 409e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok if (mExtraValueHashMapCache == null) { 410e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok mExtraValueHashMapCache = new HashMap<String, String>(); 411e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR); 412e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok final int N = pairs.length; 413e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok for (int i = 0; i < N; ++i) { 414e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR); 415e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok if (pair.length == 1) { 416e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok mExtraValueHashMapCache.put(pair[0], null); 417e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok } else if (pair.length > 1) { 418e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok if (pair.length > 2) { 419e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok Slog.w(TAG, "ExtraValue has two or more '='s"); 420e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok } 421e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok mExtraValueHashMapCache.put(pair[0], pair[1]); 422e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok } 4239c4cc03a354922df08efacfc486ef0e80144d3easatok } 4249c4cc03a354922df08efacfc486ef0e80144d3easatok } 4259c4cc03a354922df08efacfc486ef0e80144d3easatok } 4269c4cc03a354922df08efacfc486ef0e80144d3easatok } 4279c4cc03a354922df08efacfc486ef0e80144d3easatok return mExtraValueHashMapCache; 4289c4cc03a354922df08efacfc486ef0e80144d3easatok } 4299c4cc03a354922df08efacfc486ef0e80144d3easatok 4309c4cc03a354922df08efacfc486ef0e80144d3easatok /** 4319c4cc03a354922df08efacfc486ef0e80144d3easatok * The string of ExtraValue in subtype should be defined as follows: 4329c4cc03a354922df08efacfc486ef0e80144d3easatok * example: key0,key1=value1,key2,key3,key4=value4 4339a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param key The key of extra value 4349a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The subtype contains specified the extra value 4359c4cc03a354922df08efacfc486ef0e80144d3easatok */ 4369c4cc03a354922df08efacfc486ef0e80144d3easatok public boolean containsExtraValueKey(String key) { 4379c4cc03a354922df08efacfc486ef0e80144d3easatok return getExtraValueHashMap().containsKey(key); 4389c4cc03a354922df08efacfc486ef0e80144d3easatok } 4399c4cc03a354922df08efacfc486ef0e80144d3easatok 4409c4cc03a354922df08efacfc486ef0e80144d3easatok /** 4419c4cc03a354922df08efacfc486ef0e80144d3easatok * The string of ExtraValue in subtype should be defined as follows: 4429c4cc03a354922df08efacfc486ef0e80144d3easatok * example: key0,key1=value1,key2,key3,key4=value4 4439a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param key The key of extra value 4449a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The value of the specified key 4459c4cc03a354922df08efacfc486ef0e80144d3easatok */ 4469c4cc03a354922df08efacfc486ef0e80144d3easatok public String getExtraValueOf(String key) { 4479c4cc03a354922df08efacfc486ef0e80144d3easatok return getExtraValueHashMap().get(key); 4489c4cc03a354922df08efacfc486ef0e80144d3easatok } 4499c4cc03a354922df08efacfc486ef0e80144d3easatok 450ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok @Override 451ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int hashCode() { 452ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeHashCode; 453ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 454ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 455ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok @Override 456ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public boolean equals(Object o) { 457ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok if (o instanceof InputMethodSubtype) { 458ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodSubtype subtype = (InputMethodSubtype) o; 459e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka if (subtype.mSubtypeId != 0 || mSubtypeId != 0) { 460e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka return (subtype.hashCode() == hashCode()); 461e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka } 462af4bf400abab86baee44dacbcdf13444d06ee46esatok return (subtype.hashCode() == hashCode()) 463ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok && (subtype.getLocale().equals(getLocale())) 46492a6f3018ace5aa2d5ea74e7d378b6960b5e053eSatoshi Kataoka && (subtype.getMode().equals(getMode())) 465a9778d4d442db65344e32318b1fd43ab54898389satok && (subtype.getExtraValue().equals(getExtraValue())) 466dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka && (subtype.isAuxiliary() == isAuxiliary()) 46792a6f3018ace5aa2d5ea74e7d378b6960b5e053eSatoshi Kataoka && (subtype.overridesImplicitlyEnabledSubtype() 46892a6f3018ace5aa2d5ea74e7d378b6960b5e053eSatoshi Kataoka == overridesImplicitlyEnabledSubtype()) 469dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka && (subtype.isAsciiCapable() == isAsciiCapable()); 470ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 471ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return false; 472ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 473ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 4749aabb95781bee6a44684a6f6feb155e115d24983satok @Override 475ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int describeContents() { 476ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return 0; 477ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 478ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 4799aabb95781bee6a44684a6f6feb155e115d24983satok @Override 480ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public void writeToParcel(Parcel dest, int parcelableFlags) { 481ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeInt(mSubtypeNameResId); 482ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeInt(mSubtypeIconResId); 483ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeString(mSubtypeLocale); 4849ef0283bdcd9534cc09ae37eb2b78771b95247b5satok dest.writeString(mSubtypeMode); 485ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeString(mSubtypeExtraValue); 4869aabb95781bee6a44684a6f6feb155e115d24983satok dest.writeInt(mIsAuxiliary ? 1 : 0); 487a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok dest.writeInt(mOverridesImplicitlyEnabledSubtype ? 1 : 0); 488e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka dest.writeInt(mSubtypeHashCode); 489e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka dest.writeInt(mSubtypeId); 490dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka dest.writeInt(mIsAsciiCapable ? 1 : 0); 491ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 492ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 493ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public static final Parcelable.Creator<InputMethodSubtype> CREATOR 494ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok = new Parcelable.Creator<InputMethodSubtype>() { 4959aabb95781bee6a44684a6f6feb155e115d24983satok @Override 496ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public InputMethodSubtype createFromParcel(Parcel source) { 497ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return new InputMethodSubtype(source); 498ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 499ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 5009aabb95781bee6a44684a6f6feb155e115d24983satok @Override 501ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public InputMethodSubtype[] newArray(int size) { 502ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return new InputMethodSubtype[size]; 503ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 504ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok }; 505ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 506a9778d4d442db65344e32318b1fd43ab54898389satok private static Locale constructLocaleFromString(String localeStr) { 507a9778d4d442db65344e32318b1fd43ab54898389satok if (TextUtils.isEmpty(localeStr)) 508a9778d4d442db65344e32318b1fd43ab54898389satok return null; 509a9778d4d442db65344e32318b1fd43ab54898389satok String[] localeParams = localeStr.split("_", 3); 510a9778d4d442db65344e32318b1fd43ab54898389satok // The length of localeStr is guaranteed to always return a 1 <= value <= 3 511a9778d4d442db65344e32318b1fd43ab54898389satok // because localeStr is not empty. 512a9778d4d442db65344e32318b1fd43ab54898389satok if (localeParams.length == 1) { 513a9778d4d442db65344e32318b1fd43ab54898389satok return new Locale(localeParams[0]); 514a9778d4d442db65344e32318b1fd43ab54898389satok } else if (localeParams.length == 2) { 515a9778d4d442db65344e32318b1fd43ab54898389satok return new Locale(localeParams[0], localeParams[1]); 516a9778d4d442db65344e32318b1fd43ab54898389satok } else if (localeParams.length == 3) { 517a9778d4d442db65344e32318b1fd43ab54898389satok return new Locale(localeParams[0], localeParams[1], localeParams[2]); 518a9778d4d442db65344e32318b1fd43ab54898389satok } 519a9778d4d442db65344e32318b1fd43ab54898389satok return null; 520a9778d4d442db65344e32318b1fd43ab54898389satok } 521a9778d4d442db65344e32318b1fd43ab54898389satok 522a9778d4d442db65344e32318b1fd43ab54898389satok private static int hashCodeInternal(String locale, String mode, String extraValue, 523dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype, 524dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka boolean isAsciiCapable) { 5255fd5aa3d066fc12c92b5b6541d85ac243556223fSatoshi Kataoka // CAVEAT: Must revisit how to compute needsToCalculateCompatibleHashCode when a new 5265fd5aa3d066fc12c92b5b6541d85ac243556223fSatoshi Kataoka // attribute is added in order to avoid enabled subtypes being unexpectedly disabled. 5275fd5aa3d066fc12c92b5b6541d85ac243556223fSatoshi Kataoka final boolean needsToCalculateCompatibleHashCode = !isAsciiCapable; 5285fd5aa3d066fc12c92b5b6541d85ac243556223fSatoshi Kataoka if (needsToCalculateCompatibleHashCode) { 5295fd5aa3d066fc12c92b5b6541d85ac243556223fSatoshi Kataoka return Arrays.hashCode(new Object[] {locale, mode, extraValue, isAuxiliary, 5305fd5aa3d066fc12c92b5b6541d85ac243556223fSatoshi Kataoka overridesImplicitlyEnabledSubtype}); 5315fd5aa3d066fc12c92b5b6541d85ac243556223fSatoshi Kataoka } 532a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok return Arrays.hashCode(new Object[] {locale, mode, extraValue, isAuxiliary, 533dc8abf6cee0bcf44e2cad8155f0c151105d46471Satoshi Kataoka overridesImplicitlyEnabledSubtype, isAsciiCapable}); 534ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 5357265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok 5367265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok /** 5377265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * Sort the list of InputMethodSubtype 5387265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param context Context will be used for getting localized strings from IME 5397265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param flags Flags for the sort order 5407265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param imi InputMethodInfo of which subtypes are subject to be sorted 5417265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param subtypeList List of InputMethodSubtype which will be sorted 5427265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @return Sorted list of subtypes 5437265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @hide 5447265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok */ 5457265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok public static List<InputMethodSubtype> sort(Context context, int flags, InputMethodInfo imi, 5467265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok List<InputMethodSubtype> subtypeList) { 5477265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok if (imi == null) return subtypeList; 5487265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok final HashSet<InputMethodSubtype> inputSubtypesSet = new HashSet<InputMethodSubtype>( 5497265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok subtypeList); 5507265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok final ArrayList<InputMethodSubtype> sortedList = new ArrayList<InputMethodSubtype>(); 5517265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok int N = imi.getSubtypeCount(); 5527265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok for (int i = 0; i < N; ++i) { 5537265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok InputMethodSubtype subtype = imi.getSubtypeAt(i); 5547265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok if (inputSubtypesSet.contains(subtype)) { 5557265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok sortedList.add(subtype); 5567265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok inputSubtypesSet.remove(subtype); 5577265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 5587265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 5597265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok // If subtypes in inputSubtypesSet remain, that means these subtypes are not 5607265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok // contained in imi, so the remaining subtypes will be appended. 5617265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok for (InputMethodSubtype subtype: inputSubtypesSet) { 5627265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok sortedList.add(subtype); 5637265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 5647265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok return sortedList; 5657265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 566af4bf400abab86baee44dacbcdf13444d06ee46esatok} 567