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 419a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * <code><subtype></code> element. For more information, see the guide to 4244b75030931d9c65c9e495a86d11d71da59b4429satok * <a href="{@docRoot}resources/articles/creating-input-method.html"> 4344b75030931d9c65c9e495a86d11d71da59b4429satok * Creating an Input Method</a>.</p> 44ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 45ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokpublic final class InputMethodSubtype implements Parcelable { 469c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String TAG = InputMethodSubtype.class.getSimpleName(); 479c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String EXTRA_VALUE_PAIR_SEPARATOR = ","; 489c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String EXTRA_VALUE_KEY_VALUE_SEPARATOR = "="; 4983e675f5ecf9f5615f3179ac102176faa3ae2596satok // TODO: remove this 5083e675f5ecf9f5615f3179ac102176faa3ae2596satok private static final String EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME = 5183e675f5ecf9f5615f3179ac102176faa3ae2596satok "UntranslatableReplacementStringInSubtypeName"; 529c4cc03a354922df08efacfc486ef0e80144d3easatok 539aabb95781bee6a44684a6f6feb155e115d24983satok private final boolean mIsAuxiliary; 54a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok private final boolean mOverridesImplicitlyEnabledSubtype; 559aabb95781bee6a44684a6f6feb155e115d24983satok private final int mSubtypeHashCode; 56ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final int mSubtypeIconResId; 579aabb95781bee6a44684a6f6feb155e115d24983satok private final int mSubtypeNameResId; 58e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka private final int mSubtypeId; 59ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final String mSubtypeLocale; 609ef0283bdcd9534cc09ae37eb2b78771b95247b5satok private final String mSubtypeMode; 61ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final String mSubtypeExtraValue; 62e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok private volatile HashMap<String, String> mExtraValueHashMapCache; 63ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 64ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 65e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * Constructor with no subtype ID specified, overridesImplicitlyEnabledSubtype not specified. 669a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param nameId Resource ID of the subtype name string. The string resource may have exactly 679a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * one %s in it. If there is, the %s part will be replaced with the locale's display name by 689a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * the formatter. Please refer to {@link #getDisplayName} for details. 699a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param iconId Resource ID of the subtype icon drawable. 70ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param locale The locale supported by the subtype 71a9778d4d442db65344e32318b1fd43ab54898389satok * @param mode The mode supported by the subtype 729a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param extraValue The extra value of the subtype. This string is free-form, but the API 739a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * supplies tools to deal with a key-value comma-separated list; see 749a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * {@link #containsExtraValueKey} and {@link #getExtraValueOf}. 759a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param isAuxiliary true when this subtype is auxiliary, false otherwise. An auxiliary 769a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * subtype will not be shown in the list of enabled IMEs for choosing the current IME in 779a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * the Settings even when this subtype is enabled. Please note that this subtype will still 789a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * be shown in the list of IMEs in the IME switcher to allow the user to tentatively switch 799a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * to this subtype while an IME is shown. The framework will never switch the current IME to 809a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * this subtype by {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}. 819a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * The intent of having this flag is to allow for IMEs that are invoked in a one-shot way as 829a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * auxiliary input mode, and return to the previous IME once it is finished (e.g. voice input). 833889e492bcad3c6f565d30da4e02d0dcde09d084satok * @hide 84ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 85a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, 86a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok boolean isAuxiliary) { 878b83a7297680911d666546ee0b3a464514dc2c27Ken Wakasa this(nameId, iconId, locale, mode, extraValue, isAuxiliary, false); 889aabb95781bee6a44684a6f6feb155e115d24983satok } 899aabb95781bee6a44684a6f6feb155e115d24983satok 909aabb95781bee6a44684a6f6feb155e115d24983satok /** 91e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * Constructor with no subtype ID specified. 929a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param nameId Resource ID of the subtype name string. The string resource may have exactly 939a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * one %s in it. If there is, the %s part will be replaced with the locale's display name by 949a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * the formatter. Please refer to {@link #getDisplayName} for details. 959a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param iconId Resource ID of the subtype icon drawable. 969aabb95781bee6a44684a6f6feb155e115d24983satok * @param locale The locale supported by the subtype 97a9778d4d442db65344e32318b1fd43ab54898389satok * @param mode The mode supported by the subtype 989a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param extraValue The extra value of the subtype. This string is free-form, but the API 999a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * supplies tools to deal with a key-value comma-separated list; see 1009a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * {@link #containsExtraValueKey} and {@link #getExtraValueOf}. 1019a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param isAuxiliary true when this subtype is auxiliary, false otherwise. An auxiliary 1029a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * subtype will not be shown in the list of enabled IMEs for choosing the current IME in 1039a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * the Settings even when this subtype is enabled. Please note that this subtype will still 1049a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * be shown in the list of IMEs in the IME switcher to allow the user to tentatively switch 1059a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * to this subtype while an IME is shown. The framework will never switch the current IME to 1069a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * this subtype by {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}. 1079a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * The intent of having this flag is to allow for IMEs that are invoked in a one-shot way as 1089a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * auxiliary input mode, and return to the previous IME once it is finished (e.g. voice input). 1099a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param overridesImplicitlyEnabledSubtype true when this subtype should be enabled by default 1109a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * if no other subtypes in the IME are enabled explicitly. Note that a subtype with this 1119a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * parameter being true will not be shown in the list of subtypes in each IME's subtype enabler. 1129a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * Having an "automatic" subtype is an example use of this flag. 1139aabb95781bee6a44684a6f6feb155e115d24983satok */ 114a9778d4d442db65344e32318b1fd43ab54898389satok public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, 115a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) { 116e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka this(nameId, iconId, locale, mode, extraValue, isAuxiliary, 117e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka overridesImplicitlyEnabledSubtype, 0); 118e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka } 119e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka 120e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka /** 121e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * Constructor. 122e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param nameId Resource ID of the subtype name string. The string resource may have exactly 123e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * one %s in it. If there is, the %s part will be replaced with the locale's display name by 124e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * the formatter. Please refer to {@link #getDisplayName} for details. 125e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param iconId Resource ID of the subtype icon drawable. 126e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param locale The locale supported by the subtype 127e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param mode The mode supported by the subtype 128e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param extraValue The extra value of the subtype. This string is free-form, but the API 129e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * supplies tools to deal with a key-value comma-separated list; see 130e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * {@link #containsExtraValueKey} and {@link #getExtraValueOf}. 131e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param isAuxiliary true when this subtype is auxiliary, false otherwise. An auxiliary 132e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * subtype will not be shown in the list of enabled IMEs for choosing the current IME in 133e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * the Settings even when this subtype is enabled. Please note that this subtype will still 134e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * be shown in the list of IMEs in the IME switcher to allow the user to tentatively switch 135e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * to this subtype while an IME is shown. The framework will never switch the current IME to 136e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * this subtype by {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}. 137e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * The intent of having this flag is to allow for IMEs that are invoked in a one-shot way as 138e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * auxiliary input mode, and return to the previous IME once it is finished (e.g. voice input). 139e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param overridesImplicitlyEnabledSubtype true when this subtype should be enabled by default 140e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * if no other subtypes in the IME are enabled explicitly. Note that a subtype with this 141e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * parameter being true will not be shown in the list of subtypes in each IME's subtype enabler. 142e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * Having an "automatic" subtype is an example use of this flag. 143e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * @param id The unique ID for the subtype. The input method framework keeps track of enabled 144e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * subtypes by ID. When the IME package gets upgraded, enabled IDs will stay enabled even if 145e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * other attributes are different. If the ID is unspecified or 0, 146e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * Arrays.hashCode(new Object[] {locale, mode, extraValue, 147e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka * isAuxiliary, overridesImplicitlyEnabledSubtype}) will be used instead. 148e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka */ 149e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, 150e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype, int id) { 151ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeNameResId = nameId; 152ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeIconResId = iconId; 153af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeLocale = locale != null ? locale : ""; 154af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeMode = mode != null ? mode : ""; 155af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeExtraValue = extraValue != null ? extraValue : ""; 1569aabb95781bee6a44684a6f6feb155e115d24983satok mIsAuxiliary = isAuxiliary; 157a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok mOverridesImplicitlyEnabledSubtype = overridesImplicitlyEnabledSubtype; 158e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka // If hashCode() of this subtype is 0 and you want to specify it as an id of this subtype, 159e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka // just specify 0 as this subtype's id. Then, this subtype's id is treated as 0. 160e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka mSubtypeHashCode = id != 0 ? id : hashCodeInternal(mSubtypeLocale, mSubtypeMode, 161e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka mSubtypeExtraValue, mIsAuxiliary, mOverridesImplicitlyEnabledSubtype); 162e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka mSubtypeId = id; 163ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 164ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 165ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodSubtype(Parcel source) { 166af4bf400abab86baee44dacbcdf13444d06ee46esatok String s; 167ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeNameResId = source.readInt(); 168ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeIconResId = source.readInt(); 169af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 170af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeLocale = s != null ? s : ""; 171af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 172af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeMode = s != null ? s : ""; 173af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 174af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeExtraValue = s != null ? s : ""; 1759aabb95781bee6a44684a6f6feb155e115d24983satok mIsAuxiliary = (source.readInt() == 1); 176a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok mOverridesImplicitlyEnabledSubtype = (source.readInt() == 1); 177e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka mSubtypeHashCode = source.readInt(); 178e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka mSubtypeId = source.readInt(); 179ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 180ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 181ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 1829a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return Resource ID of the subtype name string. 183ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 184ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int getNameResId() { 185ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeNameResId; 186ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 187ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 188ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 1899a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return Resource ID of the subtype icon drawable. 190ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 191ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int getIconResId() { 192ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeIconResId; 193ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 194ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 195ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 1969a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The locale of the subtype. This method returns the "locale" string parameter passed 1979a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * to the constructor. 198ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 199ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public String getLocale() { 200ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeLocale; 201ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 202ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 203ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 2049a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The mode of the subtype. 205ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 2069ef0283bdcd9534cc09ae37eb2b78771b95247b5satok public String getMode() { 2079ef0283bdcd9534cc09ae37eb2b78771b95247b5satok return mSubtypeMode; 208ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 209ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 210ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 2119a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The extra value of the subtype. 212ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 213ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public String getExtraValue() { 214ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeExtraValue; 215ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 216ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 2179aabb95781bee6a44684a6f6feb155e115d24983satok /** 2189a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return true if this subtype is auxiliary, false otherwise. An auxiliary subtype will not be 2199a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * shown in the list of enabled IMEs for choosing the current IME in the Settings even when this 2209a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * subtype is enabled. Please note that this subtype will still be shown in the list of IMEs in 2219a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * the IME switcher to allow the user to tentatively switch to this subtype while an IME is 2229a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * shown. The framework will never switch the current IME to this subtype by 2239a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * {@link android.view.inputmethod.InputMethodManager#switchToLastInputMethod}. 2249a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * The intent of having this flag is to allow for IMEs that are invoked in a one-shot way as 2259a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * auxiliary input mode, and return to the previous IME once it is finished (e.g. voice input). 2269aabb95781bee6a44684a6f6feb155e115d24983satok */ 2279aabb95781bee6a44684a6f6feb155e115d24983satok public boolean isAuxiliary() { 2289aabb95781bee6a44684a6f6feb155e115d24983satok return mIsAuxiliary; 2299aabb95781bee6a44684a6f6feb155e115d24983satok } 2309aabb95781bee6a44684a6f6feb155e115d24983satok 2314f31353cb3b00c77c9420ef27ec949fd570ede3bsatok /** 2329a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return true when this subtype will be enabled by default if no other subtypes in the IME 2339a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * are enabled explicitly, false otherwise. Note that a subtype with this method returning true 2349a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * will not be shown in the list of subtypes in each IME's subtype enabler. Having an 2359a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * "automatic" subtype is an example use of this flag. 236a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok */ 237a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok public boolean overridesImplicitlyEnabledSubtype() { 238a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok return mOverridesImplicitlyEnabledSubtype; 239a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok } 240a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok 241a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok /** 2424f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @param context Context will be used for getting Locale and PackageManager. 2434f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @param packageName The package name of the IME 2444f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @param appInfo The application info of the IME 2454f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @return a display name for this subtype. The string resource of the label (mSubtypeNameResId) 2469a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * may have exactly one %s in it. If there is, the %s part will be replaced with the locale's 2479a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * display name by the formatter. If there is not, this method returns the string specified by 2489a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * mSubtypeNameResId. If mSubtypeNameResId is not specified (== 0), it's up to the framework to 2499a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * generate an appropriate display name. 2504f31353cb3b00c77c9420ef27ec949fd570ede3bsatok */ 2514f31353cb3b00c77c9420ef27ec949fd570ede3bsatok public CharSequence getDisplayName( 2524f31353cb3b00c77c9420ef27ec949fd570ede3bsatok Context context, String packageName, ApplicationInfo appInfo) { 253a9778d4d442db65344e32318b1fd43ab54898389satok final Locale locale = constructLocaleFromString(mSubtypeLocale); 254a9778d4d442db65344e32318b1fd43ab54898389satok final String localeStr = locale != null ? locale.getDisplayName() : mSubtypeLocale; 2554f31353cb3b00c77c9420ef27ec949fd570ede3bsatok if (mSubtypeNameResId == 0) { 256a9778d4d442db65344e32318b1fd43ab54898389satok return localeStr; 2574f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } 25835412d63ee59b99a43725e466c5deef52b2324dfsatok final CharSequence subtypeName = context.getPackageManager().getText( 25935412d63ee59b99a43725e466c5deef52b2324dfsatok packageName, mSubtypeNameResId, appInfo); 2604f31353cb3b00c77c9420ef27ec949fd570ede3bsatok if (!TextUtils.isEmpty(subtypeName)) { 26183e675f5ecf9f5615f3179ac102176faa3ae2596satok final String replacementString = 26283e675f5ecf9f5615f3179ac102176faa3ae2596satok containsExtraValueKey(EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME) 26383e675f5ecf9f5615f3179ac102176faa3ae2596satok ? getExtraValueOf(EXTRA_KEY_UNTRANSLATABLE_STRING_IN_SUBTYPE_NAME) 26483e675f5ecf9f5615f3179ac102176faa3ae2596satok : localeStr; 26583e675f5ecf9f5615f3179ac102176faa3ae2596satok try { 26683e675f5ecf9f5615f3179ac102176faa3ae2596satok return String.format( 26783e675f5ecf9f5615f3179ac102176faa3ae2596satok subtypeName.toString(), replacementString != null ? replacementString : ""); 26883e675f5ecf9f5615f3179ac102176faa3ae2596satok } catch (IllegalFormatException e) { 26983e675f5ecf9f5615f3179ac102176faa3ae2596satok Slog.w(TAG, "Found illegal format in subtype name("+ subtypeName + "): " + e); 27083e675f5ecf9f5615f3179ac102176faa3ae2596satok return ""; 27183e675f5ecf9f5615f3179ac102176faa3ae2596satok } 2724f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } else { 273a9778d4d442db65344e32318b1fd43ab54898389satok return localeStr; 2744f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } 2754f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } 2764f31353cb3b00c77c9420ef27ec949fd570ede3bsatok 2779c4cc03a354922df08efacfc486ef0e80144d3easatok private HashMap<String, String> getExtraValueHashMap() { 2789c4cc03a354922df08efacfc486ef0e80144d3easatok if (mExtraValueHashMapCache == null) { 279e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok synchronized(this) { 280e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok if (mExtraValueHashMapCache == null) { 281e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok mExtraValueHashMapCache = new HashMap<String, String>(); 282e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR); 283e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok final int N = pairs.length; 284e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok for (int i = 0; i < N; ++i) { 285e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR); 286e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok if (pair.length == 1) { 287e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok mExtraValueHashMapCache.put(pair[0], null); 288e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok } else if (pair.length > 1) { 289e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok if (pair.length > 2) { 290e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok Slog.w(TAG, "ExtraValue has two or more '='s"); 291e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok } 292e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok mExtraValueHashMapCache.put(pair[0], pair[1]); 293e52eb4e289bf8d7b04582803b0d0f9ab7399c1afsatok } 2949c4cc03a354922df08efacfc486ef0e80144d3easatok } 2959c4cc03a354922df08efacfc486ef0e80144d3easatok } 2969c4cc03a354922df08efacfc486ef0e80144d3easatok } 2979c4cc03a354922df08efacfc486ef0e80144d3easatok } 2989c4cc03a354922df08efacfc486ef0e80144d3easatok return mExtraValueHashMapCache; 2999c4cc03a354922df08efacfc486ef0e80144d3easatok } 3009c4cc03a354922df08efacfc486ef0e80144d3easatok 3019c4cc03a354922df08efacfc486ef0e80144d3easatok /** 3029c4cc03a354922df08efacfc486ef0e80144d3easatok * The string of ExtraValue in subtype should be defined as follows: 3039c4cc03a354922df08efacfc486ef0e80144d3easatok * example: key0,key1=value1,key2,key3,key4=value4 3049a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param key The key of extra value 3059a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The subtype contains specified the extra value 3069c4cc03a354922df08efacfc486ef0e80144d3easatok */ 3079c4cc03a354922df08efacfc486ef0e80144d3easatok public boolean containsExtraValueKey(String key) { 3089c4cc03a354922df08efacfc486ef0e80144d3easatok return getExtraValueHashMap().containsKey(key); 3099c4cc03a354922df08efacfc486ef0e80144d3easatok } 3109c4cc03a354922df08efacfc486ef0e80144d3easatok 3119c4cc03a354922df08efacfc486ef0e80144d3easatok /** 3129c4cc03a354922df08efacfc486ef0e80144d3easatok * The string of ExtraValue in subtype should be defined as follows: 3139c4cc03a354922df08efacfc486ef0e80144d3easatok * example: key0,key1=value1,key2,key3,key4=value4 3149a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @param key The key of extra value 3159a74476c0ab1aaa59e9aed6ecdeba43d5b4d3495Ken Wakasa * @return The value of the specified key 3169c4cc03a354922df08efacfc486ef0e80144d3easatok */ 3179c4cc03a354922df08efacfc486ef0e80144d3easatok public String getExtraValueOf(String key) { 3189c4cc03a354922df08efacfc486ef0e80144d3easatok return getExtraValueHashMap().get(key); 3199c4cc03a354922df08efacfc486ef0e80144d3easatok } 3209c4cc03a354922df08efacfc486ef0e80144d3easatok 321ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok @Override 322ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int hashCode() { 323ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeHashCode; 324ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 325ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 326ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok @Override 327ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public boolean equals(Object o) { 328ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok if (o instanceof InputMethodSubtype) { 329ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodSubtype subtype = (InputMethodSubtype) o; 330e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka if (subtype.mSubtypeId != 0 || mSubtypeId != 0) { 331e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka return (subtype.hashCode() == hashCode()); 332e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka } 333af4bf400abab86baee44dacbcdf13444d06ee46esatok return (subtype.hashCode() == hashCode()) 334af4bf400abab86baee44dacbcdf13444d06ee46esatok && (subtype.getNameResId() == getNameResId()) 335af4bf400abab86baee44dacbcdf13444d06ee46esatok && (subtype.getMode().equals(getMode())) 336ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok && (subtype.getIconResId() == getIconResId()) 337ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok && (subtype.getLocale().equals(getLocale())) 338a9778d4d442db65344e32318b1fd43ab54898389satok && (subtype.getExtraValue().equals(getExtraValue())) 339a9778d4d442db65344e32318b1fd43ab54898389satok && (subtype.isAuxiliary() == isAuxiliary()); 340ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 341ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return false; 342ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 343ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 3449aabb95781bee6a44684a6f6feb155e115d24983satok @Override 345ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int describeContents() { 346ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return 0; 347ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 348ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 3499aabb95781bee6a44684a6f6feb155e115d24983satok @Override 350ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public void writeToParcel(Parcel dest, int parcelableFlags) { 351ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeInt(mSubtypeNameResId); 352ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeInt(mSubtypeIconResId); 353ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeString(mSubtypeLocale); 3549ef0283bdcd9534cc09ae37eb2b78771b95247b5satok dest.writeString(mSubtypeMode); 355ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeString(mSubtypeExtraValue); 3569aabb95781bee6a44684a6f6feb155e115d24983satok dest.writeInt(mIsAuxiliary ? 1 : 0); 357a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok dest.writeInt(mOverridesImplicitlyEnabledSubtype ? 1 : 0); 358e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka dest.writeInt(mSubtypeHashCode); 359e62e6d8731ab1e02c1632ebc011792d07b902af8Satoshi Kataoka dest.writeInt(mSubtypeId); 360ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 361ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 362ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public static final Parcelable.Creator<InputMethodSubtype> CREATOR 363ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok = new Parcelable.Creator<InputMethodSubtype>() { 3649aabb95781bee6a44684a6f6feb155e115d24983satok @Override 365ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public InputMethodSubtype createFromParcel(Parcel source) { 366ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return new InputMethodSubtype(source); 367ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 368ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 3699aabb95781bee6a44684a6f6feb155e115d24983satok @Override 370ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public InputMethodSubtype[] newArray(int size) { 371ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return new InputMethodSubtype[size]; 372ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 373ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok }; 374ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 375a9778d4d442db65344e32318b1fd43ab54898389satok private static Locale constructLocaleFromString(String localeStr) { 376a9778d4d442db65344e32318b1fd43ab54898389satok if (TextUtils.isEmpty(localeStr)) 377a9778d4d442db65344e32318b1fd43ab54898389satok return null; 378a9778d4d442db65344e32318b1fd43ab54898389satok String[] localeParams = localeStr.split("_", 3); 379a9778d4d442db65344e32318b1fd43ab54898389satok // The length of localeStr is guaranteed to always return a 1 <= value <= 3 380a9778d4d442db65344e32318b1fd43ab54898389satok // because localeStr is not empty. 381a9778d4d442db65344e32318b1fd43ab54898389satok if (localeParams.length == 1) { 382a9778d4d442db65344e32318b1fd43ab54898389satok return new Locale(localeParams[0]); 383a9778d4d442db65344e32318b1fd43ab54898389satok } else if (localeParams.length == 2) { 384a9778d4d442db65344e32318b1fd43ab54898389satok return new Locale(localeParams[0], localeParams[1]); 385a9778d4d442db65344e32318b1fd43ab54898389satok } else if (localeParams.length == 3) { 386a9778d4d442db65344e32318b1fd43ab54898389satok return new Locale(localeParams[0], localeParams[1], localeParams[2]); 387a9778d4d442db65344e32318b1fd43ab54898389satok } 388a9778d4d442db65344e32318b1fd43ab54898389satok return null; 389a9778d4d442db65344e32318b1fd43ab54898389satok } 390a9778d4d442db65344e32318b1fd43ab54898389satok 391a9778d4d442db65344e32318b1fd43ab54898389satok private static int hashCodeInternal(String locale, String mode, String extraValue, 392a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) { 393a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok return Arrays.hashCode(new Object[] {locale, mode, extraValue, isAuxiliary, 394a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok overridesImplicitlyEnabledSubtype}); 395ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 3967265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok 3977265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok /** 3987265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * Sort the list of InputMethodSubtype 3997265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param context Context will be used for getting localized strings from IME 4007265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param flags Flags for the sort order 4017265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param imi InputMethodInfo of which subtypes are subject to be sorted 4027265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param subtypeList List of InputMethodSubtype which will be sorted 4037265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @return Sorted list of subtypes 4047265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @hide 4057265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok */ 4067265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok public static List<InputMethodSubtype> sort(Context context, int flags, InputMethodInfo imi, 4077265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok List<InputMethodSubtype> subtypeList) { 4087265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok if (imi == null) return subtypeList; 4097265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok final HashSet<InputMethodSubtype> inputSubtypesSet = new HashSet<InputMethodSubtype>( 4107265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok subtypeList); 4117265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok final ArrayList<InputMethodSubtype> sortedList = new ArrayList<InputMethodSubtype>(); 4127265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok int N = imi.getSubtypeCount(); 4137265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok for (int i = 0; i < N; ++i) { 4147265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok InputMethodSubtype subtype = imi.getSubtypeAt(i); 4157265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok if (inputSubtypesSet.contains(subtype)) { 4167265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok sortedList.add(subtype); 4177265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok inputSubtypesSet.remove(subtype); 4187265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 4197265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 4207265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok // If subtypes in inputSubtypesSet remain, that means these subtypes are not 4217265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok // contained in imi, so the remaining subtypes will be appended. 4227265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok for (InputMethodSubtype subtype: inputSubtypesSet) { 4237265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok sortedList.add(subtype); 4247265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 4257265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok return sortedList; 4267265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 427af4bf400abab86baee44dacbcdf13444d06ee46esatok} 428