Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6fe4865e authored by Yohei Yukawa's avatar Yohei Yukawa Committed by Android (Google) Code Review
Browse files

Merge "Quick workaround for a performance regression in IME APIs." into nyc-dev

parents 8e3a16ad ccb024aa
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -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();