Merge "Fix InputMethodInfo cache in RichInputMethodManager"

main
Tadashi G. Takaoka 2014-03-03 15:16:54 +00:00 committed by Android (Google) Code Review
commit 8df489444d
1 changed files with 48 additions and 25 deletions

View File

@ -50,7 +50,7 @@ public final class RichInputMethodManager {
private static final RichInputMethodManager sInstance = new RichInputMethodManager(); private static final RichInputMethodManager sInstance = new RichInputMethodManager();
private InputMethodManagerCompatWrapper mImmWrapper; private InputMethodManagerCompatWrapper mImmWrapper;
private InputMethodInfo mInputMethodInfoOfThisIme; private InputMethodInfoCache mInputMethodInfoCache;
final HashMap<InputMethodInfo, List<InputMethodSubtype>> final HashMap<InputMethodInfo, List<InputMethodSubtype>>
mSubtypeListCacheWithImplicitlySelectedSubtypes = CollectionUtils.newHashMap(); mSubtypeListCacheWithImplicitlySelectedSubtypes = CollectionUtils.newHashMap();
final HashMap<InputMethodInfo, List<InputMethodSubtype>> final HashMap<InputMethodInfo, List<InputMethodSubtype>>
@ -83,7 +83,8 @@ public final class RichInputMethodManager {
return; return;
} }
mImmWrapper = new InputMethodManagerCompatWrapper(context); mImmWrapper = new InputMethodManagerCompatWrapper(context);
mInputMethodInfoOfThisIme = getInputMethodInfoOfThisIme(context); mInputMethodInfoCache = new InputMethodInfoCache(
mImmWrapper.mImm, context.getPackageName());
// Initialize additional subtypes. // Initialize additional subtypes.
SubtypeLocaleUtils.init(context); SubtypeLocaleUtils.init(context);
@ -99,20 +100,10 @@ public final class RichInputMethodManager {
return mImmWrapper.mImm; return mImmWrapper.mImm;
} }
private InputMethodInfo getInputMethodInfoOfThisIme(final Context context) {
final String packageName = context.getPackageName();
for (final InputMethodInfo imi : mImmWrapper.mImm.getInputMethodList()) {
if (imi.getPackageName().equals(packageName)) {
return imi;
}
}
throw new RuntimeException("Input method id for " + packageName + " not found.");
}
public List<InputMethodSubtype> getMyEnabledInputMethodSubtypeList( public List<InputMethodSubtype> getMyEnabledInputMethodSubtypeList(
boolean allowsImplicitlySelectedSubtypes) { boolean allowsImplicitlySelectedSubtypes) {
return getEnabledInputMethodSubtypeList(mInputMethodInfoOfThisIme, return getEnabledInputMethodSubtypeList(
allowsImplicitlySelectedSubtypes); getInputMethodInfoOfThisIme(), allowsImplicitlySelectedSubtypes);
} }
public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) { public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) {
@ -153,10 +144,10 @@ public final class RichInputMethodManager {
private boolean switchToNextInputMethodAndSubtype(final IBinder token) { private boolean switchToNextInputMethodAndSubtype(final IBinder token) {
final InputMethodManager imm = mImmWrapper.mImm; final InputMethodManager imm = mImmWrapper.mImm;
final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList(); final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
final int currentIndex = getImiIndexInList(mInputMethodInfoOfThisIme, enabledImis); final int currentIndex = getImiIndexInList(getInputMethodInfoOfThisIme(), enabledImis);
if (currentIndex == INDEX_NOT_FOUND) { if (currentIndex == INDEX_NOT_FOUND) {
Log.w(TAG, "Can't find current IME in enabled IMEs: IME package=" Log.w(TAG, "Can't find current IME in enabled IMEs: IME package="
+ mInputMethodInfoOfThisIme.getPackageName()); + getInputMethodInfoOfThisIme().getPackageName());
return false; return false;
} }
final InputMethodInfo nextImi = getNextNonAuxiliaryIme(currentIndex, enabledImis); final InputMethodInfo nextImi = getNextNonAuxiliaryIme(currentIndex, enabledImis);
@ -213,16 +204,45 @@ public final class RichInputMethodManager {
return true; return true;
} }
private static class InputMethodInfoCache {
private final InputMethodManager mImm;
private final String mImePackageName;
private InputMethodInfo mCachedValue;
public InputMethodInfoCache(final InputMethodManager imm, final String imePackageName) {
mImm = imm;
mImePackageName = imePackageName;
}
public synchronized InputMethodInfo get() {
if (mCachedValue != null) {
return mCachedValue;
}
for (final InputMethodInfo imi : mImm.getInputMethodList()) {
if (imi.getPackageName().equals(mImePackageName)) {
mCachedValue = imi;
return imi;
}
}
throw new RuntimeException("Input method id for " + mImePackageName + " not found.");
}
public synchronized void clear() {
mCachedValue = null;
}
}
public InputMethodInfo getInputMethodInfoOfThisIme() { public InputMethodInfo getInputMethodInfoOfThisIme() {
return mInputMethodInfoOfThisIme; return mInputMethodInfoCache.get();
} }
public String getInputMethodIdOfThisIme() { public String getInputMethodIdOfThisIme() {
return mInputMethodInfoOfThisIme.getId(); return getInputMethodInfoOfThisIme().getId();
} }
public boolean checkIfSubtypeBelongsToThisImeAndEnabled(final InputMethodSubtype subtype) { public boolean checkIfSubtypeBelongsToThisImeAndEnabled(final InputMethodSubtype subtype) {
return checkIfSubtypeBelongsToImeAndEnabled(mInputMethodInfoOfThisIme, subtype); return checkIfSubtypeBelongsToImeAndEnabled(getInputMethodInfoOfThisIme(), subtype);
} }
public boolean checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled( public boolean checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(
@ -258,7 +278,7 @@ public final class RichInputMethodManager {
} }
public boolean checkIfSubtypeBelongsToThisIme(final InputMethodSubtype subtype) { public boolean checkIfSubtypeBelongsToThisIme(final InputMethodSubtype subtype) {
return getSubtypeIndexInIme(subtype, mInputMethodInfoOfThisIme) != INDEX_NOT_FOUND; return getSubtypeIndexInIme(subtype, getInputMethodInfoOfThisIme()) != INDEX_NOT_FOUND;
} }
private static int getSubtypeIndexInIme(final InputMethodSubtype subtype, private static int getSubtypeIndexInIme(final InputMethodSubtype subtype,
@ -286,7 +306,8 @@ public final class RichInputMethodManager {
public boolean hasMultipleEnabledSubtypesInThisIme( public boolean hasMultipleEnabledSubtypesInThisIme(
final boolean shouldIncludeAuxiliarySubtypes) { final boolean shouldIncludeAuxiliarySubtypes) {
final List<InputMethodInfo> imiList = Collections.singletonList(mInputMethodInfoOfThisIme); final List<InputMethodInfo> imiList = Collections.singletonList(
getInputMethodInfoOfThisIme());
return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList);
} }
@ -340,7 +361,7 @@ public final class RichInputMethodManager {
public InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet(final String localeString, public InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet(final String localeString,
final String keyboardLayoutSetName) { final String keyboardLayoutSetName) {
final InputMethodInfo myImi = mInputMethodInfoOfThisIme; final InputMethodInfo myImi = getInputMethodInfoOfThisIme();
final int count = myImi.getSubtypeCount(); final int count = myImi.getSubtypeCount();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
final InputMethodSubtype subtype = myImi.getSubtypeAt(i); final InputMethodSubtype subtype = myImi.getSubtypeAt(i);
@ -355,13 +376,14 @@ public final class RichInputMethodManager {
public void setInputMethodAndSubtype(final IBinder token, final InputMethodSubtype subtype) { public void setInputMethodAndSubtype(final IBinder token, final InputMethodSubtype subtype) {
mImmWrapper.mImm.setInputMethodAndSubtype( mImmWrapper.mImm.setInputMethodAndSubtype(
token, mInputMethodInfoOfThisIme.getId(), subtype); token, getInputMethodIdOfThisIme(), subtype);
} }
public void setAdditionalInputMethodSubtypes(final InputMethodSubtype[] subtypes) { public void setAdditionalInputMethodSubtypes(final InputMethodSubtype[] subtypes) {
mImmWrapper.mImm.setAdditionalInputMethodSubtypes( mImmWrapper.mImm.setAdditionalInputMethodSubtypes(
mInputMethodInfoOfThisIme.getId(), subtypes); getInputMethodIdOfThisIme(), subtypes);
// Clear the cache so that we go read the subtypes again next time. // Clear the cache so that we go read the {@link InputMethodInfo} of this IME and list of
// subtypes again next time.
clearSubtypeCaches(); clearSubtypeCaches();
} }
@ -382,5 +404,6 @@ public final class RichInputMethodManager {
public void clearSubtypeCaches() { public void clearSubtypeCaches() {
mSubtypeListCacheWithImplicitlySelectedSubtypes.clear(); mSubtypeListCacheWithImplicitlySelectedSubtypes.clear();
mSubtypeListCacheWithoutImplicitlySelectedSubtypes.clear(); mSubtypeListCacheWithoutImplicitlySelectedSubtypes.clear();
mInputMethodInfoCache.clear();
} }
} }