Merge "Implement ver4 dictionary GC."
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index d2b4475..bf3b623 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -161,7 +161,6 @@
             <ListPreference
                 android:key="pref_keyboard_layout_20110916"
                 android:title="@string/keyboard_color_scheme"
-                android:summary="%s"
                 android:persistent="true"
                 android:entryValues="@array/keyboard_color_schemes_values"
                 android:entries="@array/keyboard_color_schemes"
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index a6b293f..5abc9ab 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -44,8 +44,6 @@
 public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
     private static final String TAG = KeyboardSwitcher.class.getSimpleName();
 
-    public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916";
-
     static final class KeyboardTheme {
         public final int mThemeId;
         public final int mStyleId;
@@ -58,13 +56,14 @@
         }
     }
 
-    private static final int INDEX_THEME_ICS = 0;
-    private static final int INDEX_THEME_GB = 1;
-    private static final int INDEX_THEME_KLP = 2;
-    private static final KeyboardTheme[] KEYBOARD_THEMES = {
-        new KeyboardTheme(INDEX_THEME_ICS, R.style.KeyboardTheme_ICS),
-        new KeyboardTheme(INDEX_THEME_GB, R.style.KeyboardTheme_GB),
-        new KeyboardTheme(INDEX_THEME_KLP, R.style.KeyboardTheme_KLP),
+    public static final int THEME_INDEX_ICS = 0;
+    public static final int THEME_INDEX_GB = 1;
+    public static final int THEME_INDEX_KLP = 2;
+    public static final int THEME_INDEX_DEFAULT = THEME_INDEX_KLP;
+    public static final KeyboardTheme[] KEYBOARD_THEMES = {
+        new KeyboardTheme(THEME_INDEX_ICS, R.style.KeyboardTheme_ICS),
+        new KeyboardTheme(THEME_INDEX_GB, R.style.KeyboardTheme_GB),
+        new KeyboardTheme(THEME_INDEX_KLP, R.style.KeyboardTheme_KLP),
     };
 
     private SubtypeSwitcher mSubtypeSwitcher;
@@ -86,7 +85,7 @@
      * what user actually typed. */
     private boolean mIsAutoCorrectionActive;
 
-    private KeyboardTheme mKeyboardTheme = KEYBOARD_THEMES[INDEX_THEME_KLP];
+    private KeyboardTheme mKeyboardTheme = KEYBOARD_THEMES[THEME_INDEX_DEFAULT];
     private Context mThemeContext;
 
     private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
@@ -124,19 +123,15 @@
 
     private static KeyboardTheme getKeyboardTheme(final Context context,
             final SharedPreferences prefs) {
-        final String defaultIndex = context.getString(R.string.config_default_keyboard_theme_index);
-        final String themeIndex = prefs.getString(PREF_KEYBOARD_LAYOUT, defaultIndex);
-        try {
-            final int index = Integer.valueOf(themeIndex);
-            if (index >= 0 && index < KEYBOARD_THEMES.length) {
-                return KEYBOARD_THEMES[index];
-            }
-        } catch (NumberFormatException e) {
-            // Format error, keyboard theme is default to 0.
+        final Resources res = context.getResources();
+        final int index = Settings.readKeyboardThemeIndex(prefs, res);
+        if (index >= 0 && index < KEYBOARD_THEMES.length) {
+            return KEYBOARD_THEMES[index];
         }
-        Log.w(TAG, "Illegal keyboard theme in preference: " + themeIndex + ", default to "
-                + defaultIndex);
-        return KEYBOARD_THEMES[Integer.valueOf(defaultIndex)];
+        final int defaultThemeIndex = Settings.resetAndGetDefaultKeyboardThemeIndex(prefs, res);
+        Log.w(TAG, "Illegal keyboard theme in preference: " + index + ", default to "
+                + defaultThemeIndex);
+        return KEYBOARD_THEMES[defaultThemeIndex];
     }
 
     private boolean updateKeyboardThemeAndContextThemeWrapper(final Context context,
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 5ade707..e89699f 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -157,6 +157,7 @@
     private final SlidingKeyInputPreview mSlidingKeyInputPreview;
 
     // Key preview
+    private static final boolean FADE_OUT_KEY_TOP_LETTER_WHEN_KEY_IS_PRESSED = false;
     private final int mKeyPreviewLayoutId;
     private final int mKeyPreviewOffset;
     private final int mKeyPreviewHeight;
@@ -1177,7 +1178,8 @@
             params.mAnimAlpha = mAltCodeKeyWhileTypingAnimAlpha;
         }
         // Don't draw key top letter when key preview is showing.
-        if (mShowingKeyPreviewTextViews.containsKey(key)) {
+        if (FADE_OUT_KEY_TOP_LETTER_WHEN_KEY_IS_PRESSED
+                && mShowingKeyPreviewTextViews.containsKey(key)) {
             // TODO: Fade out animation for the key top letter, and fade in animation for the key
             // background color when the user presses the key.
             return;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 842c658..3dd0a4f 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -2152,13 +2152,6 @@
                     // This should never happen.
                     Log.e(TAG, "Backspace when we don't know the selection position");
                 }
-                final int codePointBeforeCursor = mConnection.getCodePointBeforeCursor();
-                if (codePointBeforeCursor == Constants.NOT_A_CODE) {
-                    // Nothing to delete before the cursor.
-                    return;
-                }
-                final int lengthToDelete =
-                        Character.isSupplementaryCodePoint(codePointBeforeCursor) ? 2 : 1;
                 if (mAppWorkAroundsUtils.isBeforeJellyBean() ||
                         currentSettings.mInputAttributes.isTypeNull()) {
                     // There are two possible reasons to send a key event: either the field has
@@ -2169,23 +2162,33 @@
                     // applications are relying on this behavior so we continue to support it for
                     // older apps, so we retain this behavior if the app has target SDK < JellyBean.
                     sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL);
+                    if (mDeleteCount > DELETE_ACCELERATE_AT) {
+                        sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL);
+                    }
                 } else {
+                    final int codePointBeforeCursor = mConnection.getCodePointBeforeCursor();
+                    if (codePointBeforeCursor == Constants.NOT_A_CODE) {
+                        // Nothing to delete before the cursor.
+                        return;
+                    }
+                    final int lengthToDelete =
+                            Character.isSupplementaryCodePoint(codePointBeforeCursor) ? 2 : 1;
                     mConnection.deleteSurroundingText(lengthToDelete, 0);
-                }
-                if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
-                    ResearchLogger.latinIME_handleBackspace(lengthToDelete,
-                            true /* shouldUncommitLogUnit */);
-                }
-                if (mDeleteCount > DELETE_ACCELERATE_AT) {
-                    final int codePointBeforeCursorToDeleteAgain =
-                            mConnection.getCodePointBeforeCursor();
-                    if (codePointBeforeCursorToDeleteAgain != Constants.NOT_A_CODE) {
-                        final int lengthToDeleteAgain = Character.isSupplementaryCodePoint(
-                                codePointBeforeCursorToDeleteAgain) ? 2 : 1;
-                        mConnection.deleteSurroundingText(lengthToDeleteAgain, 0);
-                        if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
-                            ResearchLogger.latinIME_handleBackspace(lengthToDeleteAgain,
-                                    true /* shouldUncommitLogUnit */);
+                    if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
+                        ResearchLogger.latinIME_handleBackspace(lengthToDelete,
+                                true /* shouldUncommitLogUnit */);
+                    }
+                    if (mDeleteCount > DELETE_ACCELERATE_AT) {
+                        final int codePointBeforeCursorToDeleteAgain =
+                                mConnection.getCodePointBeforeCursor();
+                        if (codePointBeforeCursorToDeleteAgain != Constants.NOT_A_CODE) {
+                            final int lengthToDeleteAgain = Character.isSupplementaryCodePoint(
+                                    codePointBeforeCursorToDeleteAgain) ? 2 : 1;
+                            mConnection.deleteSurroundingText(lengthToDeleteAgain, 0);
+                            if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
+                                ResearchLogger.latinIME_handleBackspace(lengthToDeleteAgain,
+                                        true /* shouldUncommitLogUnit */);
+                            }
                         }
                     }
                 }
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index dc005bb..df2c690 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -65,6 +65,7 @@
             "pref_show_language_switch_key";
     public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
             "pref_include_other_imes_in_language_switch_list";
