diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 1dd7b06dd6a38b4e198a186d1f8858759b995352..4d10f0e696b415a637fe47885d8563e9c952e272 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -1443,9 +1443,9 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
     //  fr_CA qwerty  F  Fr  Français  Français (Canada)
     //  de    qwertz  F  De  Deutsch   Deutsch
     //  zz    qwerty  F      QWERTY    QWERTY
-    //  fr    qwertz  T  Fr  Français  Français (QWERTZ)
-    //  de    qwerty  T  De  Deutsch   Deutsch (QWERTY)
-    //  en_US azerty  T  En  English   English (US) (AZERTY)
+    //  fr    qwertz  T  Fr  Français  Français
+    //  de    qwerty  T  De  Deutsch   Deutsch
+    //  en_US azerty  T  En  English   English (US)
     //  zz    azerty  T      AZERTY    AZERTY
 
     // Get InputMethodSubtype's full display name in its locale.
@@ -1453,8 +1453,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
         if (SubtypeLocale.isNoLanguage(subtype)) {
             return SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype);
         }
-
-        return SubtypeLocale.getSubtypeDisplayName(subtype);
+        return SubtypeLocale.getSubtypeLocaleDisplayName(subtype.getLocale());
     }
 
     // Get InputMethodSubtype's short display name in its locale.
@@ -1472,6 +1471,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
             return SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype);
         }
         final Locale locale = SubtypeLocale.getSubtypeLocale(subtype);
-        return StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale);
+        return SubtypeLocale.getSubtypeLocaleDisplayName(locale.getLanguage());
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
index 2f26f9296f43a1872768f8d56e8f9d2dc409015e..9cbfe66985d9db590cb68d3441bb453c8f3e64ba 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
@@ -140,26 +140,32 @@ public final class SubtypeLocale {
                 && isExceptionalLocale(localeString)) {
             return sExceptionalLocaleToWithLayoutNameIdsMap.get(localeString);
         }
-        final String key = localeString.equals(NO_LANGUAGE)
+        final String key = NO_LANGUAGE.equals(localeString)
                 ? getNoLanguageLayoutKey(keyboardLayoutName)
                 : keyboardLayoutName;
         final Integer nameId = sKeyboardLayoutToNameIdsMap.get(key);
         return nameId == null ? UNKNOWN_KEYBOARD_LAYOUT : nameId;
     }
 
+    private static Locale getDisplayLocaleOfSubtypeLocale(final String localeString) {
+        if (NO_LANGUAGE.equals(localeString)) {
+            return sResources.getConfiguration().locale;
+        }
+        return LocaleUtils.constructLocaleFromString(localeString);
+    }
+
     public static String getSubtypeLocaleDisplayNameInSystemLocale(final String localeString) {
         final Locale displayLocale = sResources.getConfiguration().locale;
         return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale);
     }
 
     public static String getSubtypeLocaleDisplayName(final String localeString) {
-        final Locale displayLocale = LocaleUtils.constructLocaleFromString(localeString);
+        final Locale displayLocale = getDisplayLocaleOfSubtypeLocale(localeString);
         return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale);
     }
 
     private static String getSubtypeLocaleDisplayNameInternal(final String localeString,
             final Locale displayLocale) {
-        final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
         final Integer exceptionalNameResId = sExceptionalLocaleToNameIdsMap.get(localeString);
         final String displayName;
         if (exceptionalNameResId != null) {
@@ -170,7 +176,11 @@ public final class SubtypeLocale {
                 }
             };
             displayName = getExceptionalName.runInLocale(sResources, displayLocale);
+        } else if (NO_LANGUAGE.equals(localeString)) {
+            // No language subtype should be displayed in system locale.
+            return sResources.getString(R.string.subtype_no_language);
         } else {
+            final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
             displayName = locale.getDisplayName(displayLocale);
         }
         return StringUtils.toTitleCase(displayName, displayLocale);
