InputMethodSubtype.java revision 9c4cc03a354922df08efacfc486ef0e80144d3ea
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; 20ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.os.Parcel; 21ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.os.Parcelable; 229c4cc03a354922df08efacfc486ef0e80144d3easatokimport android.util.Slog; 23ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 247265d9bd6d80c5bedaa6de2b80f6619a301a07c8satokimport java.util.ArrayList; 25ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport java.util.Arrays; 269c4cc03a354922df08efacfc486ef0e80144d3easatokimport java.util.HashMap; 277265d9bd6d80c5bedaa6de2b80f6619a301a07c8satokimport java.util.HashSet; 287265d9bd6d80c5bedaa6de2b80f6619a301a07c8satokimport java.util.List; 29ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 30ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok/** 31e31e9424554d5f032f578830556913b4ba78f7f9Ken Wakasa * This class is used to specify meta information of a subtype contained in an input method. 32e31e9424554d5f032f578830556913b4ba78f7f9Ken Wakasa * Subtype can describe locale (e.g. en_US, fr_FR...) and mode (e.g. voice, keyboard...), and is 33e31e9424554d5f032f578830556913b4ba78f7f9Ken Wakasa * used for IME switch and settings. The input method subtype allows the system to bring up the 34e31e9424554d5f032f578830556913b4ba78f7f9Ken Wakasa * specified subtype of the designated input method directly. 35ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 36ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokpublic final class InputMethodSubtype implements Parcelable { 379c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String TAG = InputMethodSubtype.class.getSimpleName(); 389c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String EXTRA_VALUE_PAIR_SEPARATOR = ","; 399c4cc03a354922df08efacfc486ef0e80144d3easatok private static final String EXTRA_VALUE_KEY_VALUE_SEPARATOR = "="; 409c4cc03a354922df08efacfc486ef0e80144d3easatok 41ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final int mSubtypeNameResId; 42ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final int mSubtypeIconResId; 43ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final String mSubtypeLocale; 449ef0283bdcd9534cc09ae37eb2b78771b95247b5satok private final String mSubtypeMode; 45ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final String mSubtypeExtraValue; 46ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private final int mSubtypeHashCode; 479c4cc03a354922df08efacfc486ef0e80144d3easatok private HashMap<String, String> mExtraValueHashMapCache; 48ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 49ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 50ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * Constructor 51ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param nameId The name of the subtype 52ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param iconId The icon of the subtype 53ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param locale The locale supported by the subtype 54ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param modeId The mode supported by the subtype 55ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @param extraValue The extra value of the subtype 56ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 579ef0283bdcd9534cc09ae37eb2b78771b95247b5satok InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue) { 58ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeNameResId = nameId; 59ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeIconResId = iconId; 60af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeLocale = locale != null ? locale : ""; 61af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeMode = mode != null ? mode : ""; 62af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeExtraValue = extraValue != null ? extraValue : ""; 63ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeHashCode = hashCodeInternal(mSubtypeNameResId, mSubtypeIconResId, mSubtypeLocale, 649ef0283bdcd9534cc09ae37eb2b78771b95247b5satok mSubtypeMode, mSubtypeExtraValue); 65ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 66ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 67ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodSubtype(Parcel source) { 68af4bf400abab86baee44dacbcdf13444d06ee46esatok String s; 69ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeNameResId = source.readInt(); 70ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeIconResId = source.readInt(); 71af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 72af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeLocale = s != null ? s : ""; 73af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 74af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeMode = s != null ? s : ""; 75af4bf400abab86baee44dacbcdf13444d06ee46esatok s = source.readString(); 76af4bf400abab86baee44dacbcdf13444d06ee46esatok mSubtypeExtraValue = s != null ? s : ""; 77ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeHashCode = hashCodeInternal(mSubtypeNameResId, mSubtypeIconResId, mSubtypeLocale, 789ef0283bdcd9534cc09ae37eb2b78771b95247b5satok mSubtypeMode, mSubtypeExtraValue); 79ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 80ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 81ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 82ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the name of the subtype 83ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 84ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int getNameResId() { 85ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeNameResId; 86ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 87ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 88ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 89ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the icon of the subtype 90ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 91ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int getIconResId() { 92ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeIconResId; 93ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 94ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 95ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 96ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the locale of the subtype 97ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 98ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public String getLocale() { 99ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeLocale; 100ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 101ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 102ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 103ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the mode of the subtype 104ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 1059ef0283bdcd9534cc09ae37eb2b78771b95247b5satok public String getMode() { 1069ef0283bdcd9534cc09ae37eb2b78771b95247b5satok return mSubtypeMode; 107ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 108ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 109ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 110ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return the extra value of the subtype 111ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 112ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public String getExtraValue() { 113ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeExtraValue; 114ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 115ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 1169c4cc03a354922df08efacfc486ef0e80144d3easatok private HashMap<String, String> getExtraValueHashMap() { 1179c4cc03a354922df08efacfc486ef0e80144d3easatok if (mExtraValueHashMapCache == null) { 1189c4cc03a354922df08efacfc486ef0e80144d3easatok mExtraValueHashMapCache = new HashMap<String, String>(); 1199c4cc03a354922df08efacfc486ef0e80144d3easatok final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR); 1209c4cc03a354922df08efacfc486ef0e80144d3easatok final int N = pairs.length; 1219c4cc03a354922df08efacfc486ef0e80144d3easatok for (int i = 0; i < N; ++i) { 1229c4cc03a354922df08efacfc486ef0e80144d3easatok final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR); 1239c4cc03a354922df08efacfc486ef0e80144d3easatok if (pair.length == 1) { 1249c4cc03a354922df08efacfc486ef0e80144d3easatok mExtraValueHashMapCache.put(pair[0], null); 1259c4cc03a354922df08efacfc486ef0e80144d3easatok } else if (pair.length > 1) { 1269c4cc03a354922df08efacfc486ef0e80144d3easatok if (pair.length > 2) { 1279c4cc03a354922df08efacfc486ef0e80144d3easatok Slog.w(TAG, "ExtraValue has two or more '='s"); 1289c4cc03a354922df08efacfc486ef0e80144d3easatok } 1299c4cc03a354922df08efacfc486ef0e80144d3easatok mExtraValueHashMapCache.put(pair[0], pair[1]); 1309c4cc03a354922df08efacfc486ef0e80144d3easatok } 1319c4cc03a354922df08efacfc486ef0e80144d3easatok } 1329c4cc03a354922df08efacfc486ef0e80144d3easatok } 1339c4cc03a354922df08efacfc486ef0e80144d3easatok return mExtraValueHashMapCache; 1349c4cc03a354922df08efacfc486ef0e80144d3easatok } 1359c4cc03a354922df08efacfc486ef0e80144d3easatok 1369c4cc03a354922df08efacfc486ef0e80144d3easatok /** 1379c4cc03a354922df08efacfc486ef0e80144d3easatok * The string of ExtraValue in subtype should be defined as follows: 1389c4cc03a354922df08efacfc486ef0e80144d3easatok * example: key0,key1=value1,key2,key3,key4=value4 1399c4cc03a354922df08efacfc486ef0e80144d3easatok * @param key the key of extra value 1409c4cc03a354922df08efacfc486ef0e80144d3easatok * @return the subtype contains specified the extra value 1419c4cc03a354922df08efacfc486ef0e80144d3easatok */ 1429c4cc03a354922df08efacfc486ef0e80144d3easatok public boolean containsExtraValueKey(String key) { 1439c4cc03a354922df08efacfc486ef0e80144d3easatok return getExtraValueHashMap().containsKey(key); 1449c4cc03a354922df08efacfc486ef0e80144d3easatok } 1459c4cc03a354922df08efacfc486ef0e80144d3easatok 1469c4cc03a354922df08efacfc486ef0e80144d3easatok /** 1479c4cc03a354922df08efacfc486ef0e80144d3easatok * The string of ExtraValue in subtype should be defined as follows: 1489c4cc03a354922df08efacfc486ef0e80144d3easatok * example: key0,key1=value1,key2,key3,key4=value4 1499c4cc03a354922df08efacfc486ef0e80144d3easatok * @param key the key of extra value 1509c4cc03a354922df08efacfc486ef0e80144d3easatok * @return the value of the specified key 1519c4cc03a354922df08efacfc486ef0e80144d3easatok */ 1529c4cc03a354922df08efacfc486ef0e80144d3easatok public String getExtraValueOf(String key) { 1539c4cc03a354922df08efacfc486ef0e80144d3easatok return getExtraValueHashMap().get(key); 1549c4cc03a354922df08efacfc486ef0e80144d3easatok } 1559c4cc03a354922df08efacfc486ef0e80144d3easatok 156ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok @Override 157ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int hashCode() { 158ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return mSubtypeHashCode; 159ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 160ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 161ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok @Override 162ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public boolean equals(Object o) { 163ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok if (o instanceof InputMethodSubtype) { 164ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodSubtype subtype = (InputMethodSubtype) o; 165af4bf400abab86baee44dacbcdf13444d06ee46esatok return (subtype.hashCode() == hashCode()) 166af4bf400abab86baee44dacbcdf13444d06ee46esatok && (subtype.getNameResId() == getNameResId()) 167af4bf400abab86baee44dacbcdf13444d06ee46esatok && (subtype.getMode().equals(getMode())) 168ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok && (subtype.getIconResId() == getIconResId()) 169ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok && (subtype.getLocale().equals(getLocale())) 170ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok && (subtype.getExtraValue().equals(getExtraValue())); 171ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 172ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return false; 173ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 174ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 175ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public int describeContents() { 176ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return 0; 177ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 178ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 179ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public void writeToParcel(Parcel dest, int parcelableFlags) { 180ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeInt(mSubtypeNameResId); 181ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeInt(mSubtypeIconResId); 182ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeString(mSubtypeLocale); 1839ef0283bdcd9534cc09ae37eb2b78771b95247b5satok dest.writeString(mSubtypeMode); 184ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok dest.writeString(mSubtypeExtraValue); 185ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 186ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 187ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public static final Parcelable.Creator<InputMethodSubtype> CREATOR 188ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok = new Parcelable.Creator<InputMethodSubtype>() { 189ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public InputMethodSubtype createFromParcel(Parcel source) { 190ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return new InputMethodSubtype(source); 191ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 192ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 193ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public InputMethodSubtype[] newArray(int size) { 194ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return new InputMethodSubtype[size]; 195ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 196ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok }; 197ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 198ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private static int hashCodeInternal(int nameResId, int iconResId, String locale, 1999ef0283bdcd9534cc09ae37eb2b78771b95247b5satok String mode, String extraValue) { 2009ef0283bdcd9534cc09ae37eb2b78771b95247b5satok return Arrays.hashCode(new Object[] {nameResId, iconResId, locale, mode, extraValue}); 201ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 2027265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok 2037265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok /** 2047265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * Sort the list of InputMethodSubtype 2057265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param context Context will be used for getting localized strings from IME 2067265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param flags Flags for the sort order 2077265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param imi InputMethodInfo of which subtypes are subject to be sorted 2087265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @param subtypeList List of InputMethodSubtype which will be sorted 2097265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @return Sorted list of subtypes 2107265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok * @hide 2117265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok */ 2127265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok public static List<InputMethodSubtype> sort(Context context, int flags, InputMethodInfo imi, 2137265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok List<InputMethodSubtype> subtypeList) { 2147265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok if (imi == null) return subtypeList; 2157265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok final HashSet<InputMethodSubtype> inputSubtypesSet = new HashSet<InputMethodSubtype>( 2167265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok subtypeList); 2177265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok final ArrayList<InputMethodSubtype> sortedList = new ArrayList<InputMethodSubtype>(); 2187265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok int N = imi.getSubtypeCount(); 2197265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok for (int i = 0; i < N; ++i) { 2207265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok InputMethodSubtype subtype = imi.getSubtypeAt(i); 2217265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok if (inputSubtypesSet.contains(subtype)) { 2227265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok sortedList.add(subtype); 2237265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok inputSubtypesSet.remove(subtype); 2247265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 2257265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 2267265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok // If subtypes in inputSubtypesSet remain, that means these subtypes are not 2277265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok // contained in imi, so the remaining subtypes will be appended. 2287265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok for (InputMethodSubtype subtype: inputSubtypesSet) { 2297265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok sortedList.add(subtype); 2307265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 2317265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok return sortedList; 2327265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok } 233af4bf400abab86baee44dacbcdf13444d06ee46esatok} 234