Program: 87664
Project: 87664
Buggy source:
private boolean drawGestureTrailLocked(final Canvas canvas,final Paint paint,final Rect outBoundsRect,final Params params){
  outBoundsRect.setEmpty();
  final int trailSize=mEventTimes.getLength();
  if (trailSize == 0) {
    return false;
  }
  final int[] eventTimes=mEventTimes.getPrimitiveArray();
  final int[] xCoords=mXCoordinates.getPrimitiveArray();
  final int[] yCoords=mYCoordinates.getPrimitiveArray();
  final int[] pointTypes=mPointTypes.getPrimitiveArray();
  final int sinceDown=(int)(SystemClock.uptimeMillis() - mCurrentTimeBase);
  int startIndex;
  for (startIndex=mTrailStartIndex; startIndex < trailSize; startIndex++) {
    final int elapsedTime=sinceDown - eventTimes[startIndex];
    if (elapsedTime < params.mTrailLingerDuration) {
      break;
    }
  }
  mTrailStartIndex=startIndex;
  if (startIndex < trailSize) {
    paint.setColor(params.mTrailColor);
    paint.setStyle(Paint.Style.FILL);
    final RoundedLine roundedLine=mRoundedLine;
    int p1x=getXCoordValue(xCoords[startIndex]);
    int p1y=yCoords[startIndex];
    final int lastTime=sinceDown - eventTimes[startIndex];
    float r1=getWidth(lastTime,params) / 2.0f;
    for (int i=startIndex + 1; i < trailSize; i++) {
      final int elapsedTime=sinceDown - eventTimes[i];
      final int p2x=getXCoordValue(xCoords[i]);
      final int p2y=yCoords[i];
      final float r2=getWidth(elapsedTime,params) / 2.0f;
      if (!isDownEventXCoord(xCoords[i])) {
        final float body1=r1 * params.mTrailBodyRatio;
        final float body2=r2 * params.mTrailBodyRatio;
        final Path path=roundedLine.makePath(p1x,p1y,body1,p2x,p2y,body2);
        if (path != null) {
          roundedLine.getBounds(mRoundedLineBounds);
          if (params.mTrailShadowEnabled) {
            final float shadow2=r2 * params.mTrailShadowRatio;
            paint.setShadowLayer(shadow2,0.0f,0.0f,params.mTrailColor);
            final int shadowInset=-(int)Math.ceil(shadow2);
            mRoundedLineBounds.inset(shadowInset,shadowInset);
          }
          outBoundsRect.union(mRoundedLineBounds);
          final int alpha=getAlpha(elapsedTime,params);
          paint.setAlpha(alpha);
          canvas.drawPath(path,paint);
          if (DBG_SHOW_POINTS) {
            if (pointTypes[i] == POINT_TYPE_INTERPOLATED) {
              paint.setColor(Color.RED);
            }
 else             if (pointTypes[i] == POINT_TYPE_SAMPLED) {
              paint.setColor(0xFFA000FF);
            }
 else {
              paint.setColor(Color.GREEN);
            }
            canvas.drawCircle(p1x - 1,p1y - 1,2,paint);
            paint.setColor(params.mTrailColor);
          }
        }
      }
      p1x=p2x;
      p1y=p2y;
      r1=r2;
    }
  }
  final int newSize=trailSize - startIndex;
  if (newSize < startIndex) {
    mTrailStartIndex=0;
    if (newSize > 0) {
      System.arraycopy(eventTimes,startIndex,eventTimes,0,newSize);
      System.arraycopy(xCoords,startIndex,xCoords,0,newSize);
      System.arraycopy(yCoords,startIndex,yCoords,0,newSize);
    }
    mEventTimes.setLength(newSize);
    mXCoordinates.setLength(newSize);
    mYCoordinates.setLength(newSize);
    if (DBG_SHOW_POINTS) {
      mPointTypes.setLength(newSize);
    }
    mLastInterpolatedDrawIndex=Math.max(mLastInterpolatedDrawIndex - startIndex,0);
  }
  return newSize > 0;
}

