Program: 2244
Project: 2244
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
 */
@Override public Bitmap screenshotApplications(IBinder appToken,int displayId,int width,int height){
  if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,"String_Node_Str")) {
    throw new SecurityException("String_Node_Str");
  }
  Bitmap rawss=null;
  int maxLayer=0;
  final Rect frame=new Rect();
  float scale=0;
  int dw, dh;
  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;
  do {
    if (retryCount++ > 0) {
      try {
        Thread.sleep(100);
      }
 catch (      InterruptedException e) {
      }
    }
synchronized (mWindowMap) {
      final DisplayContent displayContent=getDisplayContentLocked(displayId);
      if (displayContent == null) {
        return null;
      }
      final DisplayInfo displayInfo=displayContent.getDisplayInfo();
      dw=displayInfo.logicalWidth;
      dh=displayInfo.logicalHeight;
      int aboveAppLayer=mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
      aboveAppLayer+=TYPE_LAYER_MULTIPLIER;
      boolean isImeTarget=mInputMethodTarget != null && mInputMethodTarget.mAppToken != null && mInputMethodTarget.mAppToken.appToken != null && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
      boolean including=false;
      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 (!including && appToken != null) {
          if (!ws.mIsImWindow || !isImeTarget) {
            if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
              continue;
            }
            appWin=ws;
          }
        }
        boolean fullscreen=ws.isFullscreen(dw,dh);
        including=!ws.mIsImWindow && !fullscreen;
        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);
        }
        if (ws.mAppToken != null && ws.mAppToken.token == appToken && ws.isDisplayedLw()) {
          screenshotReady=true;
        }
        if (fullscreen) {
          break;
        }
      }
      if (appToken != null && appWin == null) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken);
        return null;
      }
      if (!screenshotReady) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ appWin+ "String_Node_Str"+ appWin.mWinAnimator.mDrawState);
        continue;
      }
      frame.intersect(0,0,dw,dh);
      if (frame.isEmpty() || maxLayer == 0) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ frame.toShortString()+ "String_Node_Str"+ maxLayer);
        return null;
      }
      rot=getDefaultDisplayContentLocked().getDisplay().getRotation();
      int fw=frame.width();
      int fh=frame.height();
      float targetWidthScale=width / (float)fw;
      float targetHeightScale=height / (float)fh;
      if (dw <= dh) {
        scale=targetWidthScale;
        if (targetHeightScale > scale && (int)(targetHeightScale * fw) == width) {
          scale=targetHeightScale;
        }
      }
 else {
        scale=targetHeightScale;
        if (targetWidthScale > scale && (int)(targetWidthScale * fh) == height) {
          scale=targetWidthScale;
        }
      }
      dw=(int)(dw * scale);
      dh=(int)(dh * scale);
      if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
        int tmp=dw;
        dw=dh;
        dh=tmp;
        rot=(rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
      }
      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);
        }
      }
      rawss=SurfaceControl.screenshot(dw,dh,minLayer,maxLayer);
    }
  }
 while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
  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)));
  if (rawss == null) {
    Slog.w(TAG,"String_Node_Str" + dw + "String_Node_Str"+ dh+ "String_Node_Str"+ maxLayer);
    return null;
  }
  Bitmap bm=Bitmap.createBitmap(width,height,rawss.getConfig());
  Matrix matrix=new Matrix();
  ScreenRotationAnimation.createRotationMatrix(rot,dw,dh,matrix);
  matrix.postTranslate(-FloatMath.ceil(frame.left * scale),-FloatMath.ceil(frame.top * scale));
  Canvas canvas=new Canvas(bm);
  canvas.drawBitmap(rawss,matrix,null);
  canvas.setBitmap(null);
  if (true || 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;
    for (int i=0; i < buffer.length; i++) {
      if (buffer[i] != Color.BLACK) {
        allBlack=false;
        break;
      }
    }
    if (allBlack) {
      Slog.i(TAG,"String_Node_Str" + appWin + "String_Node_Str"+ (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "String_Node_Str")+ "String_Node_Str"+ minLayer+ "String_Node_Str"+ maxLayer);
    }
  }
  rawss.recycle();
  return bm;
}

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
 */
