Program: 2268
Project: 2268
Buggy source:
public void draw(Canvas canvas){
  if (mState == STATE_NONE) {
    return;
  }
  final int y=mThumbY;
  final int viewWidth=mList.getWidth();
  final FastScroller.ScrollFade scrollFade=mScrollFade;
  int alpha=-1;
  if (mState == STATE_EXIT) {
    alpha=scrollFade.getAlpha();
    if (alpha < ScrollFade.ALPHA_MAX / 2) {
      mThumbDrawable.setAlpha(alpha * 2);
    }
    int left=0;
switch (mPosition) {
case View.SCROLLBAR_POSITION_RIGHT:
      left=viewWidth - (mThumbW * alpha) / ScrollFade.ALPHA_MAX;
    break;
case View.SCROLLBAR_POSITION_LEFT:
  left=-mThumbW + (mThumbW * alpha) / ScrollFade.ALPHA_MAX;
break;
}
mThumbDrawable.setBounds(left,0,left + mThumbW,mThumbH);
mChangedBounds=true;
}
if (mTrackDrawable != null) {
final Rect thumbBounds=mThumbDrawable.getBounds();
final int left=thumbBounds.left;
final int halfThumbHeight=(thumbBounds.bottom - thumbBounds.top) / 2;
final int trackWidth=mTrackDrawable.getIntrinsicWidth();
final int trackLeft=(left + mThumbW / 2) - trackWidth / 2;
mTrackDrawable.setBounds(trackLeft,halfThumbHeight,trackLeft + trackWidth,mList.getHeight() - halfThumbHeight);
mTrackDrawable.draw(canvas);
}
canvas.translate(0,y);
mThumbDrawable.draw(canvas);
canvas.translate(0,-y);
if (mState == STATE_DRAGGING && mDrawOverlay) {
if (mOverlayPosition == OVERLAY_AT_THUMB) {
int left=0;
switch (mPosition) {
default :
case View.SCROLLBAR_POSITION_RIGHT:
left=Math.max(0,mThumbDrawable.getBounds().left - mThumbW - mOverlaySize);
break;
case View.SCROLLBAR_POSITION_LEFT:
left=Math.min(mThumbDrawable.getBounds().right + mThumbW,mList.getWidth() - mOverlaySize);
break;
}
int top=Math.max(0,Math.min(y + (mThumbH - mOverlaySize) / 2,mList.getHeight() - mOverlaySize));
final RectF pos=mOverlayPos;
pos.left=left;
pos.right=pos.left + mOverlaySize;
pos.top=top;
pos.bottom=pos.top + mOverlaySize;
if (mOverlayDrawable != null) {
mOverlayDrawable.setBounds((int)pos.left,(int)pos.top,(int)pos.right,(int)pos.bottom);
}
}
mOverlayDrawable.draw(canvas);
final Paint paint=mPaint;
float descent=paint.descent();
final RectF rectF=mOverlayPos;
final Rect tmpRect=mTmpRect;
mOverlayDrawable.getPadding(tmpRect);
final int hOff=(tmpRect.right - tmpRect.left) / 2;
final int vOff=(tmpRect.bottom - tmpRect.top) / 2;
canvas.drawText(mSectionText,(int)(rectF.left + rectF.right) / 2 - hOff,(int)(rectF.bottom + rectF.top) / 2 + mOverlaySize / 4 - descent - vOff,paint);
}
 else if (mState == STATE_EXIT) {
if (alpha == 0) {
setState(STATE_NONE);
}
 else if (mTrackDrawable != null) {
mList.invalidate(viewWidth - mThumbW,0,viewWidth,mList.getHeight());
}
 else {
mList.invalidate(viewWidth - mThumbW,y,viewWidth,y + mThumbH);
}
}
}

