Program: 88297
Project: 88297
Buggy source:
private boolean onModifiedTouchEvent(MotionEvent me){
  int touchX=(int)me.getX() - getPaddingLeft();
  int touchY=(int)me.getY() + mVerticalCorrection - getPaddingTop();
  final int action=me.getAction();
  final long eventTime=me.getEventTime();
  int keyIndex=getKeyIndexAndNearbyCodes(touchX,touchY,null);
switch (action) {
case MotionEvent.ACTION_DOWN:
    mAbortKey=false;
  mCurrentKey=keyIndex;
mDownKey=keyIndex;
mStartX=touchX;
mStartY=touchY;
mDebouncer.startMoveDebouncing(touchX,touchY);
mDebouncer.startTimeDebouncing(eventTime);
checkMultiTap(eventTime,keyIndex);
mKeyboardActionListener.onPress(keyIndex != NOT_A_KEY ? mKeys[keyIndex].codes[0] : 0);
if (keyIndex >= 0 && mKeys[keyIndex].repeatable) {
repeatKey(keyIndex);
mHandler.startKeyRepeatTimer(REPEAT_START_DELAY,keyIndex);
if (mAbortKey) {
mHandler.cancelKeyRepeatTimer();
break;
}
}
if (keyIndex != NOT_A_KEY) {
mHandler.startLongPressTimer(keyIndex,LONGPRESS_TIMEOUT);
}
showPreview(keyIndex);
break;
case MotionEvent.ACTION_MOVE:
if (keyIndex != NOT_A_KEY) {
if (mCurrentKey == NOT_A_KEY) {
mDebouncer.updateTimeDebouncing(eventTime);
mCurrentKey=keyIndex;
mHandler.startLongPressTimer(keyIndex,LONGPRESS_TIMEOUT);
}
 else if (mDebouncer.isMinorMoveBounce(touchX,touchY,keyIndex,mCurrentKey)) {
mDebouncer.updateTimeDebouncing(eventTime);
}
 else {
resetMultiTap();
mDebouncer.resetTimeDebouncing(eventTime,mCurrentKey);
mDebouncer.resetMoveDebouncing();
mCurrentKey=keyIndex;
mHandler.startLongPressTimer(keyIndex,LONGPRESS_TIMEOUT);
}
}
 else {
mHandler.cancelLongPressTimer();
}
showPreview(mDebouncer.isMinorTimeBounce() ? mDebouncer.getLastKey() : mCurrentKey);
break;
case MotionEvent.ACTION_UP:
mHandler.cancelKeyTimers();
mHandler.cancelPopupPreview();
if (mDebouncer.isMinorMoveBounce(touchX,touchY,keyIndex,mCurrentKey)) {
mDebouncer.updateTimeDebouncing(eventTime);
}
 else {
resetMultiTap();
mDebouncer.resetTimeDebouncing(eventTime,mCurrentKey);
mCurrentKey=keyIndex;
}
if (mDebouncer.isMinorTimeBounce()) {
mCurrentKey=mDebouncer.getLastKey();
touchX=mDebouncer.getLastCodeX();
touchY=mDebouncer.getLastCodeY();
}
showPreview(NOT_A_KEY);
if (!mMiniKeyboardOnScreen && !mAbortKey) {
detectAndSendKey(mCurrentKey,touchX,touchY,eventTime);
}
invalidateKey(keyIndex);
break;
case MotionEvent.ACTION_CANCEL:
mHandler.cancelKeyTimers();
mHandler.cancelPopupPreview();
dismissPopupKeyboard();
mAbortKey=true;
showPreview(NOT_A_KEY);
invalidateKey(mCurrentKey);
break;
}
mDebouncer.updateMoveDebouncing(touchX,touchY);
return true;
}

Fixed version (ground truth):
private boolean onModifiedTouchEvent(MotionEvent me){
  int touchX=(int)me.getX() - getPaddingLeft();
  int touchY=(int)me.getY() + mVerticalCorrection - getPaddingTop();
  final int action=me.getAction();
  final long eventTime=me.getEventTime();
  int keyIndex=getKeyIndexAndNearbyCodes(touchX,touchY,null);
switch (action) {
case MotionEvent.ACTION_DOWN:
    mAbortKey=false;
  mCurrentKey=keyIndex;
mDownKey=keyIndex;
mStartX=touchX;
mStartY=touchY;
mDebouncer.startMoveDebouncing(touchX,touchY);
mDebouncer.startTimeDebouncing(eventTime);
checkMultiTap(eventTime,keyIndex);
mKeyboardActionListener.onPress(keyIndex != NOT_A_KEY ? mKeys[keyIndex].codes[0] : 0);
if (keyIndex >= 0 && mKeys[keyIndex].repeatable) {
repeatKey(keyIndex);
mHandler.startKeyRepeatTimer(REPEAT_START_DELAY,keyIndex);
if (mAbortKey) {
mHandler.cancelKeyRepeatTimer();
break;
}
}
if (keyIndex != NOT_A_KEY) {
mHandler.startLongPressTimer(keyIndex,LONGPRESS_TIMEOUT);
}
showPreview(keyIndex);
break;
case MotionEvent.ACTION_MOVE:
if (keyIndex != NOT_A_KEY) {
if (mCurrentKey == NOT_A_KEY) {
mDebouncer.updateTimeDebouncing(eventTime);
mCurrentKey=keyIndex;
mHandler.startLongPressTimer(keyIndex,LONGPRESS_TIMEOUT);
}
 else if (mDebouncer.isMinorMoveBounce(touchX,touchY,keyIndex,mCurrentKey)) {
mDebouncer.updateTimeDebouncing(eventTime);
}
 else {
resetMultiTap();
mDebouncer.resetTimeDebouncing(eventTime,mCurrentKey);
mDebouncer.resetMoveDebouncing();
mCurrentKey=keyIndex;
mHandler.startLongPressTimer(keyIndex,LONGPRESS_TIMEOUT);
}
}
 else {
mHandler.cancelLongPressTimer();
}
showPreview(mDebouncer.isMinorTimeBounce() ? mDebouncer.getLastKey() : mCurrentKey);
break;
case MotionEvent.ACTION_UP:
boolean wasInKeyRepeat=mHandler.isInKeyRepeat();
mHandler.cancelKeyTimers();
mHandler.cancelPopupPreview();
if (mDebouncer.isMinorMoveBounce(touchX,touchY,keyIndex,mCurrentKey)) {
mDebouncer.updateTimeDebouncing(eventTime);
}
 else {
resetMultiTap();
mDebouncer.resetTimeDebouncing(eventTime,mCurrentKey);
mCurrentKey=keyIndex;
}
if (mDebouncer.isMinorTimeBounce()) {
mCurrentKey=mDebouncer.getLastKey();
touchX=mDebouncer.getLastCodeX();
touchY=mDebouncer.getLastCodeY();
}
showPreview(NOT_A_KEY);
if (!wasInKeyRepeat && !mMiniKeyboardOnScreen && !mAbortKey) {
detectAndSendKey(mCurrentKey,touchX,touchY,eventTime);
}
invalidateKey(keyIndex);
break;
case MotionEvent.ACTION_CANCEL:
mHandler.cancelKeyTimers();
mHandler.cancelPopupPreview();
dismissPopupKeyboard();
mAbortKey=true;
showPreview(NOT_A_KEY);
invalidateKey(mCurrentKey);
break;
}
mDebouncer.updateMoveDebouncing(touchX,touchY);
return true;
}