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;
}