Fixed extra periods when chording with shift and space

Actually it was caused by canceling repeat key (space and delete) when
multiple pointer are touching.

Bug: 2975041
Change-Id: If82183b9225efdace7b5418860b9664f1705b7ec
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
index 1e95e8a..a0366c2 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
@@ -1120,7 +1120,6 @@
     public boolean onTouchEvent(MotionEvent me) {
         final int pointerCount = me.getPointerCount();
         final int action = me.getActionMasked();
-        final long eventTime = me.getEventTime();
 
         // TODO: cleanup this code into a multi-touch to single-touch event converter class?
         // If the device does not have distinct multi-touch support panel, ignore all multi-touch
@@ -1139,24 +1138,32 @@
             return true;
         }
 
+        final long eventTime = me.getEventTime();
+        final int index = me.getActionIndex();
+        final int id = me.getPointerId(index);
+        final int x = (int)me.getX(index);
+        final int y = (int)me.getY(index);
+
         // Needs to be called after the gesture detector gets a turn, as it may have
         // displayed the mini keyboard
         if (mMiniKeyboard != null) {
-            MotionEvent translated = generateMiniKeyboardMotionEvent(action, (int)me.getX(),
-                    (int)me.getY(), eventTime);
+            MotionEvent translated = generateMiniKeyboardMotionEvent(action, x, y, eventTime);
             mMiniKeyboard.onTouchEvent(translated);
             translated.recycle();
             return true;
         }
 
         if (mHandler.isInKeyRepeat()) {
-            // It'll be canceled if 2 or more keys are in action. Otherwise it will keep being in
-            // the key repeating mode while the key is being pressed.
-            if (pointerCount > 1) {
-                mHandler.cancelKeyRepeatTimer();
-            } else if (action == MotionEvent.ACTION_MOVE) {
+            // It will keep being in the key repeating mode while the key is being pressed.
+            if (action == MotionEvent.ACTION_MOVE) {
                 return true;
             }
+            final PointerTracker tracker = getPointerTracker(id);
+            // Key repeating timer will be canceled if 2 or more keys are in action, and current
+            // event (UP or DOWN) is non-modifier key.
+            if (pointerCount > 1 && !tracker.isModifier()) {
+                mHandler.cancelKeyRepeatTimer();
+            }
             // Up event will pass through.
         }
 
@@ -1166,9 +1173,6 @@
         if (!mHasDistinctMultitouch) {
             // Use only main (id=0) pointer tracker.
             PointerTracker tracker = getPointerTracker(0);
-            int index = me.getActionIndex();
-            int x = (int)me.getX(index);
-            int y = (int)me.getY(index);
             int oldPointerCount = mOldPointerCount;
             if (pointerCount == 1 && oldPointerCount == 2) {
                 // Multi-touch to single touch transition.
@@ -1189,18 +1193,11 @@
         }
 
         if (action == MotionEvent.ACTION_MOVE) {
-            for (int index = 0; index < pointerCount; index++) {
-                int x = (int)me.getX(index);
-                int y = (int)me.getY(index);
-                int id = me.getPointerId(index);
-                PointerTracker tracker = getPointerTracker(id);
-                tracker.onMoveEvent(x, y, eventTime);
+            for (int i = 0; i < pointerCount; i++) {
+                PointerTracker tracker = getPointerTracker(me.getPointerId(i));
+                tracker.onMoveEvent((int)me.getX(i), (int)me.getY(i), eventTime);
             }
         } else {
-            int index = me.getActionIndex();
-            int x = (int)me.getX(index);
-            int y = (int)me.getY(index);
-            int id = me.getPointerId(index);
             PointerTracker tracker = getPointerTracker(id);
             switch (action) {
             case MotionEvent.ACTION_DOWN:
diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/latin/PointerTracker.java
index 1f60056..f849158 100644
--- a/java/src/com/android/inputmethod/latin/PointerTracker.java
+++ b/java/src/com/android/inputmethod/latin/PointerTracker.java
@@ -65,6 +65,9 @@
     // true if event is already translated to a key action (long press or mini-keyboard)
     private boolean mKeyAlreadyProcessed;
 
+    // true if this pointer is repeatable key
+    private boolean mIsRepeatableKey;
+
     // for move de-bouncing
     private int mLastCodeX;
     private int mLastCodeY;
@@ -176,6 +179,7 @@
         mStartY = y;
         mDownTime = eventTime;
         mKeyAlreadyProcessed = false;
+        mIsRepeatableKey = false;
         startMoveDebouncing(x, y);
         startTimeDebouncing(eventTime);
         checkMultiTap(eventTime, keyIndex);
@@ -187,6 +191,7 @@
             if (mKeys[keyIndex].repeatable) {
                 repeatKey(keyIndex);
                 mHandler.startKeyRepeatTimer(REPEAT_START_DELAY, keyIndex, this);
+                mIsRepeatableKey = true;
             }
             mHandler.startLongPressTimer(LONGPRESS_TIMEOUT, keyIndex, this);
         }
@@ -246,10 +251,9 @@
             return;
         if (DEBUG)
             debugLog("onUpEvent  :", x, y);
-        int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
-        boolean wasInKeyRepeat = mHandler.isInKeyRepeat();
         mHandler.cancelKeyTimers();
         mHandler.cancelPopupPreview();
+        int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
         if (isMinorMoveBounce(x, y, keyIndex, mCurrentKey)) {
             updateTimeDebouncing(eventTime);
         } else {
@@ -263,8 +267,7 @@
             y = mLastCodeY;
         }
         showKeyPreviewAndUpdateKey(NOT_A_KEY);
-        // If we're not on a repeating key (which sends on a DOWN event)
-        if (!wasInKeyRepeat) {
+        if (!mIsRepeatableKey) {
             detectAndSendKey(mCurrentKey, x, y, eventTime);
         }
         if (isValidKeyIndex(keyIndex))