Program: 43267
Project: 43267
Buggy source:
@Override public boolean onTouchEvent(MotionEvent motionEvent){
  if (!mInputEnabled || !isEnabled()) {
    return false;
  }
  final float x=motionEvent.getX();
  final float y=motionEvent.getY();
  Cell hitCell;
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
    resetPattern();
  hitCell=detectAndAddHit(x,y);
if (hitCell != null && mOnPatternListener != null) {
  mPatternInProgress=true;
  mPatternDisplayMode=DisplayMode.Correct;
  mOnPatternListener.onPatternStart();
}
 else if (mOnPatternListener != null) {
  mPatternInProgress=false;
  mOnPatternListener.onPatternCleared();
}
if (hitCell != null) {
final float startX=getCenterXForColumn(hitCell.column);
final float startY=getCenterYForRow(hitCell.row);
final float widthOffset=mSquareWidth / 2f;
final float heightOffset=mSquareHeight / 2f;
invalidate((int)(startX - widthOffset),(int)(startY - heightOffset),(int)(startX + widthOffset),(int)(startY + heightOffset));
}
mInProgressX=x;
mInProgressY=y;
if (PROFILE_DRAWING) {
if (!mDrawingProfilingStarted) {
Debug.startMethodTracing("String_Node_Str");
mDrawingProfilingStarted=true;
}
}
return true;
case MotionEvent.ACTION_UP:
if (!mPattern.isEmpty() && mOnPatternListener != null) {
mPatternInProgress=false;
mOnPatternListener.onPatternDetected(mPattern);
invalidate();
}
if (PROFILE_DRAWING) {
if (mDrawingProfilingStarted) {
Debug.stopMethodTracing();
mDrawingProfilingStarted=false;
}
}
return true;
case MotionEvent.ACTION_MOVE:
final int patternSizePreHitDetect=mPattern.size();
hitCell=detectAndAddHit(x,y);
final int patternSize=mPattern.size();
if (hitCell != null && (mOnPatternListener != null) && (patternSize == 1)) {
mPatternInProgress=true;
mOnPatternListener.onPatternStart();
}
final float dx=Math.abs(x - mInProgressX);
final float dy=Math.abs(y - mInProgressY);
if (dx + dy > mSquareWidth * 0.01f) {
float oldX=mInProgressX;
float oldY=mInProgressY;
mInProgressX=x;
mInProgressY=y;
if (mPatternInProgress) {
final ArrayList<Cell> pattern=mPattern;
final float radius=mSquareWidth * mDiameterFactor * 0.5f;
Cell cell=pattern.get(patternSize - 1);
float startX=getCenterXForColumn(cell.column);
float startY=getCenterYForRow(cell.row);
float left;
float top;
float right;
float bottom;
final Rect invalidateRect=mInvalidate;
if (startX < x) {
left=startX;
right=x;
}
 else {
left=x;
right=startX;
}
if (startY < y) {
top=startY;
bottom=y;
}
 else {
top=y;
bottom=startY;
}
invalidateRect.set((int)(left - radius),(int)(top - radius),(int)(right + radius),(int)(bottom + radius));
if (startX < oldX) {
left=startX;
right=oldX;
}
 else {
left=oldX;
right=startX;
}
if (startY < oldY) {
top=startY;
bottom=oldY;
}
 else {
top=oldY;
bottom=startY;
}
invalidateRect.union((int)(left - radius),(int)(top - radius),(int)(right + radius),(int)(bottom + radius));
if (hitCell != null) {
startX=getCenterXForColumn(hitCell.column);
startY=getCenterYForRow(hitCell.row);
if (patternSize >= 2) {
hitCell=pattern.get(patternSize - 1 - (patternSize - patternSizePreHitDetect));
oldX=getCenterXForColumn(hitCell.column);
oldY=getCenterYForRow(hitCell.row);
if (startX < oldX) {
left=startX;
right=oldX;
}
 else {
left=oldX;
right=startX;
}
if (startY < oldY) {
top=startY;
bottom=oldY;
}
 else {
top=oldY;
bottom=startY;
}
}
 else {
left=right=startX;
top=bottom=startY;
}
final float widthOffset=mSquareWidth / 2f;
final float heightOffset=mSquareHeight / 2f;
invalidateRect.set((int)(left - widthOffset),(int)(top - heightOffset),(int)(right + widthOffset),(int)(bottom + heightOffset));
}
invalidate(invalidateRect);
}
 else {
invalidate();
}
}
return true;
case MotionEvent.ACTION_CANCEL:
resetPattern();
if (mOnPatternListener != null) {
mPatternInProgress=false;
mOnPatternListener.onPatternCleared();
}
if (PROFILE_DRAWING) {
if (mDrawingProfilingStarted) {
Debug.stopMethodTracing();
mDrawingProfilingStarted=false;
}
}
return true;
}
return false;
}

