private void track(MotionEvent event) {
    mX.saveTouchPos();
    mY.saveTouchPos();

    for (int i = 0; i < event.getHistorySize(); i++) {
      track(
          event.getHistoricalX(0, i), event.getHistoricalY(0, i), event.getHistoricalEventTime(i));
    }
    track(event.getX(0), event.getY(0), event.getEventTime());

    if (stopped()) {
      if (mState == PanZoomState.PANNING) {
        setState(PanZoomState.PANNING_HOLD);
      } else if (mState == PanZoomState.PANNING_LOCKED) {
        setState(PanZoomState.PANNING_HOLD_LOCKED);
      } else {
        // should never happen, but handle anyway for robustness
        Log.e(LOGTAG, "Impossible case " + mState + " when stopped in track");
        setState(PanZoomState.PANNING_HOLD_LOCKED);
      }
    }

    mX.startPan();
    mY.startPan();
    updatePosition();
  }
 /**
  * Add a user's movement to the tracker. You should call this for the initial {@link
  * MotionEvent#ACTION_DOWN}, the following {@link MotionEvent#ACTION_MOVE} events that you
  * receive, and the final {@link MotionEvent#ACTION_UP}. You can, however, call this for whichever
  * events you desire.
  *
  * @param ev The MotionEvent you received and would like to track.
  */
 public void addMovement(MotionEvent ev) {
   final int mN = ev.getHistorySize();
   if (++mLastTouch >= NUM_PAST) {
     mLastTouch = 0;
   }
   for (int i = 0; i < mN; ++i) {
     mPastX[mLastTouch] = ev.getHistoricalX(i);
     mPastY[mLastTouch] = ev.getHistoricalY(i);
     mPastTime[mLastTouch] = ev.getHistoricalEventTime(i);
     if (++mLastTouch >= NUM_PAST) {
       mLastTouch = 0;
     }
   }
   mPastX[mLastTouch] = ev.getX();
   mPastY[mLastTouch] = ev.getY();
   mPastTime[mLastTouch] = ev.getEventTime();
 }
 private int detectSwipe(MotionEvent move) {
   final int historySize = move.getHistorySize();
   final int pointerCount = move.getPointerCount();
   for (int p = 0; p < pointerCount; p++) {
     final int pointerId = move.getPointerId(p);
     final int i = findIndex(pointerId);
     if (i != UNTRACKED_POINTER) {
       for (int h = 0; h < historySize; h++) {
         final long time = move.getHistoricalEventTime(h);
         final float x = move.getHistoricalX(p, h);
         final float y = move.getHistoricalY(p, h);
         final int swipe = detectSwipe(i, time, x, y);
         if (swipe != SWIPE_NONE) {
           return swipe;
         }
       }
       final int swipe = detectSwipe(i, move.getEventTime(), move.getX(p), move.getY(p));
       if (swipe != SWIPE_NONE) {
         return swipe;
       }
     }
   }
   return SWIPE_NONE;
 }