Merge "Put SuggestionSpan at commitText"
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 33e76d8..3497310 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -56,7 +56,6 @@
     private SubtypeSwitcher mSubtypeSwitcher;
     private SharedPreferences mPrefs;
 
-    private View mInputView;
     private LatinKeyboardView mKeyboardView;
     private LatinIME mInputMethodService;
 
@@ -101,7 +100,7 @@
     // Default is SETTINGS_KEY_MODE_AUTO.
     private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO;
 
-    private int mLayoutId;
+    private int mThemeIndex;
     private int mKeyboardWidth;
 
     private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
@@ -122,11 +121,11 @@
         try {
             sConfigDefaultKeyboardThemeId = ims.getString(
                     R.string.config_default_keyboard_theme_id);
-            sInstance.mLayoutId = Integer.valueOf(
+            sInstance.mThemeIndex = Integer.valueOf(
                     prefs.getString(PREF_KEYBOARD_LAYOUT, sConfigDefaultKeyboardThemeId));
         } catch (NumberFormatException e) {
             sConfigDefaultKeyboardThemeId = "0";
-            sInstance.mLayoutId = 0;
+            sInstance.mThemeIndex = 0;
         }
         prefs.registerOnSharedPreferenceChangeListener(sInstance);
     }
@@ -711,49 +710,51 @@
     }
 
     public View onCreateInputView() {
-        createInputViewInternal(mLayoutId, true);
-        return mInputView;
+        return createInputView(mThemeIndex, true);
     }
 
-    private void createInputViewInternal(int newLayout, boolean forceReset) {
-        int layoutId = newLayout;
-        if (mLayoutId != layoutId || mKeyboardView == null || forceReset) {
-            if (mKeyboardView != null) {
-                mKeyboardView.closing();
-            }
-            if (KEYBOARD_THEMES.length <= layoutId) {
-                layoutId = Integer.valueOf(sConfigDefaultKeyboardThemeId);
-            }
+    // Instance variable only for {@link #createInputView(int, boolean)}.
+    private View mCurrentInputView;
 
-            Utils.GCUtils.getInstance().reset();
-            boolean tryGC = true;
-            for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
-                try {
-                    mInputView = LayoutInflater.from(mInputMethodService).inflate(
-                            KEYBOARD_THEMES[layoutId], null);
-                    tryGC = false;
-                } catch (OutOfMemoryError e) {
-                    Log.w(TAG, "load keyboard failed: " + e);
-                    tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
-                            mLayoutId + "," + layoutId, e);
-                } catch (InflateException e) {
-                    Log.w(TAG, "load keyboard failed: " + e);
-                    tryGC = Utils.GCUtils.getInstance().tryGCOrWait(
-                            mLayoutId + "," + layoutId, e);
-                }
-            }
-            mKeyboardView = (LatinKeyboardView)mInputView.findViewById(R.id.latin_keyboard_view);
-            mKeyboardView.setOnKeyboardActionListener(mInputMethodService);
-            mLayoutId = layoutId;
+    private View createInputView(final int newThemeIndex, final boolean forceRecreate) {
+        if (mCurrentInputView != null && mThemeIndex == newThemeIndex && !forceRecreate)
+            return mCurrentInputView;
+
+        if (mKeyboardView != null) {
+            mKeyboardView.closing();
         }
+        final int themeIndex = (newThemeIndex < KEYBOARD_THEMES.length) ? newThemeIndex
+                : Integer.valueOf(sConfigDefaultKeyboardThemeId);
+
+        Utils.GCUtils.getInstance().reset();
+        boolean tryGC = true;
+        for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
+            try {
+                mCurrentInputView = LayoutInflater.from(mInputMethodService).inflate(
+                        KEYBOARD_THEMES[themeIndex], null);
+                tryGC = false;
+            } catch (OutOfMemoryError e) {
+                Log.w(TAG, "load keyboard failed: " + e);
+                tryGC = Utils.GCUtils.getInstance().tryGCOrWait(mThemeIndex + "," + themeIndex, e);
+            } catch (InflateException e) {
+                Log.w(TAG, "load keyboard failed: " + e);
+                tryGC = Utils.GCUtils.getInstance().tryGCOrWait(mThemeIndex + "," + themeIndex, e);
+            }
+        }
+
+        mKeyboardView = (LatinKeyboardView) mCurrentInputView.findViewById(
+                R.id.latin_keyboard_view);
+        mKeyboardView.setOnKeyboardActionListener(mInputMethodService);
+        mThemeIndex = themeIndex;
+        return mCurrentInputView;
     }
 
