Merge "Update assets for LatinIME"
diff --git a/java/res/drawable-hdpi/ic_subtype_keyboard.png b/java/res/drawable-hdpi/ic_subtype_keyboard.png
index 7015e26..c772956 100644
--- a/java/res/drawable-hdpi/ic_subtype_keyboard.png
+++ b/java/res/drawable-hdpi/ic_subtype_keyboard.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_subtype_keyboard.png b/java/res/drawable-mdpi/ic_subtype_keyboard.png
index 0d7ebd4..9a5aada 100644
--- a/java/res/drawable-mdpi/ic_subtype_keyboard.png
+++ b/java/res/drawable-mdpi/ic_subtype_keyboard.png
Binary files differ
diff --git a/java/res/drawable/ic_sybtype_us_keyboard.png b/java/res/drawable/ic_sybtype_us_keyboard.png
new file mode 100644
index 0000000..c81b22b
--- /dev/null
+++ b/java/res/drawable/ic_sybtype_us_keyboard.png
Binary files differ
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index 410d34b..af145a6 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -28,7 +28,7 @@
     <integer name="config_delay_before_key_repeat_start">400</integer>
     <integer name="config_key_repeat_interval">50</integer>
     <integer name="config_long_press_key_timeout">400</integer>
-    <integer name="config_long_press_shift_key_timeout">1000</integer>
+    <integer name="config_long_press_shift_key_timeout">1200</integer>
     <integer name="config_multi_tap_key_timeout">800</integer>
     <string-array name="auto_complete_threshold_values">
         <!-- Off, When auto completing setting is Off, this value is not used. -->
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index fab4bd7..e631418 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -26,7 +26,7 @@
 <input-method xmlns:android="http://schemas.android.com/apk/res/android"
         android:settingsActivity="com.android.inputmethod.latin.LatinIMESettings"
         android:isDefault="@bool/im_is_default">
-    <subtype android:icon="@drawable/ic_subtype_keyboard"
+    <subtype android:icon="@drawable/ic_sybtype_us_keyboard"
             android:imeSubtypeLocale="cs"
             android:imeSubtypeMode="@string/subtype_mode_keyboard"
     />
diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index 3a54904..dcbdba1 100644
--- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -391,15 +391,17 @@
     }
 
     public void setShifted(boolean shifted) {
-        if (mInputView != null) {
-            mInputView.setShifted(shifted);
+        if (mInputView == null) return;
+        LatinKeyboard latinKeyboard = mInputView.getLatinKeyboard();
+        if (latinKeyboard == null) return;
+        if (latinKeyboard.setShifted(shifted)) {
+            mInputView.invalidateAllKeys();
         }
     }
 
     public void setShiftLocked(boolean shiftLocked) {
-        if (mInputView != null) {
-            mInputView.setShiftLocked(shiftLocked);
-        }
+        if (mInputView == null) return;
+        mInputView.setShiftLocked(shiftLocked);
     }
 
     public void toggleShift() {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 3250cdd..6d88031 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -151,7 +151,6 @@
     private static final int POS_METHOD = 0;
     private static final int POS_SETTINGS = 1;
 
-    //private LatinKeyboardView mInputView;
     private LinearLayout mCandidateViewContainer;
     private CandidateView mCandidateView;
     private Suggest mSuggest;
@@ -195,8 +194,6 @@
     private boolean mReCorrectionEnabled;
     private boolean mBigramSuggestionEnabled;
     private boolean mAutoCorrectOn;
-    // TODO move this state variable outside LatinIME
-    private boolean mCapsLock;
     private boolean mPasswordText;
     private boolean mVibrateOn;
     private boolean mSoundOn;
@@ -586,7 +583,6 @@
         mPredictionOn = false;
         mCompletionOn = false;
         mCompletions = null;
-        mCapsLock = false;
         mEnteredText = null;
 
         switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) {
@@ -991,9 +987,11 @@
                     return true;
                 }
                 LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+                if (inputView == null) break;
+                LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
+                if (latinKeyboard == null) break;
                 // Enable shift key and DPAD to do selections
-                if (inputView != null && inputView.isShown()
-                        && inputView.isShifted()) {
+                if (inputView.isShown() && latinKeyboard.isShifted()) {
                     event = new KeyEvent(event.getDownTime(), event.getEventTime(),
                             event.getAction(), event.getKeyCode(), event.getRepeatCount(),
                             event.getDeviceId(), event.getScanCode(),
@@ -1053,9 +1051,14 @@
 
     public void updateShiftKeyState(EditorInfo attr) {
         InputConnection ic = getCurrentInputConnection();
-        if (ic != null && attr != null && mKeyboardSwitcher.isAlphabetMode()) {
-            mKeyboardSwitcher.setShifted(mShiftKeyState.isMomentary() || mCapsLock
-                    || getCursorCapsMode(ic, attr) != 0);
+        LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+        if (inputView == null) return;
+        LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
+        if (latinKeyboard == null) return;
+        if (ic != null && attr != null && mKeyboardSwitcher.isAlphabetMode()
+                && !mShiftKeyState.isIgnoring()) {
+            mKeyboardSwitcher.setShifted(mShiftKeyState.isMomentary()
+                    || latinKeyboard.isShiftLocked() || getCursorCapsMode(ic, attr) != 0);
         }
     }
 
@@ -1368,11 +1371,13 @@
         KeyboardSwitcher switcher = mKeyboardSwitcher;
         if (switcher.isAlphabetMode()) {
             LatinKeyboardView inputView = switcher.getInputView();
-            if (mCapsLock || forceNormal) {
-                mCapsLock = false;
+            if (inputView == null) return;
+            LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
+            if (latinKeyboard == null) return;
+            if (latinKeyboard.isShiftLocked() || forceNormal) {
                 switcher.setShifted(false);
-            } else if (inputView != null) {
-                switcher.setShifted(!inputView.isShifted());
+            } else {
+                switcher.setShifted(!latinKeyboard.isShifted());
             }
         } else {
             switcher.toggleShift();
@@ -1383,13 +1388,15 @@
         mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
         KeyboardSwitcher switcher = mKeyboardSwitcher;
         if (switcher.isAlphabetMode()) {
-            if (mCapsLock) {
-                mCapsLock = false;
+            LatinKeyboardView inputView = switcher.getInputView();
+            if (inputView == null) return;
+            LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
+            if (latinKeyboard == null) return;
+            if (latinKeyboard.isShiftLocked()) {
                 // LatinKeyboard.setShifted(false) also disable shift locked state.
                 // Note: Caps lock LED is off when Key.on is false.
                 switcher.setShifted(false);
             } else {
-                mCapsLock = true;
                 // LatinKeyboard.setShiftLocked(true) enable shift state too.
                 // Note: Caps lock LED is on when Key.on is true.
                 switcher.setShiftLocked(true);
@@ -1425,7 +1432,8 @@
                 mWord.reset();
             }
         }
-        if (mKeyboardSwitcher.getInputView().isShifted()) {
+        LatinKeyboard latinKeyboard = mKeyboardSwitcher.getInputView().getLatinKeyboard();
+        if (latinKeyboard != null && latinKeyboard.isShifted()) {
             if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT
                     || keyCodes[0] > Character.MAX_CODE_POINT) {
                 return;
@@ -1444,7 +1452,7 @@
             }
         }
         if (mPredicting) {
-            if (mKeyboardSwitcher.getInputView().isShifted()
+            if (latinKeyboard != null && latinKeyboard.isShifted()
                     && mKeyboardSwitcher.isAlphabetMode()
                     && mComposing.length() == 0) {
                 mWord.setFirstCharCapitalized(true);
@@ -1739,7 +1747,8 @@
         final List<CharSequence> nBest = new ArrayList<CharSequence>();
         boolean capitalizeFirstWord = preferCapitalization()
                 || (mKeyboardSwitcher.isAlphabetMode()
-                        && mKeyboardSwitcher.getInputView().isShifted());
+                        && mKeyboardSwitcher.getInputView().getLatinKeyboard() != null
+                                && mKeyboardSwitcher.getInputView().getLatinKeyboard().isShifted());
         for (String c : mVoiceResults.candidates) {
             if (capitalizeFirstWord) {
                 c = Character.toUpperCase(c.charAt(0)) + c.substring(1, c.length());
@@ -1791,7 +1800,10 @@
 
     private void updateSuggestions() {
         LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
-        ((LatinKeyboard) inputView.getKeyboard()).setPreferredLetters(null);
+        LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
+        if (latinKeyboard != null) {
+            latinKeyboard.setPreferredLetters(null);
+        }
 
         // Check if we have a suggestion engine attached.
         if ((mSuggest == null || !isPredictionOn()) && !mVoiceInputHighlighted) {
@@ -1813,7 +1825,10 @@
 
     private void showCorrections(WordAlternatives alternatives) {
         List<CharSequence> stringList = alternatives.getAlternatives();
-        ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).setPreferredLetters(null);
+        LatinKeyboard latinKeyboard = mKeyboardSwitcher.getInputView().getLatinKeyboard();
+        if (latinKeyboard != null) {
+            latinKeyboard.setPreferredLetters(null);
+        }
         showSuggestions(stringList, alternatives.getOriginalWord(), false, false);
     }
 
@@ -1829,8 +1844,10 @@
 
         int[] nextLettersFrequencies = mSuggest.getNextLettersFrequencies();
 
-        ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).setPreferredLetters(
-                nextLettersFrequencies);
+        LatinKeyboard latinKeyboard = mKeyboardSwitcher.getInputView().getLatinKeyboard();
+        if (latinKeyboard != null) {
+            latinKeyboard.setPreferredLetters(nextLettersFrequencies);
+        }
 
         boolean correctionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasMinimalCorrection();
         //|| mCorrectionMode == mSuggest.CORRECTION_FULL;
@@ -2002,11 +2019,13 @@
      */
     private void pickSuggestion(CharSequence suggestion, boolean correcting) {
         LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
-        if (mCapsLock) {
+        if (inputView == null) return;
+        LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
+        if (latinKeyboard == null) return;
+        if (latinKeyboard.isShiftLocked()) {
             suggestion = suggestion.toString().toUpperCase();
         } else if (preferCapitalization()
-                || (mKeyboardSwitcher.isAlphabetMode()
-                        && inputView.isShifted())) {
+                || (mKeyboardSwitcher.isAlphabetMode() && latinKeyboard.isShifted())) {
             suggestion = suggestion.toString().toUpperCase().charAt(0)
                     + suggestion.subSequence(1, suggestion.length()).toString();
         }
@@ -2018,7 +2037,9 @@
         saveWordInHistory(suggestion);
         mPredicting = false;
         mCommittedLength = suggestion.length();
-        ((LatinKeyboard) inputView.getKeyboard()).setPreferredLetters(null);
+        if (latinKeyboard != null) {
+            latinKeyboard.setPreferredLetters(null);
+        }
         // If we just corrected a word, then don't show punctuations
         if (!correcting) {
             setNextSuggestions();
@@ -2305,11 +2326,19 @@
         vibrate();
         playKeyClick(primaryCode);
         final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch();
+        LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+        if (inputView == null) return;
+        LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
+        if (latinKeyboard == null) return;
         if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_SHIFT) {
-            mShiftKeyState.onPress();
-            // Not in caps lock mode, shift key is in effect on pressed.
-            if (mKeyboardSwitcher.isAlphabetMode() && !mCapsLock)
+            // In alphabet mode, we call handleShift() to go into the shifted mode in this
+            // method, onPress(), only when we are in the small letter mode.
+            if (mKeyboardSwitcher.isAlphabetMode() && latinKeyboard.isShifted()) {
+                mShiftKeyState.onPressOnShifted();
+            } else {
+                mShiftKeyState.onPress();
                 handleShift();
+            }
         } else if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_MODE_CHANGE) {
             mSymbolKeyState.onPress();
             changeKeyboardMode();
@@ -2319,21 +2348,34 @@
         }
     }
 
+    // TODO: Bug - onRelease() could be dropped if the user slides finger out of the key.  It's OK
+    // for general keys, but we need to obtain onRelease() for the shift key even in such case.
     public void onRelease(int primaryCode) {
         // Reset any drag flags in the keyboard
-        ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).keyReleased();
+        LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+        if (inputView == null) return;
+        LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
+        if (latinKeyboard == null) return;
+        latinKeyboard.keyReleased();
         //vibrate();
         final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch();
         if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_SHIFT) {
-            if (mShiftKeyState.isMomentary())
+            if (mShiftKeyState.isMomentary()) {
                 resetShift();
-            // In caps lock mode, shift key is in effect on released.
-            if (mKeyboardSwitcher.isAlphabetMode() && mCapsLock)
-                handleShift();
+            }
+            if (mKeyboardSwitcher.isAlphabetMode()) {
+                // In alphabet mode, we call handleShift() to go into the small letter mode in this
+                // method, onRelease(), only when we are in the shifted modes -- temporary shifted
+                // mode or caps lock mode.
+                if (latinKeyboard.isShifted() && mShiftKeyState.isPressingOnShifted()) {
+                    handleShift();
+                }
+            }
             mShiftKeyState.onRelease();
         } else if (distinctMultiTouch && primaryCode == BaseKeyboard.KEYCODE_MODE_CHANGE) {
-            if (mSymbolKeyState.isMomentary())
+            if (mSymbolKeyState.isMomentary()) {
                 changeKeyboardMode();
+            }
             mSymbolKeyState.onRelease();
         }
     }
@@ -2636,8 +2678,12 @@
 
     private void changeKeyboardMode() {
         mKeyboardSwitcher.toggleSymbols();
-        if (mCapsLock && mKeyboardSwitcher.isAlphabetMode()) {
-            mKeyboardSwitcher.setShiftLocked(mCapsLock);
+        LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
+        if (inputView == null) return;
+        LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
+        if (latinKeyboard == null) return;
+        if (latinKeyboard.isShiftLocked() && mKeyboardSwitcher.isAlphabetMode()) {
+            mKeyboardSwitcher.setShiftLocked(true);
         }
 
         updateShiftKeyState(getCurrentInputEditorInfo());
@@ -2657,7 +2703,6 @@
         final Printer p = new PrintWriterPrinter(fout);
         p.println("LatinIME state :");
         p.println("  Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode());
-        p.println("  mCapsLock=" + mCapsLock);
         p.println("  mComposing=" + mComposing.toString());
         p.println("  mPredictionOn=" + mPredictionOn);
         p.println("  mCorrectionMode=" + mCorrectionMode);
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
index 6b46ab8..b2635ad 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
@@ -598,7 +598,7 @@
      * @see #getKeyboard()
      * @param keyboard the keyboard to display in this view
      */
-    public void setKeyboard(BaseKeyboard keyboard) {
+    protected void setKeyboard(BaseKeyboard keyboard) {
         if (mKeyboard != null) {
             dismissKeyPreview();
         }
@@ -626,7 +626,7 @@
      * @return the currently attached keyboard
      * @see #setKeyboard(BaseKeyboard)
      */
-    public BaseKeyboard getKeyboard() {
+    protected BaseKeyboard getKeyboard() {
         return mKeyboard;
     }
 
@@ -639,34 +639,6 @@
     }
 
     /**
-     * Sets the state of the shift key of the keyboard, if any.
-     * @param shifted whether or not to enable the state of the shift key
-     * @return true if the shift key state changed, false if there was no change
-     */
-    public boolean setShifted(boolean shifted) {
-        if (mKeyboard != null) {
-            if (mKeyboard.setShifted(shifted)) {
-                // The whole keyboard probably needs to be redrawn
-                invalidateAllKeys();
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns the state of the shift key of the keyboard, if any.
-     * @return true if the shift is in a pressed state, false otherwise. If there is
-     * no shift key on the keyboard or there is no keyboard attached, it returns false.
-     */
-    public boolean isShifted() {
-        if (mKeyboard != null) {
-            return mKeyboard.isShifted();
-        }
-        return false;
-    }
-
-    /**
      * Enables or disables the key feedback popup. This is a popup that shows a magnified
      * version of the depressed key. By default the preview is enabled.
      * @param previewEnabled whether or not to enable the key feedback popup
@@ -1247,7 +1219,12 @@
         mMiniKeyboardOriginX = adjustedX + container.getPaddingLeft() - mWindowOffset[0];
         mMiniKeyboardOriginY = y + container.getPaddingTop() - mWindowOffset[1];
         mMiniKeyboard.setPopupOffset(adjustedX, y);
-        mMiniKeyboard.setShifted(isShifted());
+        // TODO: change the below line to use getLatinKeyboard() instead of getKeyboard()
+        BaseKeyboard baseMiniKeyboard = mMiniKeyboard.getKeyboard();
+        if (baseMiniKeyboard != null && baseMiniKeyboard.setShifted(mKeyboard == null
+                ? false : mKeyboard.isShifted())) {
+            mMiniKeyboard.invalidateAllKeys();
+        }
         // Mini keyboard needs no pop-up key preview displayed.
         mMiniKeyboard.setPreviewEnabled(false);
         mMiniKeyboardPopup.setContentView(container);
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
index 3542899..6672dd2 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
@@ -40,7 +40,7 @@
     public static final int KEYCODE_PREV_LANGUAGE = -105;
     public static final int KEYCODE_CAPSLOCK = -106;
 
-    private BaseKeyboard mPhoneKeyboard;
+    private LatinKeyboard mPhoneKeyboard;
 
     /** Whether we've started dropping move events because we found a big jump */
     private boolean mDroppingEvents;
@@ -62,13 +62,13 @@
         super(context, attrs, defStyle);
     }
 
-    public void setPhoneKeyboard(BaseKeyboard phoneKeyboard) {
+    public void setPhoneKeyboard(LatinKeyboard phoneKeyboard) {
         mPhoneKeyboard = phoneKeyboard;
     }
 
     @Override
     public void setPreviewEnabled(boolean previewEnabled) {
-        if (getKeyboard() == mPhoneKeyboard) {
+        if (getLatinKeyboard() == mPhoneKeyboard) {
             // Phone keyboard never shows popup preview (except language switch).
             super.setPreviewEnabled(false);
         } else {
@@ -76,8 +76,7 @@
         }
     }
 
-    @Override
-    public void setKeyboard(BaseKeyboard k) {
+    public void setLatinKeyboard(LatinKeyboard k) {
         super.setKeyboard(k);
         // One-seventh of the keyboard width seems like a reasonable threshold
         mJumpThresholdSquare = k.getMinWidth() / 7;
@@ -87,12 +86,21 @@
         setKeyboardLocal(k);
     }
 
+    public LatinKeyboard getLatinKeyboard() {
+        BaseKeyboard keyboard = getKeyboard();
+        if (keyboard instanceof LatinKeyboard) {
+            return (LatinKeyboard)keyboard;
+        } else {
+            return null;
+        }
+    }
+
     @Override
     protected boolean onLongPress(Key key) {
         int primaryCode = key.codes[0];
         if (primaryCode == KEYCODE_OPTIONS) {
             return invokeOnKey(KEYCODE_OPTIONS_LONGPRESS);
-        } else if (primaryCode == '0' && getKeyboard() == mPhoneKeyboard) {
+        } else if (primaryCode == '0' && getLatinKeyboard() == mPhoneKeyboard) {
             // Long pressing on 0 in phone number keypad gives you a '+'.
             return invokeOnKey('+');
         } else {
@@ -109,9 +117,8 @@
 
     @Override
     protected CharSequence adjustCase(CharSequence label) {
-        BaseKeyboard keyboard = getKeyboard();
-        if (keyboard instanceof LatinKeyboard
-                && ((LatinKeyboard) keyboard).isAlphaKeyboard()
+        LatinKeyboard keyboard = getLatinKeyboard();
+        if (keyboard.isAlphaKeyboard()
                 && keyboard.isShifted()
                 && !TextUtils.isEmpty(label) && label.length() < 3
                 && Character.isLowerCase(label.charAt(0))) {
@@ -121,13 +128,10 @@
     }
 
     public boolean setShiftLocked(boolean shiftLocked) {
-        BaseKeyboard keyboard = getKeyboard();
-        if (keyboard instanceof LatinKeyboard) {
-            ((LatinKeyboard)keyboard).setShiftLocked(shiftLocked);
-            invalidateAllKeys();
-            return true;
-        }
-        return false;
+        LatinKeyboard keyboard = getLatinKeyboard();
+        keyboard.setShiftLocked(shiftLocked);
+        invalidateAllKeys();
+        return true;
     }
 
     /**
@@ -209,7 +213,7 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent me) {
-        LatinKeyboard keyboard = (LatinKeyboard) getKeyboard();
+        LatinKeyboard keyboard = getLatinKeyboard();
         if (DEBUG_LINE) {
             mLastX = (int) me.getX();
             mLastY = (int) me.getY();
@@ -258,7 +262,7 @@
     private int mLastY;
     private Paint mPaint;
 
-    private void setKeyboardLocal(BaseKeyboard k) {
+    private void setKeyboardLocal(LatinKeyboard k) {
         if (DEBUG_AUTO_PLAY) {
             findKeys();
             if (mHandler2 == null) {
@@ -319,7 +323,7 @@
     }
 
     private void findKeys() {
-        List<Key> keys = getKeyboard().getKeys();
+        List<Key> keys = getLatinKeyboard().getKeys();
         // Get the keys on this keyboard
         for (int i = 0; i < keys.size(); i++) {
             int code = keys.get(i).codes[0];
diff --git a/java/src/com/android/inputmethod/latin/ModifierKeyState.java b/java/src/com/android/inputmethod/latin/ModifierKeyState.java
index 097e87a..75820e7 100644
--- a/java/src/com/android/inputmethod/latin/ModifierKeyState.java
+++ b/java/src/com/android/inputmethod/latin/ModifierKeyState.java
@@ -19,7 +19,9 @@
 class ModifierKeyState {
     private static final int RELEASING = 0;
     private static final int PRESSING = 1;
-    private static final int MOMENTARY = 2;
+    private static final int PRESSING_ON_SHIFTED = 2; // both temporary shifted & shift locked
+    private static final int MOMENTARY = 3;
+    private static final int IGNORING = 4;
 
     private int mState = RELEASING;
 
@@ -27,16 +29,31 @@
         mState = PRESSING;
     }
 
+    public void onPressOnShifted() {
+        mState = PRESSING_ON_SHIFTED;
+    }
+
     public void onRelease() {
         mState = RELEASING;
     }
 
     public void onOtherKeyPressed() {
-        if (mState == PRESSING)
+        if (mState == PRESSING) {
             mState = MOMENTARY;
+        } else if (mState == PRESSING_ON_SHIFTED) {
+            mState = IGNORING;
+        }
     }
 
     public boolean isMomentary() {
         return mState == MOMENTARY;
     }
+
+    public boolean isPressingOnShifted() {
+        return mState == PRESSING_ON_SHIFTED;
+    }
+
+    public boolean isIgnoring() {
+        return mState == IGNORING;
+    }
 }