@@ -203,13 +213,13 @@ public final class SubtypeLocale {
     }
 
     public static String getSubtypeDisplayNameInSystemLocale(final InputMethodSubtype subtype) {
-        final Locale subtypeLocale = sResources.getConfiguration().locale;
-        return getSubtypeDisplayNameInternal(subtype, subtypeLocale);
+        final Locale displayLocale = sResources.getConfiguration().locale;
+        return getSubtypeDisplayNameInternal(subtype, displayLocale);
     }
 
     public static String getSubtypeDisplayName(final InputMethodSubtype subtype) {
-        final Locale subtypeLocale = LocaleUtils.constructLocaleFromString(subtype.getLocale());
-        return getSubtypeDisplayNameInternal(subtype, subtypeLocale);
+        final Locale displayLocale = getDisplayLocaleOfSubtypeLocale(subtype.getLocale());
+        return getSubtypeDisplayNameInternal(subtype, displayLocale);
     }
 
     private static String getSubtypeDisplayNameInternal(final InputMethodSubtype subtype,
@@ -225,6 +235,7 @@ public final class SubtypeLocale {
                     // TODO: Remove this catch when InputMethodManager.getCurrentInputMethodSubtype
                     // is fixed.
                     Log.w(TAG, "Unknown subtype: mode=" + subtype.getMode()
+                            + " nameResId=" + subtype.getNameResId()
                             + " locale=" + subtype.getLocale()
                             + " extra=" + subtype.getExtraValue()
                             + "\n" + Utils.getStackTrace());
@@ -232,15 +243,13 @@ public final class SubtypeLocale {
                 }
             }
         };
