Merge "Show full display names in the popup of the spacebar language swicher"
diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
index 5ef236e..8dc833d 100644
--- a/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
+++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/LanguageSwitcher.java
@@ -20,6 +20,7 @@
 import com.android.inputmethod.latin.LatinImeLogger;
 import com.android.inputmethod.latin.Settings;
 import com.android.inputmethod.latin.SharedPreferencesCompat;
+import com.android.inputmethod.latin.Utils;
 
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
@@ -125,8 +126,7 @@
     private void constructLocales() {
         mLocales.clear();
         for (final String lang : mSelectedLanguageArray) {
-            final Locale locale = new Locale(lang.substring(0, 2),
-                    lang.length() > 4 ? lang.substring(3, 5) : "");
+            final Locale locale = Utils.constructLocaleFromString(lang);
             mLocales.add(locale);
         }
     }
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
index c279769..7552b8e 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java
@@ -78,7 +78,7 @@
     // of the most common key width of this keyboard).
     private static final int SPACEBAR_DRAG_WIDTH = 3;
     // Minimum width of space key preview (proportional to keyboard width).
-    private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f;
+    private static final float SPACEBAR_POPUP_MIN_RATIO = 0.5f;
     // Height in space key the language name will be drawn. (proportional to space key height)
     public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f;
     // If the full language name needs to be smaller than this value to be drawn on space key,
diff --git a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
index b279c1c..173e879 100644
--- a/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
+++ b/java/src/com/android/inputmethod/keyboard/SlidingLocaleDrawable.java
@@ -38,7 +38,7 @@
  * movement on the spacebar.
  */
 public class SlidingLocaleDrawable extends Drawable {
-
+    private static final int SLIDE_SPEED_MULTIPLIER_RATIO = 150;
     private final Context mContext;
     private final Resources mRes;
     private final int mWidth;
@@ -90,7 +90,7 @@
             mCurrentLanguage = null;
             return;
         }
-        mDiff = diff;
+        mDiff = Math.max(diff, diff * SLIDE_SPEED_MULTIPLIER_RATIO / 100);
         if (mDiff > mWidth) mDiff = mWidth;
         if (mDiff < -mWidth) mDiff = -mWidth;
         if (Math.abs(mDiff) > mThreshold) mHitThreshold = true;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 2c39eba..18f7438 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -406,7 +406,7 @@
 
     private void initSuggest() {
         final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
-        final Locale keyboardLocale = new Locale(localeStr);
+        final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr);
 
         final Resources res = mResources;
         final Locale savedLocale = Utils.setSystemLocale(res, keyboardLocale);
@@ -440,7 +440,7 @@
 
     /* package private */ void resetSuggestMainDict() {
         final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
-        final Locale keyboardLocale = new Locale(localeStr);
+        final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr);
         int mainDicResId = Utils.getMainDictionaryResourceId(mResources);
         mSuggest.resetMainDict(this, mainDicResId, keyboardLocale);
     }
@@ -1553,7 +1553,7 @@
             // a magic space even if it was a normal space. This is meant to help in case the user
             // pressed space on purpose of displaying the suggestion strip punctuation.
             final char primaryCode = suggestion.charAt(0);
