InputMethodManagerCompatWrapper.java revision 911b8f9d19c1c4903eeef29b43176cfeaa0e5d0c
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
19bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaokaimport android.app.AlertDialog;
20610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.content.Context;
21bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaokaimport android.content.DialogInterface;
22bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaokaimport android.content.DialogInterface.OnClickListener;
23bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaokaimport android.content.Intent;
24bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaokaimport android.content.pm.ApplicationInfo;
25bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaokaimport android.content.pm.PackageManager;
26610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.os.IBinder;
27742900983830386f04ccb004cd4356c8b08c61d0satokimport android.text.TextUtils;
28610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.util.Log;
29610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.view.inputmethod.InputMethodInfo;
30610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport android.view.inputmethod.InputMethodManager;
31610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
32bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaokaimport com.android.inputmethod.latin.R;
33bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaokaimport com.android.inputmethod.latin.SubtypeSwitcher;
34cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaokaimport com.android.inputmethod.latin.SubtypeUtils;
35bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka
36610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport java.lang.reflect.Method;
372e36fb68d014838a24d1daa1bcbda04254d69be1satokimport java.util.ArrayList;
389115dd272328def247116ccf1ce458d360fec4adsatokimport java.util.Collections;
39bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaokaimport java.util.Comparator;
40610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport java.util.HashMap;
41610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport java.util.List;
42742900983830386f04ccb004cd4356c8b08c61d0satokimport java.util.Locale;
43610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport java.util.Map;
44610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
45610f1dc8553cf2ed97e763a06a19380c4a6cd636satok// TODO: Override this class with the concrete implementation if we need to take care of the
46610f1dc8553cf2ed97e763a06a19380c4a6cd636satok// performance.
47610f1dc8553cf2ed97e763a06a19380c4a6cd636satokpublic class InputMethodManagerCompatWrapper {
48610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName();
49610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    private static final Method METHOD_getCurrentInputMethodSubtype =
50610f1dc8553cf2ed97e763a06a19380c4a6cd636satok            CompatUtils.getMethod(InputMethodManager.class, "getCurrentInputMethodSubtype");
5181d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka    private static final Method METHOD_getLastInputMethodSubtype =
5281d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka            CompatUtils.getMethod(InputMethodManager.class, "getLastInputMethodSubtype");
53610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    private static final Method METHOD_getEnabledInputMethodSubtypeList =
54610f1dc8553cf2ed97e763a06a19380c4a6cd636satok            CompatUtils.getMethod(InputMethodManager.class, "getEnabledInputMethodSubtypeList",
55610f1dc8553cf2ed97e763a06a19380c4a6cd636satok                    InputMethodInfo.class, boolean.class);
56610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    private static final Method METHOD_getShortcutInputMethodsAndSubtypes =
57610f1dc8553cf2ed97e763a06a19380c4a6cd636satok            CompatUtils.getMethod(InputMethodManager.class, "getShortcutInputMethodsAndSubtypes");
58610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    private static final Method METHOD_setInputMethodAndSubtype =
59610f1dc8553cf2ed97e763a06a19380c4a6cd636satok            CompatUtils.getMethod(
60610f1dc8553cf2ed97e763a06a19380c4a6cd636satok                    InputMethodManager.class, "setInputMethodAndSubtype", IBinder.class,
61610f1dc8553cf2ed97e763a06a19380c4a6cd636satok                    String.class, InputMethodSubtypeCompatWrapper.CLASS_InputMethodSubtype);
629115dd272328def247116ccf1ce458d360fec4adsatok    private static final Method METHOD_switchToLastInputMethod = CompatUtils.getMethod(
639115dd272328def247116ccf1ce458d360fec4adsatok            InputMethodManager.class, "switchToLastInputMethod", IBinder.class);
6481d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka    private static final Method METHOD_switchToNextInputMethod = CompatUtils.getMethod(
6581d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka            InputMethodManager.class, "switchToNextInputMethod", IBinder.class, Boolean.TYPE);
66610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
67610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    private static final InputMethodManagerCompatWrapper sInstance =
68610f1dc8553cf2ed97e763a06a19380c4a6cd636satok            new InputMethodManagerCompatWrapper();
69610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
70742900983830386f04ccb004cd4356c8b08c61d0satok    // For the compatibility, IMM will create dummy subtypes if subtypes are not found.
71742900983830386f04ccb004cd4356c8b08c61d0satok    // This is required to be false if the current behavior is broken. For now, it's ok to be true.
72015b21cf52fea1a96bf785c73ecb80b0b731cec3satok    public static final boolean FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES =
73015b21cf52fea1a96bf785c73ecb80b0b731cec3satok            !InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED;
74742900983830386f04ccb004cd4356c8b08c61d0satok    private static final String VOICE_MODE = "voice";
75742900983830386f04ccb004cd4356c8b08c61d0satok    private static final String KEYBOARD_MODE = "keyboard";
76742900983830386f04ccb004cd4356c8b08c61d0satok
77bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka    private InputMethodServiceCompatWrapper mService;
78610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    private InputMethodManager mImm;
79bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka    private PackageManager mPackageManager;
80bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka    private ApplicationInfo mApplicationInfo;
81742900983830386f04ccb004cd4356c8b08c61d0satok    private String mLatinImePackageName;
8288fc9d44186120f9edc5cf7ec0e2af85260fed04satok
83bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka    public static InputMethodManagerCompatWrapper getInstance() {
84bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka        if (sInstance.mImm == null)
85bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka            Log.w(TAG, "getInstance() is called before initialization");
86610f1dc8553cf2ed97e763a06a19380c4a6cd636satok        return sInstance;
87610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    }
88610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
89bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka    public static void init(InputMethodServiceCompatWrapper service) {
90bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka        sInstance.mService = service;
91bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka        sInstance.mImm = (InputMethodManager) service.getSystemService(
92610f1dc8553cf2ed97e763a06a19380c4a6cd636satok                Context.INPUT_METHOD_SERVICE);
93bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka        sInstance.mLatinImePackageName = service.getPackageName();
94bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka        sInstance.mPackageManager = service.getPackageManager();
95bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka        sInstance.mApplicationInfo = service.getApplicationInfo();
96610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    }
97610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
98610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    public InputMethodSubtypeCompatWrapper getCurrentInputMethodSubtype() {
99742900983830386f04ccb004cd4356c8b08c61d0satok        Object o = CompatUtils.invoke(mImm, null, METHOD_getCurrentInputMethodSubtype);
100742900983830386f04ccb004cd4356c8b08c61d0satok        return new InputMethodSubtypeCompatWrapper(o);
101610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    }
102610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
10381d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka    public InputMethodSubtypeCompatWrapper getLastInputMethodSubtype() {
10481d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka        Object o = CompatUtils.invoke(mImm, null, METHOD_getLastInputMethodSubtype);
10581d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka        return new InputMethodSubtypeCompatWrapper(o);
10681d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka    }
10781d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka
108610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    public List<InputMethodSubtypeCompatWrapper> getEnabledInputMethodSubtypeList(
1092e36fb68d014838a24d1daa1bcbda04254d69be1satok            InputMethodInfoCompatWrapper imi, boolean allowsImplicitlySelectedSubtypes) {
110610f1dc8553cf2ed97e763a06a19380c4a6cd636satok        Object retval = CompatUtils.invoke(mImm, null, METHOD_getEnabledInputMethodSubtypeList,
1112e36fb68d014838a24d1daa1bcbda04254d69be1satok                (imi != null ? imi.getInputMethodInfo() : null), allowsImplicitlySelectedSubtypes);
1120c8d5ca023d54b7c9ef6c20eb7988288132bacb5Jean Chalard        if (retval == null || !(retval instanceof List<?>) || ((List<?>)retval).isEmpty()) {
113015b21cf52fea1a96bf785c73ecb80b0b731cec3satok            if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) {
114742900983830386f04ccb004cd4356c8b08c61d0satok                // Returns an empty list
115742900983830386f04ccb004cd4356c8b08c61d0satok                return Collections.emptyList();
116742900983830386f04ccb004cd4356c8b08c61d0satok            }
117742900983830386f04ccb004cd4356c8b08c61d0satok            // Creates dummy subtypes
118bc3dba451a7af85eab600968fbafda3040b7ced4satok            @SuppressWarnings("unused")
119742900983830386f04ccb004cd4356c8b08c61d0satok            List<InputMethodSubtypeCompatWrapper> subtypeList =
120742900983830386f04ccb004cd4356c8b08c61d0satok                    new ArrayList<InputMethodSubtypeCompatWrapper>();
121742900983830386f04ccb004cd4356c8b08c61d0satok            InputMethodSubtypeCompatWrapper keyboardSubtype = getLastResortSubtype(KEYBOARD_MODE);
122742900983830386f04ccb004cd4356c8b08c61d0satok            InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE);
123742900983830386f04ccb004cd4356c8b08c61d0satok            if (keyboardSubtype != null) {
124742900983830386f04ccb004cd4356c8b08c61d0satok                subtypeList.add(keyboardSubtype);
125742900983830386f04ccb004cd4356c8b08c61d0satok            }
126742900983830386f04ccb004cd4356c8b08c61d0satok            if (voiceSubtype != null) {
127742900983830386f04ccb004cd4356c8b08c61d0satok                subtypeList.add(voiceSubtype);
128742900983830386f04ccb004cd4356c8b08c61d0satok            }
129742900983830386f04ccb004cd4356c8b08c61d0satok            return subtypeList;
130742900983830386f04ccb004cd4356c8b08c61d0satok        }
1310c8d5ca023d54b7c9ef6c20eb7988288132bacb5Jean Chalard        return CompatUtils.copyInputMethodSubtypeListToWrapper(retval);
132610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    }
133610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
134742900983830386f04ccb004cd4356c8b08c61d0satok    private InputMethodInfoCompatWrapper getLatinImeInputMethodInfo() {
135742900983830386f04ccb004cd4356c8b08c61d0satok        if (TextUtils.isEmpty(mLatinImePackageName))
136742900983830386f04ccb004cd4356c8b08c61d0satok            return null;
137cc8c8b99bd0463f5977dea82f5e2379ea1dd4e73Tadashi G. Takaoka        return SubtypeUtils.getInputMethodInfo(mLatinImePackageName);
138742900983830386f04ccb004cd4356c8b08c61d0satok    }
139742900983830386f04ccb004cd4356c8b08c61d0satok
1408fbf29e2d54027a17993cd0d4ad486e3454b56f6Tadashi G. Takaoka    private static InputMethodSubtypeCompatWrapper getLastResortSubtype(String mode) {
141015b21cf52fea1a96bf785c73ecb80b0b731cec3satok        if (VOICE_MODE.equals(mode) && !FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES)
142742900983830386f04ccb004cd4356c8b08c61d0satok            return null;
143742900983830386f04ccb004cd4356c8b08c61d0satok        Locale inputLocale = SubtypeSwitcher.getInstance().getInputLocale();
144742900983830386f04ccb004cd4356c8b08c61d0satok        if (inputLocale == null)
145742900983830386f04ccb004cd4356c8b08c61d0satok            return null;
146742900983830386f04ccb004cd4356c8b08c61d0satok        return new InputMethodSubtypeCompatWrapper(0, 0, inputLocale.toString(), mode, "");
147742900983830386f04ccb004cd4356c8b08c61d0satok    }
148742900983830386f04ccb004cd4356c8b08c61d0satok
1492e36fb68d014838a24d1daa1bcbda04254d69be1satok    public Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>
150610f1dc8553cf2ed97e763a06a19380c4a6cd636satok            getShortcutInputMethodsAndSubtypes() {
151610f1dc8553cf2ed97e763a06a19380c4a6cd636satok        Object retval = CompatUtils.invoke(mImm, null, METHOD_getShortcutInputMethodsAndSubtypes);
1520c8d5ca023d54b7c9ef6c20eb7988288132bacb5Jean Chalard        if (retval == null || !(retval instanceof Map<?, ?>) || ((Map<?, ?>)retval).isEmpty()) {
153015b21cf52fea1a96bf785c73ecb80b0b731cec3satok            if (!FORCE_ENABLE_VOICE_EVEN_WITH_NO_VOICE_SUBTYPES) {
154742900983830386f04ccb004cd4356c8b08c61d0satok                // Returns an empty map
155742900983830386f04ccb004cd4356c8b08c61d0satok                return Collections.emptyMap();
156742900983830386f04ccb004cd4356c8b08c61d0satok            }
157742900983830386f04ccb004cd4356c8b08c61d0satok            // Creates dummy subtypes
158bc3dba451a7af85eab600968fbafda3040b7ced4satok            @SuppressWarnings("unused")
159742900983830386f04ccb004cd4356c8b08c61d0satok            InputMethodInfoCompatWrapper imi = getLatinImeInputMethodInfo();
160742900983830386f04ccb004cd4356c8b08c61d0satok            InputMethodSubtypeCompatWrapper voiceSubtype = getLastResortSubtype(VOICE_MODE);
161742900983830386f04ccb004cd4356c8b08c61d0satok            if (imi != null && voiceSubtype != null) {
162742900983830386f04ccb004cd4356c8b08c61d0satok                Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>
163742900983830386f04ccb004cd4356c8b08c61d0satok                        shortcutMap =
164742900983830386f04ccb004cd4356c8b08c61d0satok                                new HashMap<InputMethodInfoCompatWrapper,
165742900983830386f04ccb004cd4356c8b08c61d0satok                                        List<InputMethodSubtypeCompatWrapper>>();
166742900983830386f04ccb004cd4356c8b08c61d0satok                List<InputMethodSubtypeCompatWrapper> subtypeList =
167742900983830386f04ccb004cd4356c8b08c61d0satok                        new ArrayList<InputMethodSubtypeCompatWrapper>();
168742900983830386f04ccb004cd4356c8b08c61d0satok                subtypeList.add(voiceSubtype);
169742900983830386f04ccb004cd4356c8b08c61d0satok                shortcutMap.put(imi, subtypeList);
170742900983830386f04ccb004cd4356c8b08c61d0satok                return shortcutMap;
171742900983830386f04ccb004cd4356c8b08c61d0satok            } else {
172742900983830386f04ccb004cd4356c8b08c61d0satok                return Collections.emptyMap();
173742900983830386f04ccb004cd4356c8b08c61d0satok            }
174742900983830386f04ccb004cd4356c8b08c61d0satok        }
1752e36fb68d014838a24d1daa1bcbda04254d69be1satok        Map<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>> shortcutMap =
1762e36fb68d014838a24d1daa1bcbda04254d69be1satok                new HashMap<InputMethodInfoCompatWrapper, List<InputMethodSubtypeCompatWrapper>>();
177610f1dc8553cf2ed97e763a06a19380c4a6cd636satok        final Map<?, ?> retvalMap = (Map<?, ?>)retval;
1782e36fb68d014838a24d1daa1bcbda04254d69be1satok        for (Object key : retvalMap.keySet()) {
179610f1dc8553cf2ed97e763a06a19380c4a6cd636satok            if (!(key instanceof InputMethodInfo)) {
180610f1dc8553cf2ed97e763a06a19380c4a6cd636satok                Log.e(TAG, "Class type error.");
181610f1dc8553cf2ed97e763a06a19380c4a6cd636satok                return null;
182610f1dc8553cf2ed97e763a06a19380c4a6cd636satok            }
1832e36fb68d014838a24d1daa1bcbda04254d69be1satok            shortcutMap.put(new InputMethodInfoCompatWrapper((InputMethodInfo)key),
1842e36fb68d014838a24d1daa1bcbda04254d69be1satok                    CompatUtils.copyInputMethodSubtypeListToWrapper(retvalMap.get(key)));
185610f1dc8553cf2ed97e763a06a19380c4a6cd636satok        }
186610f1dc8553cf2ed97e763a06a19380c4a6cd636satok        return shortcutMap;
187610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    }
188610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
189bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka    // We don't call this method when we switch between subtypes within this IME.
190610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    public void setInputMethodAndSubtype(
191610f1dc8553cf2ed97e763a06a19380c4a6cd636satok            IBinder token, String id, InputMethodSubtypeCompatWrapper subtype) {
192bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka        // TODO: Support subtype change on non-subtype-supported platform.
193bc3dba451a7af85eab600968fbafda3040b7ced4satok        if (subtype != null && subtype.hasOriginalObject()) {
194bc3dba451a7af85eab600968fbafda3040b7ced4satok            CompatUtils.invoke(mImm, null, METHOD_setInputMethodAndSubtype,
195bc3dba451a7af85eab600968fbafda3040b7ced4satok                    token, id, subtype.getOriginalObject());
196bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka        } else {
197bf9d8348d89be257ccc3db75333bfd4cdf0a9b7eTadashi G. Takaoka            mImm.setInputMethod(token, id);
198bc3dba451a7af85eab600968fbafda3040b7ced4satok        }
199610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    }
200610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
201610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    public boolean switchToLastInputMethod(IBinder token) {
2029115dd272328def247116ccf1ce458d360fec4adsatok        return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToLastInputMethod, token);
203610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    }
204610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
20581d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka    public boolean switchToNextInputMethod(IBinder token, boolean onlyCurrentIme) {
20681d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka        return (Boolean)CompatUtils.invoke(mImm, false, METHOD_switchToNextInputMethod, token,
20781d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka                onlyCurrentIme);
20881d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka    }
20981d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka
2102e36fb68d014838a24d1daa1bcbda04254d69be1satok    public List<InputMethodInfoCompatWrapper> getEnabledInputMethodList() {
211610f1dc8553cf2ed97e763a06a19380c4a6cd636satok        if (mImm == null) return null;
2122e36fb68d014838a24d1daa1bcbda04254d69be1satok        List<InputMethodInfoCompatWrapper> imis = new ArrayList<InputMethodInfoCompatWrapper>();
2132e36fb68d014838a24d1daa1bcbda04254d69be1satok        for (InputMethodInfo imi : mImm.getEnabledInputMethodList()) {
2142e36fb68d014838a24d1daa1bcbda04254d69be1satok            imis.add(new InputMethodInfoCompatWrapper(imi));
2152e36fb68d014838a24d1daa1bcbda04254d69be1satok        }
2162e36fb68d014838a24d1daa1bcbda04254d69be1satok        return imis;
217610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    }
218610f1dc8553cf2ed97e763a06a19380c4a6cd636satok
219610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    public void showInputMethodPicker() {
220610f1dc8553cf2ed97e763a06a19380c4a6cd636satok        if (mImm == null) return;
221911b8f9d19c1c4903eeef29b43176cfeaa0e5d0cKen Wakasa        mImm.showInputMethodPicker();
222610f1dc8553cf2ed97e763a06a19380c4a6cd636satok    }
223610f1dc8553cf2ed97e763a06a19380c4a6cd636satok}
224