+    public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916";
     public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
     public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
             "pref_key_preview_popup_dismiss_delay";
@@ -262,6 +263,28 @@
         return prefs.getBoolean(PREF_SHOW_LANGUAGE_SWITCH_KEY, true);
     }
 
+    public static int readKeyboardThemeIndex(final SharedPreferences prefs, final Resources res) {
+        final String defaultThemeIndex = res.getString(
+                R.string.config_default_keyboard_theme_index);
+        final String themeIndex = prefs.getString(PREF_KEYBOARD_LAYOUT, defaultThemeIndex);
+        try {
+            return Integer.valueOf(themeIndex);
+        } catch (final NumberFormatException e) {
+            // Format error, returns default keyboard theme index.
+            Log.e(TAG, "Illegal keyboard theme in preference: " + themeIndex + ", default to "
+                    + defaultThemeIndex, e);
+            return Integer.valueOf(defaultThemeIndex);
+        }
+    }
+
+    public static int resetAndGetDefaultKeyboardThemeIndex(final SharedPreferences prefs,
+            final Resources res) {
+        final String defaultThemeIndex = res.getString(
+                R.string.config_default_keyboard_theme_index);
+        prefs.edit().putString(PREF_KEYBOARD_LAYOUT, defaultThemeIndex).apply();
+        return Integer.valueOf(defaultThemeIndex);
+    }
+
     public static String readPrefAdditionalSubtypes(final SharedPreferences prefs,
             final Resources res) {
         final String predefinedPrefSubtypes = AdditionalSubtypeUtils.createPrefSubtypes(
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index cb7dda6..5c60a73 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -255,6 +255,7 @@
         }
         updateShowCorrectionSuggestionsSummary();
         updateKeyPreviewPopupDelaySummary();
+        updateColorSchemeSummary(prefs, getResources());
         updateCustomInputStylesSummary();
     }
 
