From 0c5f72e2bf22df48af051827f97ab6052026d531 Mon Sep 17 00:00:00 2001
From: Tom Ouyang <ouyang@google.com>
Date: Thu, 19 Jul 2012 21:53:42 +0900
Subject: [PATCH] Improve incremental gesture tracking.

Eliminates need to recreate batch InputPointers on each gesture move event.
Fixes issue where batch points from previous tapping input get mixed into next gesture.

Change-Id: I9ecac66db88f5a87c6dde2138408906dd3d11139
---
 .../inputmethod/keyboard/PointerTracker.java  | 21 +++++++++++--------
 .../keyboard/internal/GestureStroke.java      | 10 +++++++--
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index ea4d93a4a..b002ae992 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -121,6 +121,8 @@ public class PointerTracker {
     private static boolean sConfigGestureInputEnabledByBuildConfig;
 
     private static final ArrayList<PointerTracker> sTrackers = new ArrayList<PointerTracker>();
+    private static final InputPointers sAggregratedPointers = new InputPointers(
+            GestureStroke.DEFAULT_CAPACITY);
     private static PointerTrackerQueue sPointerTrackerQueue;
     // HACK: Change gesture detection criteria depending on this variable.
     // TODO: Find more comprehensive ways to detect a gesture start.
@@ -257,23 +259,19 @@ public class PointerTracker {
     // TODO: To handle multi-touch gestures we may want to move this method to
     // {@link PointerTrackerQueue}.
     private static InputPointers getIncrementalBatchPoints() {
-        // TODO: Avoid creating a new instance here?
-        final InputPointers pointers = new InputPointers(GestureStroke.DEFAULT_CAPACITY);
         for (final PointerTracker tracker : sTrackers) {
-            tracker.mGestureStroke.appendIncrementalBatchPoints(pointers);
+            tracker.mGestureStroke.appendIncrementalBatchPoints(sAggregratedPointers);
         }
-        return pointers;
+        return sAggregratedPointers;
     }
 
     // TODO: To handle multi-touch gestures we may want to move this method to
     // {@link PointerTrackerQueue}.
     private static InputPointers getAllBatchPoints() {
-        // TODO: Avoid creating a new instance here?
-        final InputPointers pointers = new InputPointers(GestureStroke.DEFAULT_CAPACITY);
         for (final PointerTracker tracker : sTrackers) {
-            tracker.mGestureStroke.appendAllBatchPoints(pointers);
+            tracker.mGestureStroke.appendAllBatchPoints(sAggregratedPointers);
         }
-        return pointers;
+        return sAggregratedPointers;
     }
 
     // TODO: To handle multi-touch gestures we may want to move this method to
@@ -282,6 +280,7 @@ public class PointerTracker {
         for (final PointerTracker tracker : sTrackers) {
             tracker.mGestureStroke.reset();
         }
+        sAggregratedPointers.reset();
     }
 
     private PointerTracker(int id, KeyEventHandler handler) {
@@ -645,6 +644,8 @@ public class PointerTracker {
             if (sIsGestureEnabled && mIsAlphabetKeyboard && key != null
                     && Keyboard.isLetterCode(key.mCode)) {
                 mIsPossibleGesture = true;
+                // TODO: pointer times should be relative to first down even in entire batch input
+                // instead of resetting to 0 for each new down event.
                 mGestureStroke.addPoint(x, y, 0, false);
             }
         }
@@ -869,7 +870,9 @@ public class PointerTracker {
             }
             return;
         }
-
+        // This event will be recognized as a regular code input. Clear unused batch points so they
+        // are not mistakenly included in the next batch event.
+        clearBatchInputPointsOfAllPointerTrackers();
         if (mKeyAlreadyProcessed)
             return;
         if (mCurrentKey != null && !mCurrentKey.isRepeatable()) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
index 6f392f145..16c8410df 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
@@ -27,6 +27,7 @@ public class GestureStroke {
     private float mLength;
     private float mAngle;
     private int mIncrementalRecognitionSize;
+    private int mLastIncrementalBatchSize;
     private long mLastPointTime;
     private int mLastPointX;
     private int mLastPointY;
@@ -73,6 +74,7 @@ public class GestureStroke {
         mLength = 0;
         mAngle = 0;
         mIncrementalRecognitionSize = 0;
+        mLastIncrementalBatchSize = 0;
         mLastPointTime = 0;
         mInputPointers.reset();
     }
@@ -126,11 +128,15 @@ public class GestureStroke {
     }
 
     public void appendAllBatchPoints(final InputPointers out) {
-        out.append(mInputPointers, 0, mInputPointers.getPointerSize());
+        final int size = mInputPointers.getPointerSize();
+        out.append(mInputPointers, mLastIncrementalBatchSize, size - mLastIncrementalBatchSize);
+        mLastIncrementalBatchSize = size;
     }
 
     public void appendIncrementalBatchPoints(final InputPointers out) {
-        out.append(mInputPointers, 0, mIncrementalRecognitionSize);
+        out.append(mInputPointers, mLastIncrementalBatchSize,
+                mIncrementalRecognitionSize - mLastIncrementalBatchSize);
+        mLastIncrementalBatchSize = mIncrementalRecognitionSize;
     }
 
     private static float getDistance(final int p1x, final int p1y,