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