Fixed version (ground truth):
private boolean drawGestureTrailLocked(final Canvas canvas,final Paint paint,final Rect outBoundsRect,final Params params){
  outBoundsRect.setEmpty();
  final int trailSize=mEventTimes.getLength();
  if (trailSize == 0) {
    return false;
  }
  final int[] eventTimes=mEventTimes.getPrimitiveArray();
  final int[] xCoords=mXCoordinates.getPrimitiveArray();
  final int[] yCoords=mYCoordinates.getPrimitiveArray();
  final int[] pointTypes=mPointTypes.getPrimitiveArray();
  final int sinceDown=(int)(SystemClock.uptimeMillis() - mCurrentTimeBase);
  int startIndex;
  for (startIndex=mTrailStartIndex; startIndex < trailSize; startIndex++) {
    final int elapsedTime=sinceDown - eventTimes[startIndex];
    if (elapsedTime < params.mTrailLingerDuration) {
      break;
    }
  }
  mTrailStartIndex=startIndex;
  if (startIndex < trailSize) {
    paint.setColor(params.mTrailColor);
    paint.setStyle(Paint.Style.FILL);
    final RoundedLine roundedLine=mRoundedLine;
    int p1x=getXCoordValue(xCoords[startIndex]);
    int p1y=yCoords[startIndex];
    final int lastTime=sinceDown - eventTimes[startIndex];
    float r1=getWidth(lastTime,params) / 2.0f;
    for (int i=startIndex + 1; i < trailSize; i++) {
      final int elapsedTime=sinceDown - eventTimes[i];
      final int p2x=getXCoordValue(xCoords[i]);
      final int p2y=yCoords[i];
      final float r2=getWidth(elapsedTime,params) / 2.0f;
      if (!isDownEventXCoord(xCoords[i])) {
        final float body1=r1 * params.mTrailBodyRatio;
        final float body2=r2 * params.mTrailBodyRatio;
        final Path path=roundedLine.makePath(p1x,p1y,body1,p2x,p2y,body2);
        if (path != null) {
          roundedLine.getBounds(mRoundedLineBounds);
          if (params.mTrailShadowEnabled) {
            final float shadow2=r2 * params.mTrailShadowRatio;
            paint.setShadowLayer(shadow2,0.0f,0.0f,params.mTrailColor);
            final int shadowInset=-(int)Math.ceil(shadow2);
            mRoundedLineBounds.inset(shadowInset,shadowInset);
          }
          outBoundsRect.union(mRoundedLineBounds);
          final int alpha=getAlpha(elapsedTime,params);
          paint.setAlpha(alpha);
          canvas.drawPath(path,paint);
        }
      }
      p1x=p2x;
      p1y=p2y;
      r1=r2;
    }
    if (DEBUG_SHOW_POINTS) {
      debugDrawPoints(canvas,startIndex,trailSize,paint);
    }
  }
  final int newSize=trailSize - startIndex;
  if (newSize < startIndex) {
    mTrailStartIndex=0;
    if (newSize > 0) {
      System.arraycopy(eventTimes,startIndex,eventTimes,0,newSize);
      System.arraycopy(xCoords,startIndex,xCoords,0,newSize);
      System.arraycopy(yCoords,startIndex,yCoords,0,newSize);
      if (DEBUG_SHOW_POINTS) {
        System.arraycopy(pointTypes,startIndex,pointTypes,0,newSize);
      }
    }
    mEventTimes.setLength(newSize);
    mXCoordinates.setLength(newSize);
    mYCoordinates.setLength(newSize);
    if (DEBUG_SHOW_POINTS) {
      mPointTypes.setLength(newSize);
    }
    mLastInterpolatedDrawIndex=Math.max(mLastInterpolatedDrawIndex - startIndex,0);
  }
  return newSize > 0;
}