Program: 26321
Project: 26321
Buggy source:
@SuppressLint("String_Node_Str") @Override public boolean onTouch(View v,MotionEvent event){
  if (mVelocityTracker == null) {
    mVelocityTracker=VelocityTracker.obtain();
  }
  mVelocityTracker.addMovement(event);
  if (event.getActionMasked() == MotionEvent.ACTION_CANCEL) {
    if (mVelocityTracker != null) {
      mVelocityTracker.recycle();
      mVelocityTracker=null;
    }
  }
  if (mTouchMode == NONE) {
    mGestureDetector.onTouchEvent(event);
  }
  if (!mChart.isDragEnabled() && (!mChart.isScaleXEnabled() && !mChart.isScaleYEnabled()))   return true;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
    startAction(event);
  stopDeceleration();
saveTouchStart(event);
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (event.getPointerCount() >= 2) {
mChart.disableScroll();
saveTouchStart(event);
mSavedXDist=getXDist(event);
mSavedYDist=getYDist(event);
mSavedDist=spacing(event);
if (mSavedDist > 10f) {
if (mChart.isPinchZoomEnabled()) {
  mTouchMode=PINCH_ZOOM;
}
 else {
  if (mSavedXDist > mSavedYDist)   mTouchMode=X_ZOOM;
 else   mTouchMode=Y_ZOOM;
}
}
midPoint(mTouchPointCenter,event);
}
break;
case MotionEvent.ACTION_MOVE:
if (mTouchMode == DRAG) {
mChart.disableScroll();
performDrag(event);
}
 else if (mTouchMode == X_ZOOM || mTouchMode == Y_ZOOM || mTouchMode == PINCH_ZOOM) {
mChart.disableScroll();
if (mChart.isScaleXEnabled() || mChart.isScaleYEnabled()) performZoom(event);
}
 else if (mTouchMode == NONE && Math.abs(distance(event.getX(),mTouchStartPoint.x,event.getY(),mTouchStartPoint.y)) > 5f) {
if (mChart.hasNoDragOffset()) {
if (!mChart.isFullyZoomedOut() && mChart.isDragEnabled()) {
mTouchMode=DRAG;
}
 else {
mLastGesture=ChartGesture.DRAG;
if (mChart.isHighlightPerDragEnabled()) performHighlightDrag(event);
}
}
 else if (mChart.isDragEnabled()) {
mLastGesture=ChartGesture.DRAG;
mTouchMode=DRAG;
}
}
break;
case MotionEvent.ACTION_UP:
final VelocityTracker velocityTracker=mVelocityTracker;
final int pointerId=event.getPointerId(0);
velocityTracker.computeCurrentVelocity(1000,Utils.getMaximumFlingVelocity());
final float velocityY=velocityTracker.getYVelocity(pointerId);
final float velocityX=velocityTracker.getXVelocity(pointerId);
if (Math.abs(velocityX) > Utils.getMinimumFlingVelocity() || Math.abs(velocityY) > Utils.getMinimumFlingVelocity()) {
if (mTouchMode == DRAG && mChart.isDragDecelerationEnabled()) {
stopDeceleration();
mDecelerationLastTime=AnimationUtils.currentAnimationTimeMillis();
mDecelerationCurrentPoint=new PointF(event.getX(),event.getY());
mDecelerationVelocity=new PointF(velocityX,velocityY);
Utils.postInvalidateOnAnimation(mChart);
}
}
if (mTouchMode == X_ZOOM || mTouchMode == Y_ZOOM || mTouchMode == PINCH_ZOOM || mTouchMode == POST_ZOOM) {
mChart.calculateOffsets();
mChart.postInvalidate();
}
mTouchMode=NONE;
mChart.enableScroll();
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker=null;
}
endAction(event);
break;
case MotionEvent.ACTION_POINTER_UP:
Utils.velocityTrackerPointerUpCleanUpIfNecessary(event,mVelocityTracker);
mTouchMode=POST_ZOOM;
break;
case MotionEvent.ACTION_CANCEL:
mTouchMode=NONE;
endAction(event);
break;
}
mMatrix=mChart.getViewPortHandler().refresh(mMatrix,mChart,true);
return true;
}

