RichInputMethodManager.java revision a7d2fc6befa1b16883200a653fc01deb4d94944d
16fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka/* 26fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * Copyright (C) 2012 The Android Open Source Project 36fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * 46fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 56fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * you may not use this file except in compliance with the License. 66fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * You may obtain a copy of the License at 76fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * 86fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 96fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * 106fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 116fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 126fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * See the License for the specific language governing permissions and 146fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * limitations under the License. 156fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka */ 166fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 176fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokapackage com.android.inputmethod.latin; 186fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 196fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport static com.android.inputmethod.latin.Constants.Subtype.KEYBOARD_MODE; 206fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 216fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport android.content.Context; 2285e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaokaimport android.content.SharedPreferences; 236fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport android.os.IBinder; 24f90fc105ab1159f43f536bcacdd1224c2c05bacbTadashi G. Takaokaimport android.preference.PreferenceManager; 2585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaokaimport android.util.Log; 266fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport android.view.inputmethod.InputMethodInfo; 276fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport android.view.inputmethod.InputMethodManager; 286fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport android.view.inputmethod.InputMethodSubtype; 296fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 306fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport com.android.inputmethod.compat.InputMethodManagerCompatWrapper; 31a7d2fc6befa1b16883200a653fc01deb4d94944dKen Wakasaimport com.android.inputmethod.latin.settings.Settings; 32e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasaimport com.android.inputmethod.latin.utils.CollectionUtils; 336fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 346fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport java.util.Collections; 35ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalardimport java.util.HashMap; 366fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport java.util.List; 376fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 386fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka/** 396fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * Enrichment class for InputMethodManager to simplify interaction and add functionality. 406fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka */ 416fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokapublic final class RichInputMethodManager { 426fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private static final String TAG = RichInputMethodManager.class.getSimpleName(); 436fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 446fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private RichInputMethodManager() { 456fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // This utility class is not publicly instantiable. 466fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 476fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 486fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private static final RichInputMethodManager sInstance = new RichInputMethodManager(); 496fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 506fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private InputMethodManagerCompatWrapper mImmWrapper; 516fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private InputMethodInfo mInputMethodInfoOfThisIme; 52ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final HashMap<InputMethodInfo, List<InputMethodSubtype>> 53ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard mSubtypeListCacheWithImplicitlySelectedSubtypes = CollectionUtils.newHashMap(); 54ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final HashMap<InputMethodInfo, List<InputMethodSubtype>> 55ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard mSubtypeListCacheWithoutImplicitlySelectedSubtypes = CollectionUtils.newHashMap(); 566fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 5785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static final int INDEX_NOT_FOUND = -1; 5885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 596fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public static RichInputMethodManager getInstance() { 606fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka sInstance.checkInitialized(); 616fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return sInstance; 626fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 636fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 64f90fc105ab1159f43f536bcacdd1224c2c05bacbTadashi G. Takaoka public static void init(final Context context) { 65f90fc105ab1159f43f536bcacdd1224c2c05bacbTadashi G. Takaoka final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 6685e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka sInstance.initInternal(context, prefs); 6785e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka } 6885e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka 6985e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka private boolean isInitialized() { 7085e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka return mImmWrapper != null; 716fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 726fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 736fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private void checkInitialized() { 7485e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka if (!isInitialized()) { 756fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka throw new RuntimeException(TAG + " is used before initialization"); 766fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 776fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 786fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 7985e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka private void initInternal(final Context context, final SharedPreferences prefs) { 8085e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka if (isInitialized()) { 8185e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka return; 8285e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka } 836fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mImmWrapper = new InputMethodManagerCompatWrapper(context); 846fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mInputMethodInfoOfThisIme = getInputMethodInfoOfThisIme(context); 8585e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka 8685e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka // Initialize additional subtypes. 8785e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka SubtypeLocale.init(context); 88d3b0ecec22cda883150851dced32c1eda2910a66Tadashi G. Takaoka final String prefAdditionalSubtypes = Settings.readPrefAdditionalSubtypes( 8985e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka prefs, context.getResources()); 9085e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka final InputMethodSubtype[] additionalSubtypes = 9185e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka AdditionalSubtype.createAdditionalSubtypesArray(prefAdditionalSubtypes); 9285e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka setAdditionalInputMethodSubtypes(additionalSubtypes); 936fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 946fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 956fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public InputMethodManager getInputMethodManager() { 966fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka checkInitialized(); 976fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return mImmWrapper.mImm; 986fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 996fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 1006fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private InputMethodInfo getInputMethodInfoOfThisIme(final Context context) { 1016fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final String packageName = context.getPackageName(); 1026fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (final InputMethodInfo imi : mImmWrapper.mImm.getInputMethodList()) { 1036fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (imi.getPackageName().equals(packageName)) { 1046fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return imi; 1056fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 1066fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 1076fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka throw new RuntimeException("Input method id for " + packageName + " not found."); 1086fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 1096fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 110b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka public List<InputMethodSubtype> getMyEnabledInputMethodSubtypeList( 111b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka boolean allowsImplicitlySelectedSubtypes) { 112ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard return getEnabledInputMethodSubtypeList(mInputMethodInfoOfThisIme, 113ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard allowsImplicitlySelectedSubtypes); 114b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka } 115b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka 1166fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) { 11785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (mImmWrapper.switchToNextInputMethod(token, onlyCurrentIme)) { 11885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 11985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 12085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // Was not able to call {@link InputMethodManager#switchToNextInputMethodIBinder,boolean)} 12185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // because the current device is running ICS or previous and lacks the API. 12285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (switchToNextInputSubtypeInThisIme(token, onlyCurrentIme)) { 12385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 12485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 12585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return switchToNextInputMethodAndSubtype(token); 12685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 12785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 12885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private boolean switchToNextInputSubtypeInThisIme(final IBinder token, 12985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final boolean onlyCurrentIme) { 13085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodManager imm = mImmWrapper.mImm; 13185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype currentSubtype = imm.getCurrentInputMethodSubtype(); 132b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka final List<InputMethodSubtype> enabledSubtypes = getMyEnabledInputMethodSubtypeList( 133b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka true /* allowsImplicitlySelectedSubtypes */); 13485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int currentIndex = getSubtypeIndexInList(currentSubtype, enabledSubtypes); 13585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (currentIndex == INDEX_NOT_FOUND) { 13685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka Log.w(TAG, "Can't find current subtype in enabled subtypes: subtype=" 13785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka + SubtypeLocale.getSubtypeDisplayName(currentSubtype)); 1386fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return false; 1396fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 14085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int nextIndex = (currentIndex + 1) % enabledSubtypes.size(); 14185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (nextIndex <= currentIndex && !onlyCurrentIme) { 14285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // The current subtype is the last or only enabled one and it needs to switch to 14385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // next IME. 14485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return false; 14585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 14685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype nextSubtype = enabledSubtypes.get(nextIndex); 14785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka setInputMethodAndSubtype(token, nextSubtype); 14885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 14985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 15085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 15185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private boolean switchToNextInputMethodAndSubtype(final IBinder token) { 15285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodManager imm = mImmWrapper.mImm; 15385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList(); 15485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int currentIndex = getImiIndexInList(mInputMethodInfoOfThisIme, enabledImis); 15585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (currentIndex == INDEX_NOT_FOUND) { 15685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka Log.w(TAG, "Can't find current IME in enabled IMEs: IME package=" 15785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka + mInputMethodInfoOfThisIme.getPackageName()); 15885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return false; 15985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 16085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodInfo nextImi = getNextNonAuxiliaryIme(currentIndex, enabledImis); 161ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final List<InputMethodSubtype> enabledSubtypes = getEnabledInputMethodSubtypeList(nextImi, 162ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard true /* allowsImplicitlySelectedSubtypes */); 16385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (enabledSubtypes.isEmpty()) { 16485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // The next IME has no subtype. 16585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka imm.setInputMethod(token, nextImi.getId()); 16685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 16785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 16885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype firstSubtype = enabledSubtypes.get(0); 16985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka imm.setInputMethodAndSubtype(token, nextImi.getId(), firstSubtype); 17085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 17185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 17285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 17385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static int getImiIndexInList(final InputMethodInfo inputMethodInfo, 17485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final List<InputMethodInfo> imiList) { 17585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = imiList.size(); 17685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int index = 0; index < count; index++) { 17785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodInfo imi = imiList.get(index); 17885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (imi.equals(inputMethodInfo)) { 17985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return index; 18085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 18185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 18285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return INDEX_NOT_FOUND; 18385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 18485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 18585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // This method mimics {@link InputMethodManager#switchToNextInputMethod(IBinder,boolean)}. 18685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static InputMethodInfo getNextNonAuxiliaryIme(final int currentIndex, 18785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final List<InputMethodInfo> imiList) { 18885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = imiList.size(); 18985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int i = 1; i < count; i++) { 19085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int nextIndex = (currentIndex + i) % count; 19185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodInfo nextImi = imiList.get(nextIndex); 19285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (!isAuxiliaryIme(nextImi)) { 19385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return nextImi; 19485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 19585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 19685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return imiList.get(currentIndex); 19785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 19885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 19985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // Copied from {@link InputMethodInfo}. See how auxiliary of IME is determined. 20085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static boolean isAuxiliaryIme(final InputMethodInfo imi) { 20185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = imi.getSubtypeCount(); 20285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (count == 0) { 20385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return false; 20485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 20585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int index = 0; index < count; index++) { 20685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype subtype = imi.getSubtypeAt(index); 20785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (!subtype.isAuxiliary()) { 20885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return false; 20985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 21085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 2116fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return true; 2126fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2136fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2146fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public InputMethodInfo getInputMethodInfoOfThisIme() { 2156fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return mInputMethodInfoOfThisIme; 2166fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2176fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2186fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public String getInputMethodIdOfThisIme() { 2196fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return mInputMethodInfoOfThisIme.getId(); 2206fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2216fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 22276d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka public boolean checkIfSubtypeBelongsToThisImeAndEnabled(final InputMethodSubtype subtype) { 22376d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka return checkIfSubtypeBelongsToImeAndEnabled(mInputMethodInfoOfThisIme, subtype); 22476d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka } 22576d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka 22676d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka public boolean checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled( 22776d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final InputMethodSubtype subtype) { 22876d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final boolean subtypeEnabled = checkIfSubtypeBelongsToThisImeAndEnabled(subtype); 22976d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final boolean subtypeExplicitlyEnabled = checkIfSubtypeBelongsToList( 230b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka subtype, getMyEnabledInputMethodSubtypeList( 231b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka false /* allowsImplicitlySelectedSubtypes */)); 23276d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka return subtypeEnabled && !subtypeExplicitlyEnabled; 2336fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2346fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2356fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public boolean checkIfSubtypeBelongsToImeAndEnabled(final InputMethodInfo imi, 23676d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final InputMethodSubtype subtype) { 237ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard return checkIfSubtypeBelongsToList(subtype, getEnabledInputMethodSubtypeList(imi, 238ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard true /* allowsImplicitlySelectedSubtypes */)); 23976d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka } 24076d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka 24176d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka private static boolean checkIfSubtypeBelongsToList(final InputMethodSubtype subtype, 24276d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final List<InputMethodSubtype> subtypes) { 24385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return getSubtypeIndexInList(subtype, subtypes) != INDEX_NOT_FOUND; 24485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 24585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 24685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static int getSubtypeIndexInList(final InputMethodSubtype subtype, 24785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final List<InputMethodSubtype> subtypes) { 24885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = subtypes.size(); 24985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int index = 0; index < count; index++) { 25085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype ims = subtypes.get(index); 25176d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka if (ims.equals(subtype)) { 25285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return index; 2536fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2546fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 25585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return INDEX_NOT_FOUND; 2566fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2576fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 25876d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka public boolean checkIfSubtypeBelongsToThisIme(final InputMethodSubtype subtype) { 25985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return getSubtypeIndexInIme(subtype, mInputMethodInfoOfThisIme) != INDEX_NOT_FOUND; 26085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 26185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 26285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static int getSubtypeIndexInIme(final InputMethodSubtype subtype, 26385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodInfo imi) { 26485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = imi.getSubtypeCount(); 26585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int index = 0; index < count; index++) { 26685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype ims = imi.getSubtypeAt(index); 26776d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka if (ims.equals(subtype)) { 26885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return index; 2696fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2706fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 27185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return INDEX_NOT_FOUND; 2726fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2736fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2746fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public InputMethodSubtype getCurrentInputMethodSubtype( 2756fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final InputMethodSubtype defaultSubtype) { 2766fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final InputMethodSubtype currentSubtype = mImmWrapper.mImm.getCurrentInputMethodSubtype(); 2776fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return (currentSubtype != null) ? currentSubtype : defaultSubtype; 2786fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2796fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2806fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public boolean hasMultipleEnabledIMEsOrSubtypes(final boolean shouldIncludeAuxiliarySubtypes) { 2816fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final List<InputMethodInfo> enabledImis = mImmWrapper.mImm.getEnabledInputMethodList(); 2826fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis); 2836fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2846fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2856fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public boolean hasMultipleEnabledSubtypesInThisIme( 2866fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final boolean shouldIncludeAuxiliarySubtypes) { 2876fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final List<InputMethodInfo> imiList = Collections.singletonList(mInputMethodInfoOfThisIme); 2886fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); 2896fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2906fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2916fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes, 2926fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final List<InputMethodInfo> imiList) { 2936fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // Number of the filtered IMEs 2946fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka int filteredImisCount = 0; 2956fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2966fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (InputMethodInfo imi : imiList) { 2976fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // We can return true immediately after we find two or more filtered IMEs. 2986fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (filteredImisCount > 1) return true; 299ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final List<InputMethodSubtype> subtypes = getEnabledInputMethodSubtypeList(imi, true); 3006fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // IMEs that have no subtypes should be counted. 3016fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (subtypes.isEmpty()) { 3026fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka ++filteredImisCount; 3036fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka continue; 3046fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3056fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3066fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka int auxCount = 0; 3076fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (InputMethodSubtype subtype : subtypes) { 3086fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (subtype.isAuxiliary()) { 3096fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka ++auxCount; 3106fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3116fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3126fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final int nonAuxCount = subtypes.size() - auxCount; 3136fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3146fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // IMEs that have one or more non-auxiliary subtypes should be counted. 3156fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary 3166fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // subtypes should be counted as well. 3176fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) { 3186fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka ++filteredImisCount; 3196fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka continue; 3206fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3216fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3226fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3236fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (filteredImisCount > 1) { 3246fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return true; 3256fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 326b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka final List<InputMethodSubtype> subtypes = getMyEnabledInputMethodSubtypeList(true); 3276fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka int keyboardCount = 0; 3286fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's 3296fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // both explicitly and implicitly enabled input method subtype. 3306fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // (The current IME should be LatinIME.) 3316fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (InputMethodSubtype subtype : subtypes) { 3326fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (KEYBOARD_MODE.equals(subtype.getMode())) { 3336fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka ++keyboardCount; 3346fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3356fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3366fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return keyboardCount > 1; 3376fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3386fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3396fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet(final String localeString, 3406fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final String keyboardLayoutSetName) { 3416fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final InputMethodInfo myImi = mInputMethodInfoOfThisIme; 3426fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final int count = myImi.getSubtypeCount(); 3436fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (int i = 0; i < count; i++) { 3446fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final InputMethodSubtype subtype = myImi.getSubtypeAt(i); 3456fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final String layoutName = SubtypeLocale.getKeyboardLayoutSetName(subtype); 3466fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (localeString.equals(subtype.getLocale()) 3476fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka && keyboardLayoutSetName.equals(layoutName)) { 3486fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return subtype; 3496fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3506fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3516fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return null; 3526fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3536fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3541931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka public void setInputMethodAndSubtype(final IBinder token, final InputMethodSubtype subtype) { 3551931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka mImmWrapper.mImm.setInputMethodAndSubtype( 3561931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka token, mInputMethodInfoOfThisIme.getId(), subtype); 3571931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka } 3581931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka 3596fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public void setAdditionalInputMethodSubtypes(final InputMethodSubtype[] subtypes) { 3606fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mImmWrapper.mImm.setAdditionalInputMethodSubtypes( 3616fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mInputMethodInfoOfThisIme.getId(), subtypes); 362ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard // Clear the cache so that we go read the subtypes again next time. 363ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard clearSubtypeCaches(); 364ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard } 365ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard 366ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard private List<InputMethodSubtype> getEnabledInputMethodSubtypeList(final InputMethodInfo imi, 367ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final boolean allowsImplicitlySelectedSubtypes) { 368ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final HashMap<InputMethodInfo, List<InputMethodSubtype>> cache = 369ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard allowsImplicitlySelectedSubtypes 370ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard ? mSubtypeListCacheWithImplicitlySelectedSubtypes 371ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard : mSubtypeListCacheWithoutImplicitlySelectedSubtypes; 372ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final List<InputMethodSubtype> cachedList = cache.get(imi); 373ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard if (null != cachedList) return cachedList; 374ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final List<InputMethodSubtype> result = mImmWrapper.mImm.getEnabledInputMethodSubtypeList( 375ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard imi, allowsImplicitlySelectedSubtypes); 376ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard cache.put(imi, result); 377ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard return result; 378ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard } 379ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard 380ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard public void clearSubtypeCaches() { 381ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard mSubtypeListCacheWithImplicitlySelectedSubtypes.clear(); 382ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard mSubtypeListCacheWithoutImplicitlySelectedSubtypes.clear(); 3836fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3846fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka} 385