diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 937a79933cd47ff9d8f60a45e05cca9596011ab6..a4e2d291415a25ce17074901c4760242c4616e6c 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -365,18 +365,12 @@
          (Compact) can be an abbreviation to fit in the CHAR LIMIT.
          TODO: Remove translatable=false once we are settled down with the naming. -->
     <string name="subtype_generic_compact" translatable="false"><xliff:g id="LANGUAGE_NAME" example="Hindi">%s</xliff:g> (Compact)</string>
-    <!-- TODO: Uncomment once we can handle IETF language tag with script name specified.
-         Description for Serbian Cyrillic keyboard subtype [CHAR LIMIT=25]
-         (Cyrillic) can be an abbreviation to fit in the CHAR LIMIT.
-    <string name="subtype_serbian_cyrillic">Serbian (Cyrillic)</string>
-         Description for Serbian Latin keyboard subtype [CHAR LIMIT=25]
-         (Latin) can be an abbreviation to fit in the CHAR LIMIT.
-    <string name="subtype_serbian_latin">Serbian (Latin)</string>
-         Description for Serbian Latin keyboard subtype with explicit keyboard layout [CHAR LIMIT=25]
-         (Latin) can be an abbreviation to fit in the CHAR LIMIT.
-         This should be identical to subtype_serbian_latin aside from the trailing (%s).
-    <string name="subtype_with_layout_sr-Latn">Serbian (Latin) (<xliff:g id="KEYBOARD_LAYOUT" example="QWERTY">%s</xliff:g>)</string>
-    -->
+    <!-- Description for "LANGUAGE_NAME" (Cyrillic) keyboard subtype [CHAR LIMIT=25]
+         (Cyrillic) can be an abbreviation to fit in the CHAR LIMIT. -->
+    <string name="subtype_generic_cyrillic"><xliff:g id="LANGUAGE_NAME" example="Serbian">%s</xliff:g> (Cyrillic)</string>
+    <!-- Description for "LANGUAGE_NAME" (Latin) keyboard subtype [CHAR LIMIT=25]
+         (Latin) can be an abbreviation to fit in the CHAR LIMIT. -->
+    <string name="subtype_generic_latin"><xliff:g id="LANGUAGE_NAME" example="Serbian">%s</xliff:g> (Latin)</string>
     <!-- This string is displayed in a language list that allows to choose a language for
 suggestions in a software keyboard. This setting won't give suggestions in any particular
 language, hence "No language".
diff --git a/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java b/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java
index 89837c641a54365944d5f498876fd66d2a88a5e7..1ca895fdbaabd498d3c01833cab2c7fd633e8123 100644
--- a/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java
@@ -18,8 +18,6 @@ package com.android.inputmethod.latin.utils;
 
 import android.view.inputmethod.InputMethodSubtype;
 
-import java.util.Locale;
-
 public final class SpacebarLanguageUtils {
     private SpacebarLanguageUtils() {
         // Intentional empty constructor for utility class.
@@ -55,7 +53,6 @@ public final class SpacebarLanguageUtils {
         if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
             return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype);
         }
-        final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
-        return SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale.getLanguage());
+        return SubtypeLocaleUtils.getSubtypeLanguageDisplayName(subtype.getLocale());
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index 2452864d56a542687449478baced3559e6960d3d..b37779bdcff7506fe6409aae0aa69a3feafe9a13 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -25,7 +25,7 @@ import android.os.Build;
 import android.util.Log;
 import android.view.inputmethod.InputMethodSubtype;
 
-import com.android.inputmethod.latin.DictionaryFactory;
+import com.android.inputmethod.latin.Constants;
 import com.android.inputmethod.latin.R;
 
 import java.util.Arrays;
@@ -33,10 +33,10 @@ import java.util.HashMap;
 import java.util.Locale;
 
 public final class SubtypeLocaleUtils {
-    static final String TAG = SubtypeLocaleUtils.class.getSimpleName();
-    // This class must be located in the same package as LatinIME.java.
-    private static final String RESOURCE_PACKAGE_NAME =
-            DictionaryFactory.class.getPackage().getName();
+    private static final String TAG = SubtypeLocaleUtils.class.getSimpleName();
+
+    // This reference class {@link Constants} must be located in the same package as LatinIME.java.
+    private static final String RESOURCE_PACKAGE_NAME = Constants.class.getPackage().getName();
 
     // Special language code to represent "no language".
     public static final String NO_LANGUAGE = "zz";
@@ -44,7 +44,8 @@ public final class SubtypeLocaleUtils {
     public static final String EMOJI = "emoji";
     public static final int UNKNOWN_KEYBOARD_LAYOUT = R.string.subtype_generic;
 
-    private static boolean sInitialized = false;
+    private static volatile boolean sInitialized = false;
+    private static final Object sInitializeLock = new Object();
     private static Resources sResources;
     private static String[] sPredefinedKeyboardLayoutSet;
     // Keyboard layout to its display name map.
@@ -77,9 +78,16 @@ public final class SubtypeLocaleUtils {
     }
 
     // Note that this initialization method can be called multiple times.
-    public static synchronized void init(final Context context) {
-        if (sInitialized) return;
+    public static void init(final Context context) {
+        synchronized (sInitializeLock) {
+            if (sInitialized == false) {
+                initLocked(context);
+                sInitialized = true;
+            }
+        }
+    }
 
+    private static void initLocked(final Context context) {
         final Resources res = context.getResources();
         sResources = res;
 
@@ -122,8 +130,6 @@ public final class SubtypeLocaleUtils {
             final String keyboardLayoutSet = keyboardLayoutSetMap[i + 1];
             sLocaleAndExtraValueToKeyboardLayoutSetMap.put(key, keyboardLayoutSet);
         }
-
-        sInitialized = true;
     }
 
     public static String[] getPredefinedKeyboardLayoutSet() {
@@ -167,8 +173,18 @@ public final class SubtypeLocaleUtils {
         return getSubtypeLocaleDisplayNameInternal(localeString, displayLocale);
     }
 
+    public static String getSubtypeLanguageDisplayName(final String localeString) {
+        final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
+        final Locale displayLocale = getDisplayLocaleOfSubtypeLocale(localeString);
+        return getSubtypeLocaleDisplayNameInternal(locale.getLanguage(), displayLocale);
+    }
+
     private static String getSubtypeLocaleDisplayNameInternal(final String localeString,
             final Locale displayLocale) {
+        if (NO_LANGUAGE.equals(localeString)) {
+            // No language subtype should be displayed in system locale.
+            return sResources.getString(R.string.subtype_no_language);
+        }
         final Integer exceptionalNameResId = sExceptionalLocaleToNameIdsMap.get(localeString);
         final String displayName;
         if (exceptionalNameResId != null) {
@@ -179,9 +195,6 @@ public final class SubtypeLocaleUtils {
                 }
             };
             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);