Program: 196154
Project: 196154
Buggy source:
private void draw(boolean fullRedrawNeeded){
  Surface surface=mSurface;
  if (!surface.isValid()) {
    return;
  }
  if (DEBUG_FPS) {
    trackFPS();
  }
  if (!sFirstDrawComplete) {
synchronized (sFirstDrawHandlers) {
      sFirstDrawComplete=true;
      final int count=sFirstDrawHandlers.size();
      for (int i=0; i < count; i++) {
        mHandler.post(sFirstDrawHandlers.get(i));
      }
    }
  }
  scrollToRectOrFocus(null,false);
  if (mAttachInfo.mViewScrollChanged) {
    mAttachInfo.mViewScrollChanged=false;
    mAttachInfo.mTreeObserver.dispatchOnScrollChanged();
  }
  boolean animating=mScroller != null && mScroller.computeScrollOffset();
  final int curScrollY;
  if (animating) {
    curScrollY=mScroller.getCurrY();
  }
 else {
    curScrollY=mScrollY;
  }
  if (mCurScrollY != curScrollY) {
    mCurScrollY=curScrollY;
    fullRedrawNeeded=true;
  }
  final float appScale=mAttachInfo.mApplicationScale;
  final boolean scalingRequired=mAttachInfo.mScalingRequired;
  int resizeAlpha=0;
  if (mResizeBuffer != null) {
    long deltaTime=SystemClock.uptimeMillis() - mResizeBufferStartTime;
    if (deltaTime < mResizeBufferDuration) {
      float amt=deltaTime / (float)mResizeBufferDuration;
      amt=mResizeInterpolator.getInterpolation(amt);
      animating=true;
      resizeAlpha=255 - (int)(amt * 255);
    }
 else {
      disposeResizeBuffer();
    }
  }
  final Rect dirty=mDirty;
  if (mSurfaceHolder != null) {
    dirty.setEmpty();
    if (animating) {
      if (mScroller != null) {
        mScroller.abortAnimation();
      }
      disposeResizeBuffer();
    }
    return;
  }
  if (fullRedrawNeeded) {
    mAttachInfo.mIgnoreDirtyState=true;
    dirty.set(0,0,(int)(mWidth * appScale + 0.5f),(int)(mHeight * appScale + 0.5f));
  }
  if (DEBUG_ORIENTATION || DEBUG_DRAW) {
    Log.v(TAG,"String_Node_Str" + mView + "String_Node_Str"+ mWindowAttributes.getTitle()+ "String_Node_Str"+ dirty.left+ "String_Node_Str"+ dirty.top+ "String_Node_Str"+ dirty.right+ "String_Node_Str"+ dirty.bottom+ "String_Node_Str"+ surface+ "String_Node_Str"+ surface.isValid()+ "String_Node_Str"+ appScale+ "String_Node_Str"+ mWidth+ "String_Node_Str"+ mHeight);
  }
  mAttachInfo.mTreeObserver.dispatchOnDraw();
  int xOffset=0;
  int yOffset=curScrollY;
  final WindowManager.LayoutParams params=mWindowAttributes;
  final Rect surfaceInsets=params != null ? params.surfaceInsets : null;
  if (surfaceInsets != null) {
    xOffset-=surfaceInsets.left;
    yOffset-=surfaceInsets.top;
    dirty.offset(surfaceInsets.left,surfaceInsets.right);
  }
  boolean accessibilityFocusDirty=false;
  final Drawable drawable=mAttachInfo.mAccessibilityFocusDrawable;
  if (drawable != null) {
    final Rect bounds=mAttachInfo.mTmpInvalRect;
    final boolean hasFocus=getAccessibilityFocusedRect(bounds);
    if (!hasFocus) {
      bounds.setEmpty();
    }
    if (!bounds.equals(drawable.getBounds())) {
      accessibilityFocusDirty=true;
    }
  }
  if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
    if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
      boolean invalidateRoot=accessibilityFocusDirty;
      mIsAnimating=false;
      if (mHardwareYOffset != yOffset || mHardwareXOffset != xOffset) {
        mHardwareYOffset=yOffset;
        mHardwareXOffset=xOffset;
        invalidateRoot=true;
      }
      mResizeAlpha=resizeAlpha;
      if (invalidateRoot) {
        mAttachInfo.mHardwareRenderer.invalidateRoot();
      }
      dirty.setEmpty();
      mBlockResizeBuffer=false;
      mAttachInfo.mHardwareRenderer.draw(mView,mAttachInfo,this);
    }
 else {
      if (mAttachInfo.mHardwareRenderer != null && !mAttachInfo.mHardwareRenderer.isEnabled() && mAttachInfo.mHardwareRenderer.isRequested()) {
        try {
          mAttachInfo.mHardwareRenderer.initializeIfNeeded(mWidth,mHeight,mSurface,surfaceInsets);
        }
 catch (        OutOfResourcesException e) {
          handleOutOfResourcesException(e);
          return;
        }
        mFullRedrawNeeded=true;
        scheduleTraversals();
        return;
      }
      if (!drawSoftware(surface,mAttachInfo,xOffset,yOffset,scalingRequired,dirty)) {
        return;
      }
    }
  }
  if (animating) {
    mFullRedrawNeeded=true;
    scheduleTraversals();
  }
}

