diff options
| -rw-r--r-- | core/java/com/android/internal/inputmethod/InputMethodUtils.java | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java index a028449e39d7..716997f815dc 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java +++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java @@ -41,6 +41,7 @@ import android.view.inputmethod.InputMethodSubtype; import android.view.textservice.SpellCheckerInfo; import android.view.textservice.TextServicesManager; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; @@ -83,6 +84,17 @@ public class InputMethodUtils { Locale.UK, // "en_GB" }; + // A temporary workaround for the performance concerns in + // #getImplicitlyApplicableSubtypesLocked(Resources, InputMethodInfo). + // TODO: Optimize all the critical paths including this one. + private static final Object sCacheLock = new Object(); + @GuardedBy("sCacheLock") + private static LocaleList sCachedSystemLocales; + @GuardedBy("sCacheLock") + private static InputMethodInfo sCachedInputMethodInfo; + @GuardedBy("sCacheLock") + private static ArrayList<InputMethodSubtype> sCachedResult; + private InputMethodUtils() { // This utility class is not publicly instantiable. } @@ -498,6 +510,32 @@ public class InputMethodUtils { @VisibleForTesting public static ArrayList<InputMethodSubtype> getImplicitlyApplicableSubtypesLocked( Resources res, InputMethodInfo imi) { + final LocaleList systemLocales = res.getConfiguration().getLocales(); + + synchronized (sCacheLock) { + // We intentionally do not use InputMethodInfo#equals(InputMethodInfo) here because + // it does not check if subtypes are also identical. + if (systemLocales.equals(sCachedSystemLocales) && sCachedInputMethodInfo == imi) { + return new ArrayList<>(sCachedResult); + } + } + + // Note: Only resource info in "res" is used in getImplicitlyApplicableSubtypesLockedImpl(). + // TODO: Refactor getImplicitlyApplicableSubtypesLockedImpl() so that it can receive + // LocaleList rather than Resource. + final ArrayList<InputMethodSubtype> result = + getImplicitlyApplicableSubtypesLockedImpl(res, imi); + synchronized (sCacheLock) { + // Both LocaleList and InputMethodInfo are immutable. No need to copy them here. + sCachedSystemLocales = systemLocales; + sCachedInputMethodInfo = imi; + sCachedResult = new ArrayList<>(result); + } + return result; + } + + private static ArrayList<InputMethodSubtype> getImplicitlyApplicableSubtypesLockedImpl( + Resources res, InputMethodInfo imi) { final List<InputMethodSubtype> subtypes = InputMethodUtils.getSubtypes(imi); final LocaleList systemLocales = res.getConfiguration().getLocales(); final String systemLocale = systemLocales.get(0).toString(); |