diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index e57fdffdfd1ad..68a7522dc59c2 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -76,9 +76,9 @@ import com.android.internal.view.InputBindResult; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.reflect.Proxy; -import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -232,6 +232,13 @@ public final class InputMethodManager { static final String PENDING_EVENT_COUNTER = "aq:imm"; + /** + * A constant that represents Voice IME. + * + * @see InputMethodSubtype#getMode() + */ + private static final String SUBTYPE_MODE_VOICE = "voice"; + /** * Ensures that {@link #sInstance} becomes non-{@code null} for application that have directly * or indirectly relied on {@link #sInstance} via reflection or something like that. @@ -2459,34 +2466,25 @@ public final class InputMethodManager { * Returns a map of all shortcut input method info and their subtypes. */ public Map> getShortcutInputMethodsAndSubtypes() { - synchronized (mH) { - HashMap> ret = new HashMap<>(); - try { - // TODO: We should change the return type from List to List - List info = mService.getShortcutInputMethodsAndSubtypes(); - // "info" has imi1, subtype1, subtype2, imi2, subtype2, imi3, subtype3..in the list - ArrayList subtypes = null; - if (info != null && !info.isEmpty()) { - final int N = info.size(); - for (int i = 0; i < N; ++i) { - Object o = info.get(i); - if (o instanceof InputMethodInfo) { - if (ret.containsKey(o)) { - Log.e(TAG, "IMI list already contains the same InputMethod."); - break; - } - subtypes = new ArrayList<>(); - ret.put((InputMethodInfo)o, subtypes); - } else if (subtypes != null && o instanceof InputMethodSubtype) { - subtypes.add((InputMethodSubtype)o); - } - } + final List enabledImes = getEnabledInputMethodList(); + + // Ensure we check system IMEs first. + enabledImes.sort(Comparator.comparingInt(imi -> imi.isSystem() ? 0 : 1)); + + final int numEnabledImes = enabledImes.size(); + for (int imiIndex = 0; imiIndex < numEnabledImes; ++imiIndex) { + final InputMethodInfo imi = enabledImes.get(imiIndex); + final List subtypes = getEnabledInputMethodSubtypeList( + imi, true); + final int subtypeCount = subtypes.size(); + for (int subtypeIndex = 0; subtypeIndex < subtypeCount; ++subtypeIndex) { + final InputMethodSubtype subtype = imi.getSubtypeAt(subtypeIndex); + if (SUBTYPE_MODE_VOICE.equals(subtype.getMode())) { + return Collections.singletonMap(imi, Collections.singletonList(subtype)); } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); } - return ret; } + return Collections.emptyMap(); } /** diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index f62c4402cb4ef..4e23396373151 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -42,9 +42,6 @@ interface IInputMethodManager { List getEnabledInputMethodSubtypeList(in String imiId, boolean allowsImplicitlySelectedSubtypes); InputMethodSubtype getLastInputMethodSubtype(); - // TODO: We should change the return type from List to List - // Currently there is a bug that aidl doesn't accept List - List getShortcutInputMethodsAndSubtypes(); boolean showSoftInput(in IInputMethodClient client, int flags, in ResultReceiver resultReceiver); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 6bad26d22d0be..46bdca788ec34 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -4084,86 +4084,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub setSelectedInputMethodAndSubtypeLocked(imi, lastSubtypeId, false); } - // If there are no selected shortcuts, tries finding the most applicable ones. - private Pair - findLastResortApplicableShortcutInputMethodAndSubtypeLocked(String mode) { - List imis = mSettings.getEnabledInputMethodListLocked(); - InputMethodInfo mostApplicableIMI = null; - InputMethodSubtype mostApplicableSubtype = null; - boolean foundInSystemIME = false; - - // Search applicable subtype for each InputMethodInfo - for (InputMethodInfo imi: imis) { - final String imiId = imi.getId(); - if (foundInSystemIME && !imiId.equals(mCurMethodId)) { - continue; - } - InputMethodSubtype subtype = null; - final List enabledSubtypes = - mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true); - // 1. Search by the current subtype's locale from enabledSubtypes. - if (mCurrentSubtype != null) { - subtype = InputMethodUtils.findLastResortApplicableSubtypeLocked( - mRes, enabledSubtypes, mode, mCurrentSubtype.getLocale(), false); - } - // 2. Search by the system locale from enabledSubtypes. - // 3. Search the first enabled subtype matched with mode from enabledSubtypes. - if (subtype == null) { - subtype = InputMethodUtils.findLastResortApplicableSubtypeLocked( - mRes, enabledSubtypes, mode, null, true); - } - final ArrayList overridingImplicitlyEnabledSubtypes = - InputMethodUtils.getOverridingImplicitlyEnabledSubtypes(imi, mode); - final ArrayList subtypesForSearch = - overridingImplicitlyEnabledSubtypes.isEmpty() - ? InputMethodUtils.getSubtypes(imi) - : overridingImplicitlyEnabledSubtypes; - // 4. Search by the current subtype's locale from all subtypes. - if (subtype == null && mCurrentSubtype != null) { - subtype = InputMethodUtils.findLastResortApplicableSubtypeLocked( - mRes, subtypesForSearch, mode, mCurrentSubtype.getLocale(), false); - } - // 5. Search by the system locale from all subtypes. - // 6. Search the first enabled subtype matched with mode from all subtypes. - if (subtype == null) { - subtype = InputMethodUtils.findLastResortApplicableSubtypeLocked( - mRes, subtypesForSearch, mode, null, true); - } - if (subtype != null) { - if (imiId.equals(mCurMethodId)) { - // The current input method is the most applicable IME. - mostApplicableIMI = imi; - mostApplicableSubtype = subtype; - break; - } else if (!foundInSystemIME) { - // The system input method is 2nd applicable IME. - mostApplicableIMI = imi; - mostApplicableSubtype = subtype; - if ((imi.getServiceInfo().applicationInfo.flags - & ApplicationInfo.FLAG_SYSTEM) != 0) { - foundInSystemIME = true; - } - } - } - } - if (DEBUG) { - if (mostApplicableIMI != null) { - Slog.w(TAG, "Most applicable shortcut input method was:" - + mostApplicableIMI.getId()); - if (mostApplicableSubtype != null) { - Slog.w(TAG, "Most applicable shortcut input method subtype was:" - + "," + mostApplicableSubtype.getMode() + "," - + mostApplicableSubtype.getLocale()); - } - } - } - if (mostApplicableIMI != null) { - return new Pair<> (mostApplicableIMI, mostApplicableSubtype); - } else { - return null; - } - } - /** * @return Return the current subtype of this input method. */ @@ -4217,26 +4137,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mCurrentSubtype; } - // TODO: We should change the return type from List to List - @SuppressWarnings("rawtypes") - @Override - public List getShortcutInputMethodsAndSubtypes() { - synchronized (mMethodMap) { - ArrayList ret = new ArrayList<>(); - // 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. - Pair info = - findLastResortApplicableShortcutInputMethodAndSubtypeLocked( - InputMethodUtils.SUBTYPE_MODE_VOICE); - if (info != null) { - ret.add(info.first); - ret.add(info.second); - } - return ret; - } - } - @Override public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) { synchronized (mMethodMap) { diff --git a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java index 918dc07835be5..1137bf967d241 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodUtils.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodUtils.java @@ -63,7 +63,6 @@ final class InputMethodUtils { public static final int NOT_A_SUBTYPE_ID = -1; public static final String SUBTYPE_MODE_ANY = null; public static final String SUBTYPE_MODE_KEYBOARD = "keyboard"; - public static final String SUBTYPE_MODE_VOICE = "voice"; private static final String TAG = "InputMethodUtils"; private static final Locale ENGLISH_LOCALE = new Locale("en"); private static final String NOT_A_SUBTYPE_ID_STR = String.valueOf(NOT_A_SUBTYPE_ID); @@ -375,19 +374,6 @@ final class InputMethodUtils { return subtypes; } - public static ArrayList getOverridingImplicitlyEnabledSubtypes( - InputMethodInfo imi, String mode) { - ArrayList subtypes = new ArrayList<>(); - final int subtypeCount = imi.getSubtypeCount(); - for (int i = 0; i < subtypeCount; ++i) { - final InputMethodSubtype subtype = imi.getSubtypeAt(i); - if (subtype.overridesImplicitlyEnabledSubtype() && subtype.getMode().equals(mode)) { - subtypes.add(subtype); - } - } - return subtypes; - } - public static InputMethodInfo getMostApplicableDefaultIME(List enabledImes) { if (enabledImes == null || enabledImes.isEmpty()) { return null; diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java index 5edb5c8e3286a..d213b2a196614 100644 --- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java @@ -1301,13 +1301,6 @@ public final class MultiClientInputMethodManagerService { return null; } - @BinderThread - @Override - public List getShortcutInputMethodsAndSubtypes() { - reportNotSupported(); - return null; - } - @BinderThread @Override public boolean showSoftInput(