Program: 196222
Project: 196222
Buggy source:
/** 
 * Takes a snapshot of the screen.  In landscape mode this grabs the whole screen. In portrait mode, it grabs the upper region of the screen based on the vertical dimension of the target image.
 * @param displayId the Display to take a screenshot of.
 * @param width the width of the target bitmap
 * @param height the height of the target bitmap
 * @param force565 if true the returned bitmap will be RGB_565, otherwise itwill be the same config as the surface
 */
@Override public Bitmap screenshotApplications(IBinder appToken,int displayId,int width,int height,boolean force565){
  if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,"String_Node_Str")) {
    throw new SecurityException("String_Node_Str");
  }
  final DisplayContent displayContent=getDisplayContentLocked(displayId);
  if (displayContent == null) {
    if (DEBUG_SCREENSHOT)     Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ displayId);
    return null;
  }
  final DisplayInfo displayInfo=displayContent.getDisplayInfo();
  int dw=displayInfo.logicalWidth;
  int dh=displayInfo.logicalHeight;
  if (dw == 0 || dh == 0) {
    if (DEBUG_SCREENSHOT)     Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ dw+ "String_Node_Str"+ dh);
    return null;
  }
  Bitmap bm=null;
  int maxLayer=0;
  final Rect frame=new Rect();
  final Rect stackBounds=new Rect();
  float scale=0;
  int rot=Surface.ROTATION_0;
  boolean screenshotReady;
  int minLayer;
  if (appToken == null) {
    screenshotReady=true;
    minLayer=0;
  }
 else {
    screenshotReady=false;
    minLayer=Integer.MAX_VALUE;
  }
  int retryCount=0;
  WindowState appWin=null;
  final boolean appIsImTarget=mInputMethodTarget != null && mInputMethodTarget.mAppToken != null && mInputMethodTarget.mAppToken.appToken != null && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
  final int aboveAppLayer=(mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
  while (true) {
    if (retryCount++ > 0) {
      try {
        Thread.sleep(100);
      }
 catch (      InterruptedException e) {
      }
    }
synchronized (mWindowMap) {
      appWin=null;
      final WindowList windows=displayContent.getWindowList();
      for (int i=windows.size() - 1; i >= 0; i--) {
        WindowState ws=windows.get(i);
        if (!ws.mHasSurface) {
          continue;
        }
        if (ws.mLayer >= aboveAppLayer) {
          continue;
        }
        if (ws.mIsImWindow) {
          if (!appIsImTarget) {
            continue;
          }
        }
 else         if (ws.mIsWallpaper) {
        }
 else         if (appToken != null) {
          if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
            continue;
          }
          appWin=ws;
        }
        final WindowStateAnimator winAnim=ws.mWinAnimator;
        if (maxLayer < winAnim.mSurfaceLayer) {
          maxLayer=winAnim.mSurfaceLayer;
        }
        if (minLayer > winAnim.mSurfaceLayer) {
          minLayer=winAnim.mSurfaceLayer;
        }
        if (!ws.mIsWallpaper) {
          final Rect wf=ws.mFrame;
          final Rect cr=ws.mContentInsets;
          int left=wf.left + cr.left;
          int top=wf.top + cr.top;
          int right=wf.right - cr.right;
          int bottom=wf.bottom - cr.bottom;
          frame.union(left,top,right,bottom);
          ws.getStackBounds(stackBounds);
          frame.intersect(stackBounds);
        }
        if (ws.mAppToken != null && ws.mAppToken.token == appToken && ws.isDisplayedLw()) {
          screenshotReady=true;
        }
      }
      if (appToken != null && appWin == null) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken);
        return null;
      }
      if (!screenshotReady) {
        if (retryCount > MAX_SCREENSHOT_RETRIES) {
          Slog.i(TAG,"String_Node_Str" + retryCount + "String_Node_Str"+ appToken+ "String_Node_Str"+ (appWin == null ? "String_Node_Str" : (appWin + "String_Node_Str" + appWin.mWinAnimator.mDrawState)));
          return null;
        }
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ appWin+ "String_Node_Str"+ appWin.mWinAnimator.mDrawState);
        continue;
      }
      if (maxLayer == 0) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ maxLayer);
        return null;
      }
      frame.intersect(0,0,dw,dh);
      Rect crop=new Rect(frame);
      if (width / (float)frame.width() < height / (float)frame.height()) {
        int cropWidth=(int)((float)width / (float)height * frame.height());
        crop.right=crop.left + cropWidth;
      }
 else {
        int cropHeight=(int)((float)height / (float)width * frame.width());
        crop.bottom=crop.top + cropHeight;
      }
      rot=getDefaultDisplayContentLocked().getDisplay().getRotation();
      if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
        rot=(rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
      }
      convertCropForSurfaceFlinger(crop,rot,dw,dh);
      if (DEBUG_SCREENSHOT) {
        Slog.i(TAG,"String_Node_Str" + dw + "String_Node_Str"+ dh+ "String_Node_Str"+ minLayer+ "String_Node_Str"+ maxLayer+ "String_Node_Str"+ appToken);
        for (int i=0; i < windows.size(); i++) {
          WindowState win=windows.get(i);
          Slog.i(TAG,win + "String_Node_Str" + win.mLayer+ "String_Node_Str"+ win.mWinAnimator.mAnimLayer+ "String_Node_Str"+ win.mWinAnimator.mSurfaceLayer);
        }
      }
      ScreenRotationAnimation screenRotationAnimation=mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
      final boolean inRotation=screenRotationAnimation != null && screenRotationAnimation.isAnimating();
      if (DEBUG_SCREENSHOT && inRotation)       Slog.v(TAG,"String_Node_Str");
      bm=SurfaceControl.screenshot(crop,width,height,minLayer,maxLayer,inRotation,rot);
      if (bm == null) {
        Slog.w(TAG,"String_Node_Str" + dw + "String_Node_Str"+ dh+ "String_Node_Str"+ maxLayer);
        return null;
      }
    }
    break;
  }
  if (DEBUG_SCREENSHOT) {
    int[] buffer=new int[bm.getWidth() * bm.getHeight()];
    bm.getPixels(buffer,0,bm.getWidth(),0,0,bm.getWidth(),bm.getHeight());
    boolean allBlack=true;
    final int firstColor=buffer[0];
    for (int i=0; i < buffer.length; i++) {
      if (buffer[i] != firstColor) {
        allBlack=false;
        break;
      }
    }
    if (allBlack) {
      Slog.i(TAG,"String_Node_Str" + appWin + "String_Node_Str"+ Integer.toHexString(firstColor)+ "String_Node_Str"+ (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "String_Node_Str")+ "String_Node_Str"+ minLayer+ "String_Node_Str"+ maxLayer);
    }
  }
  Bitmap ret=bm.copy(bm.getConfig(),true);
  bm.recycle();
  return ret;
}

