Program: 21767
Project: 21767
Buggy source:
/** 
 * <p>Forces the drawing cache to be built if the drawing cache is invalid.</p> <p>If you call   {@link #buildDrawingCache()} manually without calling{@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you should cleanup the cache by calling   {@link #destroyDrawingCache()} afterwards.</p><p>Note about auto scaling in compatibility mode: When auto scaling is not enabled, this method will create a bitmap of the same size as this view. Because this bitmap will be drawn scaled by the parent ViewGroup, the result on screen might show scaling artifacts. To avoid such artifacts, you should call this method by setting the auto scaling to true. Doing so, however, will generate a bitmap of a different size than the view. This implies that your application must be able to handle this size.</p>
 * @see #getDrawingCache()
 * @see #destroyDrawingCache()
 */
public void buildDrawingCache(boolean autoScale){
  if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || (autoScale ? (mDrawingCache == null || mDrawingCache.get() == null) : (mUnscaledDrawingCache == null || mUnscaledDrawingCache.get() == null))) {
    if (ViewDebug.TRACE_HIERARCHY) {
      ViewDebug.trace(this,ViewDebug.HierarchyTraceType.BUILD_CACHE);
    }
    if (Config.DEBUG && ViewDebug.profileDrawing) {
      EventLog.writeEvent(60002,hashCode());
    }
    int width=mRight - mLeft;
    int height=mBottom - mTop;
    final AttachInfo attachInfo=mAttachInfo;
    final boolean scalingRequired=attachInfo != null && attachInfo.mScalingRequired;
    if (autoScale && scalingRequired) {
      width=(int)((width * attachInfo.mApplicationScale) + 0.5f);
      height=(int)((height * attachInfo.mApplicationScale) + 0.5f);
    }
    final int drawingCacheBackgroundColor=mDrawingCacheBackgroundColor;
    final boolean opaque=drawingCacheBackgroundColor != 0 || isOpaque();
    final boolean translucentWindow=attachInfo != null && attachInfo.mTranslucentWindow;
    if (width <= 0 || height <= 0 || (width * height * (opaque && !translucentWindow ? 2 : 4) > ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {
      destroyDrawingCache();
      return;
    }
    boolean clear=true;
    Bitmap bitmap=autoScale ? (mDrawingCache == null ? null : mDrawingCache.get()) : (mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
    if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
      Bitmap.Config quality;
      if (!opaque) {
switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
case DRAWING_CACHE_QUALITY_AUTO:
          quality=Bitmap.Config.ARGB_8888;
        break;
case DRAWING_CACHE_QUALITY_LOW:
      quality=Bitmap.Config.ARGB_4444;
    break;
case DRAWING_CACHE_QUALITY_HIGH:
  quality=Bitmap.Config.ARGB_8888;
break;
default :
quality=Bitmap.Config.ARGB_8888;
break;
}
}
 else {
quality=translucentWindow ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
}
if (bitmap != null) bitmap.recycle();
try {
bitmap=Bitmap.createBitmap(width,height,quality);
bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
if (autoScale) {
mDrawingCache=new SoftReference<Bitmap>(bitmap);
}
 else {
mUnscaledDrawingCache=new SoftReference<Bitmap>(bitmap);
}
if (opaque && translucentWindow) bitmap.setHasAlpha(false);
}
 catch (OutOfMemoryError e) {
if (autoScale) {
mDrawingCache=null;
}
 else {
mUnscaledDrawingCache=null;
}
return;
}
clear=drawingCacheBackgroundColor != 0;
}
Canvas canvas;
if (attachInfo != null) {
canvas=attachInfo.mCanvas;
if (canvas == null) {
canvas=new Canvas();
}
canvas.setBitmap(bitmap);
attachInfo.mCanvas=null;
}
 else {
canvas=new Canvas(bitmap);
}
if (clear) {
bitmap.eraseColor(drawingCacheBackgroundColor);
}
computeScroll();
final int restoreCount=canvas.save();
if (autoScale && scalingRequired) {
final float scale=attachInfo.mApplicationScale;
canvas.scale(scale,scale);
}
canvas.translate(-mScrollX,-mScrollY);
mPrivateFlags|=DRAWN;
mPrivateFlags|=DRAWING_CACHE_VALID;
if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this,ViewDebug.HierarchyTraceType.DRAW);
}
mPrivateFlags&=~DIRTY_MASK;
dispatchDraw(canvas);
}
 else {
draw(canvas);
}
canvas.restoreToCount(restoreCount);
if (attachInfo != null) {
attachInfo.mCanvas=canvas;
}
}
}

