Follow-up change to revise Caps Lock sequence.

bug: 3122877
Change-Id: I44c539d7c041443f3ad027de4b75a67adf6b2c87
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/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index a5a262e..dcbdba1 100644
--- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -391,18 +391,17 @@
     }
 
     public void setShifted(boolean shifted) {
-        if (mInputView != null) {
-            LatinKeyboard latinKeyboard = mInputView.getLatinKeyboard();
-            if (latinKeyboard != null && latinKeyboard.setShifted(shifted)) {
-                mInputView.invalidateAllKeys();
-            }
+        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 0d2e50b..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;
@@ -1056,7 +1055,8 @@
         if (inputView == null) return;
         LatinKeyboard latinKeyboard = inputView.getLatinKeyboard();
         if (latinKeyboard == null) return;
-        if (ic != null && attr != null && mKeyboardSwitcher.isAlphabetMode()) {
+        if (ic != null && attr != null && mKeyboardSwitcher.isAlphabetMode()
+                && !mShiftKeyState.isIgnoring()) {
             mKeyboardSwitcher.setShifted(mShiftKeyState.isMomentary()
                     || latinKeyboard.isShiftLocked() || getCursorCapsMode(ic, attr) != 0);
         }
@@ -2331,9 +2331,12 @@
         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() && !latinKeyboard.isShiftLocked()) {
+            // 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) {
@@ -2345,6 +2348,8 @@
         }
     }
 
+    // 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
         LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
@@ -2358,9 +2363,13 @@
             if (mShiftKeyState.isMomentary()) {
                 resetShift();
             }
-            // In caps lock mode, shift key is in effect on released.
-            if (mKeyboardSwitcher.isAlphabetMode() && latinKeyboard.isShiftLocked()) {
-                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) {
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;
+    }
 }