Program: 199948
Project: 199948
Buggy source:
@Override public boolean onTouchEvent(MotionEvent ev){
  if (DISABLE_TOUCH_INTERACTION) {
    return false;
  }
  if (getChildCount() <= 0)   return super.onTouchEvent(ev);
  acquireVelocityTrackerAndAddMovement(ev);
  final int action=ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
    if (!mScroller.isFinished()) {
      mScroller.abortAnimation();
    }
  saveDownState(ev);
if (mTouchState == TOUCH_STATE_SCROLLING) {
  pageBeginMoving();
}
 else {
  setTouchState(TOUCH_STATE_READY);
}
if (mIsCameraEvent) {
animateWarpPageOnScreen("String_Node_Str");
}
break;
case MotionEvent.ACTION_MOVE:
if (mTouchState == TOUCH_STATE_SCROLLING) {
final int pointerIndex=ev.findPointerIndex(mActivePointerId);
if (pointerIndex == -1) return true;
final float x=ev.getX(pointerIndex);
final float deltaX=mLastMotionX + mLastMotionXRemainder - x;
mTotalMotionX+=Math.abs(deltaX);
if (Math.abs(deltaX) >= 1.0f) {
mTouchX+=deltaX;
mSmoothingTime=System.nanoTime() / NANOTIME_DIV;
if (isWarping()) {
KeyguardWidgetFrame v=(KeyguardWidgetFrame)getPageAt(mPageWarpIndex);
v.setTranslationX(v.getTranslationX() - deltaX);
}
 else if (!mDeferScrollUpdate) {
scrollBy((int)deltaX,0);
if (DEBUG) Log.d(TAG,"String_Node_Str" + deltaX);
}
 else {
invalidate();
}
mLastMotionX=x;
mLastMotionXRemainder=deltaX - (int)deltaX;
}
 else {
awakenScrollBars();
}
}
 else if (mTouchState == TOUCH_STATE_REORDERING) {
mLastMotionX=ev.getX();
mLastMotionY=ev.getY();
float[] pt=mapPointFromViewToParent(this,mLastMotionX,mLastMotionY);
mParentDownMotionX=pt[0];
mParentDownMotionY=pt[1];
updateDragViewTranslationDuringDrag();
final int dragViewIndex=indexOfChild(mDragView);
int bufferSize=(int)(REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE * getViewportWidth());
int leftBufferEdge=(int)(mapPointFromViewToParent(this,mViewport.left,0)[0] + bufferSize);
int rightBufferEdge=(int)(mapPointFromViewToParent(this,mViewport.right,0)[0] - bufferSize);
boolean isHoveringOverDelete=isHoveringOverDeleteDropTarget((int)mParentDownMotionX,(int)mParentDownMotionY);
setPageHoveringOverDeleteDropTarget(dragViewIndex,isHoveringOverDelete);
if (DEBUG) Log.d(TAG,"String_Node_Str" + leftBufferEdge);
if (DEBUG) Log.d(TAG,"String_Node_Str" + rightBufferEdge);
if (DEBUG) Log.d(TAG,"String_Node_Str" + mLastMotionX);
if (DEBUG) Log.d(TAG,"String_Node_Str" + mLastMotionY);
if (DEBUG) Log.d(TAG,"String_Node_Str" + mParentDownMotionX);
if (DEBUG) Log.d(TAG,"String_Node_Str" + mParentDownMotionY);
float parentX=mParentDownMotionX;
int pageIndexToSnapTo=-1;
if (parentX < leftBufferEdge && dragViewIndex > 0) {
pageIndexToSnapTo=dragViewIndex - 1;
}
 else if (parentX > rightBufferEdge && dragViewIndex < getChildCount() - 1) {
pageIndexToSnapTo=dragViewIndex + 1;
}
final int pageUnderPointIndex=pageIndexToSnapTo;
if (pageUnderPointIndex > -1 && !isHoveringOverDelete) {
mTempVisiblePagesRange[0]=0;
mTempVisiblePagesRange[1]=getPageCount() - 1;
boundByReorderablePages(true,mTempVisiblePagesRange);
if (mTempVisiblePagesRange[0] <= pageUnderPointIndex && pageUnderPointIndex <= mTempVisiblePagesRange[1] && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
mSidePageHoverIndex=pageUnderPointIndex;
mSidePageHoverRunnable=new Runnable(){
  @Override public void run(){
    mDownScrollX=getChildOffset(pageUnderPointIndex) - getRelativeChildOffset(pageUnderPointIndex);
    snapToPage(pageUnderPointIndex);
    int shiftDelta=(dragViewIndex < pageUnderPointIndex) ? -1 : 1;
    int lowerIndex=(dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1 : pageUnderPointIndex;
    int upperIndex=(dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1 : pageUnderPointIndex;
    for (int i=lowerIndex; i <= upperIndex; ++i) {
      View v=getChildAt(i);
      int oldX=getViewportOffsetX() + getChildOffset(i);
      int newX=getViewportOffsetX() + getChildOffset(i + shiftDelta);
      AnimatorSet anim=(AnimatorSet)v.getTag();
      if (anim != null) {
        anim.cancel();
      }
      v.setTranslationX(oldX - newX);
      anim=new AnimatorSet();
      anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
      anim.playTogether(ObjectAnimator.ofFloat(v,"String_Node_Str",0f));
      anim.start();
      v.setTag(anim);
    }
    removeView(mDragView);
    onRemoveView(mDragView,false);
    addView(mDragView,pageUnderPointIndex);
    onAddView(mDragView,pageUnderPointIndex);
    mSidePageHoverIndex=-1;
  }
}
;
postDelayed(mSidePageHoverRunnable,REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
}
}
 else {
removeCallbacks(mSidePageHoverRunnable);
mSidePageHoverIndex=-1;
}
}
 else if (mIsCameraEvent || determineScrollingStart(ev)) {
startScrolling(ev);
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
final int activePointerId=mActivePointerId;
final int pointerIndex=ev.findPointerIndex(activePointerId);
if (pointerIndex == -1) return true;
final float x=ev.getX(pointerIndex);
final VelocityTracker velocityTracker=mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000,mMaximumVelocity);
int velocityX=(int)velocityTracker.getXVelocity(activePointerId);
final int deltaX=(int)(x - mDownMotionX);
final int pageWidth=getScaledMeasuredWidth(getPageAt(mCurrentPage));
boolean isSignificantMove=Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD;
mTotalMotionX+=Math.abs(mLastMotionX + mLastMotionXRemainder - x);
boolean isFling=mTotalMotionX > MIN_LENGTH_FOR_FLING && Math.abs(velocityX) > mFlingThresholdVelocity;
boolean returnToOriginalPage=false;
if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD && Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
returnToOriginalPage=true;
}
int finalPage;
if (((isSignificantMove && deltaX > 0 && !isFling) || (isFling && velocityX > 0)) && mCurrentPage > 0) {
finalPage=returnToOriginalPage || isWarping() ? mCurrentPage : mCurrentPage - 1;
snapToPageWithVelocity(finalPage,velocityX);
}
 else if (((isSignificantMove && deltaX < 0 && !isFling) || (isFling && velocityX < 0)) && mCurrentPage < getChildCount() - 1) {
finalPage=returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
snapToPageWithVelocity(finalPage,velocityX);
}
 else {
snapToDestination();
}
}
 else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
int nextPage=Math.max(0,mCurrentPage - 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
}
 else {
snapToDestination();
}
}
 else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
int nextPage=Math.min(getChildCount() - 1,mCurrentPage + 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
}
 else {
snapToDestination();
}
}
 else if (mTouchState == TOUCH_STATE_REORDERING) {
mLastMotionX=ev.getX();
mLastMotionY=ev.getY();
float[] pt=mapPointFromViewToParent(this,mLastMotionX,mLastMotionY);
mParentDownMotionX=pt[0];
mParentDownMotionY=pt[1];
updateDragViewTranslationDuringDrag();
boolean handledFling=false;
if (!DISABLE_FLING_TO_DELETE) {
PointF flingToDeleteVector=isFlingingToDelete();
if (flingToDeleteVector != null) {
onFlingToDelete(flingToDeleteVector);
handledFling=true;
}
}
if (!handledFling && isHoveringOverDeleteDropTarget((int)mParentDownMotionX,(int)mParentDownMotionY)) {
onDropToDelete();
}
}
 else {
if (DEBUG_WARP) Log.v(TAG,"String_Node_Str");
if (mWarpPageExposed && !isAnimatingWarpPage()) {
animateWarpPageOffScreen("String_Node_Str",true);
}
onUnhandledTap(ev);
}
removeCallbacks(mSidePageHoverRunnable);
resetTouchState();
break;
case MotionEvent.ACTION_CANCEL:
if (mTouchState == TOUCH_STATE_SCROLLING) {
snapToDestination();
}
resetTouchState();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}
return true;
}