Fixed version (ground truth):
@Override public boolean onTouchEvent(MotionEvent motionEvent){
  if (!mInputEnabled || !isEnabled()) {
    return false;
  }
  final float x=motionEvent.getX();
  final float y=motionEvent.getY();
  Cell hitCell;
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
    resetPattern();
  hitCell=detectAndAddHit(x,y);
if (hitCell != null && mOnPatternListener != null) {
  mPatternInProgress=true;
  mPatternDisplayMode=DisplayMode.Correct;
  mOnPatternListener.onPatternStart();
}
 else if (mOnPatternListener != null) {
  mPatternInProgress=false;
  mOnPatternListener.onPatternCleared();
}
if (hitCell != null) {
final float startX=getCenterXForColumn(hitCell.column);
final float startY=getCenterYForRow(hitCell.row);
final float widthOffset=mSquareWidth / 2f;
final float heightOffset=mSquareHeight / 2f;
invalidate((int)(startX - widthOffset),(int)(startY - heightOffset),(int)(startX + widthOffset),(int)(startY + heightOffset));
}
mInProgressX=x;
mInProgressY=y;
if (PROFILE_DRAWING) {
if (!mDrawingProfilingStarted) {
Debug.startMethodTracing("String_Node_Str");
mDrawingProfilingStarted=true;
}
}
return true;
case MotionEvent.ACTION_UP:
if (!mPattern.isEmpty() && mOnPatternListener != null) {
mPatternInProgress=false;
mOnPatternListener.onPatternDetected(mPattern);
invalidate();
}
if (PROFILE_DRAWING) {
if (mDrawingProfilingStarted) {
Debug.stopMethodTracing();
mDrawingProfilingStarted=false;
}
}
return true;
case MotionEvent.ACTION_MOVE:
final int patternSizePreHitDetect=mPattern.size();
hitCell=detectAndAddHit(x,y);
final int patternSize=mPattern.size();
if (hitCell != null && (mOnPatternListener != null) && (patternSize == 1)) {
mPatternInProgress=true;
mOnPatternListener.onPatternStart();
}
final float dx=Math.abs(x - mInProgressX);
final float dy=Math.abs(y - mInProgressY);
if (dx + dy > mSquareWidth * 0.01f) {
float oldX=mInProgressX;
float oldY=mInProgressY;
mInProgressX=x;
mInProgressY=y;
if (mPatternInProgress) {
if (mPattern.isEmpty()) return false;
final ArrayList<Cell> pattern=mPattern;
final float radius=mSquareWidth * mDiameterFactor * 0.5f;
Cell cell=pattern.get(patternSize - 1);
float startX=getCenterXForColumn(cell.column);
float startY=getCenterYForRow(cell.row);
float left;
float top;
float right;
float bottom;
final Rect invalidateRect=mInvalidate;
if (startX < x) {
left=startX;
right=x;
}
 else {
left=x;
right=startX;
}
if (startY < y) {
top=startY;
bottom=y;
}
 else {
top=y;
bottom=startY;
}
invalidateRect.set((int)(left - radius),(int)(top - radius),(int)(right + radius),(int)(bottom + radius));
if (startX < oldX) {
left=startX;
right=oldX;
}
 else {
left=oldX;
right=startX;
}
if (startY < oldY) {
top=startY;
bottom=oldY;
}
 else {
top=oldY;
bottom=startY;
}
invalidateRect.union((int)(left - radius),(int)(top - radius),(int)(right + radius),(int)(bottom + radius));
if (hitCell != null) {
startX=getCenterXForColumn(hitCell.column);
startY=getCenterYForRow(hitCell.row);
if (patternSize >= 2) {
hitCell=pattern.get(patternSize - 1 - (patternSize - patternSizePreHitDetect));
oldX=getCenterXForColumn(hitCell.column);
oldY=getCenterYForRow(hitCell.row);
if (startX < oldX) {
left=startX;
right=oldX;
}
 else {
left=oldX;
right=startX;
}
if (startY < oldY) {
top=startY;
bottom=oldY;
}
 else {
top=oldY;
bottom=startY;
}
}
 else {
left=right=startX;
top=bottom=startY;
}
final float widthOffset=mSquareWidth / 2f;
final float heightOffset=mSquareHeight / 2f;
invalidateRect.set((int)(left - widthOffset),(int)(top - heightOffset),(int)(right + widthOffset),(int)(bottom + heightOffset));
}
invalidate(invalidateRect);
}
 else {
invalidate();
}
}
return true;
case MotionEvent.ACTION_CANCEL:
resetPattern();
if (mOnPatternListener != null) {
mPatternInProgress=false;
mOnPatternListener.onPatternCleared();
}
if (PROFILE_DRAWING) {
if (mDrawingProfilingStarted) {
Debug.stopMethodTracing();
mDrawingProfilingStarted=false;
}
}
return true;
}
return false;
}