Store the current IME's token in the system bar for changing the current IME to a shortcut IME from the system bar
Bug: 3212206
Bug: 3201828
- Added a shortcut IME button. This will be used for calling a shortcut IME (e.g. Voice input)
- Made the positions of IME buttons left aligned
- IME token is required to change IME because of the security reasons.
Change-Id: I48ba5e2509b3aa1bfd2394f9201427fa6b93c6d3
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 723432d..c574058 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -964,7 +964,7 @@
}
synchronized (mMethodMap) {
- mStatusBar.setIMEButtonVisible(visible);
+ mStatusBar.setIMEButtonVisible(token, visible);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -1007,23 +1007,29 @@
if (id.equals(mCurMethodId)) {
ArrayList<InputMethodSubtype> subtypes = info.getSubtypes();
+ InputMethodSubtype subtype = null;
if (subtypeId >= 0 && subtypeId < subtypes.size()) {
- InputMethodSubtype subtype = subtypes.get(subtypeId);
- if (subtype != mCurrentSubtype) {
- synchronized (mMethodMap) {
- if (mCurMethod != null) {
- try {
- setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true);
- if (mInputShown) {
- // If mInputShown is false, there is no IME button on the
- // system bar.
- // Thus there is no need to make it invisible explicitly.
- mStatusBar.setIMEButtonVisible(true);
- }
- mCurMethod.changeInputMethodSubtype(subtype);
- } catch (RemoteException e) {
- return;
+ subtype = subtypes.get(subtypeId);
+ }
+ if (subtype != mCurrentSubtype) {
+ synchronized (mMethodMap) {
+ if (mCurMethod != null) {
+ try {
+ setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true);
+ if (mInputShown) {
+ // If mInputShown is false, there is no IME button on the
+ // system bar.
+ // Thus there is no need to make it invisible explicitly.
+ mStatusBar.setIMEButtonVisible(mCurToken, true);
}
+ // If subtype is null, try to find the most applicable one from
+ // getCurrentInputMethodSubtype.
+ if (subtype == null) {
+ subtype = getCurrentInputMethodSubtype();
+ }
+ mCurMethod.changeInputMethodSubtype(subtype);
+ } catch (RemoteException e) {
+ return;
}
}
}
@@ -1942,28 +1948,29 @@
* return defaultSubtypeId
* @return the most applicable subtypeId
*/
- private int findLastResortApplicableSubtypeLocked(
+ private InputMethodSubtype findLastResortApplicableSubtypeLocked(
List<InputMethodSubtype> subtypes, String mode, String locale, int defaultSubtypeId) {
if (subtypes == null || subtypes.size() == 0) {
- return NOT_A_SUBTYPE_ID;
+ return null;
}
if (TextUtils.isEmpty(locale)) {
locale = mContext.getResources().getConfiguration().locale.toString();
}
final String language = locale.substring(0, 2);
boolean partialMatchFound = false;
- int applicableSubtypeId = defaultSubtypeId;
+ InputMethodSubtype applicableSubtype = null;
for (int i = 0; i < subtypes.size(); ++i) {
- final String subtypeLocale = subtypes.get(i).getLocale();
+ InputMethodSubtype subtype = subtypes.get(i);
+ final String subtypeLocale = subtype.getLocale();
// 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;
+ applicableSubtype = subtype;
break;
} else if (!partialMatchFound && subtypeLocale.startsWith(language)) {
// Partial match (e.g. system locale is "en_US" and subtype locale is "en")
- applicableSubtypeId = i;
+ applicableSubtype = subtype;
partialMatchFound = true;
}
}
@@ -1972,10 +1979,10 @@
// 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: " + applicableSubtypeId + ","
- + subtypes.get(applicableSubtypeId).getLocale());
+ Slog.d(TAG, "Applicable InputMethodSubtype was found: " + applicableSubtype.getMode()
+ + "," + applicableSubtype.getLocale());
}
- return applicableSubtypeId;
+ return applicableSubtype;
}
// If there are no selected shortcuts, tries finding the most applicable ones.
@@ -1983,59 +1990,66 @@
findLastResortApplicableShortcutInputMethodAndSubtypeLocked(String mode) {
List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked();
InputMethodInfo mostApplicableIMI = null;
- int mostApplicableSubtypeId = NOT_A_SUBTYPE_ID;
+ InputMethodSubtype mostApplicableSubtype = null;
boolean foundInSystemIME = false;
// Search applicable subtype for each InputMethodInfo
for (InputMethodInfo imi: imis) {
- int subtypeId = NOT_A_SUBTYPE_ID;
+ InputMethodSubtype subtype = null;
if (mCurrentSubtype != null) {
// 1. Search with the current subtype's locale and the enabled subtypes
- subtypeId = findLastResortApplicableSubtypeLocked(
+ subtype = findLastResortApplicableSubtypeLocked(
mSettings.getEnabledInputMethodSubtypeListLocked(
imi), mode, mCurrentSubtype.getLocale(), NOT_A_SUBTYPE_ID);
- if (subtypeId == NOT_A_SUBTYPE_ID) {
+ if (subtype == null) {
// 2. Search with the current subtype's locale and all subtypes
- subtypeId = findLastResortApplicableSubtypeLocked(imi.getSubtypes(),
+ subtype = 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(
+ if (subtype == null) {
+ subtype = findLastResortApplicableSubtypeLocked(
mSettings.getEnabledInputMethodSubtypeListLocked(
imi), mode, null, NOT_A_SUBTYPE_ID);
}
- if (subtypeId == NOT_A_SUBTYPE_ID) {
+ if (subtype == null) {
// 4. Search with the system locale and all subtypes
- subtypeId = findLastResortApplicableSubtypeLocked(imi.getSubtypes(),
+ subtype = findLastResortApplicableSubtypeLocked(imi.getSubtypes(),
mode, null, NOT_A_SUBTYPE_ID);
}
- if (subtypeId != NOT_A_SUBTYPE_ID) {
+ if (subtype != null) {
if (imi.getId().equals(mCurMethodId)) {
// The current input method is the most applicable IME.
mostApplicableIMI = imi;
- mostApplicableSubtypeId = subtypeId;
+ mostApplicableSubtype = subtype;
break;
} else if ((imi.getServiceInfo().applicationInfo.flags
& ApplicationInfo.FLAG_SYSTEM) != 0) {
// The system input method is 2nd applicable IME.
mostApplicableIMI = imi;
- mostApplicableSubtypeId = subtypeId;
+ mostApplicableSubtype = subtype;
foundInSystemIME = true;
} else if (!foundInSystemIME) {
mostApplicableIMI = imi;
- mostApplicableSubtypeId = subtypeId;
+ mostApplicableSubtype = subtype;
}
}
}
if (DEBUG) {
- Slog.w(TAG, "Most applicable shortcut input method subtype was:"
- + mostApplicableIMI.getId() + "," + mostApplicableSubtypeId);
+ 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 && mostApplicableSubtypeId != NOT_A_SUBTYPE_ID) {
+ if (mostApplicableIMI != null) {
return new Pair<InputMethodInfo, InputMethodSubtype> (mostApplicableIMI,
- mostApplicableIMI.getSubtypes().get(mostApplicableSubtypeId));
+ mostApplicableSubtype);
} else {
return null;
}
@@ -2063,15 +2077,12 @@
// 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(),
+ mCurrentSubtype = findLastResortApplicableSubtypeLocked(imi.getSubtypes(),
SUBTYPE_MODE_KEYBOARD, null, DEFAULT_SUBTYPE_ID);
}
- }
- if (subtypeId != NOT_A_SUBTYPE_ID) {
+ } else {
mCurrentSubtype =
mMethodMap.get(lastInputMethodId).getSubtypes().get(subtypeId);
- } else {
- mCurrentSubtype = null;
}
}
return mCurrentSubtype;
@@ -2101,7 +2112,7 @@
SUBTYPE_MODE_VOICE);
addShortcutInputMethodAndSubtypes(info.first, info.second);
}
- ArrayList ret = new ArrayList<Object>();
+ ArrayList<Object> ret = new ArrayList<Object>();
for (InputMethodInfo imi: mShortcutInputMethodsAndSubtypes.keySet()) {
ret.add(imi);
for (InputMethodSubtype subtype: mShortcutInputMethodsAndSubtypes.get(imi)) {