Fixed version (ground truth):
public void draw(Canvas canvas){
  if (mState == STATE_NONE) {
    return;
  }
  final int y=mThumbY;
  final int viewWidth=mList.getWidth();
  final FastScroller.ScrollFade scrollFade=mScrollFade;
  int alpha=-1;
  if (mState == STATE_EXIT) {
    alpha=scrollFade.getAlpha();
    if (alpha < ScrollFade.ALPHA_MAX / 2) {
      mThumbDrawable.setAlpha(alpha * 2);
    }
    int left=0;
switch (mPosition) {
case View.SCROLLBAR_POSITION_RIGHT:
      left=viewWidth - (mThumbW * alpha) / ScrollFade.ALPHA_MAX;
    break;
case View.SCROLLBAR_POSITION_LEFT:
  left=-mThumbW + (mThumbW * alpha) / ScrollFade.ALPHA_MAX;
break;
}
mThumbDrawable.setBounds(left,0,left + mThumbW,mThumbH);
mChangedBounds=true;
}
if (mTrackDrawable != null) {
final Rect thumbBounds=mThumbDrawable.getBounds();
final int left=thumbBounds.left;
final int halfThumbHeight=(thumbBounds.bottom - thumbBounds.top) / 2;
final int trackWidth=mTrackDrawable.getIntrinsicWidth();
final int trackLeft=(left + mThumbW / 2) - trackWidth / 2;
mTrackDrawable.setBounds(trackLeft,halfThumbHeight,trackLeft + trackWidth,mList.getHeight() - halfThumbHeight);
mTrackDrawable.draw(canvas);
}
canvas.translate(0,y);
mThumbDrawable.draw(canvas);
canvas.translate(0,-y);
if (mState == STATE_DRAGGING && mDrawOverlay) {
if (mOverlayPosition == OVERLAY_AT_THUMB) {
int left=0;
switch (mPosition) {
default :
case View.SCROLLBAR_POSITION_RIGHT:
left=Math.max(0,mThumbDrawable.getBounds().left - mThumbW - mOverlaySize);
break;
case View.SCROLLBAR_POSITION_LEFT:
left=Math.min(mThumbDrawable.getBounds().right + mThumbW,mList.getWidth() - mOverlaySize);
break;
}
int top=Math.max(0,Math.min(y + (mThumbH - mOverlaySize) / 2,mList.getHeight() - mOverlaySize));
final RectF pos=mOverlayPos;
pos.left=left;
pos.right=pos.left + mOverlaySize;
pos.top=top;
pos.bottom=pos.top + mOverlaySize;
if (mOverlayDrawable != null) {
mOverlayDrawable.setBounds((int)pos.left,(int)pos.top,(int)pos.right,(int)pos.bottom);
}
}
mOverlayDrawable.draw(canvas);
final Paint paint=mPaint;
float descent=paint.descent();
final RectF rectF=mOverlayPos;
final Rect tmpRect=mTmpRect;
mOverlayDrawable.getPadding(tmpRect);
final int hOff=(tmpRect.right - tmpRect.left) / 2;
final int vOff=(tmpRect.bottom - tmpRect.top) / 2;
canvas.drawText(mSectionText,(int)(rectF.left + rectF.right) / 2 - hOff,(int)(rectF.bottom + rectF.top) / 2 + mOverlaySize / 4 - descent - vOff,paint);
}
 else if (mState == STATE_EXIT) {
if (alpha == 0) {
setState(STATE_NONE);
}
 else {
final int left, right, top, bottom;
if (mTrackDrawable != null) {
top=0;
bottom=mList.getHeight();
}
 else {
top=y;
bottom=y + mThumbH;
}
switch (mList.getLayoutDirection()) {
case View.LAYOUT_DIRECTION_RTL:
left=0;
right=mThumbW;
break;
case View.LAYOUT_DIRECTION_LTR:
default :
left=viewWidth - mThumbW;
right=viewWidth;
}
mList.invalidate(left,top,right,bottom);
}
}
}