InputMethodManagerCompatWrapper.java revision 88fc9d44186120f9edc5cf7ec0e2af85260fed04
1610f1dc8553cf2ed97e763a06a19380c4a6cd636satok/* 2610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * Copyright (C) 2011 The Android Open Source Project 3610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * 4610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * Licensed under the Apache License, Version 2.0 (the "License"); 5610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * you may not use this file except in compliance with the License. 6610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * You may obtain a copy of the License at 7610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * 8610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * http://www.apache.org/licenses/LICENSE-2.0 9610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * 10610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * Unless required by applicable law or agreed to in writing, software 11610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * distributed under the License is distributed on an "AS IS" BASIS, 12610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * See the License for the specific language governing permissions and 14610f1dc8553cf2ed97e763a06a19380c4a6cd636satok * limitations under the License. 15610f1dc8553cf2ed97e763a06a19380c4a6cd636satok */ 16610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 17610f1dc8553cf2ed97e763a06a19380c4a6cd636satokpackage com.android.inputmethod.compat; 18610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 1988fc9d44186120f9edc5cf7ec0e2af85260fed04satokimport com.android.inputmethod.deprecated.LanguageSwitcherProxy; 20742900983830386f04ccb004cd4356c8b08c61d0satokimport com.android.inputmethod.latin.LatinIME; 21742900983830386f04ccb004cd4356c8b08c61d0satokimport com.android.inputmethod.latin.SubtypeSwitcher; 22742900983830386f04ccb004cd4356c8b08c61d0satokimport com.android.inputmethod.latin.Utils; 23742900983830386f04ccb004cd4356c8b08c61d0satok 24610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.content.Context; 25610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.os.IBinder; 26742900983830386f04ccb004cd4356c8b08c61d0satokimport android.text.TextUtils; 27610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.util.Log; 28610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.view.inputmethod.InputMethodInfo; 29610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.view.inputmethod.InputMethodManager; 30610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 31610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport java.lang.reflect.Method; 322e36fb68d014838a24d1daa1bcbda04254d69be1satokimport java.util.ArrayList; 339115dd272328def247116ccf1ce458d360fec4adsatokimport java.util.Collections; 34610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport java.util.HashMap; 35610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport java.util.List; 36742900983830386f04ccb004cd4356c8b08c61d0satokimport java.util.Locale; 37610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport java.util.Map; 38610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 39610f1dc8553cf2ed97e763a06a19380c4a6cd636satok// TODO: Override this class with the concrete implementation if we need to take care of the 40610f1dc8553cf2ed97e763a06a19380c4a6cd636satok// performance. 41610f1dc8553cf2ed97e763a06a19380c4a6cd636satokpublic class InputMethodManagerCompatWrapper { 42610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName(); 43610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private static final Method METHOD_getCurrentInputMethodSubtype = 44610f1dc8553cf2ed97e763a06a19380c4a6cd636satok CompatUtils.getMethod(InputMethodManager.class, "getCurrentInputMethodSubtype"); 45610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private static final Method METHOD_getEnabledInputMethodSubtypeList = 46610f1dc8553cf2ed97e763a06a19380c4a6cd636satok CompatUtils.getMethod(InputMethodManager.class, "getEnabledInputMethodSubtypeList", 47610f1dc8553cf2ed97e763a06a19380c4a6cd636satok InputMethodInfo.class, boolean.class); 48610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private static final Method METHOD_getShortcutInputMethodsAndSubtypes = 49610f1dc8553cf2ed97e763a06a19380c4a6cd636satok CompatUtils.getMethod(InputMethodManager.class, "getShortcutInputMethodsAndSubtypes"); 50610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private static final Method METHOD_setInputMethodAndSubtype = 51610f1dc8553cf2ed97e763a06a19380c4a6cd636satok CompatUtils.getMethod( 52610f1dc8553cf2ed97e763a06a19380c4a6cd636satok InputMethodManager.class, "setInputMethodAndSubtype", IBinder.class, 53610f1dc8553cf2ed97e763a06a19380c4a6cd636satok String.class, InputMethodSubtypeCompatWrapper.CLASS_InputMethodSubtype); 549115dd272328def247116ccf1ce458d360fec4adsatok private static final Method METHOD_switchToLastInputMethod = CompatUtils.getMethod( 559115dd272328def247116ccf1ce458d360fec4adsatok InputMethodManager.class, "switchToLastInputMethod", IBinder.class); 56610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 57610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private static final InputMethodManagerCompatWrapper sInstance = 58610f1dc8553cf2ed97e763a06a19380c4a6cd636satok new InputMethodManagerCompatWrapper(); 59610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 6088fc9d44186120f9edc5cf7ec0e2af85260fed04satok public static final boolean SUBTYPE_SUPPORTED; 6188fc9d44186120f9edc5cf7ec0e2af85260fed04satok 6288fc9d44186120f9edc5cf7ec0e2af85260fed04satok static { 6388fc9d44186120f9edc5cf7ec0e2af85260fed04satok // This static initializer guarantees that METHOD_getShortcutInputMethodsAndSubtypes is 6488fc9d44186120f9edc5cf7ec0e2af85260fed04satok // already instantiated. 6588fc9d44186120f9edc5cf7ec0e2af85260fed04satok SUBTYPE_SUPPORTED = METHOD_getShortcutInputMethodsAndSubtypes != null; 6688fc9d44186120f9edc5cf7ec0e2af85260fed04satok } 6788fc9d44186120f9edc5cf7ec0e2af85260fed04satok 68742900983830386f04ccb004cd4356c8b08c61d0satok // For the compatibility, IMM will create dummy subtypes if subtypes are not found. 69742900983830386f04ccb004cd4356c8b08c61d0satok // This is required to be false if the current behavior is broken. For now, it's ok to be true. 70742900983830386f04ccb004cd4356c8b08c61d0satok private static final boolean ALLOW_DUMMY_SUBTYPE = true; 71742900983830386f04ccb004cd4356c8b08c61d0satok private static final boolean HAS_VOICE_FUNCTION = true; 72742900983830386f04ccb004cd4356c8b08c61d0satok private static final String VOICE_MODE = "voice"; 73742900983830386f04ccb004cd4356c8b08c61d0satok private static final String KEYBOARD_MODE = "keyboard"; 74742900983830386f04ccb004cd4356c8b08c61d0satok 75610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private InputMethodManager mImm; 7688fc9d44186120f9edc5cf7ec0e2af85260fed04satok private LanguageSwitcherProxy mLanguageSwitcherProxy; 77742900983830386f04ccb004cd4356c8b08c61d0satok private String mLatinImePackageName; 7888fc9d44186120f9edc5cf7ec0e2af85260fed04satok 79610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private InputMethodManagerCompatWrapper() { 80610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 81610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 82610f1dc8553cf2ed97e763a06a19380c4a6cd636satok public static InputMethodManagerCompatWrapper getInstance(Context context) { 83610f1dc8553cf2ed97e763a06a19380c4a6cd636satok if (sInstance.mImm == null) { 84610f1dc8553cf2ed97e763a06a19380c4a6cd636satok sInstance.init(context); 85610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 86610f1dc8553cf2ed97e763a06a19380c4a6cd636satok return sInstance; 87610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 88610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 89610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private synchronized void init(Context context) { 90610f1dc8553cf2ed97e763a06a19380c4a6cd636satok mImm = (InputMethodManager) context.getSystemService( 91610f1dc8553cf2ed97e763a06a19380c4a6cd636satok Context.INPUT_METHOD_SERVICE); 92742900983830386f04ccb004cd4356c8b08c61d0satok if (context instanceof LatinIME) { 93742900983830386f04ccb004cd4356c8b08c61d0satok mLatinImePackageName = context.getPackageName(); 94742900983830386f04ccb004cd4356c8b08c61d0satok } 9588fc9d44186120f9edc5cf7ec0e2af85260fed04satok mLanguageSwitcherProxy = LanguageSwitcherProxy.getInstance(); 96610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 97610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 98610f1dc8553cf2ed97e763a06a19380c4a6cd636satok public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() { 9988fc9d44186120f9edc5cf7ec0e2af85260fed04satok if (!SUBTYPE_SUPPORTED) { 10088fc9d44186120f9edc5cf7ec0e2af85260fed04satok return new InputMethodSubtypeCompatWrapper( 10188fc9d44186120f9edc5cf7ec0e2af85260fed04satok 0, 0, mLanguageSwitcherProxy.getInputLocale().toString(), KEYBOARD_MODE, ""); 10288fc9d44186120f9edc5cf7ec0e2af85260fed04satok } 103742900983830386f04ccb004cd4356c8b08c61d0satok Object o = CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype); 104742900983830386f04ccb004cd4356c8b08c61d0satok return new InputMethodSubtypeCompatWrapper(o); 105610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 106610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 107610f1dc8553cf2ed97e763a06a19380c4a6cd636satok public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList( 1082e36fb68d014838a24d1daa1bcbda04254d69be1satok InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) { 10988fc9d44186120f9edc5cf7ec0e2af85260fed04satok if (!SUBTYPE_SUPPORTED) { 11088fc9d44186120f9edc5cf7ec0e2af85260fed04satok String[] languages = mLanguageSwitcherProxy.getEnabledLanguages(); 11188fc9d44186120f9edc5cf7ec0e2af85260fed04satok List<InputMethodSubtypeCompatWrapper> subtypeList = 11288fc9d44186120f9edc5cf7ec0e2af85260fed04satok new ArrayList<InputMethodSubtypeCompatWrapper>(); 11388fc9d44186120f9edc5cf7ec0e2af85260fed04satok for (String lang: languages) { 11488fc9d44186120f9edc5cf7ec0e2af85260fed04satok subtypeList.add(new InputMethodSubtypeCompatWrapper(0, 0, lang, KEYBOARD_MODE, "")); 11588fc9d44186120f9edc5cf7ec0e2af85260fed04satok } 11688fc9d44186120f9edc5cf7ec0e2af85260fed04satok return subtypeList; 11788fc9d44186120f9edc5cf7ec0e2af85260fed04satok } 118610f1dc8553cf2ed97e763a06a19380c4a6cd636satok Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList, 1192e36fb68d014838a24d1daa1bcbda04254d69be1satok (imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes); 120742900983830386f04ccb004cd4356c8b08c61d0satok if (retval == null || !(retval instanceof List) || ((List<?>)retval).isEmpty()) { 121742900983830386f04ccb004cd4356c8b08c61d0satok if (!ALLOW_DUMMY_SUBTYPE) { 122742900983830386f04ccb004cd4356c8b08c61d0satok // Returns an empty list 123742900983830386f04ccb004cd4356c8b08c61d0satok return Collections.emptyList(); 124742900983830386f04ccb004cd4356c8b08c61d0satok } 125742900983830386f04ccb004cd4356c8b08c61d0satok // Creates dummy subtypes 126742900983830386f04ccb004cd4356c8b08c61d0satok List<InputMethodSubtypeCompatWrapper> subtypeList = 127742900983830386f04ccb004cd4356c8b08c61d0satok new ArrayList<InputMethodSubtypeCompatWrapper>(); 128742900983830386f04ccb004cd4356c8b08c61d0satok InputMethodSubtypeCompatWrapper keyboardSubtype = getLastResortSubtype(KEYBOARD_MODE); 129742900983830386f04ccb004cd4356c8b08c61d0satok InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE); 130742900983830386f04ccb004cd4356c8b08c61d0satok if (keyboardSubtype != null) { 131742900983830386f04ccb004cd4356c8b08c61d0satok subtypeList.add(keyboardSubtype); 132742900983830386f04ccb004cd4356c8b08c61d0satok } 133742900983830386f04ccb004cd4356c8b08c61d0satok if (voiceSubtype != null) { 134742900983830386f04ccb004cd4356c8b08c61d0satok subtypeList.add(voiceSubtype); 135742900983830386f04ccb004cd4356c8b08c61d0satok } 136742900983830386f04ccb004cd4356c8b08c61d0satok return subtypeList; 137742900983830386f04ccb004cd4356c8b08c61d0satok } 13810dd34de0ffcde0104f7d2dae3a3c9fd66abffccsatok return CompatUtils.copyInputMethodSubtypeListToWrapper((List<?>)retval); 139610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 140610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 141742900983830386f04ccb004cd4356c8b08c61d0satok private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() { 142742900983830386f04ccb004cd4356c8b08c61d0satok if (TextUtils.isEmpty(mLatinImePackageName)) 143742900983830386f04ccb004cd4356c8b08c61d0satok return null; 144742900983830386f04ccb004cd4356c8b08c61d0satok return Utils.getInputMethodInfo(this, mLatinImePackageName); 145742900983830386f04ccb004cd4356c8b08c61d0satok } 146742900983830386f04ccb004cd4356c8b08c61d0satok 147742900983830386f04ccb004cd4356c8b08c61d0satok @SuppressWarnings("unused") 148742900983830386f04ccb004cd4356c8b08c61d0satok private InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) { 149742900983830386f04ccb004cd4356c8b08c61d0satok if (VOICE_MODE.equals(mode) && !HAS_VOICE_FUNCTION) 150742900983830386f04ccb004cd4356c8b08c61d0satok return null; 151742900983830386f04ccb004cd4356c8b08c61d0satok Locale inputLocale = SubtypeSwitcher.getInstance().getInputLocale(); 152742900983830386f04ccb004cd4356c8b08c61d0satok if (inputLocale == null) 153742900983830386f04ccb004cd4356c8b08c61d0satok return null; 154742900983830386f04ccb004cd4356c8b08c61d0satok return new InputMethodSubtypeCompatWrapper(0, 0, inputLocale.toString(), mode, ""); 155742900983830386f04ccb004cd4356c8b08c61d0satok } 156742900983830386f04ccb004cd4356c8b08c61d0satok 1572e36fb68d014838a24d1daa1bcbda04254d69be1satok public Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> 158610f1dc8553cf2ed97e763a06a19380c4a6cd636satok getShortcutInputMethodsAndSubtypes() { 159610f1dc8553cf2ed97e763a06a19380c4a6cd636satok Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes); 160742900983830386f04ccb004cd4356c8b08c61d0satok if (retval == null || !(retval instanceof Map) || ((Map<?, ?>)retval).isEmpty()) { 161742900983830386f04ccb004cd4356c8b08c61d0satok if (!ALLOW_DUMMY_SUBTYPE) { 162742900983830386f04ccb004cd4356c8b08c61d0satok // Returns an empty map 163742900983830386f04ccb004cd4356c8b08c61d0satok return Collections.emptyMap(); 164742900983830386f04ccb004cd4356c8b08c61d0satok } 165742900983830386f04ccb004cd4356c8b08c61d0satok // Creates dummy subtypes 166742900983830386f04ccb004cd4356c8b08c61d0satok InputMethodInfoCompatWrapper imi = getLatinImeInputMethodInfo(); 167742900983830386f04ccb004cd4356c8b08c61d0satok InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE); 168742900983830386f04ccb004cd4356c8b08c61d0satok if (imi != null && voiceSubtype != null) { 169742900983830386f04ccb004cd4356c8b08c61d0satok Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> 170742900983830386f04ccb004cd4356c8b08c61d0satok shortcutMap = 171742900983830386f04ccb004cd4356c8b08c61d0satok new HashMap<InputMethodInfoCompatWrapper, 172742900983830386f04ccb004cd4356c8b08c61d0satok List<InputMethodSubtypeCompatWrapper>>(); 173742900983830386f04ccb004cd4356c8b08c61d0satok List<InputMethodSubtypeCompatWrapper> subtypeList = 174742900983830386f04ccb004cd4356c8b08c61d0satok new ArrayList<InputMethodSubtypeCompatWrapper>(); 175742900983830386f04ccb004cd4356c8b08c61d0satok subtypeList.add(voiceSubtype); 176742900983830386f04ccb004cd4356c8b08c61d0satok shortcutMap.put(imi, subtypeList); 177742900983830386f04ccb004cd4356c8b08c61d0satok return shortcutMap; 178742900983830386f04ccb004cd4356c8b08c61d0satok } else { 179742900983830386f04ccb004cd4356c8b08c61d0satok return Collections.emptyMap(); 180742900983830386f04ccb004cd4356c8b08c61d0satok } 181742900983830386f04ccb004cd4356c8b08c61d0satok } 1822e36fb68d014838a24d1daa1bcbda04254d69be1satok Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> shortcutMap = 1832e36fb68d014838a24d1daa1bcbda04254d69be1satok new HashMap<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>(); 184610f1dc8553cf2ed97e763a06a19380c4a6cd636satok final Map<?, ?> retvalMap = (Map<?, ?>)retval; 1852e36fb68d014838a24d1daa1bcbda04254d69be1satok for (Object key : retvalMap.keySet()) { 186610f1dc8553cf2ed97e763a06a19380c4a6cd636satok if (!(key instanceof InputMethodInfo)) { 187610f1dc8553cf2ed97e763a06a19380c4a6cd636satok Log.e(TAG, "Class type error."); 188610f1dc8553cf2ed97e763a06a19380c4a6cd636satok return null; 189610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 1902e36fb68d014838a24d1daa1bcbda04254d69be1satok shortcutMap.put(new InputMethodInfoCompatWrapper((InputMethodInfo)key), 1912e36fb68d014838a24d1daa1bcbda04254d69be1satok CompatUtils.copyInputMethodSubtypeListToWrapper(retvalMap.get(key))); 192610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 193610f1dc8553cf2ed97e763a06a19380c4a6cd636satok return shortcutMap; 194610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 195610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 196610f1dc8553cf2ed97e763a06a19380c4a6cd636satok public void setInputMethodAndSubtype( 197610f1dc8553cf2ed97e763a06a19380c4a6cd636satok IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) { 19888fc9d44186120f9edc5cf7ec0e2af85260fed04satok if (!SUBTYPE_SUPPORTED) { 19988fc9d44186120f9edc5cf7ec0e2af85260fed04satok mLanguageSwitcherProxy.setLocale(subtype.getLocale()); 20088fc9d44186120f9edc5cf7ec0e2af85260fed04satok return; 20188fc9d44186120f9edc5cf7ec0e2af85260fed04satok } 202610f1dc8553cf2ed97e763a06a19380c4a6cd636satok CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype, 203610f1dc8553cf2ed97e763a06a19380c4a6cd636satok token, id, subtype.getOriginalObject()); 204610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 205610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 206610f1dc8553cf2ed97e763a06a19380c4a6cd636satok public boolean switchToLastInputMethod(IBinder token) { 207742900983830386f04ccb004cd4356c8b08c61d0satok if (SubtypeSwitcher.getInstance().isDummyVoiceMode()) { 208742900983830386f04ccb004cd4356c8b08c61d0satok return true; 209742900983830386f04ccb004cd4356c8b08c61d0satok } 2109115dd272328def247116ccf1ce458d360fec4adsatok return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token); 211610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 212610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 2132e36fb68d014838a24d1daa1bcbda04254d69be1satok public List<InputMethodInfoCompatWrapper> getEnabledInputMethodList() { 214610f1dc8553cf2ed97e763a06a19380c4a6cd636satok if (mImm == null) return null; 2152e36fb68d014838a24d1daa1bcbda04254d69be1satok List<InputMethodInfoCompatWrapper> imis = new ArrayList<InputMethodInfoCompatWrapper>(); 2162e36fb68d014838a24d1daa1bcbda04254d69be1satok for (InputMethodInfo imi : mImm.getEnabledInputMethodList()) { 2172e36fb68d014838a24d1daa1bcbda04254d69be1satok imis.add(new InputMethodInfoCompatWrapper(imi)); 2182e36fb68d014838a24d1daa1bcbda04254d69be1satok } 2192e36fb68d014838a24d1daa1bcbda04254d69be1satok return imis; 220610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 221610f1dc8553cf2ed97e763a06a19380c4a6cd636satok 222610f1dc8553cf2ed97e763a06a19380c4a6cd636satok public void showInputMethodPicker() { 223610f1dc8553cf2ed97e763a06a19380c4a6cd636satok if (mImm == null) return; 224610f1dc8553cf2ed97e763a06a19380c4a6cd636satok mImm.showInputMethodPicker(); 225610f1dc8553cf2ed97e763a06a19380c4a6cd636satok } 226610f1dc8553cf2ed97e763a06a19380c4a6cd636satok} 227