diff --git a/api/current.xml b/api/current.xml index 0bbdc888266d9..8f29ff2e4f66c 100644 --- a/api/current.xml +++ b/api/current.xml @@ -222719,6 +222719,8 @@ > + + - + diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 867bb8366b4a6..d310237d65636 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -506,9 +506,10 @@ public final class InputMethodManager { } } - public List getEnabledInputMethodSubtypeList(InputMethodInfo imi) { + public List getEnabledInputMethodSubtypeList(InputMethodInfo imi, + boolean allowsImplicitlySelectedSubtypes) { try { - return mService.getEnabledInputMethodSubtypeList(imi); + return mService.getEnabledInputMethodSubtypeList(imi, allowsImplicitlySelectedSubtypes); } catch (RemoteException e) { throw new RuntimeException(e); } diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 215809f07ea11..b2fbd3a7c1e53 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -31,7 +31,8 @@ import com.android.internal.view.IInputMethodClient; interface IInputMethodManager { List getInputMethodList(); List getEnabledInputMethodList(); - List getEnabledInputMethodSubtypeList(in InputMethodInfo imi); + List getEnabledInputMethodSubtypeList(in InputMethodInfo imi, + boolean allowsImplicitlySelectedSubtypes); // TODO: We should change the return type from List to List // Currently there is a bug that aidl doesn't accept List List getShortcutInputMethodsAndSubtypes(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java index 2d6ae0d3bf58d..f5e677dc4df64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java @@ -174,7 +174,7 @@ public class InputMethodButton extends ImageView { switch (visibility) { case ID_IME_BUTTON_VISIBILITY_AUTO: return size > 1 || (size == 1 - && mImm.getEnabledInputMethodSubtypeList(imis.get(0)).size() > 1); + && mImm.getEnabledInputMethodSubtypeList(imis.get(0), false).size() > 1); case ID_IME_BUTTON_VISIBILITY_ALWAYS_SHOW: return true; case ID_IME_BUTTON_VISIBILITY_ALWAYS_HIDE: diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 9c56a2a4c3627..8a488df1b71c2 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -566,12 +566,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } - public List getEnabledInputMethodSubtypeList(InputMethodInfo imi) { + public List getEnabledInputMethodSubtypeList(InputMethodInfo imi, + boolean allowsImplicitlySelectedSubtypes) { synchronized (mMethodMap) { if (imi == null && mCurMethodId != null) { imi = mMethodMap.get(mCurMethodId); } - return mSettings.getEnabledInputMethodSubtypeListLocked(imi); + final List enabledSubtypes = + mSettings.getEnabledInputMethodSubtypeListLocked(imi); + if (!allowsImplicitlySelectedSubtypes || enabledSubtypes.size() > 0) { + return enabledSubtypes; + } else { + return getApplicableSubtypesLocked(imi.getSubtypes()); + } } } @@ -1665,6 +1672,22 @@ public class InputMethodManagerService extends IInputMethodManager.Stub synchronized (mMethodMap) { final List>> immis = mSettings.getEnabledInputMethodAndSubtypeHashCodeListLocked(); + int N = immis.size(); + + // Add applicable subtypes if no subtype for each IME is enabled. + for (int i = 0; i < N; ++i) { + InputMethodInfo imi = immis.get(i).first; + ArrayList subtypes = immis.get(i).second; + if (subtypes != null && subtypes.size() == 0) { + ArrayList applicableSubtypes = + getApplicableSubtypesLocked(imi.getSubtypes()); + final int numSubtypes = applicableSubtypes.size(); + for (int j = 0; j < numSubtypes; ++j) { + subtypes.add(String.valueOf(applicableSubtypes.get(j).hashCode())); + } + } + } + ArrayList subtypeIds = new ArrayList(); if (immis == null || immis.size() == 0) { @@ -1673,7 +1696,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub hideInputMethodMenuLocked(); - int N = immis.size(); final Map> imMap = new TreeMap>(Collator.getInstance()); @@ -1960,6 +1982,33 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return NOT_A_SUBTYPE_ID; } + private ArrayList getApplicableSubtypesLocked( + List subtypes) { + ArrayList applicableSubtypes = new ArrayList(); + final String systemLocale = mRes.getConfiguration().locale.toString(); + if (TextUtils.isEmpty(systemLocale)) return applicableSubtypes; + final int N = subtypes.size(); + boolean containsKeyboardSubtype = false; + for (int i = 0; i < N; ++i) { + InputMethodSubtype subtype = subtypes.get(i); + if (subtype.getLocale().equals(systemLocale)) { + applicableSubtypes.add(subtype); + if (!containsKeyboardSubtype + && SUBTYPE_MODE_KEYBOARD.equalsIgnoreCase(subtype.getMode())) { + containsKeyboardSubtype = true; + } + } + } + if (!containsKeyboardSubtype) { + InputMethodSubtype lastResortKeyboardSubtype = findLastResortApplicableSubtypeLocked( + subtypes, SUBTYPE_MODE_KEYBOARD, systemLocale, DEFAULT_SUBTYPE_ID); + if (lastResortKeyboardSubtype != null) { + applicableSubtypes.add(lastResortKeyboardSubtype); + } + } + return applicableSubtypes; + } + /** * If there are no selected subtypes, tries finding the most applicable one according to the * given locale. @@ -1967,7 +2016,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub * @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 defaultSubtypeId filtered by mode * @return the most applicable subtypeId */ private InputMethodSubtype findLastResortApplicableSubtypeLocked( @@ -1981,7 +2030,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final String language = locale.substring(0, 2); boolean partialMatchFound = false; InputMethodSubtype applicableSubtype = null; - for (int i = 0; i < subtypes.size(); ++i) { + final int N = subtypes.size(); + for (int i = 0; i < N; ++i) { InputMethodSubtype subtype = subtypes.get(i); final String subtypeLocale = subtype.getLocale(); // An applicable subtype should match "mode". @@ -1998,11 +2048,22 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } + if (applicableSubtype == null && defaultSubtypeId != NOT_A_SUBTYPE_ID) { + if (defaultSubtypeId >= 0 && N > defaultSubtypeId) { + InputMethodSubtype defaultSubtype = subtypes.get(defaultSubtypeId); + if (defaultSubtype.getMode().equalsIgnoreCase(mode)) { + return defaultSubtype; + } + } + } + // The first subtype applicable to the system locale will be defined as the most applicable // subtype. if (DEBUG) { - Slog.d(TAG, "Applicable InputMethodSubtype was found: " + applicableSubtype.getMode() - + "," + applicableSubtype.getLocale()); + if (applicableSubtype != null) { + Slog.d(TAG, "Applicable InputMethodSubtype was found: " + + applicableSubtype.getMode() + "," + applicableSubtype.getLocale()); + } } return applicableSubtype; }