InputMethodSubtype.java revision a86f5e448cd6d29340ca6cbe509bc6384bc0d711
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; 307265d9bd6d80c5bedaa6de2b80f6619a301a07c8satokimport java.util.List; 31a9778d4d442db65344e32318b1fd43ab54898389satokimport java.util.Locale; 32ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 33ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok/** 34e31e9424554d5f032f578830556913b4ba78f7f9Ken Wakasa * This class is used to specify meta information of a subtype contained in an input method. 35e31e9424554d5f032f578830556913b4ba78f7f9Ken Wakasa * Subtype can describe locale (e.g. en_US, fr_FR...) and mode (e.g. voice, keyboard...), and is 36e31e9424554d5f032f578830556913b4ba78f7f9Ken Wakasa * used for IME switch and settings. The input method subtype allows the system to bring up the 37e31e9424554d5f032f578830556913b4ba78f7f9Ken Wakasa * specified subtype of the designated input method directly. 38ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 39ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokpublic final class InputMethodSubtype implements Parcelable { 409c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String TAG = InputMethodSubtype.class.getSimpleName(); 419c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String EXTRA_VALUE_PAIR_SEPARATOR = ","; 429c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String EXTRA_VALUE_KEY_VALUE_SEPARATOR = "="; 439c4cc03a354922df08efacfc486ef0e80144d3easatok 449aabb95781bee6a44684a6f6feb155e115d24983satok private final boolean mIsAuxiliary; 45a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok private final boolean mOverridesImplicitlyEnabledSubtype; 469aabb95781bee6a44684a6f6feb155e115d24983satok private final int mSubtypeHashCode; 47ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final int mSubtypeIconResId; 489aabb95781bee6a44684a6f6feb155e115d24983satok private final int mSubtypeNameResId; 49ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final String mSubtypeLocale; 509ef0283bdcd9534cc09ae37eb2b78771b95247b5satok private final String mSubtypeMode; 51ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final String mSubtypeExtraValue; 529c4cc03a354922df08efacfc486ef0e80144d3easatok private HashMap<String, String> mExtraValueHashMapCache; 53ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 54ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 55ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * Constructor 56ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param nameId The name of the subtype 57ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param iconId The icon of the subtype 58ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param locale The locale supported by the subtype 59a9778d4d442db65344e32318b1fd43ab54898389satok * @param mode The mode supported by the subtype 60ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param extraValue The extra value of the subtype 61a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok * @param isAuxiliary true when this subtype is one shot subtype. 623889e492bcad3c6f565d30da4e02d0dcde09d084satok * @hide 63ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 64a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, 65a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok boolean isAuxiliary) { 66a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok this(nameId, iconId, locale, mode, extraValue, false, false); 679aabb95781bee6a44684a6f6feb155e115d24983satok } 689aabb95781bee6a44684a6f6feb155e115d24983satok 699aabb95781bee6a44684a6f6feb155e115d24983satok /** 709aabb95781bee6a44684a6f6feb155e115d24983satok * Constructor 719aabb95781bee6a44684a6f6feb155e115d24983satok * @param nameId The name of the subtype 729aabb95781bee6a44684a6f6feb155e115d24983satok * @param iconId The icon of the subtype 739aabb95781bee6a44684a6f6feb155e115d24983satok * @param locale The locale supported by the subtype 74a9778d4d442db65344e32318b1fd43ab54898389satok * @param mode The mode supported by the subtype 759aabb95781bee6a44684a6f6feb155e115d24983satok * @param extraValue The extra value of the subtype 769aabb95781bee6a44684a6f6feb155e115d24983satok * @param isAuxiliary true when this subtype is one shot subtype. 77a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok * @param overridesImplicitlyEnabledSubtype true when this subtype should be selected by default 78a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok * if no other subtypes are selected explicitly. Note that a subtype with this parameter being 79a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok * true will not be shown in the subtypes list. 809aabb95781bee6a44684a6f6feb155e115d24983satok */ 81a9778d4d442db65344e32318b1fd43ab54898389satok public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, 82a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) { 83ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeNameResId = nameId; 84ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeIconResId = iconId; 85af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeLocale = locale != null ? locale : ""; 86af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeMode = mode != null ? mode : ""; 87af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeExtraValue = extraValue != null ? extraValue : ""; 889aabb95781bee6a44684a6f6feb155e115d24983satok mIsAuxiliary = isAuxiliary; 89a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok mOverridesImplicitlyEnabledSubtype = overridesImplicitlyEnabledSubtype; 90a9778d4d442db65344e32318b1fd43ab54898389satok mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeMode, mSubtypeExtraValue, 91a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok mIsAuxiliary, mOverridesImplicitlyEnabledSubtype); 92ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 93ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 94ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodSubtype(Parcel source) { 95af4bf400abab86baee44dacbcdf13444d06ee46esatok String s; 96ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeNameResId = source.readInt(); 97ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeIconResId = source.readInt(); 98af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 99af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeLocale = s != null ? s : ""; 100af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 101af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeMode = s != null ? s : ""; 102af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 103af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeExtraValue = s != null ? s : ""; 1049aabb95781bee6a44684a6f6feb155e115d24983satok mIsAuxiliary = (source.readInt() == 1); 105a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok mOverridesImplicitlyEnabledSubtype = (source.readInt() == 1); 106a9778d4d442db65344e32318b1fd43ab54898389satok mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeMode, mSubtypeExtraValue, 107a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok mIsAuxiliary, mOverridesImplicitlyEnabledSubtype); 108ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 109ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 110ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 111ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the name of the subtype 112ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 113ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int getNameResId() { 114ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeNameResId; 115ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 116ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 117ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 118ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the icon of the subtype 119ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 120ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int getIconResId() { 121ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeIconResId; 122ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 123ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 124ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 125ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the locale of the subtype 126ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 127ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public String getLocale() { 128ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeLocale; 129ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 130ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 131ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 132ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the mode of the subtype 133ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 1349ef0283bdcd9534cc09ae37eb2b78771b95247b5satok public String getMode() { 1359ef0283bdcd9534cc09ae37eb2b78771b95247b5satok return mSubtypeMode; 136ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 137ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 138ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 139ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the extra value of the subtype 140ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 141ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public String getExtraValue() { 142ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeExtraValue; 143ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 144ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 1459aabb95781bee6a44684a6f6feb155e115d24983satok /** 1469aabb95781bee6a44684a6f6feb155e115d24983satok * @return true if this subtype is one shot subtype. One shot subtype will not be shown in the 1479aabb95781bee6a44684a6f6feb155e115d24983satok * ime switch list when this subtype is implicitly enabled. The framework will never 1489aabb95781bee6a44684a6f6feb155e115d24983satok * switch the current ime to this subtype by switchToLastInputMethod in InputMethodManager. 1499aabb95781bee6a44684a6f6feb155e115d24983satok */ 1509aabb95781bee6a44684a6f6feb155e115d24983satok public boolean isAuxiliary() { 1519aabb95781bee6a44684a6f6feb155e115d24983satok return mIsAuxiliary; 1529aabb95781bee6a44684a6f6feb155e115d24983satok } 1539aabb95781bee6a44684a6f6feb155e115d24983satok 1544f31353cb3b00c77c9420ef27ec949fd570ede3bsatok /** 155a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok * @return true when this subtype is selected by default if no other subtypes are selected 156a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok * explicitly. Note that a subtype that returns true will not be shown in the subtypes list. 157a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok */ 158a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok public boolean overridesImplicitlyEnabledSubtype() { 159a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok return mOverridesImplicitlyEnabledSubtype; 160a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok } 161a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok 162a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok /** 1634f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @param context Context will be used for getting Locale and PackageManager. 1644f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @param packageName The package name of the IME 1654f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @param appInfo The application info of the IME 1664f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * @return a display name for this subtype. The string resource of the label (mSubtypeNameResId) 1674f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * can have only one %s in it. If there is, the %s part will be replaced with the locale's 1684f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * display name by the formatter. If there is not, this method simply returns the string 1694f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * specified by mSubtypeNameResId. If mSubtypeNameResId is not specified (== 0), it's up to the 1704f31353cb3b00c77c9420ef27ec949fd570ede3bsatok * framework to generate an appropriate display name. 1714f31353cb3b00c77c9420ef27ec949fd570ede3bsatok */ 1724f31353cb3b00c77c9420ef27ec949fd570ede3bsatok public CharSequence getDisplayName( 1734f31353cb3b00c77c9420ef27ec949fd570ede3bsatok Context context, String packageName, ApplicationInfo appInfo) { 174a9778d4d442db65344e32318b1fd43ab54898389satok final Locale locale = constructLocaleFromString(mSubtypeLocale); 175a9778d4d442db65344e32318b1fd43ab54898389satok final String localeStr = locale != null ? locale.getDisplayName() : mSubtypeLocale; 1764f31353cb3b00c77c9420ef27ec949fd570ede3bsatok if (mSubtypeNameResId == 0) { 177a9778d4d442db65344e32318b1fd43ab54898389satok return localeStr; 1784f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } 17935412d63ee59b99a43725e466c5deef52b2324dfsatok final CharSequence subtypeName = context.getPackageManager().getText( 18035412d63ee59b99a43725e466c5deef52b2324dfsatok packageName, mSubtypeNameResId, appInfo); 1814f31353cb3b00c77c9420ef27ec949fd570ede3bsatok if (!TextUtils.isEmpty(subtypeName)) { 18235412d63ee59b99a43725e466c5deef52b2324dfsatok return String.format(subtypeName.toString(), localeStr); 1834f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } else { 184a9778d4d442db65344e32318b1fd43ab54898389satok return localeStr; 1854f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } 1864f31353cb3b00c77c9420ef27ec949fd570ede3bsatok } 1874f31353cb3b00c77c9420ef27ec949fd570ede3bsatok 1889c4cc03a354922df08efacfc486ef0e80144d3easatok private HashMap<String, String> getExtraValueHashMap() { 1899c4cc03a354922df08efacfc486ef0e80144d3easatok if (mExtraValueHashMapCache == null) { 1909c4cc03a354922df08efacfc486ef0e80144d3easatok mExtraValueHashMapCache = new HashMap<String, String>(); 1919c4cc03a354922df08efacfc486ef0e80144d3easatok final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR); 1929c4cc03a354922df08efacfc486ef0e80144d3easatok final int N = pairs.length; 1939c4cc03a354922df08efacfc486ef0e80144d3easatok for (int i = 0; i < N; ++i) { 1949c4cc03a354922df08efacfc486ef0e80144d3easatok final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR); 1959c4cc03a354922df08efacfc486ef0e80144d3easatok if (pair.length == 1) { 1969c4cc03a354922df08efacfc486ef0e80144d3easatok mExtraValueHashMapCache.put(pair[0], null); 1979c4cc03a354922df08efacfc486ef0e80144d3easatok } else if (pair.length > 1) { 1989c4cc03a354922df08efacfc486ef0e80144d3easatok if (pair.length > 2) { 1999c4cc03a354922df08efacfc486ef0e80144d3easatok Slog.w(TAG, "ExtraValue has two or more '='s"); 2009c4cc03a354922df08efacfc486ef0e80144d3easatok } 2019c4cc03a354922df08efacfc486ef0e80144d3easatok mExtraValueHashMapCache.put(pair[0], pair[1]); 2029c4cc03a354922df08efacfc486ef0e80144d3easatok } 2039c4cc03a354922df08efacfc486ef0e80144d3easatok } 2049c4cc03a354922df08efacfc486ef0e80144d3easatok } 2059c4cc03a354922df08efacfc486ef0e80144d3easatok return mExtraValueHashMapCache; 2069c4cc03a354922df08efacfc486ef0e80144d3easatok } 2079c4cc03a354922df08efacfc486ef0e80144d3easatok 2089c4cc03a354922df08efacfc486ef0e80144d3easatok /** 2099c4cc03a354922df08efacfc486ef0e80144d3easatok * The string of ExtraValue in subtype should be defined as follows: 2109c4cc03a354922df08efacfc486ef0e80144d3easatok * example: key0,key1=value1,key2,key3,key4=value4 2119c4cc03a354922df08efacfc486ef0e80144d3easatok * @param key the key of extra value 2129c4cc03a354922df08efacfc486ef0e80144d3easatok * @return the subtype contains specified the extra value 2139c4cc03a354922df08efacfc486ef0e80144d3easatok */ 2149c4cc03a354922df08efacfc486ef0e80144d3easatok public boolean containsExtraValueKey(String key) { 2159c4cc03a354922df08efacfc486ef0e80144d3easatok return getExtraValueHashMap().containsKey(key); 2169c4cc03a354922df08efacfc486ef0e80144d3easatok } 2179c4cc03a354922df08efacfc486ef0e80144d3easatok 2189c4cc03a354922df08efacfc486ef0e80144d3easatok /** 2199c4cc03a354922df08efacfc486ef0e80144d3easatok * The string of ExtraValue in subtype should be defined as follows: 2209c4cc03a354922df08efacfc486ef0e80144d3easatok * example: key0,key1=value1,key2,key3,key4=value4 2219c4cc03a354922df08efacfc486ef0e80144d3easatok * @param key the key of extra value 2229c4cc03a354922df08efacfc486ef0e80144d3easatok * @return the value of the specified key 2239c4cc03a354922df08efacfc486ef0e80144d3easatok */ 2249c4cc03a354922df08efacfc486ef0e80144d3easatok public String getExtraValueOf(String key) { 2259c4cc03a354922df08efacfc486ef0e80144d3easatok return getExtraValueHashMap().get(key); 2269c4cc03a354922df08efacfc486ef0e80144d3easatok } 2279c4cc03a354922df08efacfc486ef0e80144d3easatok 228ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok @Override 229ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int hashCode() { 230ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeHashCode; 231ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 232ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 233ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok @Override 234ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public boolean equals(Object o) { 235ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok if (o instanceof InputMethodSubtype) { 236ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodSubtype subtype = (InputMethodSubtype) o; 237af4bf400abab86baee44dacbcdf13444d06ee46esatok return (subtype.hashCode() == hashCode()) 238af4bf400abab86baee44dacbcdf13444d06ee46esatok && (subtype.getNameResId() == getNameResId()) 239af4bf400abab86baee44dacbcdf13444d06ee46esatok && (subtype.getMode().equals(getMode())) 240ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok && (subtype.getIconResId() == getIconResId()) 241ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok && (subtype.getLocale().equals(getLocale())) 242a9778d4d442db65344e32318b1fd43ab54898389satok && (subtype.getExtraValue().equals(getExtraValue())) 243a9778d4d442db65344e32318b1fd43ab54898389satok && (subtype.isAuxiliary() == isAuxiliary()); 244ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 245ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return false; 246ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 247ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 2489aabb95781bee6a44684a6f6feb155e115d24983satok @Override 249ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int describeContents() { 250ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return 0; 251ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 252ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 2539aabb95781bee6a44684a6f6feb155e115d24983satok @Override 254ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public void writeToParcel(Parcel dest, int parcelableFlags) { 255ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeInt(mSubtypeNameResId); 256ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeInt(mSubtypeIconResId); 257ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeString(mSubtypeLocale); 2589ef0283bdcd9534cc09ae37eb2b78771b95247b5satok dest.writeString(mSubtypeMode); 259ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeString(mSubtypeExtraValue); 2609aabb95781bee6a44684a6f6feb155e115d24983satok dest.writeInt(mIsAuxiliary ? 1 : 0); 261a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok dest.writeInt(mOverridesImplicitlyEnabledSubtype ? 1 : 0); 262ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 263ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 264ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public static final Parcelable.Creator<InputMethodSubtype> CREATOR 265ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok = new Parcelable.Creator<InputMethodSubtype>() { 2669aabb95781bee6a44684a6f6feb155e115d24983satok @Override 267ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public InputMethodSubtype createFromParcel(Parcel source) { 268ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return new InputMethodSubtype(source); 269ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 270ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 2719aabb95781bee6a44684a6f6feb155e115d24983satok @Override 272ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public InputMethodSubtype[] newArray(int size) { 273ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return new InputMethodSubtype[size]; 274ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 275ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok }; 276ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 277a9778d4d442db65344e32318b1fd43ab54898389satok private static Locale constructLocaleFromString(String localeStr) { 278a9778d4d442db65344e32318b1fd43ab54898389satok if (TextUtils.isEmpty(localeStr)) 279a9778d4d442db65344e32318b1fd43ab54898389satok return null; 280a9778d4d442db65344e32318b1fd43ab54898389satok String[] localeParams = localeStr.split("_", 3); 281a9778d4d442db65344e32318b1fd43ab54898389satok // The length of localeStr is guaranteed to always return a 1 <= value <= 3 282a9778d4d442db65344e32318b1fd43ab54898389satok // because localeStr is not empty. 283a9778d4d442db65344e32318b1fd43ab54898389satok if (localeParams.length == 1) { 284a9778d4d442db65344e32318b1fd43ab54898389satok return new Locale(localeParams[0]); 285a9778d4d442db65344e32318b1fd43ab54898389satok } else if (localeParams.length == 2) { 286a9778d4d442db65344e32318b1fd43ab54898389satok return new Locale(localeParams[0], localeParams[1]); 287a9778d4d442db65344e32318b1fd43ab54898389satok } else if (localeParams.length == 3) { 288a9778d4d442db65344e32318b1fd43ab54898389satok return new Locale(localeParams[0], localeParams[1], localeParams[2]); 289a9778d4d442db65344e32318b1fd43ab54898389satok } 290a9778d4d442db65344e32318b1fd43ab54898389satok return null; 291a9778d4d442db65344e32318b1fd43ab54898389satok } 292a9778d4d442db65344e32318b1fd43ab54898389satok 293a9778d4d442db65344e32318b1fd43ab54898389satok private static int hashCodeInternal(String locale, String mode, String extraValue, 294a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) { 295a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok return Arrays.hashCode(new Object[] {locale, mode, extraValue, isAuxiliary, 296a86f5e448cd6d29340ca6cbe509bc6384bc0d711satok overridesImplicitlyEnabledSubtype}); 297ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 2987265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok 2997265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok /** 3007265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * Sort the list of InputMethodSubtype 3017265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param context Context will be used for getting localized strings from IME 3027265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param flags Flags for the sort order 3037265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param imi InputMethodInfo of which subtypes are subject to be sorted 3047265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param subtypeList List of InputMethodSubtype which will be sorted 3057265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @return Sorted list of subtypes 3067265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @hide 3077265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok */ 3087265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok public static List<InputMethodSubtype> sort(Context context, int flags, InputMethodInfo imi, 3097265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok List<InputMethodSubtype> subtypeList) { 3107265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok if (imi == null) return subtypeList; 3117265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok final HashSet<InputMethodSubtype> inputSubtypesSet = new HashSet<InputMethodSubtype>( 3127265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok subtypeList); 3137265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok final ArrayList<InputMethodSubtype> sortedList = new ArrayList<InputMethodSubtype>(); 3147265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok int N = imi.getSubtypeCount(); 3157265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok for (int i = 0; i < N; ++i) { 3167265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok InputMethodSubtype subtype = imi.getSubtypeAt(i); 3177265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok if (inputSubtypesSet.contains(subtype)) { 3187265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok sortedList.add(subtype); 3197265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok inputSubtypesSet.remove(subtype); 3207265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 3217265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 3227265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok // If subtypes in inputSubtypesSet remain, that means these subtypes are not 3237265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok // contained in imi, so the remaining subtypes will be appended. 3247265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok for (InputMethodSubtype subtype: inputSubtypesSet) { 3257265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok sortedList.add(subtype); 3267265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 3277265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok return sortedList; 3287265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 329af4bf400abab86baee44dacbcdf13444d06ee46esatok} 330