Merge "Get rid of public KeyboardState.setShifted and setShiftLocked"
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 7e7f2b8..1f70ecc 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -138,7 +138,8 @@
             mMainKeyboardId = getKeyboardId(editorInfo, false, false, settingsValues);
             mSymbolsKeyboardId = getKeyboardId(editorInfo, true, false, settingsValues);
             mSymbolsShiftedKeyboardId = getKeyboardId(editorInfo, true, true, settingsValues);
-            mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols));
+            mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols),
+                    hasDistinctMultitouch());
         } catch (RuntimeException e) {
             Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e);
             LatinImeLogger.logOnException(mMainKeyboardId.toString(), e);
@@ -318,7 +319,6 @@
         if (latinKeyboard == null)
             return;
         if (shiftMode == AUTOMATIC_SHIFT) {
-            mState.setAutomaticTemporaryUpperCase();
             latinKeyboard.setAutomaticTemporaryUpperCase();
         } else {
             final boolean shifted = (shiftMode == MANUAL_SHIFT);
@@ -326,11 +326,9 @@
             // state when shift key is pressed to go to normal mode.
             // On the other hand, on distinct multi touch panel device, turning off the shift
             // locked state with shift key pressing is handled by onReleaseShift().
-            if (!hasDistinctMultitouch() && !shifted && latinKeyboard.isShiftLocked()) {
-                mState.setShiftLocked(false);
+            if (!hasDistinctMultitouch() && !shifted && mState.isShiftLocked()) {
                 latinKeyboard.setShiftLocked(false);
             }
-            mState.setShifted(shifted);
             latinKeyboard.setShifted(shifted);
         }
         mKeyboardView.invalidateAllKeys();
@@ -343,7 +341,6 @@
         LatinKeyboard latinKeyboard = getLatinKeyboard();
         if (latinKeyboard == null)
             return;
-        mState.setShiftLocked(shiftLocked);
         latinKeyboard.setShiftLocked(shiftLocked);
         mKeyboardView.invalidateAllKeys();
         if (!shiftLocked) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index c952ea6..8cf0539 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -22,6 +22,12 @@
 import com.android.inputmethod.keyboard.Keyboard;
 
 // TODO: Add unit tests
+/**
+ * Keyboard state machine.
+ *
+ * This class contains all keyboard state transition logic.
+ * TODO: List up input events and actions.
+ */
 public class KeyboardState {
     private static final String TAG = KeyboardState.class.getSimpleName();
     private static final boolean DEBUG_STATE = false;
@@ -53,6 +59,7 @@
     private int mSwitchState = SWITCH_STATE_ALPHA;
 
     private String mLayoutSwitchBackSymbols;
+    private boolean mHasDistinctMultitouch;
 
     private final SwitchActions mSwitchActions;
 
@@ -70,8 +77,9 @@
         mSwitchActions = switchActions;
     }
 
-    public void onLoadKeyboard(String layoutSwitchBackSymbols) {
+    public void onLoadKeyboard(String layoutSwitchBackSymbols, boolean hasDistinctMultitouch) {
         mLayoutSwitchBackSymbols = layoutSwitchBackSymbols;
+        mHasDistinctMultitouch = hasDistinctMultitouch;
         mKeyboardShiftState.setShifted(false);
         mKeyboardShiftState.setShiftLocked(false);
         mShiftKeyState.onRelease();
@@ -118,10 +126,9 @@
         state.mIsValid = false;
 
         if (state.mIsAlphabetMode) {
-            mSwitchActions.setShiftLocked(state.mIsShiftLocked);
+            setShiftLocked(state.mIsShiftLocked);
             if (!state.mIsShiftLocked) {
-                mSwitchActions.setShifted(
-                        state.mIsShifted ? SwitchActions.MANUAL_SHIFT : SwitchActions.UNSHIFT);
+                setShifted(state.mIsShifted ? SwitchActions.MANUAL_SHIFT : SwitchActions.UNSHIFT);
             }
         }
     }
@@ -150,19 +157,27 @@
         return mKeyboardShiftState.isManualTemporaryUpperCaseFromAuto();
     }
 
-    // TODO: Get rid of this method
-    public void setShifted(boolean shifted) {
-        mKeyboardShiftState.setShifted(shifted);
+    private void setShifted(int shiftMode) {
+        if (shiftMode == SwitchActions.AUTOMATIC_SHIFT) {
+            mKeyboardShiftState.setAutomaticTemporaryUpperCase();
+        } else {
+            // TODO: Duplicated logic in KeyboardSwitcher#setShifted()
+            final boolean shifted = (shiftMode == SwitchActions.MANUAL_SHIFT);
+            // On non-distinct multi touch panel device, we should also turn off the shift locked
+            // state when shift key is pressed to go to normal mode.
+            // On the other hand, on distinct multi touch panel device, turning off the shift
+            // locked state with shift key pressing is handled by onReleaseShift().
+            if (!mHasDistinctMultitouch && !shifted && isShiftLocked()) {
+                mKeyboardShiftState.setShiftLocked(false);
+            }
+            mKeyboardShiftState.setShifted(shifted);
+        }
+        mSwitchActions.setShifted(shiftMode);
     }
 
-    // TODO: Get rid of this method
-    public void setShiftLocked(boolean shiftLocked) {
+    private void setShiftLocked(boolean shiftLocked) {
         mKeyboardShiftState.setShiftLocked(shiftLocked);
-    }
-
-    // TODO: Get rid of this method
-    public void setAutomaticTemporaryUpperCase() {
-        mKeyboardShiftState.setAutomaticTemporaryUpperCase();
+        mSwitchActions.setShiftLocked(shiftLocked);
     }
 
     private void toggleAlphabetAndSymbols(boolean isAlphabetMode) {
@@ -184,7 +199,7 @@
     private void setAlphabetKeyboard() {
         mSwitchActions.setAlphabetKeyboard();
         mSwitchState = SWITCH_STATE_ALPHA;
-        mSwitchActions.setShiftLocked(mPrevMainKeyboardWasShiftLocked);
+        setShiftLocked(mPrevMainKeyboardWasShiftLocked);
         mPrevMainKeyboardWasShiftLocked = false;
     }
 
@@ -227,9 +242,9 @@
             if (!isShiftLocked() && !mShiftKeyState.isIgnoring()) {
                 if (mShiftKeyState.isReleasing() && autoCaps) {
                     // Only when shift key is releasing, automatic temporary upper case will be set.
-                    mSwitchActions.setShifted(SwitchActions.AUTOMATIC_SHIFT);
+                    setShifted(SwitchActions.AUTOMATIC_SHIFT);
                 } else {
-                    mSwitchActions.setShifted(mShiftKeyState.isMomentary()
+                    setShifted(mShiftKeyState.isMomentary()
                             ? SwitchActions.MANUAL_SHIFT : SwitchActions.UNSHIFT);
                 }
             }
@@ -246,12 +261,12 @@
             if (isShiftLocked()) {
                 // Shift key is pressed while caps lock state, we will treat this state as shifted
                 // caps lock state and mark as if shift key pressed while normal state.
-                mSwitchActions.setShifted(SwitchActions.MANUAL_SHIFT);
+                setShifted(SwitchActions.MANUAL_SHIFT);
                 mShiftKeyState.onPress();
             } else if (isAutomaticTemporaryUpperCase()) {
                 // Shift key is pressed while automatic temporary upper case, we have to move to
                 // manual temporary upper case.
-                mSwitchActions.setShifted(SwitchActions.MANUAL_SHIFT);
+                setShifted(SwitchActions.MANUAL_SHIFT);
                 mShiftKeyState.onPress();
             } else if (isShiftedOrShiftLocked()) {
                 // In manual upper case state, we just record shift key has been pressing while
@@ -259,7 +274,7 @@
                 mShiftKeyState.onPressOnShifted();
             } else {
                 // In base layout, chording or manual temporary upper case mode is started.
-                mSwitchActions.setShifted(SwitchActions.MANUAL_SHIFT);
+                setShifted(SwitchActions.MANUAL_SHIFT);
                 mShiftKeyState.onPress();
             }
         } else {
@@ -277,22 +292,22 @@
             final boolean isShiftLocked = isShiftLocked();
             if (mShiftKeyState.isMomentary()) {
                 // After chording input while normal state.
-                mSwitchActions.setShifted(SwitchActions.UNSHIFT);
+                setShifted(SwitchActions.UNSHIFT);
             } else if (isShiftLocked && !isShiftLockShifted() && (mShiftKeyState.isPressing()
                     || mShiftKeyState.isPressingOnShifted()) && !withSliding) {
                 // Shift has been long pressed, ignore this release.
             } else if (isShiftLocked && !mShiftKeyState.isIgnoring() && !withSliding) {
                 // Shift has been pressed without chording while caps lock state.
-                mSwitchActions.setShiftLocked(false);
+                setShiftLocked(false);
             } else if (isShiftedOrShiftLocked() && mShiftKeyState.isPressingOnShifted()
                     && !withSliding) {
                 // Shift has been pressed without chording while shifted state.
-                mSwitchActions.setShifted(SwitchActions.UNSHIFT);
+                setShifted(SwitchActions.UNSHIFT);
             } else if (isManualTemporaryUpperCaseFromAuto() && mShiftKeyState.isPressing()
                     && !withSliding) {
                 // Shift has been pressed without chording while manual temporary upper case
                 // transited from automatic temporary upper case.
-                mSwitchActions.setShifted(SwitchActions.UNSHIFT);
+                setShifted(SwitchActions.UNSHIFT);
             }
         } else {
             // In symbol mode, snap back to the previous keyboard mode if the user chords the shift
@@ -400,8 +415,8 @@
     // TODO: Get rid of isAlphabetMode and isSymbolShifted arguments.
     public void onToggleShift(boolean isAlphabetMode, boolean isSymbolShifted) {
         if (isAlphabetMode) {
-            mSwitchActions.setShifted(
-                    isShiftedOrShiftLocked() ? SwitchActions.UNSHIFT : SwitchActions.MANUAL_SHIFT);
+            setShifted(isShiftedOrShiftLocked()
+                    ? SwitchActions.UNSHIFT : SwitchActions.MANUAL_SHIFT);
         } else {
             toggleShiftInSymbols(isSymbolShifted);
         }
@@ -411,12 +426,12 @@
     public void onToggleCapsLock(boolean isAlphabetMode) {
         if (isAlphabetMode) {
             if (isShiftLocked()) {
-                mSwitchActions.setShiftLocked(false);
+                setShiftLocked(false);
                 // Shift key is long pressed while caps lock state, we will toggle back to normal
                 // state. And mark as if shift key is released.
                 mShiftKeyState.onRelease();
             } else {
-                mSwitchActions.setShiftLocked(true);
+                setShiftLocked(true);
             }
         }
     }