Loading api/current.xml +16 −5 Original line number Diff line number Diff line Loading @@ -156003,22 +156003,22 @@ visibility="public" > </field> <field name="GROUP_VISIBLE" <field name="GROUP_IS_READ_ONLY" type="java.lang.String" transient="false" volatile="false" value=""group_visible"" value=""group_is_read_only"" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="GROUP_IS_READ_ONLY" <field name="GROUP_VISIBLE" type="java.lang.String" transient="false" volatile="false" value=""group_is_read_only"" value=""group_visible"" static="true" final="true" deprecated="not deprecated" Loading Loading @@ -220894,6 +220894,17 @@ visibility="public" > </method> <method name="getShortcutInputMethodsAndSubtypes" return="java.util.List<android.util.Pair<android.view.inputmethod.InputMethodInfo, android.view.inputmethod.InputMethodSubtype>>" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="hideSoftInputFromInputMethod" return="void" abstract="false" Loading Loading @@ -248473,7 +248484,7 @@ deprecated="not deprecated" visibility="public" > <parameter name="t" type="T"> <parameter name="arg0" type="T"> </parameter> </method> </interface> core/java/android/view/inputmethod/InputMethodManager.java +34 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Parcelable; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; Loading @@ -47,6 +48,7 @@ import com.android.internal.view.InputBindResult; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -1452,6 +1454,38 @@ public final class InputMethodManager { } } public List<Pair<InputMethodInfo, InputMethodSubtype>> getShortcutInputMethodsAndSubtypes() { synchronized (mH) { List<Pair<InputMethodInfo, InputMethodSubtype>> ret = new ArrayList<Pair<InputMethodInfo, InputMethodSubtype>>(); try { // TODO: We should change the return type from List<Object> to List<Parcelable> List<Object> info = mService.getShortcutInputMethodsAndSubtypes(); // "info" has imi1, subtype1, imi2, subtype2, imi3, subtype3,..... in the list Object imi; Object subtype; if (info != null && info.size() > 0) { final int N = info.size(); if (N % 2 == 0) { for (int i = 0; i < N;) { if ((imi = info.get(i++)) instanceof InputMethodInfo) { subtype = info.get(i++); ret.add(new Pair<InputMethodInfo, InputMethodSubtype> ( (InputMethodInfo)imi, (subtype instanceof InputMethodSubtype) ? (InputMethodSubtype)subtype : null)); } } } else { Log.w(TAG, "The size of list was illegal."); } } } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId, e); } return ret; } } public boolean switchToLastInputMethod(IBinder imeToken) { synchronized (mH) { try { Loading core/java/com/android/internal/view/IInputMethodManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ interface IInputMethodManager { List<InputMethodInfo> getInputMethodList(); List<InputMethodInfo> getEnabledInputMethodList(); List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in InputMethodInfo imi); // TODO: We should change the return type from List to List<Parcelable> // Currently there is a bug that aidl doesn't accept List<Parcelable> List getShortcutInputMethodsAndSubtypes(); void addClient(in IInputMethodClient client, in IInputContext inputContext, int uid, int pid); void removeClient(in IInputMethodClient client); Loading services/java/com/android/server/InputMethodManagerService.java +133 −22 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ import android.os.IBinder; import android.os.IInterface; import android.os.Message; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; Loading Loading @@ -120,6 +121,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // If IME doesn't support the system locale, the default subtype will be the first defined one. private static final int DEFAULT_SUBTYPE_ID = 0; private static final String SUBTYPE_MODE_KEYBOARD = "keyboard"; private static final String SUBTYPE_MODE_VOICE = "voice"; final Context mContext; final Handler mHandler; final InputMethodSettings mSettings; Loading Loading @@ -235,6 +239,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ private InputMethodSubtype mCurrentSubtype; // This list contains the pairs of InputMethodInfo and InputMethodSubtype. private List<Pair<InputMethodInfo, InputMethodSubtype>> mShortcutInputMethodsAndSubtypes; // This list is used for returning the pairs of InputMethodInfo and InputMethodSubtype through // aidl. This list has imi1, subtype1 imi2, subtype2... private List mShortcutInputMethodsAndSubtypesObjectList; /** * Set to true if our ServiceConnection is currently actively bound to Loading Loading @@ -983,6 +992,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mCurMethodId = null; unbindCurrentMethodLocked(true); } mShortcutInputMethodsAndSubtypes = null; } else { // There is no longer an input method set, so stop any current one. mCurMethodId = null; Loading Loading @@ -1910,25 +1920,31 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return NOT_A_SUBTYPE_ID; } // If there are no selected subtypes, tries finding the most applicable one according to the // current system locale private int findApplicableSubtypeLocked(String id) { InputMethodInfo imi = mMethodMap.get(id); if (imi == null) { return NOT_A_SUBTYPE_ID; } ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes(); /** * If there are no selected subtypes, tries finding the most applicable one according to the * given locale. * @param subtypes this function will search the most applicable subtype in subtypes * @param mode subtypes will be filtered by mode * @param locale subtypes will be filtered by locale * @param defaultSubtypeId if this function can't find the most applicable subtype, it will * return defaultSubtypeId * @return the most applicable subtypeId */ private int findLastResortApplicableSubtypeLocked( List<InputMethodSubtype> subtypes, String mode, String locale, int defaultSubtypeId) { if (subtypes == null || subtypes.size() == 0) { return NOT_A_SUBTYPE_ID; } final String locale = mContext.getResources().getConfiguration().locale.toString(); if (TextUtils.isEmpty(locale)) { locale = mContext.getResources().getConfiguration().locale.toString(); } final String language = locale.substring(0, 2); boolean partialMatchFound = false; int applicableSubtypeId = DEFAULT_SUBTYPE_ID; int applicableSubtypeId = defaultSubtypeId; for (int i = 0; i < subtypes.size(); ++i) { final String subtypeLocale = subtypes.get(i).getLocale(); // An applicable subtype should be a keyboard subtype if (subtypes.get(i).getMode().equalsIgnoreCase("keyboard")) { // An applicable subtype should match "mode". if (subtypes.get(i).getMode().equalsIgnoreCase(mode)) { if (locale.equals(subtypeLocale)) { // Exact match (e.g. system locale is "en_US" and subtype locale is "en_US") applicableSubtypeId = i; Loading @@ -1950,34 +1966,129 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return applicableSubtypeId; } // If there are no selected shortcuts, tries finding the most applicable ones. private Pair<InputMethodInfo, InputMethodSubtype> findLastResortApplicableShortcutInputMethodAndSubtypeLocked(String mode) { List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked(); InputMethodInfo mostApplicableIMI = null; int mostApplicableSubtypeId = NOT_A_SUBTYPE_ID; boolean foundInSystemIME = false; // Search applicable subtype for each InputMethodInfo for (InputMethodInfo imi: imis) { int subtypeId = NOT_A_SUBTYPE_ID; if (mCurrentSubtype != null) { // 1. Search with the current subtype's locale and the enabled subtypes subtypeId = findLastResortApplicableSubtypeLocked( mSettings.getEnabledInputMethodSubtypeListLocked( imi), mode, mCurrentSubtype.getLocale(), NOT_A_SUBTYPE_ID); if (subtypeId == NOT_A_SUBTYPE_ID) { // 2. Search with the current subtype's locale and all subtypes subtypeId = findLastResortApplicableSubtypeLocked(imi.getSubtypes(), mode, mCurrentSubtype.getLocale(), NOT_A_SUBTYPE_ID); } } // 3. Search with the system locale and the enabled subtypes if (subtypeId == NOT_A_SUBTYPE_ID) { subtypeId = findLastResortApplicableSubtypeLocked( mSettings.getEnabledInputMethodSubtypeListLocked( imi), mode, null, NOT_A_SUBTYPE_ID); } if (subtypeId == NOT_A_SUBTYPE_ID) { // 4. Search with the system locale and all subtypes subtypeId = findLastResortApplicableSubtypeLocked(imi.getSubtypes(), mode, null, NOT_A_SUBTYPE_ID); } if (subtypeId != NOT_A_SUBTYPE_ID) { if (imi.getId().equals(mCurMethodId)) { // The current input method is the most applicable IME. mostApplicableIMI = imi; mostApplicableSubtypeId = subtypeId; break; } else if ((imi.getServiceInfo().applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { // The system input method is 2nd applicable IME. mostApplicableIMI = imi; mostApplicableSubtypeId = subtypeId; foundInSystemIME = true; } else if (!foundInSystemIME) { mostApplicableIMI = imi; mostApplicableSubtypeId = subtypeId; } } } if (DEBUG) { Slog.w(TAG, "Most applicable shortcut input method subtype was:" + mostApplicableIMI.getId() + "," + mostApplicableSubtypeId); } if (mostApplicableIMI != null && mostApplicableSubtypeId != NOT_A_SUBTYPE_ID) { ArrayList<Parcelable> ret = new ArrayList<Parcelable>(2); return new Pair<InputMethodInfo, InputMethodSubtype> (mostApplicableIMI, mostApplicableIMI.getSubtypes().get(mostApplicableSubtypeId)); } else { return null; } } /** * @return Return the current subtype of this input method. */ public InputMethodSubtype getCurrentInputMethodSubtype() { synchronized (mMethodMap) { boolean subtypeIsSelected = false; try { subtypeIsSelected = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE) != NOT_A_SUBTYPE_ID; } catch (SettingNotFoundException e) { } synchronized (mMethodMap) { if (!subtypeIsSelected || mCurrentSubtype == null) { String lastInputMethodId = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); String lastInputMethodId = Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); int subtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId); if (subtypeId == NOT_A_SUBTYPE_ID) { subtypeId = findApplicableSubtypeLocked(lastInputMethodId); InputMethodInfo imi = mMethodMap.get(lastInputMethodId); if (imi != null) { // If there are no selected subtypes, the framework will try to find // the most applicable subtype from all subtypes whose mode is // SUBTYPE_MODE_KEYBOARD. This is an exceptional case, so we will hardcode // the mode. subtypeId = findLastResortApplicableSubtypeLocked(imi.getSubtypes(), SUBTYPE_MODE_KEYBOARD, null, DEFAULT_SUBTYPE_ID); } } if (subtypeId != NOT_A_SUBTYPE_ID) { mCurrentSubtype = mMethodMap.get(lastInputMethodId).getSubtypes().get(subtypeId); } else { mCurrentSubtype = null; } } return mCurrentSubtype; } } // TODO: We should change the return type from List to List<Parcelable> public List getShortcutInputMethodsAndSubtypes() { synchronized (mMethodMap) { if (mShortcutInputMethodsAndSubtypesObjectList != null) { // If there are no selected shortcut subtypes, the framework will try to find // the most applicable subtype from all subtypes whose mode is // SUBTYPE_MODE_VOICE. This is an exceptional case, so we will hardcode the mode. mShortcutInputMethodsAndSubtypes = new ArrayList<Pair<InputMethodInfo, InputMethodSubtype>>(); mShortcutInputMethodsAndSubtypes.add( findLastResortApplicableShortcutInputMethodAndSubtypeLocked( SUBTYPE_MODE_VOICE)); mShortcutInputMethodsAndSubtypesObjectList = new ArrayList<Parcelable>(); for (Pair ime: mShortcutInputMethodsAndSubtypes) { mShortcutInputMethodsAndSubtypesObjectList.add(ime.first); mShortcutInputMethodsAndSubtypesObjectList.add(ime.second); } } return mShortcutInputMethodsAndSubtypesObjectList; } } public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) { synchronized (mMethodMap) { if (subtype != null && mCurMethodId != null) { Loading Loading
api/current.xml +16 −5 Original line number Diff line number Diff line Loading @@ -156003,22 +156003,22 @@ visibility="public" > </field> <field name="GROUP_VISIBLE" <field name="GROUP_IS_READ_ONLY" type="java.lang.String" transient="false" volatile="false" value=""group_visible"" value=""group_is_read_only"" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="GROUP_IS_READ_ONLY" <field name="GROUP_VISIBLE" type="java.lang.String" transient="false" volatile="false" value=""group_is_read_only"" value=""group_visible"" static="true" final="true" deprecated="not deprecated" Loading Loading @@ -220894,6 +220894,17 @@ visibility="public" > </method> <method name="getShortcutInputMethodsAndSubtypes" return="java.util.List<android.util.Pair<android.view.inputmethod.InputMethodInfo, android.view.inputmethod.InputMethodSubtype>>" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public" > </method> <method name="hideSoftInputFromInputMethod" return="void" abstract="false" Loading Loading @@ -248473,7 +248484,7 @@ deprecated="not deprecated" visibility="public" > <parameter name="t" type="T"> <parameter name="arg0" type="T"> </parameter> </method> </interface>
core/java/android/view/inputmethod/InputMethodManager.java +34 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Parcelable; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; Loading @@ -47,6 +48,7 @@ import com.android.internal.view.InputBindResult; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; Loading Loading @@ -1452,6 +1454,38 @@ public final class InputMethodManager { } } public List<Pair<InputMethodInfo, InputMethodSubtype>> getShortcutInputMethodsAndSubtypes() { synchronized (mH) { List<Pair<InputMethodInfo, InputMethodSubtype>> ret = new ArrayList<Pair<InputMethodInfo, InputMethodSubtype>>(); try { // TODO: We should change the return type from List<Object> to List<Parcelable> List<Object> info = mService.getShortcutInputMethodsAndSubtypes(); // "info" has imi1, subtype1, imi2, subtype2, imi3, subtype3,..... in the list Object imi; Object subtype; if (info != null && info.size() > 0) { final int N = info.size(); if (N % 2 == 0) { for (int i = 0; i < N;) { if ((imi = info.get(i++)) instanceof InputMethodInfo) { subtype = info.get(i++); ret.add(new Pair<InputMethodInfo, InputMethodSubtype> ( (InputMethodInfo)imi, (subtype instanceof InputMethodSubtype) ? (InputMethodSubtype)subtype : null)); } } } else { Log.w(TAG, "The size of list was illegal."); } } } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId, e); } return ret; } } public boolean switchToLastInputMethod(IBinder imeToken) { synchronized (mH) { try { Loading
core/java/com/android/internal/view/IInputMethodManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ interface IInputMethodManager { List<InputMethodInfo> getInputMethodList(); List<InputMethodInfo> getEnabledInputMethodList(); List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in InputMethodInfo imi); // TODO: We should change the return type from List to List<Parcelable> // Currently there is a bug that aidl doesn't accept List<Parcelable> List getShortcutInputMethodsAndSubtypes(); void addClient(in IInputMethodClient client, in IInputContext inputContext, int uid, int pid); void removeClient(in IInputMethodClient client); Loading
services/java/com/android/server/InputMethodManagerService.java +133 −22 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ import android.os.IBinder; import android.os.IInterface; import android.os.Message; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; Loading Loading @@ -120,6 +121,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // If IME doesn't support the system locale, the default subtype will be the first defined one. private static final int DEFAULT_SUBTYPE_ID = 0; private static final String SUBTYPE_MODE_KEYBOARD = "keyboard"; private static final String SUBTYPE_MODE_VOICE = "voice"; final Context mContext; final Handler mHandler; final InputMethodSettings mSettings; Loading Loading @@ -235,6 +239,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub */ private InputMethodSubtype mCurrentSubtype; // This list contains the pairs of InputMethodInfo and InputMethodSubtype. private List<Pair<InputMethodInfo, InputMethodSubtype>> mShortcutInputMethodsAndSubtypes; // This list is used for returning the pairs of InputMethodInfo and InputMethodSubtype through // aidl. This list has imi1, subtype1 imi2, subtype2... private List mShortcutInputMethodsAndSubtypesObjectList; /** * Set to true if our ServiceConnection is currently actively bound to Loading Loading @@ -983,6 +992,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mCurMethodId = null; unbindCurrentMethodLocked(true); } mShortcutInputMethodsAndSubtypes = null; } else { // There is no longer an input method set, so stop any current one. mCurMethodId = null; Loading Loading @@ -1910,25 +1920,31 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return NOT_A_SUBTYPE_ID; } // If there are no selected subtypes, tries finding the most applicable one according to the // current system locale private int findApplicableSubtypeLocked(String id) { InputMethodInfo imi = mMethodMap.get(id); if (imi == null) { return NOT_A_SUBTYPE_ID; } ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes(); /** * If there are no selected subtypes, tries finding the most applicable one according to the * given locale. * @param subtypes this function will search the most applicable subtype in subtypes * @param mode subtypes will be filtered by mode * @param locale subtypes will be filtered by locale * @param defaultSubtypeId if this function can't find the most applicable subtype, it will * return defaultSubtypeId * @return the most applicable subtypeId */ private int findLastResortApplicableSubtypeLocked( List<InputMethodSubtype> subtypes, String mode, String locale, int defaultSubtypeId) { if (subtypes == null || subtypes.size() == 0) { return NOT_A_SUBTYPE_ID; } final String locale = mContext.getResources().getConfiguration().locale.toString(); if (TextUtils.isEmpty(locale)) { locale = mContext.getResources().getConfiguration().locale.toString(); } final String language = locale.substring(0, 2); boolean partialMatchFound = false; int applicableSubtypeId = DEFAULT_SUBTYPE_ID; int applicableSubtypeId = defaultSubtypeId; for (int i = 0; i < subtypes.size(); ++i) { final String subtypeLocale = subtypes.get(i).getLocale(); // An applicable subtype should be a keyboard subtype if (subtypes.get(i).getMode().equalsIgnoreCase("keyboard")) { // An applicable subtype should match "mode". if (subtypes.get(i).getMode().equalsIgnoreCase(mode)) { if (locale.equals(subtypeLocale)) { // Exact match (e.g. system locale is "en_US" and subtype locale is "en_US") applicableSubtypeId = i; Loading @@ -1950,34 +1966,129 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return applicableSubtypeId; } // If there are no selected shortcuts, tries finding the most applicable ones. private Pair<InputMethodInfo, InputMethodSubtype> findLastResortApplicableShortcutInputMethodAndSubtypeLocked(String mode) { List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked(); InputMethodInfo mostApplicableIMI = null; int mostApplicableSubtypeId = NOT_A_SUBTYPE_ID; boolean foundInSystemIME = false; // Search applicable subtype for each InputMethodInfo for (InputMethodInfo imi: imis) { int subtypeId = NOT_A_SUBTYPE_ID; if (mCurrentSubtype != null) { // 1. Search with the current subtype's locale and the enabled subtypes subtypeId = findLastResortApplicableSubtypeLocked( mSettings.getEnabledInputMethodSubtypeListLocked( imi), mode, mCurrentSubtype.getLocale(), NOT_A_SUBTYPE_ID); if (subtypeId == NOT_A_SUBTYPE_ID) { // 2. Search with the current subtype's locale and all subtypes subtypeId = findLastResortApplicableSubtypeLocked(imi.getSubtypes(), mode, mCurrentSubtype.getLocale(), NOT_A_SUBTYPE_ID); } } // 3. Search with the system locale and the enabled subtypes if (subtypeId == NOT_A_SUBTYPE_ID) { subtypeId = findLastResortApplicableSubtypeLocked( mSettings.getEnabledInputMethodSubtypeListLocked( imi), mode, null, NOT_A_SUBTYPE_ID); } if (subtypeId == NOT_A_SUBTYPE_ID) { // 4. Search with the system locale and all subtypes subtypeId = findLastResortApplicableSubtypeLocked(imi.getSubtypes(), mode, null, NOT_A_SUBTYPE_ID); } if (subtypeId != NOT_A_SUBTYPE_ID) { if (imi.getId().equals(mCurMethodId)) { // The current input method is the most applicable IME. mostApplicableIMI = imi; mostApplicableSubtypeId = subtypeId; break; } else if ((imi.getServiceInfo().applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { // The system input method is 2nd applicable IME. mostApplicableIMI = imi; mostApplicableSubtypeId = subtypeId; foundInSystemIME = true; } else if (!foundInSystemIME) { mostApplicableIMI = imi; mostApplicableSubtypeId = subtypeId; } } } if (DEBUG) { Slog.w(TAG, "Most applicable shortcut input method subtype was:" + mostApplicableIMI.getId() + "," + mostApplicableSubtypeId); } if (mostApplicableIMI != null && mostApplicableSubtypeId != NOT_A_SUBTYPE_ID) { ArrayList<Parcelable> ret = new ArrayList<Parcelable>(2); return new Pair<InputMethodInfo, InputMethodSubtype> (mostApplicableIMI, mostApplicableIMI.getSubtypes().get(mostApplicableSubtypeId)); } else { return null; } } /** * @return Return the current subtype of this input method. */ public InputMethodSubtype getCurrentInputMethodSubtype() { synchronized (mMethodMap) { boolean subtypeIsSelected = false; try { subtypeIsSelected = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE) != NOT_A_SUBTYPE_ID; } catch (SettingNotFoundException e) { } synchronized (mMethodMap) { if (!subtypeIsSelected || mCurrentSubtype == null) { String lastInputMethodId = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); String lastInputMethodId = Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); int subtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId); if (subtypeId == NOT_A_SUBTYPE_ID) { subtypeId = findApplicableSubtypeLocked(lastInputMethodId); InputMethodInfo imi = mMethodMap.get(lastInputMethodId); if (imi != null) { // If there are no selected subtypes, the framework will try to find // the most applicable subtype from all subtypes whose mode is // SUBTYPE_MODE_KEYBOARD. This is an exceptional case, so we will hardcode // the mode. subtypeId = findLastResortApplicableSubtypeLocked(imi.getSubtypes(), SUBTYPE_MODE_KEYBOARD, null, DEFAULT_SUBTYPE_ID); } } if (subtypeId != NOT_A_SUBTYPE_ID) { mCurrentSubtype = mMethodMap.get(lastInputMethodId).getSubtypes().get(subtypeId); } else { mCurrentSubtype = null; } } return mCurrentSubtype; } } // TODO: We should change the return type from List to List<Parcelable> public List getShortcutInputMethodsAndSubtypes() { synchronized (mMethodMap) { if (mShortcutInputMethodsAndSubtypesObjectList != null) { // If there are no selected shortcut subtypes, the framework will try to find // the most applicable subtype from all subtypes whose mode is // SUBTYPE_MODE_VOICE. This is an exceptional case, so we will hardcode the mode. mShortcutInputMethodsAndSubtypes = new ArrayList<Pair<InputMethodInfo, InputMethodSubtype>>(); mShortcutInputMethodsAndSubtypes.add( findLastResortApplicableShortcutInputMethodAndSubtypeLocked( SUBTYPE_MODE_VOICE)); mShortcutInputMethodsAndSubtypesObjectList = new ArrayList<Parcelable>(); for (Pair ime: mShortcutInputMethodsAndSubtypes) { mShortcutInputMethodsAndSubtypesObjectList.add(ime.first); mShortcutInputMethodsAndSubtypesObjectList.add(ime.second); } } return mShortcutInputMethodsAndSubtypesObjectList; } } public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) { synchronized (mMethodMap) { if (subtype != null && mCurMethodId != null) { Loading