RichInputMethodManager.java revision e28eba5074664d5716b8e58b8d0a235746b261eb
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; 31e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasaimport com.android.inputmethod.latin.utils.CollectionUtils; 326fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 336fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport java.util.Collections; 34ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalardimport java.util.HashMap; 356fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport java.util.List; 366fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 376fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka/** 386fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka * Enrichment class for InputMethodManager to simplify interaction and add functionality. 396fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka */ 406fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokapublic final class RichInputMethodManager { 416fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private static final String TAG = RichInputMethodManager.class.getSimpleName(); 426fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 436fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private RichInputMethodManager() { 446fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // This utility class is not publicly instantiable. 456fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 466fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 476fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private static final RichInputMethodManager sInstance = new RichInputMethodManager(); 486fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 496fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private InputMethodManagerCompatWrapper mImmWrapper; 506fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private InputMethodInfo mInputMethodInfoOfThisIme; 51ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final HashMap<InputMethodInfo, List<InputMethodSubtype>> 52ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard mSubtypeListCacheWithImplicitlySelectedSubtypes = CollectionUtils.newHashMap(); 53ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final HashMap<InputMethodInfo, List<InputMethodSubtype>> 54ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard mSubtypeListCacheWithoutImplicitlySelectedSubtypes = CollectionUtils.newHashMap(); 556fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 5685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static final int INDEX_NOT_FOUND = -1; 5785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 586fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public static RichInputMethodManager getInstance() { 596fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka sInstance.checkInitialized(); 606fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return sInstance; 616fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 626fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 63f90fc105ab1159f43f536bcacdd1224c2c05bacbTadashi G. Takaoka public static void init(final Context context) { 64f90fc105ab1159f43f536bcacdd1224c2c05bacbTadashi G. Takaoka final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 6585e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka sInstance.initInternal(context, prefs); 6685e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka } 6785e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka 6885e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka private boolean isInitialized() { 6985e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka return mImmWrapper != null; 706fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 716fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 726fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private void checkInitialized() { 7385e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka if (!isInitialized()) { 746fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka throw new RuntimeException(TAG + " is used before initialization"); 756fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 766fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 776fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 7885e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka private void initInternal(final Context context, final SharedPreferences prefs) { 7985e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka if (isInitialized()) { 8085e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka return; 8185e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka } 826fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mImmWrapper = new InputMethodManagerCompatWrapper(context); 836fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mInputMethodInfoOfThisIme = getInputMethodInfoOfThisIme(context); 8485e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka 8585e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka // Initialize additional subtypes. 8685e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka SubtypeLocale.init(context); 87d3b0ecec22cda883150851dced32c1eda2910a66Tadashi G. Takaoka final String prefAdditionalSubtypes = Settings.readPrefAdditionalSubtypes( 8885e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka prefs, context.getResources()); 8985e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka final InputMethodSubtype[] additionalSubtypes = 9085e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka AdditionalSubtype.createAdditionalSubtypesArray(prefAdditionalSubtypes); 9185e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka setAdditionalInputMethodSubtypes(additionalSubtypes); 926fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 936fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 946fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public InputMethodManager getInputMethodManager() { 956fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka checkInitialized(); 966fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return mImmWrapper.mImm; 976fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 986fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 996fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private InputMethodInfo getInputMethodInfoOfThisIme(final Context context) { 1006fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final String packageName = context.getPackageName(); 1016fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (final InputMethodInfo imi : mImmWrapper.mImm.getInputMethodList()) { 1026fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (imi.getPackageName().equals(packageName)) { 1036fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return imi; 1046fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 1056fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 1066fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka throw new RuntimeException("Input method id for " + packageName + " not found."); 1076fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 1086fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 109b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka public List<InputMethodSubtype> getMyEnabledInputMethodSubtypeList( 110b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka boolean allowsImplicitlySelectedSubtypes) { 111ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard return getEnabledInputMethodSubtypeList(mInputMethodInfoOfThisIme, 112ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard allowsImplicitlySelectedSubtypes); 113b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka } 114b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka 1156fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) { 11685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (mImmWrapper.switchToNextInputMethod(token, onlyCurrentIme)) { 11785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 11885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 11985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // Was not able to call {@link InputMethodManager#switchToNextInputMethodIBinder,boolean)} 12085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // because the current device is running ICS or previous and lacks the API. 12185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (switchToNextInputSubtypeInThisIme(token, onlyCurrentIme)) { 12285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 12385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 12485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return switchToNextInputMethodAndSubtype(token); 12585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 12685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 12785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private boolean switchToNextInputSubtypeInThisIme(final IBinder token, 12885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final boolean onlyCurrentIme) { 12985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodManager imm = mImmWrapper.mImm; 13085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype currentSubtype = imm.getCurrentInputMethodSubtype(); 131b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka final List<InputMethodSubtype> enabledSubtypes = getMyEnabledInputMethodSubtypeList( 132b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka true /* allowsImplicitlySelectedSubtypes */); 13385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int currentIndex = getSubtypeIndexInList(currentSubtype, enabledSubtypes); 13485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (currentIndex == INDEX_NOT_FOUND) { 13585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka Log.w(TAG, "Can't find current subtype in enabled subtypes: subtype=" 13685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka + SubtypeLocale.getSubtypeDisplayName(currentSubtype)); 1376fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return false; 1386fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 13985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int nextIndex = (currentIndex + 1) % enabledSubtypes.size(); 14085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (nextIndex <= currentIndex && !onlyCurrentIme) { 14185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // The current subtype is the last or only enabled one and it needs to switch to 14285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // next IME. 14385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return false; 14485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 14585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype nextSubtype = enabledSubtypes.get(nextIndex); 14685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka setInputMethodAndSubtype(token, nextSubtype); 14785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 14885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 14985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 15085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private boolean switchToNextInputMethodAndSubtype(final IBinder token) { 15185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodManager imm = mImmWrapper.mImm; 15285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList(); 15385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int currentIndex = getImiIndexInList(mInputMethodInfoOfThisIme, enabledImis); 15485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (currentIndex == INDEX_NOT_FOUND) { 15585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka Log.w(TAG, "Can't find current IME in enabled IMEs: IME package=" 15685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka + mInputMethodInfoOfThisIme.getPackageName()); 15785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return false; 15885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 15985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodInfo nextImi = getNextNonAuxiliaryIme(currentIndex, enabledImis); 160ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final List<InputMethodSubtype> enabledSubtypes = getEnabledInputMethodSubtypeList(nextImi, 161ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard true /* allowsImplicitlySelectedSubtypes */); 16285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (enabledSubtypes.isEmpty()) { 16385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // The next IME has no subtype. 16485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka imm.setInputMethod(token, nextImi.getId()); 16585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 16685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 16785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype firstSubtype = enabledSubtypes.get(0); 16885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka imm.setInputMethodAndSubtype(token, nextImi.getId(), firstSubtype); 16985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return true; 17085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 17185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 17285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static int getImiIndexInList(final InputMethodInfo inputMethodInfo, 17385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final List<InputMethodInfo> imiList) { 17485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = imiList.size(); 17585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int index = 0; index < count; index++) { 17685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodInfo imi = imiList.get(index); 17785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (imi.equals(inputMethodInfo)) { 17885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return index; 17985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 18085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 18185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return INDEX_NOT_FOUND; 18285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 18385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 18485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // This method mimics {@link InputMethodManager#switchToNextInputMethod(IBinder,boolean)}. 18585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static InputMethodInfo getNextNonAuxiliaryIme(final int currentIndex, 18685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final List<InputMethodInfo> imiList) { 18785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = imiList.size(); 18885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int i = 1; i < count; i++) { 18985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int nextIndex = (currentIndex + i) % count; 19085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodInfo nextImi = imiList.get(nextIndex); 19185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (!isAuxiliaryIme(nextImi)) { 19285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return nextImi; 19385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 19485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 19585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return imiList.get(currentIndex); 19685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 19785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 19885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka // Copied from {@link InputMethodInfo}. See how auxiliary of IME is determined. 19985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static boolean isAuxiliaryIme(final InputMethodInfo imi) { 20085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = imi.getSubtypeCount(); 20185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (count == 0) { 20285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return false; 20385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 20485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int index = 0; index < count; index++) { 20585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype subtype = imi.getSubtypeAt(index); 20685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka if (!subtype.isAuxiliary()) { 20785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return false; 20885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 20985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 2106fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return true; 2116fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2126fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2136fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public InputMethodInfo getInputMethodInfoOfThisIme() { 2146fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return mInputMethodInfoOfThisIme; 2156fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2166fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2176fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public String getInputMethodIdOfThisIme() { 2186fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return mInputMethodInfoOfThisIme.getId(); 2196fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2206fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 22176d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka public boolean checkIfSubtypeBelongsToThisImeAndEnabled(final InputMethodSubtype subtype) { 22276d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka return checkIfSubtypeBelongsToImeAndEnabled(mInputMethodInfoOfThisIme, subtype); 22376d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka } 22476d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka 22576d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka public boolean checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled( 22676d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final InputMethodSubtype subtype) { 22776d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final boolean subtypeEnabled = checkIfSubtypeBelongsToThisImeAndEnabled(subtype); 22876d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final boolean subtypeExplicitlyEnabled = checkIfSubtypeBelongsToList( 229b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka subtype, getMyEnabledInputMethodSubtypeList( 230b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka false /* allowsImplicitlySelectedSubtypes */)); 23176d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka return subtypeEnabled && !subtypeExplicitlyEnabled; 2326fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2336fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2346fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public boolean checkIfSubtypeBelongsToImeAndEnabled(final InputMethodInfo imi, 23576d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final InputMethodSubtype subtype) { 236ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard return checkIfSubtypeBelongsToList(subtype, getEnabledInputMethodSubtypeList(imi, 237ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard true /* allowsImplicitlySelectedSubtypes */)); 23876d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka } 23976d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka 24076d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka private static boolean checkIfSubtypeBelongsToList(final InputMethodSubtype subtype, 24176d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka final List<InputMethodSubtype> subtypes) { 24285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return getSubtypeIndexInList(subtype, subtypes) != INDEX_NOT_FOUND; 24385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 24485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 24585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static int getSubtypeIndexInList(final InputMethodSubtype subtype, 24685629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final List<InputMethodSubtype> subtypes) { 24785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = subtypes.size(); 24885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int index = 0; index < count; index++) { 24985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype ims = subtypes.get(index); 25076d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka if (ims.equals(subtype)) { 25185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return index; 2526fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2536fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 25485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return INDEX_NOT_FOUND; 2556fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2566fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 25776d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka public boolean checkIfSubtypeBelongsToThisIme(final InputMethodSubtype subtype) { 25885629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return getSubtypeIndexInIme(subtype, mInputMethodInfoOfThisIme) != INDEX_NOT_FOUND; 25985629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka } 26085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka 26185629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka private static int getSubtypeIndexInIme(final InputMethodSubtype subtype, 26285629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodInfo imi) { 26385629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final int count = imi.getSubtypeCount(); 26485629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka for (int index = 0; index < count; index++) { 26585629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka final InputMethodSubtype ims = imi.getSubtypeAt(index); 26676d4ffeebfd084913a8c1b7433dff48f5b2063dfTadashi G. Takaoka if (ims.equals(subtype)) { 26785629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return index; 2686fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2696fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 27085629debaaaa576047a4f01430411f0d7b41762dTadashi G. Takaoka return INDEX_NOT_FOUND; 2716fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2726fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2736fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public InputMethodSubtype getCurrentInputMethodSubtype( 2746fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final InputMethodSubtype defaultSubtype) { 2756fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final InputMethodSubtype currentSubtype = mImmWrapper.mImm.getCurrentInputMethodSubtype(); 2766fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return (currentSubtype != null) ? currentSubtype : defaultSubtype; 2776fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2786fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2796fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public boolean hasMultipleEnabledIMEsOrSubtypes(final boolean shouldIncludeAuxiliarySubtypes) { 2806fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final List<InputMethodInfo> enabledImis = mImmWrapper.mImm.getEnabledInputMethodList(); 2816fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis); 2826fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2836fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2846fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public boolean hasMultipleEnabledSubtypesInThisIme( 2856fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final boolean shouldIncludeAuxiliarySubtypes) { 2866fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final List<InputMethodInfo> imiList = Collections.singletonList(mInputMethodInfoOfThisIme); 2876fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); 2886fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 2896fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2906fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes, 2916fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final List<InputMethodInfo> imiList) { 2926fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // Number of the filtered IMEs 2936fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka int filteredImisCount = 0; 2946fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 2956fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (InputMethodInfo imi : imiList) { 2966fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // We can return true immediately after we find two or more filtered IMEs. 2976fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (filteredImisCount > 1) return true; 298ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final List<InputMethodSubtype> subtypes = getEnabledInputMethodSubtypeList(imi, true); 2996fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // IMEs that have no subtypes should be counted. 3006fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (subtypes.isEmpty()) { 3016fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka ++filteredImisCount; 3026fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka continue; 3036fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3046fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3056fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka int auxCount = 0; 3066fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (InputMethodSubtype subtype : subtypes) { 3076fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (subtype.isAuxiliary()) { 3086fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka ++auxCount; 3096fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3106fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3116fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final int nonAuxCount = subtypes.size() - auxCount; 3126fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3136fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // IMEs that have one or more non-auxiliary subtypes should be counted. 3146fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary 3156fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // subtypes should be counted as well. 3166fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) { 3176fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka ++filteredImisCount; 3186fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka continue; 3196fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3206fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3216fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3226fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (filteredImisCount > 1) { 3236fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return true; 3246fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 325b902109000bcef184e69daac7dc3906fc969791eSatoshi Kataoka final List<InputMethodSubtype> subtypes = getMyEnabledInputMethodSubtypeList(true); 3266fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka int keyboardCount = 0; 3276fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's 3286fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // both explicitly and implicitly enabled input method subtype. 3296fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka // (The current IME should be LatinIME.) 3306fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (InputMethodSubtype subtype : subtypes) { 3316fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (KEYBOARD_MODE.equals(subtype.getMode())) { 3326fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka ++keyboardCount; 3336fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3346fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3356fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return keyboardCount > 1; 3366fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3376fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3386fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet(final String localeString, 3396fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final String keyboardLayoutSetName) { 3406fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final InputMethodInfo myImi = mInputMethodInfoOfThisIme; 3416fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final int count = myImi.getSubtypeCount(); 3426fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka for (int i = 0; i < count; i++) { 3436fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final InputMethodSubtype subtype = myImi.getSubtypeAt(i); 3446fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka final String layoutName = SubtypeLocale.getKeyboardLayoutSetName(subtype); 3456fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (localeString.equals(subtype.getLocale()) 3466fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka && keyboardLayoutSetName.equals(layoutName)) { 3476fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return subtype; 3486fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3496fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3506fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka return null; 3516fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3526fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka 3531931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka public void setInputMethodAndSubtype(final IBinder token, final InputMethodSubtype subtype) { 3541931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka mImmWrapper.mImm.setInputMethodAndSubtype( 3551931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka token, mInputMethodInfoOfThisIme.getId(), subtype); 3561931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka } 3571931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka 3586fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka public void setAdditionalInputMethodSubtypes(final InputMethodSubtype[] subtypes) { 3596fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mImmWrapper.mImm.setAdditionalInputMethodSubtypes( 3606fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mInputMethodInfoOfThisIme.getId(), subtypes); 361ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard // Clear the cache so that we go read the subtypes again next time. 362ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard clearSubtypeCaches(); 363ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard } 364ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard 365ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard private List<InputMethodSubtype> getEnabledInputMethodSubtypeList(final InputMethodInfo imi, 366ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final boolean allowsImplicitlySelectedSubtypes) { 367ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final HashMap<InputMethodInfo, List<InputMethodSubtype>> cache = 368ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard allowsImplicitlySelectedSubtypes 369ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard ? mSubtypeListCacheWithImplicitlySelectedSubtypes 370ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard : mSubtypeListCacheWithoutImplicitlySelectedSubtypes; 371ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final List<InputMethodSubtype> cachedList = cache.get(imi); 372ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard if (null != cachedList) return cachedList; 373ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard final List<InputMethodSubtype> result = mImmWrapper.mImm.getEnabledInputMethodSubtypeList( 374ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard imi, allowsImplicitlySelectedSubtypes); 375ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard cache.put(imi, result); 376ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard return result; 377ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard } 378ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard 379ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard public void clearSubtypeCaches() { 380ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard mSubtypeListCacheWithImplicitlySelectedSubtypes.clear(); 381ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard mSubtypeListCacheWithoutImplicitlySelectedSubtypes.clear(); 3826fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka } 3836fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka} 384