Fixed version (ground truth):
@Override public boolean onTouchEvent(MotionEvent ev){
  if (DISABLE_TOUCH_INTERACTION) {
    return false;
  }
  if (getChildCount() <= 0)   return super.onTouchEvent(ev);
  acquireVelocityTrackerAndAddMovement(ev);
  final int action=ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
    if (!mScroller.isFinished()) {
      mScroller.abortAnimation();
    }
  saveDownState(ev);
if (mTouchState == TOUCH_STATE_SCROLLING) {
  pageBeginMoving();
}
 else {
  setTouchState(TOUCH_STATE_READY);
}
if (mIsCameraEvent) {
animateWarpPageOnScreen("String_Node_Str");
}
break;
case MotionEvent.ACTION_MOVE:
if (mTouchState == TOUCH_STATE_SCROLLING) {
final int pointerIndex=ev.findPointerIndex(mActivePointerId);
if (pointerIndex == -1) return true;
final float x=ev.getX(pointerIndex);
final float deltaX=mLastMotionX + mLastMotionXRemainder - x;
mTotalMotionX+=Math.abs(deltaX);
if (Math.abs(deltaX) >= 1.0f) {
mTouchX+=deltaX;
mSmoothingTime=System.nanoTime() / NANOTIME_DIV;
if (isWarping()) {
KeyguardWidgetFrame v=(KeyguardWidgetFrame)getPageAt(getPageWarpIndex());
v.setTranslationX(v.getTranslationX() - deltaX);
}
 else if (!mDeferScrollUpdate) {
scrollBy((int)deltaX,0);
if (DEBUG) Log.d(TAG,"String_Node_Str" + deltaX);
}
 else {
invalidate();
}
mLastMotionX=x;
mLastMotionXRemainder=deltaX - (int)deltaX;
}
 else {
awakenScrollBars();
}
}
 else if (mTouchState == TOUCH_STATE_REORDERING) {
mLastMotionX=ev.getX();
mLastMotionY=ev.getY();
float[] pt=mapPointFromViewToParent(this,mLastMotionX,mLastMotionY);
mParentDownMotionX=pt[0];
mParentDownMotionY=pt[1];
updateDragViewTranslationDuringDrag();
final int dragViewIndex=indexOfChild(mDragView);
int bufferSize=(int)(REORDERING_SIDE_PAGE_BUFFER_PERCENTAGE * getViewportWidth());
int leftBufferEdge=(int)(mapPointFromViewToParent(this,mViewport.left,0)[0] + bufferSize);
int rightBufferEdge=(int)(mapPointFromViewToParent(this,mViewport.right,0)[0] - bufferSize);
boolean isHoveringOverDelete=isHoveringOverDeleteDropTarget((int)mParentDownMotionX,(int)mParentDownMotionY);
setPageHoveringOverDeleteDropTarget(dragViewIndex,isHoveringOverDelete);
if (DEBUG) Log.d(TAG,"String_Node_Str" + leftBufferEdge);
if (DEBUG) Log.d(TAG,"String_Node_Str" + rightBufferEdge);
if (DEBUG) Log.d(TAG,"String_Node_Str" + mLastMotionX);
if (DEBUG) Log.d(TAG,"String_Node_Str" + mLastMotionY);
if (DEBUG) Log.d(TAG,"String_Node_Str" + mParentDownMotionX);
if (DEBUG) Log.d(TAG,"String_Node_Str" + mParentDownMotionY);
float parentX=mParentDownMotionX;
int pageIndexToSnapTo=-1;
if (parentX < leftBufferEdge && dragViewIndex > 0) {
pageIndexToSnapTo=dragViewIndex - 1;
}
 else if (parentX > rightBufferEdge && dragViewIndex < getChildCount() - 1) {
pageIndexToSnapTo=dragViewIndex + 1;
}
final int pageUnderPointIndex=pageIndexToSnapTo;
if (pageUnderPointIndex > -1 && !isHoveringOverDelete) {
mTempVisiblePagesRange[0]=0;
mTempVisiblePagesRange[1]=getPageCount() - 1;
boundByReorderablePages(true,mTempVisiblePagesRange);
if (mTempVisiblePagesRange[0] <= pageUnderPointIndex && pageUnderPointIndex <= mTempVisiblePagesRange[1] && pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
mSidePageHoverIndex=pageUnderPointIndex;
mSidePageHoverRunnable=new Runnable(){
  @Override public void run(){
    mDownScrollX=getChildOffset(pageUnderPointIndex) - getRelativeChildOffset(pageUnderPointIndex);
    snapToPage(pageUnderPointIndex);
    int shiftDelta=(dragViewIndex < pageUnderPointIndex) ? -1 : 1;
    int lowerIndex=(dragViewIndex < pageUnderPointIndex) ? dragViewIndex + 1 : pageUnderPointIndex;
    int upperIndex=(dragViewIndex > pageUnderPointIndex) ? dragViewIndex - 1 : pageUnderPointIndex;
    for (int i=lowerIndex; i <= upperIndex; ++i) {
      View v=getChildAt(i);
      int oldX=getViewportOffsetX() + getChildOffset(i);
      int newX=getViewportOffsetX() + getChildOffset(i + shiftDelta);
      AnimatorSet anim=(AnimatorSet)v.getTag();
      if (anim != null) {
        anim.cancel();
      }
      v.setTranslationX(oldX - newX);
      anim=new AnimatorSet();
      anim.setDuration(REORDERING_REORDER_REPOSITION_DURATION);
      anim.playTogether(ObjectAnimator.ofFloat(v,"String_Node_Str",0f));
      anim.start();
      v.setTag(anim);
    }
    removeView(mDragView);
    onRemoveView(mDragView,false);
    addView(mDragView,pageUnderPointIndex);
    onAddView(mDragView,pageUnderPointIndex);
    mSidePageHoverIndex=-1;
  }
}
;
postDelayed(mSidePageHoverRunnable,REORDERING_SIDE_PAGE_HOVER_TIMEOUT);
}
}
 else {
removeCallbacks(mSidePageHoverRunnable);
mSidePageHoverIndex=-1;
}
}
 else if (determineScrollingStart(ev)) {
startScrolling(ev);
}
 else if (isHorizontalCameraScroll(ev)) {
startScrolling(ev);
KeyguardWidgetFrame v=(KeyguardWidgetFrame)getPageAt(getPageWarpIndex());
v.animate().cancel();
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
final int activePointerId=mActivePointerId;
final int pointerIndex=ev.findPointerIndex(activePointerId);
if (pointerIndex == -1) return true;
final float x=ev.getX(pointerIndex);
final VelocityTracker velocityTracker=mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000,mMaximumVelocity);
int velocityX=(int)velocityTracker.getXVelocity(activePointerId);
final int deltaX=(int)(x - mDownMotionX);
final int pageWidth=getScaledMeasuredWidth(getPageAt(mCurrentPage));
boolean isSignificantMove=Math.abs(deltaX) > pageWidth * SIGNIFICANT_MOVE_THRESHOLD;
mTotalMotionX+=Math.abs(mLastMotionX + mLastMotionXRemainder - x);
boolean isFling=mTotalMotionX > MIN_LENGTH_FOR_FLING && Math.abs(velocityX) > mFlingThresholdVelocity;
boolean returnToOriginalPage=false;
if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD && Math.signum(velocityX) != Math.signum(deltaX) && isFling) {
returnToOriginalPage=true;
}
int finalPage;
if (((isSignificantMove && deltaX > 0 && !isFling) || (isFling && velocityX > 0)) && mCurrentPage > 0) {
finalPage=returnToOriginalPage || isWarping() ? mCurrentPage : mCurrentPage - 1;
snapToPageWithVelocity(finalPage,velocityX);
}
 else if (((isSignificantMove && deltaX < 0 && !isFling) || (isFling && velocityX < 0)) && mCurrentPage < getChildCount() - 1) {
finalPage=returnToOriginalPage ? mCurrentPage : isWarping() ? getPageWarpIndex() : mCurrentPage + 1;
snapToPageWithVelocity(finalPage,velocityX);
}
 else {
snapToDestination();
}
}
 else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