-    private void postSetInputView() {
+    private void postSetInputView(final View newInputView) {
         mInputMethodService.mHandler.post(new Runnable() {
             @Override
             public void run() {
-                if (mKeyboardView != null) {
-                    mInputMethodService.setInputView(mKeyboardView);
+                if (newInputView != null) {
+                    mInputMethodService.setInputView(newInputView);
                 }
                 mInputMethodService.updateInputViewShown();
             }
@@ -765,13 +766,11 @@
         if (PREF_KEYBOARD_LAYOUT.equals(key)) {
             final int layoutId = Integer.valueOf(
                     sharedPreferences.getString(key, sConfigDefaultKeyboardThemeId));
-            createInputViewInternal(layoutId, false);
-            postSetInputView();
+            postSetInputView(createInputView(layoutId, false));
         } else if (Settings.PREF_SETTINGS_KEY.equals(key)) {
             mSettingsKeyEnabledInSettings = getSettingsKeyMode(sharedPreferences,
                     mInputMethodService);
-            createInputViewInternal(mLayoutId, true);
-            postSetInputView();
+            postSetInputView(createInputView(mThemeIndex, true));
         }
     }
 
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 1df6444..f8bce40 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -121,7 +121,7 @@
     private float mPreviewTextRatio;
     private int mPreviewTextSize;
     private boolean mShowKeyPreviewPopup = true;
-    private int mKeyPreviewPopupDisplayedY;
+    private int mKeyPreviewPopupDisplayedY = -1;
     private final int mDelayBeforePreview;
     private int mDelayAfterPreview;
     private ViewGroup mPreviewPlacer;
@@ -876,6 +876,8 @@
             // Dismiss key preview (in this case, slide language switcher) without any delay.
             mPreviewText.setVisibility(View.INVISIBLE);
         }
+        // Clear key preview display position.
+        mKeyPreviewPopupDisplayedY = -1;
     }
 
     private void addKeyPreview(TextView keyPreview) {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index a489245..6b4e946 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -633,8 +633,6 @@
 
     private void startLongPressTimer(int keyIndex) {
         Key key = getKey(keyIndex);
-        if (!key.mEnabled)
-            return;
         if (key.mCode == Keyboard.CODE_SHIFT) {
             mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this);
         } else if (key.mManualTemporaryUpperCaseCode != Keyboard.CODE_DUMMY
diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
index 561dcbc..62a32cf 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
@@ -16,8 +16,6 @@
 
 package com.android.inputmethod.keyboard;
 
-import com.android.inputmethod.latin.R;
-
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.SystemClock;
@@ -27,6 +25,8 @@
 import android.view.View;
 import android.widget.PopupWindow;
 
+import com.android.inputmethod.latin.R;
+
 /**
  * A view that renders a virtual {@link MiniKeyboard}. It handles rendering of keys and detecting
  * key presses and touch movements.
@@ -84,7 +84,7 @@
                 + parentKeyboardView.getPaddingTop() + mCoordinates[1];
         final int x = miniKeyboardX;
         final int y = parentKeyboardView.isKeyPreviewPopupEnabled() &&
-                miniKeyboard.isOneRowKeyboard() ? keyPreviewY : miniKeyboardY;
+                miniKeyboard.isOneRowKeyboard() && keyPreviewY >= 0 ? keyPreviewY : miniKeyboardY;
 
         if (miniKeyboard.setShifted(parentKeyboard.isShiftedOrShiftLocked())) {
             invalidateAllKeys();
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 2afee1f..346af3a 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -485,6 +485,7 @@
         final View inputView = mKeyboardSwitcher.onCreateInputView();
         mCandidateViewContainer = inputView.findViewById(R.id.candidates_container);
         mCandidateView = (CandidateView) inputView.findViewById(R.id.candidates);
+        mCandidateView.setService(this);
         mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height);
         return inputView;
     }
diff --git a/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java b/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
index cf4ccfe..28766c2 100644
--- a/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/SuggestTestsBase.java
@@ -42,7 +42,7 @@
         final int displayWidth = getContext().getResources().getDisplayMetrics().widthPixels;
         return new KeyboardId(locale.toString() + " keyboard",
                 com.android.inputmethod.latin.R.xml.kbd_qwerty, KeyboardView.COLOR_SCHEME_WHITE,
-                locale, displayWidth, Configuration.ORIENTATION_LANDSCAPE, KeyboardId.MODE_TEXT,
+                locale, Configuration.ORIENTATION_LANDSCAPE, displayWidth, KeyboardId.MODE_TEXT,
                 new EditorInfo(), false, false, false, false);
     }