Track all pointers events

Bug: 2910379
Change-Id: I179ae4359afb57c351d5fcc5f5453c30d3ef0c01
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 0896f6c..9312ce2 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -965,6 +965,7 @@
 
     private void postUpdateShiftKeyState() {
         mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
+        // TODO: Should remove this 300ms delay?
         mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SHIFT_STATE), 300);
     }
 
@@ -1090,7 +1091,7 @@
                 LatinImeLogger.logOnDelete();
                 break;
             case Keyboard.KEYCODE_SHIFT:
-                handleShift();
+                // Shift key is handled in onPress().
                 break;
             case Keyboard.KEYCODE_CANCEL:
                 if (mOptionsDialog == null || !mOptionsDialog.isShowing()) {
@@ -1107,6 +1108,7 @@
                 toggleLanguage(false, false);
                 break;
             case Keyboard.KEYCODE_MODE_CHANGE:
+                // TODO: Mode change (symbol key) should be handled in onPress().
                 changeKeyboardMode();
                 break;
             case LatinKeyboardView.KEYCODE_VOICE:
@@ -1248,19 +1250,6 @@
         }
     }
 
-    private void handleCapsLock() {
-        mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
-        KeyboardSwitcher switcher = mKeyboardSwitcher;
-        if (switcher.isAlphabetMode()) {
-            mCapsLock = !mCapsLock;
-            if (mCapsLock) {
-                switcher.setShiftLocked(true);
-            } else {
-                switcher.setShifted(false);
-            }
-        }
-    }
-
     private void abortCorrection(boolean force) {
         if (force || TextEntryState.isCorrecting()) {
             getCurrentInputConnection().finishComposingText();
@@ -2157,6 +2146,10 @@
     public void onPress(int primaryCode) {
         vibrate();
         playKeyClick(primaryCode);
+        if (primaryCode == Keyboard.KEYCODE_SHIFT) {
+            handleShift();
+        }
+        // TODO: We should handle KEYCODE_MODE_CHANGE (symbol) here as well.
     }
 
     public void onRelease(int primaryCode) {
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
index 3efb16b..d1a5cd8 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
@@ -204,11 +204,6 @@
 
     private final ProximityKeyDetector mProximityKeyDetector = new ProximityKeyDetector();
 
-    // Variables for dealing with multiple pointers
-    private int mOldPointerCount = 1;
-    private int mOldPointerX;
-    private int mOldPointerY;
-
     // Swipe gesture detector
     private final GestureDetector mGestureDetector;
     private final SwipeTracker mSwipeTracker = new SwipeTracker();
@@ -1070,17 +1065,10 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent me) {
-        // Convert multi-pointer up/down events to single up/down events to
-        // deal with the typical multi-pointer behavior of two-thumb typing
         final int pointerCount = me.getPointerCount();
-        final int action = me.getAction();
+        final int action = me.getActionMasked();
         final long eventTime = me.getEventTime();
 
-        if (pointerCount > 1 && mOldPointerCount > 1) {
-            // Don't do anything when 2 or more pointers are down and moving.
-            return true;
-        }
-
         // Track the last few movements to look for spurious swipes.
         mSwipeTracker.addMovement(me);
 
@@ -1108,34 +1096,36 @@
             // Up event will pass through.
         }
 
-        // TODO: Should remove this implicit reference to id=0 pointer tracker in the future.
-        PointerTracker tracker = getPointerTracker(0);
-        int touchX = getTouchX(me.getX());
-        int touchY = getTouchY(me.getY());
-        if (pointerCount != mOldPointerCount) {
-            if (pointerCount == 1) {
-                // Send a down event for the latest pointer
-                tracker.onDownEvent(touchX, touchY, eventTime);
-                // If it's an up action, then deliver the up as well.
-                if (action == MotionEvent.ACTION_UP) {
-                    tracker.onUpEvent(touchX, touchY, eventTime);
-                }
-            } else {
-                // Send an up event for the last pointer
-                tracker.onUpEvent(mOldPointerX, mOldPointerY, eventTime);
+        if (action == MotionEvent.ACTION_MOVE) {
+            for (int index = 0; index < pointerCount; index++) {
+                int touchX = getTouchX(me.getX(index));
+                int touchY = getTouchY(me.getY(index));
+                int id = me.getPointerId(index);
+                PointerTracker tracker = getPointerTracker(id);
+                tracker.onMoveEvent(touchX, touchY, eventTime);
             }
-            mOldPointerCount = pointerCount;
-            return true;
         } else {
-            if (pointerCount == 1) {
-                tracker.onModifiedTouchEvent(action, touchX, touchY, eventTime);
-                mOldPointerX = touchX;
-                mOldPointerY = touchY;
-                return true;
+            int index = me.getActionIndex();
+            int touchX = getTouchX(me.getX(index));
+            int touchY = getTouchY(me.getY(index));
+            int id = me.getPointerId(index);
+            PointerTracker tracker = getPointerTracker(id);
+            switch (action) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_POINTER_DOWN:
+                tracker.onDownEvent(touchX, touchY, eventTime);
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_POINTER_UP:
+                tracker.onUpEvent(touchX, touchY, eventTime);
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                tracker.onCancelEvent(touchX, touchY, eventTime);
+                break;
             }
         }
 
-        return false;
+        return true;
     }
 
     protected void swipeRight() {
diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/latin/PointerTracker.java
index 185fca4..3c67ebe 100644
--- a/java/src/com/android/inputmethod/latin/PointerTracker.java
+++ b/java/src/com/android/inputmethod/latin/PointerTracker.java
@@ -21,7 +21,6 @@
 
 import android.inputmethodservice.Keyboard;
 import android.inputmethodservice.Keyboard.Key;
-import android.view.MotionEvent;
 import android.view.ViewConfiguration;
 
 public class PointerTracker {
@@ -119,23 +118,6 @@
         }
     }
 
-    public void onModifiedTouchEvent(int action, int touchX, int touchY, long eventTime) {
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                onDownEvent(touchX, touchY, eventTime);
-                break;
-            case MotionEvent.ACTION_MOVE:
-                onMoveEvent(touchX, touchY, eventTime);
-                break;
-            case MotionEvent.ACTION_UP:
-                onUpEvent(touchX, touchY, eventTime);
-                break;
-            case MotionEvent.ACTION_CANCEL:
-                onCancelEvent(touchX, touchY, eventTime);
-                break;
-        }
-    }
-
     public void onDownEvent(int touchX, int touchY, long eventTime) {
         int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(touchX, touchY, null);
         mCurrentKey = keyIndex;