Do not merge. Backport two fixes for InputMethethodFramework

Bug: 3420384

backport cl1: Iaf293cf6c6fb35a994f344b0afc30e9f523032f4
backport cl2: I29d2555aeb7d0e51205d9f1fe0da708df0890942

Change-Id: Ia71ba27957fa818dc4ef8ff05b5fdb120b9650e0
This commit is contained in:
satok
2011-05-20 18:19:53 +09:00
parent 69cb87576b
commit b4788fdbfd
2 changed files with 65 additions and 29 deletions

View File

@ -60,8 +60,7 @@ public final class InputMethodSubtype implements Parcelable {
mSubtypeLocale = locale != null ? locale : ""; mSubtypeLocale = locale != null ? locale : "";
mSubtypeMode = mode != null ? mode : ""; mSubtypeMode = mode != null ? mode : "";
mSubtypeExtraValue = extraValue != null ? extraValue : ""; mSubtypeExtraValue = extraValue != null ? extraValue : "";
mSubtypeHashCode = hashCodeInternal(mSubtypeNameResId, mSubtypeIconResId, mSubtypeLocale, mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeMode, mSubtypeExtraValue);
mSubtypeMode, mSubtypeExtraValue);
} }
InputMethodSubtype(Parcel source) { InputMethodSubtype(Parcel source) {
@ -74,8 +73,7 @@ public final class InputMethodSubtype implements Parcelable {
mSubtypeMode = s != null ? s : ""; mSubtypeMode = s != null ? s : "";
s = source.readString(); s = source.readString();
mSubtypeExtraValue = s != null ? s : ""; mSubtypeExtraValue = s != null ? s : "";
mSubtypeHashCode = hashCodeInternal(mSubtypeNameResId, mSubtypeIconResId, mSubtypeLocale, mSubtypeHashCode = hashCodeInternal(mSubtypeLocale, mSubtypeMode, mSubtypeExtraValue);
mSubtypeMode, mSubtypeExtraValue);
} }
/** /**
@ -195,9 +193,8 @@ public final class InputMethodSubtype implements Parcelable {
} }
}; };
private static int hashCodeInternal(int nameResId, int iconResId, String locale, private static int hashCodeInternal(String locale, String mode, String extraValue) {
String mode, String extraValue) { return Arrays.hashCode(new Object[] {locale, mode, extraValue});
return Arrays.hashCode(new Object[] {nameResId, iconResId, locale, mode, extraValue});
} }
/** /**

View File

@ -1371,33 +1371,72 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
} }
@Override
public boolean switchToLastInputMethod(IBinder token) { public boolean switchToLastInputMethod(IBinder token) {
synchronized (mMethodMap) { synchronized (mMethodMap) {
final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked(); final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
if (lastIme == null) return false; final InputMethodInfo lastImi;
final InputMethodInfo lastImi = mMethodMap.get(lastIme.first); if (lastIme != null) {
if (lastImi == null) return false; lastImi = mMethodMap.get(lastIme.first);
} else {
lastImi = null;
}
String targetLastImiId = null;
int subtypeId = NOT_A_SUBTYPE_ID;
if (lastIme != null && lastImi != null) {
final boolean imiIdIsSame = lastImi.getId().equals(mCurMethodId); final boolean imiIdIsSame = lastImi.getId().equals(mCurMethodId);
final int lastSubtypeHash = Integer.valueOf(lastIme.second); final int lastSubtypeHash = Integer.valueOf(lastIme.second);
// If the last IME is the same as the current IME and the last subtype is not defined, final int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID
// there is no need to switch to the last IME.
if (imiIdIsSame && lastSubtypeHash == NOT_A_SUBTYPE_ID) return false;
int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID
: mCurrentSubtype.hashCode(); : mCurrentSubtype.hashCode();
// If the last IME is the same as the current IME and the last subtype is not
// defined, there is no need to switch to the last IME.
if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) { if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) {
targetLastImiId = lastIme.first;
subtypeId = getSubtypeIdFromHashCode(lastImi, lastSubtypeHash);
}
}
if (TextUtils.isEmpty(targetLastImiId) && !canAddToLastInputMethod(mCurrentSubtype)) {
// This is a safety net. If the currentSubtype can't be added to the history
// and the framework couldn't find the last ime, we will make the last ime be
// the most applicable enabled keyboard subtype of the system imes.
final List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();
if (enabled != null) {
final int N = enabled.size();
final String locale = mCurrentSubtype == null
? mRes.getConfiguration().locale.toString()
: mCurrentSubtype.getLocale();
for (int i = 0; i < N; ++i) {
final InputMethodInfo imi = enabled.get(i);
if (imi.getSubtypeCount() > 0 && isSystemIme(imi)) {
InputMethodSubtype keyboardSubtype =
findLastResortApplicableSubtypeLocked(mRes, getSubtypes(imi),
SUBTYPE_MODE_KEYBOARD, locale, true);
if (keyboardSubtype != null) {
targetLastImiId = imi.getId();
subtypeId = getSubtypeIdFromHashCode(
imi, keyboardSubtype.hashCode());
if(keyboardSubtype.getLocale().equals(locale)) {
break;
}
}
}
}
}
}
if (!TextUtils.isEmpty(targetLastImiId)) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second + ", from: " Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second
+ mCurMethodId + ", " + currentSubtypeHash); + ", from: " + mCurMethodId + ", " + subtypeId);
} }
setInputMethodWithSubtypeId(token, lastIme.first, getSubtypeIdFromHashCode( setInputMethodWithSubtypeId(token, targetLastImiId, subtypeId);
lastImi, lastSubtypeHash));
return true; return true;
} } else {
return false; return false;
} }
} }
}
private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) { private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) {
synchronized (mMethodMap) { synchronized (mMethodMap) {
@ -2601,7 +2640,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
List<Pair<String, ArrayList<String>>> enabledImes = List<Pair<String, ArrayList<String>>> enabledImes =
getEnabledInputMethodsAndSubtypeListLocked(); getEnabledInputMethodsAndSubtypeListLocked();
List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked(); List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked();
for (Pair<String, String> imeAndSubtype: subtypeHistory) { for (Pair<String, String> imeAndSubtype : subtypeHistory) {
final String imeInTheHistory = imeAndSubtype.first; final String imeInTheHistory = imeAndSubtype.first;
// If imeId is empty, returns the first IME and subtype in the history // If imeId is empty, returns the first IME and subtype in the history
if (TextUtils.isEmpty(imeId) || imeInTheHistory.equals(imeId)) { if (TextUtils.isEmpty(imeId) || imeInTheHistory.equals(imeId)) {