@Override public Bitmap screenshotApplications(IBinder appToken,int displayId,int width,int height){
  if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,"String_Node_Str")) {
    throw new SecurityException("String_Node_Str");
  }
  Bitmap rawss=null;
  int maxLayer=0;
  final Rect frame=new Rect();
  float scale=0;
  int dw, dh;
  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;
  do {
    if (retryCount++ > 0) {
      try {
        Thread.sleep(100);
      }
 catch (      InterruptedException e) {
      }
    }
synchronized (mWindowMap) {
      final DisplayContent displayContent=getDisplayContentLocked(displayId);
      if (displayContent == null) {
        return null;
      }
      final DisplayInfo displayInfo=displayContent.getDisplayInfo();
      dw=displayInfo.logicalWidth;
      dh=displayInfo.logicalHeight;
      int aboveAppLayer=mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
      aboveAppLayer+=TYPE_LAYER_MULTIPLIER;
      boolean isImeTarget=mInputMethodTarget != null && mInputMethodTarget.mAppToken != null && mInputMethodTarget.mAppToken.appToken != null && mInputMethodTarget.mAppToken.appToken.asBinder() == appToken;
      boolean including=false;
      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 (!including && appToken != null) {
          if (!ws.mIsImWindow || !isImeTarget) {
            if (ws.mAppToken == null || ws.mAppToken.token != appToken) {
              continue;
            }
            appWin=ws;
          }
        }
        boolean fullscreen=ws.isFullscreen(dw,dh);
        including=!ws.mIsImWindow && !fullscreen;
        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);
        }
        if (ws.mAppToken != null && ws.mAppToken.token == appToken && ws.isDisplayedLw()) {
          screenshotReady=true;
        }
        if (fullscreen) {
          break;
        }
      }
      if (appToken != null && appWin == null) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken);
        return null;
      }
      if (!screenshotReady) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ appWin+ "String_Node_Str"+ appWin.mWinAnimator.mDrawState);
        continue;
      }
      frame.intersect(0,0,dw,dh);
      if (frame.isEmpty() || maxLayer == 0) {
        if (DEBUG_SCREENSHOT)         Slog.i(TAG,"String_Node_Str" + appToken + "String_Node_Str"+ frame.toShortString()+ "String_Node_Str"+ maxLayer);
        return null;
      }
      rot=getDefaultDisplayContentLocked().getDisplay().getRotation();
      int fw=frame.width();
      int fh=frame.height();
      float targetWidthScale=width / (float)fw;
      float targetHeightScale=height / (float)fh;
      if (dw <= dh) {
        scale=targetWidthScale;
        if (targetHeightScale > scale && (int)(targetHeightScale * fw) == width) {
          scale=targetHeightScale;
        }
      }
 else {
        scale=targetHeightScale;
        if (targetWidthScale > scale && (int)(targetWidthScale * fh) == height) {
          scale=targetWidthScale;
        }
      }
      dw=(int)(dw * scale);
      dh=(int)(dh * scale);
      if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
        int tmp=dw;
        dw=dh;
        dh=tmp;
        rot=(rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
      }
      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);
        }
      }
      rawss=SurfaceControl.screenshot(dw,dh,minLayer,maxLayer);
    }
  }
 while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
  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)));
  if (rawss == null) {
    Slog.w(TAG,"String_Node_Str" + dw + "String_Node_Str"+ dh+ "String_Node_Str"+ maxLayer);
    return null;
  }
  Bitmap bm=Bitmap.createBitmap(width,height,rawss.getConfig());
  Matrix matrix=new Matrix();
  ScreenRotationAnimation.createRotationMatrix(rot,dw,dh,matrix);
  matrix.postTranslate(-FloatMath.ceil(frame.left * scale),-FloatMath.ceil(frame.top * scale));
  Canvas canvas=new Canvas(bm);
  canvas.drawColor(0xFF000000);
  canvas.drawBitmap(rawss,matrix,null);
  canvas.setBitmap(null);
  if (true || 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;
    for (int i=0; i < buffer.length; i++) {
      if (buffer[i] != Color.BLACK) {
        allBlack=false;
        break;
      }
    }
    if (allBlack) {
      Slog.i(TAG,"String_Node_Str" + appWin + "String_Node_Str"+ (appWin != null ? appWin.mWinAnimator.mSurfaceLayer : "String_Node_Str")+ "String_Node_Str"+ minLayer+ "String_Node_Str"+ maxLayer);
    }
  }
  rawss.recycle();
  return bm;
}