Fixed version (ground truth):
/** 
 * Takes a snapshot of the screen.  In landscape mode this grabs the whole screen. In portrait mode, it grabs the upper region of the screen based on the vertical dimension of the target image.
 * @param displayId the Display to take a screenshot of.
 * @param width the width of the target bitmap
 * @param height the height of the target bitmap
 * @param force565 if true the returned bitmap will be RGB_565, otherwise itwill be the same config as the surface
 */
@Override public Bitmap screenshotApplications(IBinder appToken,int displayId,int width,int height,boolean force565){
  if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,"String_Node_Str")) {
    throw new SecurityException("String_Node_Str");
  }
  final DisplayContent displayContent=getDisplayContentLocked(displayId);
  if (displayContent == null) {
    if (DEBUG_SCREENSHOT)     Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ displayId);
    return null;
  }
  final DisplayInfo displayInfo=displayContent.getDisplayInfo();
  int dw=displayInfo.logicalWidth;
  int dh=displayInfo.logicalHeight;
  if (dw == 0 || dh == 0) {
    if (DEBUG_SCREENSHOT)     Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ dw+ "String_Node_Str"+ dh);
    return null;
  }
  Bitmap bm=null;
  int maxLayer=0;
  final Rect frame=new Rect();
  final Rect stackBounds=new Rect();
  float scale=0;
  int rot=Surface.ROTATION_0;
  boolean screenshotReady;
  int minLayer;
  if (appToken == null) {
    screenshotReady=true;
    minLayer=0;
  }
 else {
    screenshotReady=false;
    minLayer=Integer.MAX_VALUE;
  }
  int retryCount=0;
  WindowState appWin=null;
  final boolean appIsImTarget=mInputMethodTarget != null && mInputMethodTarget.mAppToken != null && mInputMethodTarget.mAppToken.appToken != null && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
  final int aboveAppLayer=(mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
  while (true) {
    if (retryCount++ > 0) {
      maxLayer=0;
      minLayer=Integer.MAX_VALUE;
      try {
        Thread.sleep(100);
      }
 catch (      InterruptedException e) {
      }
    }
synchronized (mWindowMap) {
      appWin=null;
      final WindowList windows=displayContent.getWindowList();
      for (int i=windows.size() - 1; i >= 0; i--) {
        WindowState ws=windows.get(i);
        if (!ws.mHasSurface) {
          continue;
        }
        if (ws.mLayer >= aboveAppLayer) {
          continue;
        }
        if (ws.mIsImWindow) {
          if (!appIsImTarget) {
            continue;
          }
        }
 else         if (ws.mIsWallpaper) {
          if (appWin == null) {
            continue;
          }
        }
 else         if (appToken != null) {
          if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
            continue;
          }
          appWin=ws;
        }
        final WindowStateAnimator winAnim=ws.mWinAnimator;
        if (maxLayer < winAnim.mSurfaceLayer) {
          maxLayer=winAnim.mSurfaceLayer;
        }
        if (minLayer > winAnim.mSurfaceLayer) {
          minLayer=winAnim.mSurfaceLayer;
        }
        if (!ws.mIsWallpaper) {
          final Rect wf=ws.mFrame;
          final Rect cr=ws.mContentInsets;
          int left=wf.left + cr.left;
          int top=wf.top + cr.top;
          int right=wf.right - cr.right;
          int bottom=wf.bottom - cr.bottom;
          frame.union(left,top,right,bottom);
          ws.getStackBounds(stackBounds);
          frame.intersect(stackBounds);
        }
        if (ws.mAppToken != null && ws.mAppToken.token == appToken && ws.isDisplayedLw()) {
          screenshotReady=true;
        }
      }
      if (appToken != null && appWin == null) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken);
        return null;
      }
      if (!screenshotReady) {
        if (retryCount > MAX_SCREENSHOT_RETRIES) {
          Slog.i(TAG,"String_Node_Str" + retryCount + "String_Node_Str"+ appToken+ "String_Node_Str"+ (appWin == null ? "String_Node_Str" : (appWin + "String_Node_Str" + appWin.mWinAnimator.mDrawState)));
          return null;
        }
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ appWin+ "String_Node_Str"+ appWin.mWinAnimator.mDrawState);
        continue;
      }
      if (maxLayer == 0) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ maxLayer);
        return null;
      }
      frame.intersect(0,0,dw,dh);
      Rect crop=new Rect(frame);
      if (width / (float)frame.width() < height / (float)frame.height()) {
        int cropWidth=(int)((float)width / (float)height * frame.height());
        crop.right=crop.left + cropWidth;
      }
 else {
        int cropHeight=(int)((float)height / (float)width * frame.width());
        crop.bottom=crop.top + cropHeight;
      }
      rot=getDefaultDisplayContentLocked().getDisplay().getRotation();
      if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
        rot=(rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
      }
      convertCropForSurfaceFlinger(crop,rot,dw,dh);
      if (DEBUG_SCREENSHOT) {
        Slog.i(TAG,"String_Node_Str" + dw + "String_Node_Str"+ dh+ "String_Node_Str"+ minLayer+ "String_Node_Str"+ maxLayer+ "String_Node_Str"+ appToken);
        for (int i=0; i < windows.size(); i++) {
          WindowState win=windows.get(i);
          Slog.i(TAG,win + "String_Node_Str" + win.mLayer+ "String_Node_Str"+ win.mWinAnimator.mAnimLayer+ "String_Node_Str"+ win.mWinAnimator.mSurfaceLayer);
        }
      }
      ScreenRotationAnimation screenRotationAnimation=mAnimator.getScreenRotationAnimationLocked(Display.DEFAULT_DISPLAY);
      final boolean inRotation=screenRotationAnimation != null && screenRotationAnimation.isAnimating();
      if (DEBUG_SCREENSHOT && inRotation)       Slog.v(TAG,"String_Node_Str");
      bm=SurfaceControl.screenshot(crop,width,height,minLayer,maxLayer,inRotation,rot);
      if (bm == null) {
        Slog.w(TAG,"String_Node_Str" + dw + "String_Node_Str"+ dh+ "String_Node_Str"+ maxLayer);
        return null;
      }
    }
    break;
  }
  if (DEBUG_SCREENSHOT) {
    int[] buffer=new int[bm.getWidth() * bm.getHeight()];
    bm.getPixels(buffer,0,bm.getWidth(),0,0,bm.getWidth(),bm.getHeight());
    boolean allBlack=true;
    final int firstColor=buffer[0];
    for (int i=0; i < buffer.length; i++) {
      if (buffer[i] != firstColor) {
        allBlack=false;
        break;
      }
    }
    if (allBlack) {
      Slog.i(TAG,"String_Node_Str" + appWin + "String_Node_Str"+ Integer.toHexString(firstColor)+ "String_Node_Str"+ (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "String_Node_Str")+ "String_Node_Str"+ minLayer+ "String_Node_Str"+ maxLayer);
    }
  }
  Bitmap ret=bm.copy(bm.getConfig(),true);
  bm.recycle();
  return ret;
}