Fixed version (ground truth):
/** 
 * <p>Forces the drawing cache to be built if the drawing cache is invalid.</p> <p>If you call   {@link #buildDrawingCache()} manually without calling{@link #setDrawingCacheEnabled(boolean) setDrawingCacheEnabled(true)}, you should cleanup the cache by calling   {@link #destroyDrawingCache()} afterwards.</p><p>Note about auto scaling in compatibility mode: When auto scaling is not enabled, this method will create a bitmap of the same size as this view. Because this bitmap will be drawn scaled by the parent ViewGroup, the result on screen might show scaling artifacts. To avoid such artifacts, you should call this method by setting the auto scaling to true. Doing so, however, will generate a bitmap of a different size than the view. This implies that your application must be able to handle this size.</p>
 * @see #getDrawingCache()
 * @see #destroyDrawingCache()
 */
public void buildDrawingCache(boolean autoScale){
  if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || (autoScale ? (mDrawingCache == null || mDrawingCache.get() == null) : (mUnscaledDrawingCache == null || mUnscaledDrawingCache.get() == null))) {
    if (ViewDebug.TRACE_HIERARCHY) {
      ViewDebug.trace(this,ViewDebug.HierarchyTraceType.BUILD_CACHE);
    }
    if (Config.DEBUG && ViewDebug.profileDrawing) {
      EventLog.writeEvent(60002,hashCode());
    }
    int width=mRight - mLeft;
    int height=mBottom - mTop;
    final AttachInfo attachInfo=mAttachInfo;
    final boolean scalingRequired=attachInfo != null && attachInfo.mScalingRequired;
    if (autoScale && scalingRequired) {
      width=(int)((width * attachInfo.mApplicationScale) + 0.5f);
      height=(int)((height * attachInfo.mApplicationScale) + 0.5f);
    }
    final int drawingCacheBackgroundColor=mDrawingCacheBackgroundColor;
    final boolean opaque=drawingCacheBackgroundColor != 0 || isOpaque();
    final boolean use32BitCache=attachInfo != null && attachInfo.mUse32BitDrawingCache;
    if (width <= 0 || height <= 0 || (width * height * (opaque && !use32BitCache ? 2 : 4) > ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {
      destroyDrawingCache();
      return;
    }
    boolean clear=true;
    Bitmap bitmap=autoScale ? (mDrawingCache == null ? null : mDrawingCache.get()) : (mUnscaledDrawingCache == null ? null : mUnscaledDrawingCache.get());
    if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
      Bitmap.Config quality;
      if (!opaque) {
switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
case DRAWING_CACHE_QUALITY_AUTO:
          quality=Bitmap.Config.ARGB_8888;
        break;
case DRAWING_CACHE_QUALITY_LOW:
      quality=Bitmap.Config.ARGB_4444;
    break;
case DRAWING_CACHE_QUALITY_HIGH:
  quality=Bitmap.Config.ARGB_8888;
break;
default :
quality=Bitmap.Config.ARGB_8888;
break;
}
}
 else {
quality=use32BitCache ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
}
if (bitmap != null) bitmap.recycle();
try {
bitmap=Bitmap.createBitmap(width,height,quality);
bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
if (autoScale) {
mDrawingCache=new SoftReference<Bitmap>(bitmap);
}
 else {
mUnscaledDrawingCache=new SoftReference<Bitmap>(bitmap);
}
if (opaque && use32BitCache) bitmap.setHasAlpha(false);
}
 catch (OutOfMemoryError e) {
if (autoScale) {
mDrawingCache=null;
}
 else {
mUnscaledDrawingCache=null;
}
return;
}
clear=drawingCacheBackgroundColor != 0;
}
Canvas canvas;
if (attachInfo != null) {
canvas=attachInfo.mCanvas;
if (canvas == null) {
canvas=new Canvas();
}
canvas.setBitmap(bitmap);
attachInfo.mCanvas=null;
}
 else {
canvas=new Canvas(bitmap);
}
if (clear) {
bitmap.eraseColor(drawingCacheBackgroundColor);
}
computeScroll();
final int restoreCount=canvas.save();
if (autoScale && scalingRequired) {
final float scale=attachInfo.mApplicationScale;
canvas.scale(scale,scale);
}
canvas.translate(-mScrollX,-mScrollY);
mPrivateFlags|=DRAWN;
mPrivateFlags|=DRAWING_CACHE_VALID;
if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this,ViewDebug.HierarchyTraceType.DRAW);
}
mPrivateFlags&=~DIRTY_MASK;
dispatchDraw(canvas);
}
 else {
draw(canvas);
}
canvas.restoreToCount(restoreCount);
if (attachInfo != null) {
attachInfo.mCanvas=canvas;
}
}
}