@@ -288,6 +289,7 @@
         ensureConsistencyOfAutoCorrectionSettings();
         updateShowCorrectionSuggestionsSummary();
         updateKeyPreviewPopupDelaySummary();
+        updateColorSchemeSummary(prefs, res);
         refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, getResources());
     }
 
@@ -305,6 +307,25 @@
                         mShowCorrectionSuggestionsPreference.getValue())]);
     }
 
+    private void updateColorSchemeSummary(final SharedPreferences prefs, final Resources res) {
+        // Because the "%s" summary trick of {@link ListPreference} doesn't work properly before
+        // KitKat, we need to update the summary by code.
+        final Preference preference = findPreference(Settings.PREF_KEYBOARD_LAYOUT);
+        if (!(preference instanceof ListPreference)) {
+            Log.w(TAG, "Can't find Keyboard Color Scheme preference");
+            return;
+        }
+        final ListPreference colorSchemePreference = (ListPreference)preference;
+        final int themeIndex = Settings.readKeyboardThemeIndex(prefs, res);
+        int entryIndex = colorSchemePreference.findIndexOfValue(Integer.toString(themeIndex));
+        if (entryIndex < 0) {
+            final int defaultThemeIndex = Settings.resetAndGetDefaultKeyboardThemeIndex(prefs, res);
+            entryIndex = colorSchemePreference.findIndexOfValue(
+                    Integer.toString(defaultThemeIndex));
+        }
+        colorSchemePreference.setSummary(colorSchemePreference.getEntries()[entryIndex]);
+    }
+
     private void updateCustomInputStylesSummary() {
         final PreferenceScreen customInputStyles =
                 (PreferenceScreen)findPreference(Settings.PREF_CUSTOM_INPUT_STYLES);