Fixed version (ground truth):
private void draw(boolean fullRedrawNeeded){
  Surface surface=mSurface;
  if (!surface.isValid()) {
    return;
  }
  if (DEBUG_FPS) {
    trackFPS();
  }
  if (!sFirstDrawComplete) {
synchronized (sFirstDrawHandlers) {
      sFirstDrawComplete=true;
      final int count=sFirstDrawHandlers.size();
      for (int i=0; i < count; i++) {
        mHandler.post(sFirstDrawHandlers.get(i));
      }
    }
  }
  scrollToRectOrFocus(null,false);
  if (mAttachInfo.mViewScrollChanged) {
    mAttachInfo.mViewScrollChanged=false;
    mAttachInfo.mTreeObserver.dispatchOnScrollChanged();
  }
  boolean animating=mScroller != null && mScroller.computeScrollOffset();
  final int curScrollY;
  if (animating) {
    curScrollY=mScroller.getCurrY();
  }
 else {
    curScrollY=mScrollY;
  }
  if (mCurScrollY != curScrollY) {
    mCurScrollY=curScrollY;
    fullRedrawNeeded=true;
    if (mView instanceof RootViewSurfaceTaker) {
      ((RootViewSurfaceTaker)mView).onRootViewScrollYChanged(mCurScrollY);
    }
  }
  final float appScale=mAttachInfo.mApplicationScale;
  final boolean scalingRequired=mAttachInfo.mScalingRequired;
  int resizeAlpha=0;
  if (mResizeBuffer != null) {
    long deltaTime=SystemClock.uptimeMillis() - mResizeBufferStartTime;
    if (deltaTime < mResizeBufferDuration) {
      float amt=deltaTime / (float)mResizeBufferDuration;
      amt=mResizeInterpolator.getInterpolation(amt);
      animating=true;
      resizeAlpha=255 - (int)(amt * 255);
    }
 else {
      disposeResizeBuffer();
    }
  }
  final Rect dirty=mDirty;
  if (mSurfaceHolder != null) {
    dirty.setEmpty();
    if (animating) {
      if (mScroller != null) {
        mScroller.abortAnimation();
      }
      disposeResizeBuffer();
    }
    return;
  }
  if (fullRedrawNeeded) {
    mAttachInfo.mIgnoreDirtyState=true;
    dirty.set(0,0,(int)(mWidth * appScale + 0.5f),(int)(mHeight * appScale + 0.5f));
  }
  if (DEBUG_ORIENTATION || DEBUG_DRAW) {
    Log.v(TAG,"String_Node_Str" + mView + "String_Node_Str"+ mWindowAttributes.getTitle()+ "String_Node_Str"+ dirty.left+ "String_Node_Str"+ dirty.top+ "String_Node_Str"+ dirty.right+ "String_Node_Str"+ dirty.bottom+ "String_Node_Str"+ surface+ "String_Node_Str"+ surface.isValid()+ "String_Node_Str"+ appScale+ "String_Node_Str"+ mWidth+ "String_Node_Str"+ mHeight);
  }
  mAttachInfo.mTreeObserver.dispatchOnDraw();
  int xOffset=0;
  int yOffset=curScrollY;
  final WindowManager.LayoutParams params=mWindowAttributes;
  final Rect surfaceInsets=params != null ? params.surfaceInsets : null;
  if (surfaceInsets != null) {
    xOffset-=surfaceInsets.left;
    yOffset-=surfaceInsets.top;
    dirty.offset(surfaceInsets.left,surfaceInsets.right);
  }
  boolean accessibilityFocusDirty=false;
  final Drawable drawable=mAttachInfo.mAccessibilityFocusDrawable;
  if (drawable != null) {
    final Rect bounds=mAttachInfo.mTmpInvalRect;
    final boolean hasFocus=getAccessibilityFocusedRect(bounds);
    if (!hasFocus) {
      bounds.setEmpty();
    }
    if (!bounds.equals(drawable.getBounds())) {
      accessibilityFocusDirty=true;
    }
  }
  if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
    if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
      boolean invalidateRoot=accessibilityFocusDirty;
      mIsAnimating=false;
      if (mHardwareYOffset != yOffset || mHardwareXOffset != xOffset) {
        mHardwareYOffset=yOffset;
        mHardwareXOffset=xOffset;
        invalidateRoot=true;
      }
      mResizeAlpha=resizeAlpha;
      if (invalidateRoot) {
        mAttachInfo.mHardwareRenderer.invalidateRoot();
      }
      dirty.setEmpty();
      mBlockResizeBuffer=false;
      mAttachInfo.mHardwareRenderer.draw(mView,mAttachInfo,this);
    }
 else {
      if (mAttachInfo.mHardwareRenderer != null && !mAttachInfo.mHardwareRenderer.isEnabled() && mAttachInfo.mHardwareRenderer.isRequested()) {
        try {
          mAttachInfo.mHardwareRenderer.initializeIfNeeded(mWidth,mHeight,mSurface,surfaceInsets);
        }
 catch (        OutOfResourcesException e) {
          handleOutOfResourcesException(e);
          return;
        }
        mFullRedrawNeeded=true;
        scheduleTraversals();
        return;
      }
      if (!drawSoftware(surface,mAttachInfo,xOffset,yOffset,scalingRequired,dirty)) {
        return;
      }
    }
  }
  if (animating) {
    mFullRedrawNeeded=true;
    scheduleTraversals();
  }
}