-        final Locale locale = isNoLanguage(subtype)
-                ? sResources.getConfiguration().locale : displayLocale;
         return StringUtils.toTitleCase(
-                getSubtypeName.runInLocale(sResources, locale), locale);
+                getSubtypeName.runInLocale(sResources, displayLocale), displayLocale);
     }
 
     public static boolean isNoLanguage(final InputMethodSubtype subtype) {
         final String localeString = subtype.getLocale();
-        return localeString.equals(NO_LANGUAGE);
+        return NO_LANGUAGE.equals(localeString);
     }
 
     public static Locale getSubtypeLocale(final InputMethodSubtype subtype) {
diff --git a/tests/src/com/android/inputmethod/keyboard/SpacebarTextTests.java b/tests/src/com/android/inputmethod/keyboard/SpacebarTextTests.java
index 4db54477c15ac53cad10a999d99f65c6f49ccc21..05b1376357fe6754c54eefd7de1b7deb26fe53a8 100644
--- a/tests/src/com/android/inputmethod/keyboard/SpacebarTextTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/SpacebarTextTests.java
@@ -17,6 +17,7 @@
 package com.android.inputmethod.keyboard;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.test.AndroidTestCase;
 import android.view.inputmethod.InputMethodSubtype;
 
@@ -25,6 +26,7 @@ import com.android.inputmethod.latin.CollectionUtils;
 import com.android.inputmethod.latin.RichInputMethodManager;
 import com.android.inputmethod.latin.StringUtils;
 import com.android.inputmethod.latin.SubtypeLocale;
+import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
 
 import java.util.ArrayList;
 import java.util.Locale;
@@ -34,6 +36,19 @@ public class SpacebarTextTests extends AndroidTestCase {
     private final ArrayList<InputMethodSubtype> mSubtypesList = CollectionUtils.newArrayList();
 
     private RichInputMethodManager mRichImm;
+    private Resources mRes;
+
+    InputMethodSubtype EN_US;
+    InputMethodSubtype EN_GB;
+    InputMethodSubtype ES_US;
+    InputMethodSubtype FR;
+    InputMethodSubtype FR_CA;
+    InputMethodSubtype DE;
+    InputMethodSubtype ZZ;
+    InputMethodSubtype DE_QWERTY;
+    InputMethodSubtype FR_QWERTZ;
+    InputMethodSubtype US_AZERTY;
+    InputMethodSubtype ZZ_AZERTY;
 
     @Override
     protected void setUp() throws Exception {
@@ -41,7 +56,25 @@ public class SpacebarTextTests extends AndroidTestCase {
         final Context context = getContext();
         RichInputMethodManager.init(context);
         mRichImm = RichInputMethodManager.getInstance();
+        mRes = context.getResources();
         SubtypeLocale.init(context);
+
+        EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(Locale.US.toString(), "qwerty");
+        EN_GB = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(Locale.UK.toString(), "qwerty");
+        ES_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet("es_US", "spanish");
+        FR = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(Locale.FRENCH.toString(), "azerty");
+        FR_CA = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+                Locale.CANADA_FRENCH.toString(), "qwerty");
+        DE = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(Locale.GERMAN.toString(), "qwertz");
+        ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(SubtypeLocale.NO_LANGUAGE, "qwerty");
+        DE_QWERTY = AdditionalSubtype.createAdditionalSubtype(
+                Locale.GERMAN.toString(), "qwerty", null);
+        FR_QWERTZ = AdditionalSubtype.createAdditionalSubtype(
+                Locale.FRENCH.toString(), "qwertz", null);
+        US_AZERTY = AdditionalSubtype.createAdditionalSubtype(
+                Locale.US.toString(), "azerty", null);
+        ZZ_AZERTY = AdditionalSubtype.createAdditionalSubtype(
+                SubtypeLocale.NO_LANGUAGE, "azerty", null);
     }
 
     public void testAllFullDisplayName() {
@@ -89,88 +122,92 @@ public class SpacebarTextTests extends AndroidTestCase {
 
     // InputMethodSubtype's display name for spacebar text in its locale.
     //        isAdditionalSubtype (T=true, F=false)
-    // locale layout | Short  Middle      Full
-    // ------ ------ - ---- --------- ----------------------
-    //  en_US qwerty F  En  English   English (US)           exception
-    //  en_GB qwerty F  En  English   English (UK)           exception
-    //  fr    azerty F  Fr  Français  Français
-    //  fr_CA qwerty F  Fr  Français  Français (Canada)
-    //  de    qwertz F  De  Deutsch   Deutsch
-    //  zz    qwerty F      QWERTY    QWERTY
-    //  fr    qwertz T  Fr  Français  Français (QWERTZ)
-    //  de    qwerty T  De  Deutsch   Deutsch (QWERTY)
-    //  en_US azerty T  En  English   English (US) (AZERTY)
-    //  zz    azerty T      AZERTY    AZERTY
-
-    public void testPredefinedSubtypes() {
-        final InputMethodSubtype EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.US.toString(), "qwerty");
-        final InputMethodSubtype EN_GB = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.UK.toString(), "qwerty");
-        final InputMethodSubtype FR = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.FRENCH.toString(), "azerty");
-        final InputMethodSubtype FR_CA = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.CANADA_FRENCH.toString(), "qwerty");
-        final InputMethodSubtype DE = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                Locale.GERMAN.toString(), "qwertz");
-        final InputMethodSubtype ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
-                SubtypeLocale.NO_LANGUAGE, "qwerty");
-
-        assertEquals("en_US", "English (US)",
-                MainKeyboardView.getFullDisplayName(EN_US));
-        assertEquals("en_GB", "English (UK)",
-                MainKeyboardView.getFullDisplayName(EN_GB));
-        assertEquals("fr   ", "Français",
-                MainKeyboardView.getFullDisplayName(FR));
-        assertEquals("fr_CA", "Français (Canada)",
-                MainKeyboardView.getFullDisplayName(FR_CA));
-        assertEquals("de   ", "Deutsch",
-                MainKeyboardView.getFullDisplayName(DE));
-        assertEquals("zz   ", "QWERTY",
-                MainKeyboardView.getFullDisplayName(ZZ));
-
-        assertEquals("en_US", "English",  MainKeyboardView.getMiddleDisplayName(EN_US));
-        assertEquals("en_GB", "English",  MainKeyboardView.getMiddleDisplayName(EN_GB));
-        assertEquals("fr   ", "Français", MainKeyboardView.getMiddleDisplayName(FR));
-        assertEquals("fr_CA", "Français", MainKeyboardView.getMiddleDisplayName(FR_CA));
-        assertEquals("de   ", "Deutsch",  MainKeyboardView.getMiddleDisplayName(DE));
-        assertEquals("zz   ", "QWERTY",   MainKeyboardView.getMiddleDisplayName(ZZ));
-
-        assertEquals("en_US", "En", MainKeyboardView.getShortDisplayName(EN_US));
-        assertEquals("en_GB", "En", MainKeyboardView.getShortDisplayName(EN_GB));
-        assertEquals("fr   ", "Fr", MainKeyboardView.getShortDisplayName(FR));
-        assertEquals("fr_CA", "Fr", MainKeyboardView.getShortDisplayName(FR_CA));
-        assertEquals("de   ", "De", MainKeyboardView.getShortDisplayName(DE));
-        assertEquals("zz   ", "",   MainKeyboardView.getShortDisplayName(ZZ));
+    // locale layout  | Short  Middle      Full
+    // ------ ------- - ---- --------- ----------------------
+    //  en_US qwerty  F  En  English   English (US)           exception
+    //  en_GB qwerty  F  En  English   English (UK)           exception
+    //  es_US spanish F  Es  Español   Español (EE.UU.)       exception
+    //  fr    azerty  F  Fr  Français  Français
+    //  fr_CA qwerty  F  Fr  Français  Français (Canada)
+    //  de    qwertz  F  De  Deutsch   Deutsch
+    //  zz    qwerty  F      QWERTY    QWERTY
+    //  fr    qwertz  T  Fr  Français  Français
+    //  de    qwerty  T  De  Deutsch   Deutsch
+    //  en_US azerty  T  En  English   English (US)
+    //  zz    azerty  T      AZERTY    AZERTY
+
+    private final RunInLocale<Void> testsPredefinedSubtypes = new RunInLocale<Void>() {
+        @Override
+        protected Void job(Resources res) {
+            assertEquals("en_US", "English (US)",      MainKeyboardView.getFullDisplayName(EN_US));
+            assertEquals("en_GB", "English (UK)",      MainKeyboardView.getFullDisplayName(EN_GB));
+            assertEquals("es_US", "Español (EE.UU.)",  MainKeyboardView.getFullDisplayName(ES_US));
+            assertEquals("fr   ", "Français",          MainKeyboardView.getFullDisplayName(FR));
+            assertEquals("fr_CA", "Français (Canada)", MainKeyboardView.getFullDisplayName(FR_CA));
+            assertEquals("de   ", "Deutsch",           MainKeyboardView.getFullDisplayName(DE));
+            assertEquals("zz   ", "QWERTY",            MainKeyboardView.getFullDisplayName(ZZ));
+
+            assertEquals("en_US", "English",  MainKeyboardView.getMiddleDisplayName(EN_US));
+            assertEquals("en_GB", "English",  MainKeyboardView.getMiddleDisplayName(EN_GB));
+            assertEquals("es_US", "Español",  MainKeyboardView.getMiddleDisplayName(ES_US));
+            assertEquals("fr   ", "Français", MainKeyboardView.getMiddleDisplayName(FR));
+            assertEquals("fr_CA", "Français", MainKeyboardView.getMiddleDisplayName(FR_CA));
+            assertEquals("de   ", "Deutsch",  MainKeyboardView.getMiddleDisplayName(DE));
+            assertEquals("zz   ", "QWERTY",   MainKeyboardView.getMiddleDisplayName(ZZ));
+
+            assertEquals("en_US", "En", MainKeyboardView.getShortDisplayName(EN_US));
+            assertEquals("en_GB", "En", MainKeyboardView.getShortDisplayName(EN_GB));
+            assertEquals("es_US", "Es", MainKeyboardView.getShortDisplayName(ES_US));
+            assertEquals("fr   ", "Fr", MainKeyboardView.getShortDisplayName(FR));
+            assertEquals("fr_CA", "Fr", MainKeyboardView.getShortDisplayName(FR_CA));
+            assertEquals("de   ", "De", MainKeyboardView.getShortDisplayName(DE));
+            assertEquals("zz   ", "",   MainKeyboardView.getShortDisplayName(ZZ));
+            return null;
+        }
+    };
+
+    private final RunInLocale<Void> testsAdditionalSubtypes = new RunInLocale<Void>() {
+        @Override
+        protected Void job(Resources res) {
+            assertEquals("fr qwertz",    "Français",
+                    MainKeyboardView.getFullDisplayName(FR_QWERTZ));
+            assertEquals("de qwerty",    "Deutsch",
+                    MainKeyboardView.getFullDisplayName(DE_QWERTY));
+            assertEquals("en_US azerty", "English (US)",
+                    MainKeyboardView.getFullDisplayName(US_AZERTY));
+            assertEquals("zz azerty",    "AZERTY",
+                    MainKeyboardView.getFullDisplayName(ZZ_AZERTY));
+
+            assertEquals("fr qwertz",    "Français",
+                    MainKeyboardView.getMiddleDisplayName(FR_QWERTZ));
+            assertEquals("de qwerty",    "Deutsch",
+                    MainKeyboardView.getMiddleDisplayName(DE_QWERTY));
+            assertEquals("en_US azerty", "English",
+                    MainKeyboardView.getMiddleDisplayName(US_AZERTY));
+            assertEquals("zz azerty",    "AZERTY",
+                    MainKeyboardView.getMiddleDisplayName(ZZ_AZERTY));
+
+            assertEquals("fr qwertz",    "Fr", MainKeyboardView.getShortDisplayName(FR_QWERTZ));
+            assertEquals("de qwerty",    "De", MainKeyboardView.getShortDisplayName(DE_QWERTY));
+            assertEquals("en_US azerty", "En", MainKeyboardView.getShortDisplayName(US_AZERTY));
+            assertEquals("zz azerty",    "",   MainKeyboardView.getShortDisplayName(ZZ_AZERTY));
+            return null;
+        }
+    };
+
+    public void testPredefinedSubtypesInEnglish() {
+        testsPredefinedSubtypes.runInLocale(mRes, Locale.ENGLISH);
     }
 
