Merge "Merge missing space and mistyped space correction algorithm"
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index a89356c..5542bd3 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -216,10 +216,24 @@
     }
 
     private void toggleAlphabetAndSymbols() {
+        if (DEBUG_ACTION) {
+            Log.d(TAG, "toggleAlphabetAndSymbols: " + this);
+        }
         if (mIsAlphabetMode) {
-            setSymbolsKeyboard();
+            mPrevMainKeyboardWasShiftLocked = mAlphabetShiftState.isShiftLocked();
+            if (mPrevSymbolsKeyboardWasShifted) {
+                setSymbolsShiftedKeyboard();
+            } else {
+                setSymbolsKeyboard();
+            }
+            mPrevSymbolsKeyboardWasShifted = false;
         } else {
+            mPrevSymbolsKeyboardWasShifted = mIsSymbolShifted;
             setAlphabetKeyboard();
+            if (mPrevMainKeyboardWasShiftLocked) {
+                setShiftLocked(true);
+            }
+            mPrevMainKeyboardWasShiftLocked = false;
         }
     }
 
@@ -235,24 +249,15 @@
         if (DEBUG_ACTION) {
             Log.d(TAG, "setAlphabetKeyboard");
         }
-        mPrevSymbolsKeyboardWasShifted = mIsSymbolShifted;
         mSwitchActions.setAlphabetKeyboard();
         mIsAlphabetMode = true;
         mIsSymbolShifted = false;
         mSwitchState = SWITCH_STATE_ALPHA;
-        setShiftLocked(mPrevMainKeyboardWasShiftLocked);
-        mPrevMainKeyboardWasShiftLocked = false;
         mSwitchActions.requestUpdatingShiftState();
     }
 
     // TODO: Make this method private
     public void setSymbolsKeyboard() {
-        mPrevMainKeyboardWasShiftLocked = mAlphabetShiftState.isShiftLocked();
-        if (mPrevSymbolsKeyboardWasShifted) {
-            setSymbolsShiftedKeyboard();
-            return;
-        }
-
         if (DEBUG_ACTION) {
             Log.d(TAG, "setSymbolsKeyboard");
         }
@@ -261,7 +266,6 @@
         mIsSymbolShifted = false;
         // Reset alphabet shift state.
         mAlphabetShiftState.setShiftLocked(false);
-        mPrevSymbolsKeyboardWasShifted = false;
         mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
     }
 
@@ -274,7 +278,6 @@
         mIsSymbolShifted = true;
         // Reset alphabet shift state.
         mAlphabetShiftState.setShiftLocked(false);
-        mPrevSymbolsKeyboardWasShifted = false;
         mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
     }
 
@@ -495,14 +498,14 @@
             }
             // Switch back to alpha keyboard mode immediately if user types a quote character.
             if (isLayoutSwitchBackCharacter(code)) {
-                setAlphabetKeyboard();
+                toggleAlphabetAndSymbols();
             }
             break;
         case SWITCH_STATE_SYMBOL:
             // Switch back to alpha keyboard mode if user types one or more non-space/enter
             // characters followed by a space/enter or a quote character.
             if (isSpaceCharacter(code) || isLayoutSwitchBackCharacter(code)) {
-                setAlphabetKeyboard();
+                toggleAlphabetAndSymbols();
             }
             break;
         }
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index b96b084..230c291 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -311,8 +311,10 @@
         // instead of only on cancel), and ultimately we want to figure it out even earlier anyway.
         final LastComposedWord lastComposedWord = new LastComposedWord(mCodes,
                 mXCoordinates, mYCoordinates, mTypedWord.toString(),
-                (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD) || (null == mAutoCorrection)
-                        ? null : mAutoCorrection.toString());
+                null == mAutoCorrection ? null : mAutoCorrection.toString());
+        if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD) {
+            lastComposedWord.deactivate();
+        }
         mCodes.clear();
         mTypedWord.setLength(0);
         mAutoCorrection = null;
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
index d1887a1..c689384 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateMultiTouchTests.java
@@ -72,6 +72,57 @@
         chordingPressAndReleaseKey('a', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
         // Release "ABC" key, switch back to symbols.
         releaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED);