Fixed version (ground truth):
@SuppressLint("String_Node_Str") @Override public boolean onTouch(View v,MotionEvent event){
  if (mVelocityTracker == null) {
    mVelocityTracker=VelocityTracker.obtain();
  }
  mVelocityTracker.addMovement(event);
  if (event.getActionMasked() == MotionEvent.ACTION_CANCEL) {
    if (mVelocityTracker != null) {
      mVelocityTracker.recycle();
      mVelocityTracker=null;
    }
  }
  if (mTouchMode == NONE) {
    mGestureDetector.onTouchEvent(event);
  }
  if (!mChart.isDragEnabled() && (!mChart.isScaleXEnabled() && !mChart.isScaleYEnabled()))   return true;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
    startAction(event);
  stopDeceleration();
saveTouchStart(event);
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (event.getPointerCount() >= 2) {
mChart.disableScroll();
saveTouchStart(event);
mSavedXDist=getXDist(event);
mSavedYDist=getYDist(event);
mSavedDist=spacing(event);
if (mSavedDist > 10f) {
if (mChart.isPinchZoomEnabled()) {
  mTouchMode=PINCH_ZOOM;
}
 else {
  if (mSavedXDist > mSavedYDist)   mTouchMode=X_ZOOM;
 else   mTouchMode=Y_ZOOM;
}
}
midPoint(mTouchPointCenter,event);
}
break;
case MotionEvent.ACTION_MOVE:
if (mTouchMode == DRAG) {
mChart.disableScroll();
performDrag(event);
}
 else if (mTouchMode == X_ZOOM || mTouchMode == Y_ZOOM || mTouchMode == PINCH_ZOOM) {
mChart.disableScroll();
if (mChart.isScaleXEnabled() || mChart.isScaleYEnabled()) performZoom(event);
}
 else if (mTouchMode == NONE && Math.abs(distance(event.getX(),mTouchStartPoint.x,event.getY(),mTouchStartPoint.y)) > mDragTriggerDist) {
if (mChart.hasNoDragOffset()) {
if (!mChart.isFullyZoomedOut() && mChart.isDragEnabled()) {
mTouchMode=DRAG;
}
 else {
mLastGesture=ChartGesture.DRAG;
if (mChart.isHighlightPerDragEnabled()) performHighlightDrag(event);
}
}
 else if (mChart.isDragEnabled()) {
mLastGesture=ChartGesture.DRAG;
mTouchMode=DRAG;
}
}
break;
case MotionEvent.ACTION_UP:
final VelocityTracker velocityTracker=mVelocityTracker;
final int pointerId=event.getPointerId(0);
velocityTracker.computeCurrentVelocity(1000,Utils.getMaximumFlingVelocity());
final float velocityY=velocityTracker.getYVelocity(pointerId);
final float velocityX=velocityTracker.getXVelocity(pointerId);
if (Math.abs(velocityX) > Utils.getMinimumFlingVelocity() || Math.abs(velocityY) > Utils.getMinimumFlingVelocity()) {
if (mTouchMode == DRAG && mChart.isDragDecelerationEnabled()) {
stopDeceleration();
mDecelerationLastTime=AnimationUtils.currentAnimationTimeMillis();
mDecelerationCurrentPoint=new PointF(event.getX(),event.getY());
mDecelerationVelocity=new PointF(velocityX,velocityY);
Utils.postInvalidateOnAnimation(mChart);
}
}
if (mTouchMode == X_ZOOM || mTouchMode == Y_ZOOM || mTouchMode == PINCH_ZOOM || mTouchMode == POST_ZOOM) {
mChart.calculateOffsets();
mChart.postInvalidate();
}
mTouchMode=NONE;
mChart.enableScroll();
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker=null;
}
endAction(event);
break;
case MotionEvent.ACTION_POINTER_UP:
Utils.velocityTrackerPointerUpCleanUpIfNecessary(event,mVelocityTracker);
mTouchMode=POST_ZOOM;
break;
case MotionEvent.ACTION_CANCEL:
mTouchMode=NONE;
endAction(event);
break;
}
mMatrix=mChart.getViewPortHandler().refresh(mMatrix,mChart,true);
return true;
}