Performance fix for multiple language subtypes

The code would iterate all enabled subtypes each time
getCurrentSubtype() is called, which is really quite frequent.

Bug: 11230254
Change-Id: I91feb36de6eca84967e848fc585aae04b350be89
diff --git a/java-overridable/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java b/java-overridable/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
index 204d5f3..747a3b0 100644
--- a/java-overridable/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
+++ b/java-overridable/src/com/android/inputmethod/latin/settings/AdditionalFeaturesSettingUtils.java
@@ -46,7 +46,7 @@
         // do nothing.
     }
 
-    public static RichInputMethodSubtype getRichInputMethodSubtype(
+    public static RichInputMethodSubtype createRichInputMethodSubtype(
             @Nonnull final RichInputMethodManager imm,
             @Nonnull final InputMethodSubtype subtype) {
         return new RichInputMethodSubtype(subtype);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 3b995f9..77016cb 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -568,6 +568,7 @@
         // TODO: Resolve mutual dependencies of {@link #loadSettings()} and
         // {@link #resetDictionaryFacilitatorIfNecessary()}.
         loadSettings();
+        mSubtypeSwitcher.onSubtypeChanged(mRichImm.getCurrentRawSubtype());
         resetDictionaryFacilitatorIfNecessary();
 
         // Register to receive ringer mode change and network state change.
@@ -837,8 +838,7 @@
     public void onCurrentInputMethodSubtypeChanged(final InputMethodSubtype subtype) {
         // Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
         // is not guaranteed. It may even be called at the same time on a different thread.
-        final RichInputMethodSubtype richSubtype = new RichInputMethodSubtype(subtype);
-        mSubtypeSwitcher.onSubtypeChanged(richSubtype);
+        mSubtypeSwitcher.onSubtypeChanged(subtype);
         mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype),
                 mSettings.getCurrent());
         loadKeyboard();
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index b4ec8d6..3fcae58 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -299,13 +299,13 @@
         return INDEX_NOT_FOUND;
     }
 
-    public RichInputMethodSubtype getCurrentInputMethodSubtype(
-            final RichInputMethodSubtype defaultSubtype) {
-        final InputMethodSubtype currentSubtype = mImmWrapper.mImm.getCurrentInputMethodSubtype();
-        if (currentSubtype == null) {
-            return defaultSubtype;
-        }
-        return AdditionalFeaturesSettingUtils.getRichInputMethodSubtype(this, currentSubtype);
+    public InputMethodSubtype getCurrentRawSubtype() {
+        return mImmWrapper.mImm.getCurrentInputMethodSubtype();
+    }
+
+    public RichInputMethodSubtype createCurrentRichInputMethodSubtype(
+            final InputMethodSubtype rawSubtype) {
+        return AdditionalFeaturesSettingUtils.createRichInputMethodSubtype(this, rawSubtype);
     }
 
     public boolean hasMultipleEnabledIMEsOrSubtypes(final boolean shouldIncludeAuxiliarySubtypes) {
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index c339e96..0d742e9 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -58,6 +58,7 @@
             new LanguageOnSpacebarHelper();
     private InputMethodInfo mShortcutInputMethodInfo;
     private InputMethodSubtype mShortcutSubtype;
+    private RichInputMethodSubtype mCurrentRichInputMethodSubtype;
     private RichInputMethodSubtype mNoLanguageSubtype;
     private RichInputMethodSubtype mEmojiSubtype;
     private boolean mIsNetworkConnected;
@@ -117,7 +118,7 @@
         final NetworkInfo info = connectivityManager.getActiveNetworkInfo();
         mIsNetworkConnected = (info != null && info.isConnected());
 
-        onSubtypeChanged(getCurrentSubtype());
+        onSubtypeChanged(mRichImm.getCurrentRawSubtype());
         updateParametersOnStartInputView();
     }
 
@@ -165,12 +166,14 @@
     }
 
     // Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function.
-    public void onSubtypeChanged(final RichInputMethodSubtype newSubtype) {
+    public void onSubtypeChanged(final InputMethodSubtype newSubtype) {
+        final RichInputMethodSubtype richSubtype =
+                mRichImm.createCurrentRichInputMethodSubtype(newSubtype);
         if (DBG) {
-            Log.w(TAG, "onSubtypeChanged: " + newSubtype.getNameForLogging());
+            Log.w(TAG, "onSubtypeChanged: " + richSubtype.getNameForLogging());
         }
-
-        final Locale[] newLocales = newSubtype.getLocales();
+        mCurrentRichInputMethodSubtype = richSubtype;
+        final Locale[] newLocales = richSubtype.getLocales();
         if (newLocales.length > 1) {
             // In multi-locales mode, the system language is never the same as the input language
             // because there is no single input language.
@@ -181,7 +184,7 @@
             final boolean sameLocale = systemLocale.equals(newLocale);
             final boolean sameLanguage = systemLocale.getLanguage().equals(newLocale.getLanguage());
             final boolean implicitlyEnabled = mRichImm
-                    .checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype.getRawSubtype());
+                    .checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype);
             mLanguageOnSpacebarHelper.updateIsSystemLanguageSameAsInputLanguage(
                     sameLocale || (sameLanguage && implicitlyEnabled));
         }
@@ -301,7 +304,7 @@
         if (null != sForcedSubtypeForTesting) {
             return sForcedSubtypeForTesting;
         }
-        return mRichImm.getCurrentInputMethodSubtype(getNoLanguageSubtype());
+        return mCurrentRichInputMethodSubtype;
     }
 
     public RichInputMethodSubtype getNoLanguageSubtype() {