int nextPage=Math.max(0,mCurrentPage - 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
}
 else {
snapToDestination();
}
}
 else if (mTouchState == TOUCH_STATE_NEXT_PAGE) {
int nextPage=Math.min(getChildCount() - 1,mCurrentPage + 1);
if (nextPage != mCurrentPage) {
snapToPage(nextPage);
}
 else {
snapToDestination();
}
}
 else if (mTouchState == TOUCH_STATE_REORDERING) {
mLastMotionX=ev.getX();
mLastMotionY=ev.getY();
float[] pt=mapPointFromViewToParent(this,mLastMotionX,mLastMotionY);
mParentDownMotionX=pt[0];
mParentDownMotionY=pt[1];
updateDragViewTranslationDuringDrag();
boolean handledFling=false;
if (!DISABLE_FLING_TO_DELETE) {
PointF flingToDeleteVector=isFlingingToDelete();
if (flingToDeleteVector != null) {
onFlingToDelete(flingToDeleteVector);
handledFling=true;
}
}
if (!handledFling && isHoveringOverDeleteDropTarget((int)mParentDownMotionX,(int)mParentDownMotionY)) {
onDropToDelete();
}
}
 else {
if (DEBUG_WARP) Log.v(TAG,"String_Node_Str");
if (mWarpPageExposed && !isAnimatingWarpPage()) {
animateWarpPageOffScreen("String_Node_Str",true);
}
onUnhandledTap(ev);
}
removeCallbacks(mSidePageHoverRunnable);
resetTouchState();
break;
case MotionEvent.ACTION_CANCEL:
if (mTouchState == TOUCH_STATE_SCROLLING) {
snapToDestination();
}
resetTouchState();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}
return true;
}