-    public void testAdditionalSubtype() {
-        final InputMethodSubtype DE_QWERTY = AdditionalSubtype.createAdditionalSubtype(
-                Locale.GERMAN.toString(), "qwerty", null);
-        final InputMethodSubtype FR_QWERTZ = AdditionalSubtype.createAdditionalSubtype(
-                Locale.FRENCH.toString(), "qwertz", null);
-        final InputMethodSubtype US_AZERTY = AdditionalSubtype.createAdditionalSubtype(
-                Locale.US.toString(), "azerty", null);
-        final InputMethodSubtype ZZ_AZERTY = AdditionalSubtype.createAdditionalSubtype(
-                SubtypeLocale.NO_LANGUAGE, "azerty", null);
+    public void testAdditionalSubtypeInEnglish() {
+        testsAdditionalSubtypes.runInLocale(mRes, Locale.ENGLISH);
+    }
+
+    public void testPredefinedSubtypesInFrench() {
+        testsPredefinedSubtypes.runInLocale(mRes, Locale.FRENCH);
+    }
 
-        assertEquals("fr qwertz",    "Français (QWERTZ)",
-                MainKeyboardView.getFullDisplayName(FR_QWERTZ));
-        assertEquals("de qwerty",    "Deutsch (QWERTY)",
-                MainKeyboardView.getFullDisplayName(DE_QWERTY));
-        assertEquals("en_US azerty", "English (US) (AZERTY)",
-                MainKeyboardView.getFullDisplayName(US_AZERTY));
-        assertEquals("zz azerty",    "AZERTY",
-                MainKeyboardView.getFullDisplayName(ZZ_AZERTY));
-
-        assertEquals("fr qwertz",    "Français", MainKeyboardView.getMiddleDisplayName(FR_QWERTZ));
-        assertEquals("de qwerty",    "Deutsch",  MainKeyboardView.getMiddleDisplayName(DE_QWERTY));
-        assertEquals("en_US azerty", "English",  MainKeyboardView.getMiddleDisplayName(US_AZERTY));
-        assertEquals("zz azerty",    "AZERTY",   MainKeyboardView.getMiddleDisplayName(ZZ_AZERTY));
-
-        assertEquals("fr qwertz",    "Fr", MainKeyboardView.getShortDisplayName(FR_QWERTZ));
-        assertEquals("de qwerty",    "De", MainKeyboardView.getShortDisplayName(DE_QWERTY));
-        assertEquals("en_US azerty", "En", MainKeyboardView.getShortDisplayName(US_AZERTY));
-        assertEquals("zz azerty",    "",  MainKeyboardView.getShortDisplayName(ZZ_AZERTY));
+    public void testAdditionalSubtypeInFrench() {
+        testsAdditionalSubtypes.runInLocale(mRes, Locale.FRENCH);
     }
 }