-            final CharSequence beforeText = ic.getTextBeforeCursor(1, 0);
+            final CharSequence beforeText = ic != null ? ic.getTextBeforeCursor(1, 0) : "";
             final int toLeft = (ic == null || TextUtils.isEmpty(beforeText))
                     ? 0 : beforeText.charAt(0);
             final boolean oldMagicSpace = mJustAddedMagicSpace;
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 7c323c1..d64410a 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -121,7 +121,7 @@
             final Resources res = context.getResources();
             final Locale savedLocale;
             if (null != localeStr) {
-                final Locale keyboardLocale = new Locale(localeStr);
+                final Locale keyboardLocale = Utils.constructLocaleFromString(localeStr);
                 savedLocale = Utils.setSystemLocale(res, keyboardLocale);
             } else {
                 savedLocale = null;
@@ -354,8 +354,6 @@
                 (PreferenceGroup) findPreference(PREF_GENERAL_SETTINGS_KEY);
         final PreferenceGroup textCorrectionGroup =
                 (PreferenceGroup) findPreference(PREF_CORRECTION_SETTINGS_KEY);
-        final PreferenceGroup bigramGroup =
-                (PreferenceGroup) findPreference(PREF_NGRAM_SETTINGS_KEY);
 
         final boolean showSettingsKeyOption = res.getBoolean(
                 R.bool.config_enable_show_settings_key_option);
@@ -499,7 +497,6 @@
     }
 
     private void updateSettingsKeySummary() {
-        final ListPreference lp = mSettingsKeyPreference;
         mSettingsKeyPreference.setSummary(
                 getResources().getStringArray(R.array.settings_key_modes)
                 [mSettingsKeyPreference.findIndexOfValue(mSettingsKeyPreference.getValue())]);
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index d801208..5012843 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -92,10 +92,9 @@
     }
 
     public static void init(LatinIME service, SharedPreferences prefs) {
+        SubtypeLocale.init(service);
         sInstance.initialize(service, prefs);
         sInstance.updateAllParameters();
-
-        SubtypeLocale.init(service);
     }
 
     private SubtypeSwitcher() {
@@ -281,14 +280,8 @@
         // "en_US" --> language: en  & country: US
         // "en" --> language: en
         // "" --> the system locale
-        mLocaleSplitter.setString(inputLocaleStr);
-        if (mLocaleSplitter.hasNext()) {
-            String language = mLocaleSplitter.next();
-            if (mLocaleSplitter.hasNext()) {
-                mInputLocale = new Locale(language, mLocaleSplitter.next());
-            } else {
-                mInputLocale = new Locale(language);
-            }
+        if (!TextUtils.isEmpty(inputLocaleStr)) {
+            mInputLocale = Utils.constructLocaleFromString(inputLocaleStr);
             mInputLocaleStr = inputLocaleStr;
         } else {
             mInputLocale = mSystemLocale;
@@ -549,12 +542,12 @@
                     || mEnabledKeyboardSubtypesOfCurrentInputMethod.size() == 0) return;
             mCurrentKeyboardSubtypeIndex = getCurrentIndex();
             mNextKeyboardSubtype = getNextKeyboardSubtypeInternal(mCurrentKeyboardSubtypeIndex);
-            Locale locale = new Locale(mNextKeyboardSubtype.getLocale());
-            mNextLanguage = getDisplayLanguage(locale);
+            Locale locale = Utils.constructLocaleFromString(mNextKeyboardSubtype.getLocale());
+            mNextLanguage = getFullDisplayName(locale, true);
             mPreviousKeyboardSubtype = getPreviousKeyboardSubtypeInternal(
                     mCurrentKeyboardSubtypeIndex);
-            locale = new Locale(mPreviousKeyboardSubtype.getLocale());
-            mPreviousLanguage = getDisplayLanguage(locale);
+            locale = Utils.constructLocaleFromString(mPreviousKeyboardSubtype.getLocale());
+            mPreviousLanguage = getFullDisplayName(locale, true);
         }
 
         private int normalize(int index) {
@@ -591,11 +584,12 @@
     }
 
     public static String getDisplayLanguage(Locale locale) {
-        return toTitleCase(locale.getDisplayLanguage(locale));
+        return toTitleCase(SubtypeLocale.getFullDisplayName(locale));
     }
 
     public static String getMiddleDisplayLanguage(Locale locale) {
-        return toTitleCase((new Locale(locale.getLanguage()).getDisplayLanguage(locale)));
+        return toTitleCase((Utils.constructLocaleFromString(
+                locale.getLanguage()).getDisplayLanguage(locale)));
     }
 
     public static String getShortDisplayLanguage(Locale locale) {
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java
index d165de3..5207f38 100644
--- a/java/src/com/android/inputmethod/latin/Utils.java
+++ b/java/src/com/android/inputmethod/latin/Utils.java
@@ -44,6 +44,7 @@
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.Locale;
 
 public class Utils {
@@ -662,4 +663,28 @@
         res.updateConfiguration(conf, res.getDisplayMetrics());
         return saveLocale;
     }
+
+    private static final HashMap<String, Locale> sLocaleCache = new HashMap<String, Locale>();
+
+    public static Locale constructLocaleFromString(String localeStr) {
+        if (localeStr == null)
+            return null;
+        synchronized (sLocaleCache) {
+            if (sLocaleCache.containsKey(localeStr))
+                return sLocaleCache.get(localeStr);
+            Locale retval = null;
+            String[] localeParams = localeStr.split("_", 3);
+            if (localeParams.length == 1) {
+                retval = new Locale(localeParams[0]);
+            } else if (localeParams.length == 2) {
+                retval = new Locale(localeParams[0], localeParams[1]);
+            } else if (localeParams.length == 3) {
+                retval = new Locale(localeParams[0], localeParams[1], localeParams[2]);
+            }
+            if (retval != null) {
+                sLocaleCache.put(localeStr, retval);
+            }
+            return retval;
+        }
+    }
 }
diff --git a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
index d128cb3..d102aa4 100644
--- a/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
+++ b/tests/src/com/android/inputmethod/latin/SubtypeLocaleTests.java
@@ -16,6 +16,8 @@
 
 package com.android.inputmethod.latin;
 
+import com.android.inputmethod.latin.Utils;
+
 import android.content.Context;
 import android.content.res.Resources;
 import android.test.AndroidTestCase;
@@ -75,7 +77,7 @@
         int failedCount = 0;
         for (final InputMethodSubtype subtype : mKeyboardSubtypes) {
             final String localeCode = subtype.getLocale();
-            final Locale locale = new Locale(localeCode);
+            final Locale locale = Utils.constructLocaleFromString(localeCode);
             // The locale name which will be displayed on spacebar.  For example 'English (US)' or
             // 'Francais (Canada)'.  (c=\u008d)
             final String displayName = SubtypeLocale.getFullDisplayName(locale);