Merge "Use edit distance for transposing correction"
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index e6f036d..8bd25c0 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -120,6 +120,7 @@
     <!-- Title for Latin keyboard debug settings activity / dialog -->
     <string name="english_ime_debug_settings">Android keyboard Debug settings</string>
     <string name="prefs_debug_mode">Debug Mode</string>
+    <string name="prefs_force_non_distinct_multitouch">Force non-distinct multitouch</string>
 
     <!-- Keyboard theme names -->
     <string name="layout_basic">Basic</string>
diff --git a/java/res/xml/prefs_for_debug.xml b/java/res/xml/prefs_for_debug.xml
index 80613a5..f38b85f 100644
--- a/java/res/xml/prefs_for_debug.xml
+++ b/java/res/xml/prefs_for_debug.xml
@@ -42,4 +42,10 @@
             android:defaultValue="false"
             />
 
+    <CheckBoxPreference
+            android:key="force_non_distinct_multitouch"
+            android:title="@string/prefs_force_non_distinct_multitouch"
+            android:persistent="true"
+            android:defaultValue="false"
+            />
 </PreferenceScreen>
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index df61689..af1c3ee 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -28,6 +28,7 @@
 
 import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
 import com.android.inputmethod.keyboard.internal.KeyboardState;
+import com.android.inputmethod.latin.DebugSettings;
 import com.android.inputmethod.latin.InputView;
 import com.android.inputmethod.latin.LatinIME;
 import com.android.inputmethod.latin.LatinImeLogger;
@@ -53,6 +54,7 @@
 
     private SubtypeSwitcher mSubtypeSwitcher;
     private SharedPreferences mPrefs;
+    private boolean mForceNonDistinctMultitouch;
 
     private InputView mCurrentInputView;
     private LatinKeyboardView mKeyboardView;
@@ -92,6 +94,8 @@
         mState = new KeyboardState(this);
         setContextThemeWrapper(ims, getKeyboardThemeIndex(ims, prefs));
         prefs.registerOnSharedPreferenceChangeListener(this);
+        mForceNonDistinctMultitouch = prefs.getBoolean(
+                DebugSettings.FORCE_NON_DISTINCT_MULTITOUCH_KEY, false);
     }
 
     private static int getKeyboardThemeIndex(Context context, SharedPreferences prefs) {
@@ -221,19 +225,16 @@
         Keyboard keyboard = getKeyboard();
         if (keyboard == null)
             return;
-        if (shiftMode == AUTOMATIC_SHIFT) {
+        switch (shiftMode) {
+        case AUTOMATIC_SHIFT:
             keyboard.setAutomaticTemporaryUpperCase();
-        } else {
-            final boolean shifted = (shiftMode == MANUAL_SHIFT);
-            // TODO: Remove duplicated logic in KeyboardState#setShifted
-            // 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 (!hasDistinctMultitouch() && !shifted && mState.isShiftLocked()) {
-                setShiftLocked(false);
-            }
-            keyboard.setShifted(shifted);
+            break;
+        case MANUAL_SHIFT:
+            keyboard.setShifted(true);
+            break;
+        case UNSHIFT:
+            keyboard.setShifted(false);
+            break;
         }
         mKeyboardView.invalidateAllKeys();
     }
@@ -392,6 +393,9 @@
 
         mKeyboardView = (LatinKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
         mKeyboardView.setKeyboardActionListener(mInputMethodService);
+        if (mForceNonDistinctMultitouch) {
+            mKeyboardView.setDistinctMultitouch(false);
+        }
 
         // This always needs to be set since the accessibility state can
         // potentially change without the input view being re-created.
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 4d2aeec..8aa7f88 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -115,7 +115,7 @@
     /** Listener for {@link KeyboardActionListener}. */
     private KeyboardActionListener mKeyboardActionListener;
 
-    private final boolean mHasDistinctMultitouch;
+    private boolean mHasDistinctMultitouch;
     private int mOldPointerCount = 1;
     private Key mOldKey;
 
@@ -371,6 +371,10 @@
         return mHasDistinctMultitouch;
     }
 
+    public void setDistinctMultitouch(boolean hasDistinctMultitouch) {
+        mHasDistinctMultitouch = hasDistinctMultitouch;
+    }
+
     /**
      * When enabled, calls to {@link KeyboardActionListener#onCodeInput} will include key
      * codes for adjacent keys.  When disabled, only the primary key code will be
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 609593e..bb75111 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -166,29 +166,20 @@
         if (DEBUG_STATE) {
             Log.d(TAG, "setShifted: shiftMode=" + shiftModeToString(shiftMode));
         }
-        // TODO: Remove this hack in conjunction with duplicated logic below.
-        boolean needsToTurnOffShiftLockedLater = false;
         if (shiftMode == SwitchActions.AUTOMATIC_SHIFT) {
             mKeyboardShiftState.setAutomaticTemporaryUpperCase();
         } else {
-            // TODO: Remove 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 && mKeyboardShiftState.isShiftLocked()) {
-                // Setting shift lock state should be delayed after
-                // mSwitchActions.setShifted(shiftMode) is called, because in that call the state
-                // is referenced.
-                needsToTurnOffShiftLockedLater = true;
+                mSwitchActions.setShiftLocked(false);
             }
             mKeyboardShiftState.setShifted(shifted);
         }
         mSwitchActions.setShifted(shiftMode);
-        if (needsToTurnOffShiftLockedLater) {
-            mKeyboardShiftState.setShiftLocked(false);
-        }
     }
 
     private void setShiftLocked(boolean shiftLocked) {
diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java
index 2f1e7c2..3805da1 100644
--- a/java/src/com/android/inputmethod/latin/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/DebugSettings.java
@@ -30,6 +30,7 @@
 
     private static final String TAG = "DebugSettings";
     private static final String DEBUG_MODE_KEY = "debug_mode";
+    public static final String FORCE_NON_DISTINCT_MULTITOUCH_KEY = "force_non_distinct_multitouch";
 
     private boolean mServiceNeedsRestart = false;
     private CheckBoxPreference mDebugMode;
@@ -60,6 +61,8 @@
                 updateDebugMode();
                 mServiceNeedsRestart = true;
             }
+        } else if (key.equals(FORCE_NON_DISTINCT_MULTITOUCH_KEY)) {
+            mServiceNeedsRestart = true;
         }
     }