diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index e20ec88fa5c3ad4509bf411a2de4b6308af0a886..bd660c5f31f92fd7cc4ce27d99f6822260061e62 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -591,7 +591,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         // 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.
@@ -867,7 +866,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     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.
-        mSubtypeSwitcher.onSubtypeChanged(subtype);
+        mRichImm.onSubtypeChanged(subtype);
+        mSubtypeSwitcher.onSubtypeChanged(mRichImm.getCurrentSubtype());
         mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype),
                 mSettings.getCurrent());
         loadKeyboard();
@@ -883,8 +883,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
         // Switch to the null consumer to handle cases leading to early exit below, for which we
         // also wouldn't be consuming gesture data.
         mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER;
-        mRichImm.clearSubtypeCaches();
-        mSubtypeSwitcher.onSubtypeChanged(mRichImm.getCurrentRawSubtype());
+        mRichImm.refreshSubtypeCaches();
+        mSubtypeSwitcher.onSubtypeChanged(mRichImm.getCurrentSubtype());
         final KeyboardSwitcher switcher = mKeyboardSwitcher;
         switcher.updateKeyboardTheme();
         final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
@@ -1453,7 +1453,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
     // completely replace #onCodeInput.
     public void onEvent(@Nonnull final Event event) {
         if (Constants.CODE_SHORTCUT == event.mKeyCode) {
-            mRichImm.switchToShortcutIME(this);
+            mRichImm.switchToShortcutIme(this);
         }
         final InputTransaction completeInputTransaction =
                 mInputLogic.onCodeInput(mSettings.getCurrent(), event,
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index 686c3a4b24c8a5129453ff3d7b83650dcc400b5a..4621217892a2b3510784fe0d564ffeeafef0b21f 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -111,7 +111,11 @@ public class RichInputMethodManager {
         // Initialize additional subtypes.
         SubtypeLocaleUtils.init(context);
         final InputMethodSubtype[] additionalSubtypes = getAdditionalSubtypes();
-        setAdditionalInputMethodSubtypes(additionalSubtypes);
+        mImmWrapper.mImm.setAdditionalInputMethodSubtypes(
+                getInputMethodIdOfThisIme(), additionalSubtypes);
+
+        // Initialize the current input method subtype and the shortcut IME.
+        refreshSubtypeCaches();
 
         final ConnectivityManager connectivityManager =
                 (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -324,23 +328,22 @@ public class RichInputMethodManager {
         return INDEX_NOT_FOUND;
     }
 
-    @Nonnull
-    public RichInputMethodSubtype onSubtypeChanged(@Nonnull final InputMethodSubtype newSubtype) {
-        final RichInputMethodSubtype richSubtype = createCurrentRichInputMethodSubtype(newSubtype);
+    public void onSubtypeChanged(@Nonnull final InputMethodSubtype newSubtype) {
+        updateCurrentSubtype(newSubtype);
+        updateShortcutIme();
         if (DEBUG) {
-            Log.w(TAG, "onSubtypeChanged: " + richSubtype.getNameForLogging());
+            Log.w(TAG, "onSubtypeChanged: " + mCurrentRichInputMethodSubtype.getNameForLogging());
         }
-        mCurrentRichInputMethodSubtype = richSubtype;
-        return richSubtype;
     }
 
     private static RichInputMethodSubtype sForcedSubtypeForTesting = null;
 
     @UsedForTesting
-    static void forceSubtype(final InputMethodSubtype subtype) {
+    static void forceSubtype(@Nonnull final InputMethodSubtype subtype) {
         sForcedSubtypeForTesting = new RichInputMethodSubtype(subtype);
     }
 
+    @Nonnull
     public Locale[] getCurrentSubtypeLocales() {
         if (null != sForcedSubtypeForTesting) {
             return sForcedSubtypeForTesting.getLocales();
@@ -348,6 +351,7 @@ public class RichInputMethodManager {
         return getCurrentSubtype().getLocales();
     }
 
+    @Nonnull
     public RichInputMethodSubtype getCurrentSubtype() {
         if (null != sForcedSubtypeForTesting) {
             return sForcedSubtypeForTesting;
@@ -360,18 +364,6 @@ public class RichInputMethodManager {
         return SubtypeLocaleUtils.getCombiningRulesExtraValue(getCurrentSubtype().getRawSubtype());
     }
 
-    @Nonnull
-    public InputMethodSubtype getCurrentRawSubtype() {
-        return mImmWrapper.mImm.getCurrentInputMethodSubtype();
-    }
-
-    @Nonnull
-    public RichInputMethodSubtype createCurrentRichInputMethodSubtype(
-            @Nonnull final InputMethodSubtype rawSubtype) {
-        return AdditionalFeaturesSettingUtils.createRichInputMethodSubtype(this, rawSubtype,
-                mContext);
-    }
-
     public boolean hasMultipleEnabledIMEsOrSubtypes(final boolean shouldIncludeAuxiliarySubtypes) {
         final List<InputMethodInfo> enabledImis = mImmWrapper.mImm.getEnabledInputMethodList();
         return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis);
@@ -457,7 +449,7 @@ public class RichInputMethodManager {
                 getInputMethodIdOfThisIme(), subtypes);
         // Clear the cache so that we go read the {@link InputMethodInfo} of this IME and list of
         // subtypes again next time.
-        clearSubtypeCaches();
+        refreshSubtypeCaches();
     }
 
     private List<InputMethodSubtype> getEnabledInputMethodSubtypeList(final InputMethodInfo imi,
@@ -474,10 +466,12 @@ public class RichInputMethodManager {
         return result;
     }
 
-    public void clearSubtypeCaches() {
+    public void refreshSubtypeCaches() {
         mSubtypeListCacheWithImplicitlySelectedSubtypes.clear();
         mSubtypeListCacheWithoutImplicitlySelectedSubtypes.clear();
         mInputMethodInfoCache.clear();
+        updateCurrentSubtype(mImmWrapper.mImm.getCurrentInputMethodSubtype());
+        updateShortcutIme();
     }
 
     public boolean shouldOfferSwitchingToNextInputMethod(final IBinder binder,
@@ -516,8 +510,13 @@ public class RichInputMethodManager {
         return true;
     }
 
-    // TODO: Make this private
-    void updateShortcutIME() {
+    private void updateCurrentSubtype(@Nonnull final InputMethodSubtype subtype) {
+        final RichInputMethodSubtype richSubtype = AdditionalFeaturesSettingUtils
+                .createRichInputMethodSubtype(this, subtype, mContext);
+        mCurrentRichInputMethodSubtype = richSubtype;
+    }
+
+    private void updateShortcutIme() {
         if (DEBUG) {
             Log.d(TAG, "Update shortcut IME from : "
                     + (mShortcutInputMethodInfo == null
@@ -549,7 +548,7 @@ public class RichInputMethodManager {
         }
     }
 
-    public void switchToShortcutIME(final InputMethodService context) {
+    public void switchToShortcutIme(final InputMethodService context) {
         if (mShortcutInputMethodInfo == null) {
             return;
         }
@@ -575,19 +574,16 @@ public class RichInputMethodManager {
     }
 
     public boolean isShortcutImeEnabled() {
-        updateShortcutIME();
         if (mShortcutInputMethodInfo == null) {
             return false;
         }
         if (mShortcutSubtype == null) {
             return true;
         }
-        return checkIfSubtypeBelongsToImeAndEnabled(
-                mShortcutInputMethodInfo, mShortcutSubtype);
+        return checkIfSubtypeBelongsToImeAndEnabled(mShortcutInputMethodInfo, mShortcutSubtype);
     }
 
     public boolean isShortcutImeReady() {
-        updateShortcutIME();
         if (mShortcutInputMethodInfo == null) {
             return false;
         }
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 23e348bff29dfc1a7924a261746b1404e71af8e4..92ba6c2d901184cb63de68481c6e8712d2b11f1c 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -57,7 +57,7 @@ public final class SubtypeSwitcher {
         mResources = context.getResources();
         mRichImm = RichInputMethodManager.getInstance();
 
-        onSubtypeChanged(mRichImm.getCurrentRawSubtype());
+        onSubtypeChanged(mRichImm.getCurrentSubtype());
         updateParametersOnStartInputView();
     }
 
@@ -69,17 +69,14 @@ public final class SubtypeSwitcher {
         final List<InputMethodSubtype> enabledSubtypesOfThisIme =
                 mRichImm.getMyEnabledInputMethodSubtypeList(true);
         mLanguageOnSpacebarHelper.onUpdateEnabledSubtypes(enabledSubtypesOfThisIme);
-        mRichImm.updateShortcutIME();
     }
 
     // Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function.
-    public void onSubtypeChanged(@Nonnull final InputMethodSubtype newSubtype) {
-        final RichInputMethodSubtype richSubtype = mRichImm.onSubtypeChanged(newSubtype);
+    public void onSubtypeChanged(@Nonnull final RichInputMethodSubtype richSubtype) {
         final boolean implicitlyEnabledSubtype = mRichImm
-                .checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(newSubtype);
+                .checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(richSubtype.getRawSubtype());
         mLanguageOnSpacebarHelper.onSubtypeChanged(
                 richSubtype, implicitlyEnabledSubtype, mResources.getConfiguration().locale);
-        mRichImm.updateShortcutIME();
     }
 
     public int getLanguageOnSpacebarFormatType(final RichInputMethodSubtype subtype) {
diff --git a/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java
index c0ceb8857b5fcac3f1724c32aee19c21fab910de..975396d2d09bfbd09bd69a5ee06c1a7f18546cc2 100644
--- a/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/PreferencesSettingsFragment.java
@@ -71,6 +71,7 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
         super.onResume();
         final Preference voiceInputKeyOption = findPreference(Settings.PREF_VOICE_INPUT_KEY);
         if (voiceInputKeyOption != null) {
+            RichInputMethodManager.getInstance().refreshSubtypeCaches();
             final boolean isShortcutImeEnabled = RichInputMethodManager.getInstance()
                     .isShortcutImeEnabled();
             voiceInputKeyOption.setEnabled(isShortcutImeEnabled);