+
+        // Alphabet shifted -> symbols -> "ABC" key + letter -> symbols
+        // -> alphabet.
+        // Load keyboard
+        loadKeyboard(ALPHABET_UNSHIFTED);
+        // Press/release shift key, enter alphabet shifted.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Press/release "?123" key, enter into symbols.
+        pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Press "ABC" key, enter into chording alphabet state.
+        pressKey(CODE_SYMBOL, ALPHABET_UNSHIFTED);
+        // Enter/release letter key.
+        chordingPressAndReleaseKey('a', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
+        // Release "ABC" key, switch back to symbols.
+        releaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED);
+        // Press/release "ABC" key, switch to alphabet (not alphabet shifted).
+        pressAndReleaseKey(CODE_SYMBOL, ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
+
+        // Alphabet shift locked -> symbols -> "ABC" key + letter -> symbols ->
+        // alphabet shift locked.
+        // Load keyboard
+        loadKeyboard(ALPHABET_UNSHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release "?123" key, enter into symbols.
+        pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Press "ABC" key, enter into chording alphabet shift locked.
+        pressKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED);
+        // Enter/release letter key.
+        chordingPressAndReleaseKey('A', ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
+        // Release "ABC" key, switch back to symbols.
+        releaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED);
+        // Press/release "ABC" key, switch to alphabet shift locked.
+        pressAndReleaseKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
+
+        // Alphabet shift locked -> symbols -> "=\<" key + letter -> symbols ->
+        // alphabet shift locked.
+        // Load keyboard
+        loadKeyboard(ALPHABET_UNSHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release "?123" key, enter into symbols.
+        pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Press "=\<" key, enter into symbols shifted chording state.
+        pressKey(CODE_SHIFT, SYMBOLS_SHIFTED);
+        // Enter/release symbols shift letter key.
+        chordingPressAndReleaseKey('~', SYMBOLS_SHIFTED, SYMBOLS_SHIFTED);
+        // Release "=\<" key, switch back to symbols.
+        releaseKey(CODE_SHIFT, SYMBOLS_UNSHIFTED);
+        // Press/release "ABC" key, switch to alphabet shift locked.
+        pressAndReleaseKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
     }
 
     // Chording input in symbol shifted.
@@ -81,7 +132,7 @@
         // Press/release "=\<" key, enter symbols shifted.
         pressAndReleaseKey(CODE_SHIFT, SYMBOLS_SHIFTED, SYMBOLS_SHIFTED);
 
-        // Press "=\<" key and hold, enter into chording symbols state.
+        // Press "?123" key and hold, enter into chording symbols state.
         pressKey(CODE_SHIFT, SYMBOLS_UNSHIFTED);
         // Press/release symbol letter key.
         chordingPressAndReleaseKey('1', SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
@@ -94,6 +145,63 @@
         chordingPressAndReleaseKey('a', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
         // Release "ABC" key, switch back to symbols.
         releaseKey(CODE_SYMBOL, SYMBOLS_SHIFTED);
+
+        // Alphabet shifted -> symbols shifted -> "ABC" key + letter -> symbols shifted ->
+        // alphabet.
+        // Load keyboard
+        loadKeyboard(ALPHABET_UNSHIFTED);
+        // Press/release shift key, enter alphabet shifted.
+        pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
+        // Press/release "?123" key, enter into symbols.
+        pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Press/release "=\<" key, enter symbols shifted.
+        pressAndReleaseKey(CODE_SHIFT, SYMBOLS_SHIFTED, SYMBOLS_SHIFTED);
+        // Press "ABC" key, enter into chording alphabet state.
+        pressKey(CODE_SYMBOL, ALPHABET_UNSHIFTED);
+        // Enter/release letter key.
+        chordingPressAndReleaseKey('a', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
+        // Release "ABC" key, switch back to symbols shifted.
+        releaseKey(CODE_SYMBOL, SYMBOLS_SHIFTED);
+        // Press/release "ABC" key, switch to alphabet (not alphabet shifted).
+        pressAndReleaseKey(CODE_SYMBOL, ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
+
+        // Alphabet shift locked -> symbols shifted -> "ABC" key + letter -> symbols shifted
+        // -> alphabet shift locked.
+        // Load keyboard
+        loadKeyboard(ALPHABET_UNSHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release "?123" key, enter into symbols.
+        pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Press/release "=\<" key, enter symbols shifted.
+        pressAndReleaseKey(CODE_SHIFT, SYMBOLS_SHIFTED, SYMBOLS_SHIFTED);
+        // Press "ABC" key, enter into chording alphabet shift locked.
+        pressKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED);
+        // Enter/release letter key.
+        chordingPressAndReleaseKey('A', ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
+        // Release "ABC" key, switch back to symbols shifted.
+        releaseKey(CODE_SYMBOL, SYMBOLS_SHIFTED);
+        // Press/release "ABC" key, switch to alphabet shift locked.
+        pressAndReleaseKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
+
+        // Alphabet shift locked -> symbols shifted -> "=\<" key + letter -> symbols shifted
+        // -> alphabet shift locked.
+        // Load keyboard
+        loadKeyboard(ALPHABET_UNSHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release "?123" key, enter into symbols.
+        pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Press/release "=\<" key, enter symbols shifted.
+        pressAndReleaseKey(CODE_SHIFT, SYMBOLS_SHIFTED, SYMBOLS_SHIFTED);
+        // Press "=\<" key, enter into symbols chording state.
+        pressKey(CODE_SHIFT, SYMBOLS_UNSHIFTED);
+        // Enter/release symbols letter key.
+        chordingPressAndReleaseKey('1', SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Release "=\<" key, switch back to symbols shifted.
+        releaseKey(CODE_SHIFT, SYMBOLS_SHIFTED);
+        // Press/release "ABC" key, switch to alphabet shift locked.
+        pressAndReleaseKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
     }
 
     // Chording input in automatic upper case.
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
index a1f28dc..e2feb9e 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateSingleTouchTests.java
@@ -398,7 +398,8 @@
         // Press/release "ABC" key, switch to alphabet.
         pressAndReleaseKey(CODE_SYMBOL, ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
 
-        // Alphabet shifted -> symbols -> "ABC" key + letter -> symbols -> alphabet.
+        // Alphabet shifted -> symbols -> "ABC" key + letter -> symbols ->
+        // alphabet.
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Press/release shift key, enter alphabet shifted.
@@ -412,8 +413,8 @@
         // Press/release "ABC" key, switch to alphabet (not alphabet shifted).
         pressAndReleaseKey(CODE_SYMBOL, ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
 
-        // Alphabet shift locked -> symbols -> "ABC" key + letter -> symbols.
-        // -> alphabet shift locked.
+        // Alphabet shift locked -> symbols -> "ABC" key + letter -> symbols ->
+        // alphabet shift locked.
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
@@ -426,6 +427,21 @@
         pressAndReleaseKey('A', ALPHABET_SHIFT_LOCKED, SYMBOLS_UNSHIFTED);
         // Press/release "ABC" key, switch to alphabet shift locked.
         pressAndReleaseKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
+
+        // Alphabet shift locked -> symbols -> "=\<" key + letter -> symbols ->
+        // alphabet shift locked.
+        // Load keyboard
+        loadKeyboard(ALPHABET_UNSHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release "?123" key, enter into symbols.
+        pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Press and slide from "=\<" key, enter symbols shifted.
+        pressAndSlideFromKey(CODE_SHIFT, SYMBOLS_SHIFTED, SYMBOLS_SHIFTED);
+        // Enter/release symbols shift letter key, switch back to symbols.
+        pressAndReleaseKey('~', SYMBOLS_SHIFTED, SYMBOLS_UNSHIFTED);
+        // Press/release "ABC" key, switch to alphabet shift locked.
+        pressAndReleaseKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
     }
 
     // Sliding input in symbols shifted.
@@ -448,7 +464,8 @@
         // Press/release "ABC" key, switch to alphabet.
         pressAndReleaseKey(CODE_SYMBOL, ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
 
-        // Alphabet shifted -> symbols shifted -> "ABC" + letter -> symbols shifted -> alphabet.
+        // Alphabet shifted -> symbols shifted -> "ABC" + letter -> symbols shifted ->
+        // alphabet.
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Press/release shift key, enter alphabet shifted.
@@ -464,8 +481,8 @@
         // Press/release "ABC" key, switch to alphabet (not alphabet shifted).
         pressAndReleaseKey(CODE_SYMBOL, ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
 
-        // Alphabet shift locked -> symbols shifted -> "ABC" + letter -> symbols shifted
-        // -> alphabet shift locked.
+        // Alphabet shift locked -> symbols shifted -> "ABC" + letter -> symbols shifted ->
+        // alphabet shift locked.
         // Load keyboard
         loadKeyboard(ALPHABET_UNSHIFTED);
         // Long press shift key, enter alphabet shift locked.
@@ -480,6 +497,23 @@
         pressAndReleaseKey('A', ALPHABET_SHIFT_LOCKED, SYMBOLS_SHIFTED);
         // Press/release "ABC" key, switch to alphabet shift locked.
         pressAndReleaseKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
+
+        // Alphabet shift locked -> symbols shifted -> "?123" + letter -> symbols shifted ->
+        // alphabet shift locked.
+        // Load keyboard
+        loadKeyboard(ALPHABET_UNSHIFTED);
+        // Long press shift key, enter alphabet shift locked.
+        longPressShiftKey(ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
+        // Press/release "?123" key, enter into symbols.
+        pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Press/release "=\<" key, enter into symbols shifted.
+        pressAndReleaseKey(CODE_SHIFT, SYMBOLS_SHIFTED, SYMBOLS_SHIFTED);
+        // Press and slide from "?123" key.
+        pressAndSlideFromKey(CODE_SHIFT, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
+        // Enter/release symbol letter key, switch back to symbols shifted.
+        pressAndReleaseKey('1', SYMBOLS_UNSHIFTED, SYMBOLS_SHIFTED);
+        // Press/release "ABC" key, switch to alphabet shift locked.
+        pressAndReleaseKey(CODE_SYMBOL, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
     }
 
     // Change focus to new text field.