am 87da8606: Manually merged VelocityTracker changes

Merge commit '87da860616009a86e260e49bbefffe12c1a06607'

* commit '87da860616009a86e260e49bbefffe12c1a06607':
  Use a circular buffer in VelocityTracker
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 9581080..9a8ee02 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -61,6 +61,7 @@
 
     float mYVelocity[] = new float[MotionEvent.BASE_AVAIL_POINTERS];
     float mXVelocity[] = new float[MotionEvent.BASE_AVAIL_POINTERS];
+    int mLastTouch;
 
     private VelocityTracker mNext;
 
@@ -105,8 +106,11 @@
      * Reset the velocity tracker back to its initial state.
      */
     public void clear() {
-        for (int i = 0; i < MotionEvent.BASE_AVAIL_POINTERS; i++) {
-            mPastTime[i][0] = 0;
+        final long[][] pastTime = mPastTime;
+        for (int p = 0; p < MotionEvent.BASE_AVAIL_POINTERS; p++) {
+            for (int i = 0; i < NUM_PAST; i++) {
+                pastTime[p][i] = 0;
+            }
         }
     }
     
@@ -133,42 +137,11 @@
     }
 
     private void addPoint(int pos, float x, float y, long time) {
-        int drop = -1;
-        int i;
-        if (localLOGV) Log.v(TAG, "Adding past y=" + y + " time=" + time);
-        final long[] pastTime = mPastTime[pos];
-        for (i=0; i<NUM_PAST; i++) {
-            if (pastTime[i] == 0) {
-                break;
-            } else if (pastTime[i] < time-LONGEST_PAST_TIME) {
-                if (localLOGV) Log.v(TAG, "Dropping past too old at "
-                        + i + " time=" + pastTime[i]);
-                drop = i;
-            }
-        }
-        if (localLOGV) Log.v(TAG, "Add index: " + i);
-        if (i == NUM_PAST && drop < 0) {
-            drop = 0;
-        }
-        if (drop == i) drop--;
-        final float[] pastX = mPastX[pos];
-        final float[] pastY = mPastY[pos];
-        if (drop >= 0) {
-            if (localLOGV) Log.v(TAG, "Dropping up to #" + drop);
-            final int start = drop+1;
-            final int count = NUM_PAST-drop-1;
-            System.arraycopy(pastX, start, pastX, 0, count);
-            System.arraycopy(pastY, start, pastY, 0, count);
-            System.arraycopy(pastTime, start, pastTime, 0, count);
-            i -= (drop+1);
-        }
-        pastX[i] = x;
-        pastY[i] = y;
-        pastTime[i] = time;
-        i++;
-        if (i < NUM_PAST) {
-            pastTime[i] = 0;
-        }
+        final int lastTouch = (mLastTouch + 1) % NUM_PAST;
+        mPastX[pos][lastTouch] = x;
+        mPastY[pos][lastTouch] = y;
+        mPastTime[pos][lastTouch] = time;
+        mLastTouch = lastTouch;
     }
 
     /**
@@ -199,36 +172,41 @@
             final float[] pastX = mPastX[pos];
             final float[] pastY = mPastY[pos];
             final long[] pastTime = mPastTime[pos];
-
+            final int lastTouch = mLastTouch;
+        
+            // find oldest acceptable time
+            int oldestTouch = lastTouch;
+            if (pastTime[lastTouch] > 0) { // cleared ?
+                oldestTouch = (lastTouch + 1) % NUM_PAST;
+                final float acceptableTime = pastTime[lastTouch] - LONGEST_PAST_TIME;
+                while (pastTime[oldestTouch] < acceptableTime) {
+                    oldestTouch = (oldestTouch + 1) % NUM_PAST;
+                }
+            }
+        
             // Kind-of stupid.
-            final float oldestX = pastX[0];
-            final float oldestY = pastY[0];
-            final long oldestTime = pastTime[0];
+            final float oldestX = pastX[oldestTouch];
+            final float oldestY = pastY[oldestTouch];
+            final long oldestTime = pastTime[oldestTouch];
             float accumX = 0;
             float accumY = 0;
-            int N=0;
-            while (N < NUM_PAST) {
-                if (pastTime[N] == 0) {
-                    break;
-                }
-                N++;
-            }
+            float N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1;
             // Skip the last received event, since it is probably pretty noisy.
             if (N > 3) N--;
 
             for (int i=1; i < N; i++) {
-                final int dur = (int)(pastTime[i] - oldestTime);
+                final int j = (oldestTouch + i) % NUM_PAST;
+                final int dur = (int)(pastTime[j] - oldestTime);
                 if (dur == 0) continue;
-                float dist = pastX[i] - oldestX;
+                float dist = pastX[j] - oldestX;
                 float vel = (dist/dur) * units;   // pixels/frame.
-                if (accumX == 0) accumX = vel;
-                else accumX = (accumX + vel) * .5f;
-
-                dist = pastY[i] - oldestY;
+                accumX = (accumX == 0) ? vel : (accumX + vel) * .5f;
+            
+                dist = pastY[j] - oldestY;
                 vel = (dist/dur) * units;   // pixels/frame.
-                if (accumY == 0) accumY = vel;
-                else accumY = (accumY + vel) * .5f;
+                accumY = (accumY == 0) ? vel : (accumY + vel) * .5f;
             }
+            
             mXVelocity[pos] = accumX < 0.0f ? Math.max(accumX, -maxVelocity)
                     : Math.min(accumX, maxVelocity);
             mYVelocity[pos] = accumY < 0.0f ? Math.max(accumY, -maxVelocity)