Fix issue space key preview remains on screen and would not dismiss

The space key preview should be displayed one of the following case.
- Popup preview is enabled
- Language switcher is in action, whether popup preview is enabled or
  not.

For phone number keyboard, popup preview is never displayed even if
popup preview is enabled.

Bug: 3006612
Bug: 3021091
Change-Id: I5385c776d0e8e3981fc8d8851db9140d92599ce5
diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index 0ccb7d9..ebf2f4e 100644
--- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -16,7 +16,6 @@
 
 package com.android.inputmethod.latin;
 
-import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -87,7 +86,7 @@
     private static final int SYMBOLS_MODE_STATE_BEGIN = 1;
     private static final int SYMBOLS_MODE_STATE_SYMBOL = 2;
 
-    LatinKeyboardView mInputView;
+    private LatinKeyboardView mInputView;
     private static final int[] ALPHABET_MODES = {
         KEYBOARDMODE_NORMAL,
         KEYBOARDMODE_URL,
@@ -100,7 +99,7 @@
         KEYBOARDMODE_IM_WITH_SETTINGS_KEY,
         KEYBOARDMODE_WEB_WITH_SETTINGS_KEY };
 
-    final LatinIME mInputMethodService;
+    private final LatinIME mInputMethodService;
 
     private KeyboardId mSymbolsId;
     private KeyboardId mSymbolsShiftedId;
@@ -120,7 +119,7 @@
     private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
 
     // Indicates whether or not we have the settings key
-    boolean mHasSettingsKey;
+    private boolean mHasSettingsKey;
     private static final int SETTINGS_KEY_MODE_AUTO = R.string.settings_key_mode_auto;
     private static final int SETTINGS_KEY_MODE_ALWAYS_SHOW = R.string.settings_key_mode_always_show;
     // NOTE: No need to have SETTINGS_KEY_MODE_ALWAYS_HIDE here because it's not being referred to
@@ -134,7 +133,7 @@
 
     private int mLayoutId;
 
