Program: 182122
Project: 182122
Buggy source:
@Override public boolean onTouchEvent(MotionEvent ev){
  if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
    return false;
  }
  if (mVelocityTracker == null) {
    mVelocityTracker=VelocityTracker.obtain();
  }
  mVelocityTracker.addMovement(ev);
  final int action=ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
{
      if (!mScroller.isFinished()) {
        mScroller.abortAnimation();
      }
      final float y=ev.getY();
      if (!(mIsBeingDragged=inChild((int)ev.getX(),(int)y))) {
        return false;
      }
      mLastMotionY=y;
      mActivePointerId=ev.getPointerId(0);
      break;
    }
case MotionEvent.ACTION_MOVE:
  if (mIsBeingDragged) {
    final int activePointerIndex=ev.findPointerIndex(mActivePointerId);
    final float y=ev.getY(activePointerIndex);
    final int deltaY=(int)(mLastMotionY - y);
    mLastMotionY=y;
    final int oldX=mScrollX;
    final int oldY=mScrollY;
    overscrollBy(0,deltaY,0,mScrollY,0,getScrollRange(),0,getOverscrollMax(),true);
    onScrollChanged(mScrollX,mScrollY,oldX,oldY);
  }
break;
case MotionEvent.ACTION_UP:
if (mIsBeingDragged) {
final VelocityTracker velocityTracker=mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000,mMaximumVelocity);
int initialVelocity=(int)velocityTracker.getYVelocity(mActivePointerId);
if (getChildCount() > 0) {
  if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
    fling(-initialVelocity);
  }
 else {
    final int bottom=getScrollRange();
    if (mScroller.springback(mScrollX,mScrollY,0,0,0,bottom)) {
      invalidate();
    }
  }
}
mActivePointerId=INVALID_POINTER;
mIsBeingDragged=false;
if (mVelocityTracker != null) {
  mVelocityTracker.recycle();
  mVelocityTracker=null;
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}
return true;
}

Fixed version (ground truth):
@Override public boolean onTouchEvent(MotionEvent ev){
  if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
    return false;
  }
  if (mVelocityTracker == null) {
    mVelocityTracker=VelocityTracker.obtain();
  }
  mVelocityTracker.addMovement(ev);
  final int action=ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
{
      final float y=ev.getY();
      if (!(mIsBeingDragged=inChild((int)ev.getX(),(int)y))) {
        return false;
      }
      if (!mScroller.isFinished()) {
        mScroller.abortAnimation();
      }
      mLastMotionY=y;
      mActivePointerId=ev.getPointerId(0);
      break;
    }
case MotionEvent.ACTION_MOVE:
  if (mIsBeingDragged) {
    final int activePointerIndex=ev.findPointerIndex(mActivePointerId);
    final float y=ev.getY(activePointerIndex);
    final int deltaY=(int)(mLastMotionY - y);
    mLastMotionY=y;
    final int oldX=mScrollX;
    final int oldY=mScrollY;
    overscrollBy(0,deltaY,0,mScrollY,0,getScrollRange(),0,getOverscrollMax(),true);
    onScrollChanged(mScrollX,mScrollY,oldX,oldY);
  }
break;
case MotionEvent.ACTION_UP:
if (mIsBeingDragged) {
final VelocityTracker velocityTracker=mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000,mMaximumVelocity);
int initialVelocity=(int)velocityTracker.getYVelocity(mActivePointerId);
if (getChildCount() > 0) {
  if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
    fling(-initialVelocity);
  }
 else {
    final int bottom=getScrollRange();
    if (mScroller.springback(mScrollX,mScrollY,0,0,0,bottom)) {
      invalidate();
    }
  }
}
mActivePointerId=INVALID_POINTER;
mIsBeingDragged=false;
if (mVelocityTracker != null) {
  mVelocityTracker.recycle();
  mVelocityTracker=null;
}
}
break;
case MotionEvent.ACTION_CANCEL:
if (mIsBeingDragged && getChildCount() > 0) {
if (mScroller.springback(mScrollX,mScrollY,0,0,0,getScrollRange())) {
invalidate();
}
mActivePointerId=INVALID_POINTER;
mIsBeingDragged=false;
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker=null;
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}
return true;
}