-    KeyboardSwitcher(LatinIME ims) {
+    public KeyboardSwitcher(LatinIME ims) {
         mInputMethodService = ims;
 
         final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ims);
@@ -153,15 +152,11 @@
      * @param locale the current input locale, or null for default locale with no locale 
      * button.
      */
-    void setLanguageSwitcher(LanguageSwitcher languageSwitcher) {
+    public void setLanguageSwitcher(LanguageSwitcher languageSwitcher) {
         mLanguageSwitcher = languageSwitcher;
         mInputLocale = mLanguageSwitcher.getInputLocale();
     }
 
-    void setInputView(LatinKeyboardView inputView) {
-        mInputView = inputView;
-    }
-
     private KeyboardId makeSymbolsId(boolean hasVoice) {
         return new KeyboardId(KBD_SYMBOLS[getCharColorId()], mHasSettingsKey ?
                 KEYBOARDMODE_SYMBOLS_WITH_SETTINGS_KEY : KEYBOARDMODE_SYMBOLS,
@@ -174,7 +169,7 @@
                 false, hasVoice);
     }
 
-    void makeKeyboards(boolean forceCreate) {
+    public void makeKeyboards(boolean forceCreate) {
         mSymbolsId = makeSymbolsId(mHasVoice && !mVoiceOnPrimary);
         mSymbolsShiftedId = makeSymbolsShiftedId(mHasVoice && !mVoiceOnPrimary);
 
@@ -229,7 +224,7 @@
         }
     }
 
-    void setVoiceMode(boolean enableVoice, boolean voiceOnPrimary) {
+    public void setVoiceMode(boolean enableVoice, boolean voiceOnPrimary) {
         if (enableVoice != mHasVoice || voiceOnPrimary != mVoiceOnPrimary) {
             mKeyboards.clear();
         }
@@ -238,11 +233,11 @@
         setKeyboardMode(mMode, mImeOptions, mHasVoice, mIsSymbols);
     }
 
-    boolean hasVoiceButton(boolean isSymbols) {
+    private boolean hasVoiceButton(boolean isSymbols) {
         return mHasVoice && (isSymbols != mVoiceOnPrimary);
     }
 
-    void setKeyboardMode(int mode, int imeOptions, boolean enableVoice) {
+    public void setKeyboardMode(int mode, int imeOptions, boolean enableVoice) {
         mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
         mPreferSymbols = mode == MODE_SYMBOLS;
         if (mode == MODE_SYMBOLS) {
@@ -255,7 +250,7 @@
         }
     }
 
-    void setKeyboardMode(int mode, int imeOptions, boolean enableVoice, boolean isSymbols) {
+    private void setKeyboardMode(int mode, int imeOptions, boolean enableVoice, boolean isSymbols) {
         if (mInputView == null) return;
         mMode = mode;
         mImeOptions = imeOptions;
@@ -271,7 +266,6 @@
 
         if (mode == MODE_PHONE) {
             mInputView.setPhoneKeyboard(keyboard);
-            mInputView.setPreviewEnabled(false);
         }
 
         mCurrentId = id;
@@ -354,15 +348,11 @@
         return null;
     }
 
-    int getKeyboardMode() {
+    public int getKeyboardMode() {
         return mMode;
     }
     
-    boolean isTextMode() {
-        return mMode == MODE_TEXT;
-    }
-
-    boolean isAlphabetMode() {
+    public boolean isAlphabetMode() {
         if (mCurrentId == null) {
             return false;
         }
@@ -375,19 +365,19 @@
         return false;
     }
 
-    void setShifted(boolean shifted) {
+    public void setShifted(boolean shifted) {
         if (mInputView != null) {
             mInputView.setShifted(shifted);
         }
     }
 
-    void setShiftLocked(boolean shiftLocked) {
+    public void setShiftLocked(boolean shiftLocked) {
         if (mInputView != null) {
             mInputView.setShiftLocked(shiftLocked);
         }
     }
 
-    void toggleShift() {
+    public void toggleShift() {
         if (mCurrentId.equals(mSymbolsId)) {
             LatinKeyboard symbolsShiftedKeyboard = getKeyboard(mSymbolsShiftedId);
             mCurrentId = mSymbolsShiftedId;
@@ -412,7 +402,7 @@
         }
     }
 
-    void toggleSymbols() {
+    public void toggleSymbols() {
         setKeyboardMode(mMode, mImeOptions, mHasVoice, !mIsSymbols);
         if (mIsSymbols && !mPreferSymbols) {
             mSymbolsModeState = SYMBOLS_MODE_STATE_BEGIN;
@@ -429,7 +419,7 @@
      * Updates state machine to figure out when to automatically switch back to alpha mode.
      * Returns true if the keyboard needs to switch back 
      */
-    boolean onKey(int key) {
+    public boolean onKey(int key) {
         // Switch back to alpha mode if user types one or more non-space/enter characters
         // followed by a space/enter
         switch (mSymbolsModeState) {
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboard.java b/java/src/com/android/inputmethod/latin/LatinKeyboard.java
index 8b89f39..d39766d 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboard.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboard.java
@@ -131,7 +131,7 @@
                 R.dimen.spacebar_vertical_correction);
         mIsAlphaKeyboard = xmlLayoutResId == R.xml.kbd_qwerty
                 || xmlLayoutResId == R.xml.kbd_qwerty_black;
-        mSpaceKeyIndex = indexOf(' ');
+        mSpaceKeyIndex = indexOf(LatinIME.KEYCODE_SPACE);
         initializeNumberHintResources(context);
     }
 
@@ -384,6 +384,10 @@
         }
     }
 
+    public boolean isLanguageSwitchEnabled() {
+        return mLocale != null;
+    }
+
     private void updateSpaceBarForLocale(boolean isAutoCompletion, boolean isBlack) {
         // If application locales are explicitly selected.
         if (mLocale != null) {
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
index 26b3c05..fd25d75 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
@@ -881,8 +881,17 @@
     public void showPreview(int keyIndex, PointerTracker tracker) {
         int oldKeyIndex = mOldPreviewKeyIndex;
         mOldPreviewKeyIndex = keyIndex;
-        // If key changed and preview is on ...
-        if (oldKeyIndex != keyIndex && mShowPreview) {
+        final boolean isLanguageSwitchEnabled = (mKeyboard instanceof LatinKeyboard)
+                && ((LatinKeyboard)mKeyboard).isLanguageSwitchEnabled();
+        // We should re-draw popup preview when 1) we need to hide the preview, 2) we will show
+        // the space key preview and 3) pointer moves off the space key to other letter key, we
+        // should hide the preview of the previous key.
+        final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null)
+                || tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex);
+        // If key changed and preview is on or the key is space (language switch is enabled)
+        if (oldKeyIndex != keyIndex
+                && (mShowPreview
+                        || (hidePreviewOrShowSpaceKeyPreview && isLanguageSwitchEnabled))) {
             if (keyIndex == NOT_A_KEY) {
                 mHandler.cancelPopupPreview();
                 mHandler.dismissPreview(DELAY_AFTER_PREVIEW);
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
index a45bb21..2872f6b 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
@@ -66,6 +66,16 @@
     }
 
     @Override
+    public void setPreviewEnabled(boolean previewEnabled) {
+        if (getKeyboard() == mPhoneKeyboard) {
+            // Phone keyboard never shows popup preview (except language switch).
+            super.setPreviewEnabled(false);
+        } else {
+            super.setPreviewEnabled(previewEnabled);
+        }
+    }
+
+    @Override
     public void setKeyboard(Keyboard k) {
         super.setKeyboard(k);
         // One-seventh of the keyboard width seems like a reasonable threshold
diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/latin/PointerTracker.java
index a612c8e..cb717cb 100644
--- a/java/src/com/android/inputmethod/latin/PointerTracker.java
+++ b/java/src/com/android/inputmethod/latin/PointerTracker.java
@@ -140,6 +140,11 @@
         return isModifierInternal(mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null));
     }
 
+    public boolean isSpaceKey(int keyIndex) {
+        Key key = getKey(keyIndex);
+        return key != null && key.codes[0] == LatinIME.KEYCODE_SPACE;
+    }
+
     public void updateKey(int keyIndex) {
         if (mKeyAlreadyProcessed)
             return;