protected void cropImageAndSetWallpaper(
     Resources res, int resId, final boolean finishActivityWhenDone) {
   // crop this image and scale it down to the default wallpaper size for
   // this device
   int rotation = getRotationFromExif(res, resId);
   Point inSize = mCropView.getSourceDimensions();
   Point outSize = getDefaultWallpaperSize(getResources(), getWindowManager());
   RectF crop = getMaxCropRect(inSize.x, inSize.y, outSize.x, outSize.y, false);
   Runnable onEndCrop =
       new Runnable() {
         public void run() {
           // Passing 0, 0 will cause launcher to revert to using the
           // default wallpaper size
           updateWallpaperDimensions(0, 0);
           if (finishActivityWhenDone) {
             setResult(Activity.RESULT_OK);
             finish();
           }
         }
       };
   BitmapCropTask cropTask =
       new BitmapCropTask(
           this, res, resId, crop, rotation, outSize.x, outSize.y, true, false, onEndCrop);
   cropTask.execute();
 }
  private static Bitmap createThumbnail(
      Point size,
      Context context,
      Uri uri,
      byte[] imageBytes,
      Resources res,
      int resId,
      int rotation,
      boolean leftAligned) {
    int width = size.x;
    int height = size.y;

    BitmapCropTask cropTask;
    if (uri != null) {
      cropTask = new BitmapCropTask(context, uri, null, rotation, width, height, false, true, null);
    } else if (imageBytes != null) {
      cropTask = new BitmapCropTask(imageBytes, null, rotation, width, height, false, true, null);
    } else {
      cropTask =
          new BitmapCropTask(context, res, resId, null, rotation, width, height, false, true, null);
    }
    Point bounds = cropTask.getImageBounds();
    if (bounds == null || bounds.x == 0 || bounds.y == 0) {
      return null;
    }

    Matrix rotateMatrix = new Matrix();
    rotateMatrix.setRotate(rotation);
    float[] rotatedBounds = new float[] {bounds.x, bounds.y};
    rotateMatrix.mapPoints(rotatedBounds);
    rotatedBounds[0] = Math.abs(rotatedBounds[0]);
    rotatedBounds[1] = Math.abs(rotatedBounds[1]);

    RectF cropRect =
        WallpaperCropActivity.getMaxCropRect(
            (int) rotatedBounds[0], (int) rotatedBounds[1], width, height, leftAligned);
    cropTask.setCropBounds(cropRect);

    if (cropTask.cropBitmap()) {
      return cropTask.getCroppedBitmap();
    } else {
      return null;
    }
  }
 protected void setWallpaper(Uri uri, final boolean finishActivityWhenDone) {
   int rotation = getRotationFromExif(this, uri);
   BitmapCropTask cropTask =
       new BitmapCropTask(this, uri, null, rotation, 0, 0, true, false, null);
   final Point bounds = cropTask.getImageBounds();
   Runnable onEndCrop =
       new Runnable() {
         public void run() {
           updateWallpaperDimensions(bounds.x, bounds.y);
           if (finishActivityWhenDone) {
             setResult(Activity.RESULT_OK);
             finish();
           }
         }
       };
   cropTask.setOnEndRunnable(onEndCrop);
   cropTask.setNoCrop(true);
   cropTask.execute();
 }
  protected void cropImageAndSetWallpaper(
      Uri uri,
      OnBitmapCroppedHandler onBitmapCroppedHandler,
      final boolean finishActivityWhenDone) {
    boolean centerCrop = getResources().getBoolean(R.bool.center_crop);
    // Get the crop
    boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;

    Display d = getWindowManager().getDefaultDisplay();

    Point displaySize = new Point();
    d.getSize(displaySize);
    boolean isPortrait = displaySize.x < displaySize.y;

    Point defaultWallpaperSize = getDefaultWallpaperSize(getResources(), getWindowManager());
    // Get the crop
    RectF cropRect = mCropView.getCrop();

    Point inSize = mCropView.getSourceDimensions();

    int cropRotation = mCropView.getImageRotation();
    float cropScale = mCropView.getWidth() / (float) cropRect.width();

    Matrix rotateMatrix = new Matrix();
    rotateMatrix.setRotate(cropRotation);
    float[] rotatedInSize = new float[] {inSize.x, inSize.y};
    rotateMatrix.mapPoints(rotatedInSize);
    rotatedInSize[0] = Math.abs(rotatedInSize[0]);
    rotatedInSize[1] = Math.abs(rotatedInSize[1]);

    // due to rounding errors in the cropview renderer the edges can be slightly offset
    // therefore we ensure that the boundaries are sanely defined
    cropRect.left = Math.max(0, cropRect.left);
    cropRect.right = Math.min(rotatedInSize[0], cropRect.right);
    cropRect.top = Math.max(0, cropRect.top);
    cropRect.bottom = Math.min(rotatedInSize[1], cropRect.bottom);

    // ADJUST CROP WIDTH
    // Extend the crop all the way to the right, for parallax
    // (or all the way to the left, in RTL)
    float extraSpace;
    if (centerCrop) {
      extraSpace = 2f * Math.min(rotatedInSize[0] - cropRect.right, cropRect.left);
    } else {
      extraSpace = ltr ? rotatedInSize[0] - cropRect.right : cropRect.left;
    }
    // Cap the amount of extra width
    float maxExtraSpace = defaultWallpaperSize.x / cropScale - cropRect.width();
    extraSpace = Math.min(extraSpace, maxExtraSpace);

    if (centerCrop) {
      cropRect.left -= extraSpace / 2f;
      cropRect.right += extraSpace / 2f;
    } else {
      if (ltr) {
        cropRect.right += extraSpace;
      } else {
        cropRect.left -= extraSpace;
      }
    }

    // ADJUST CROP HEIGHT
    if (isPortrait) {
      cropRect.bottom = cropRect.top + defaultWallpaperSize.y / cropScale;
    } else { // LANDSCAPE
      float extraPortraitHeight = defaultWallpaperSize.y / cropScale - cropRect.height();
      float expandHeight =
          Math.min(
              Math.min(rotatedInSize[1] - cropRect.bottom, cropRect.top), extraPortraitHeight / 2);
      cropRect.top -= expandHeight;
      cropRect.bottom += expandHeight;
    }
    final int outWidth = (int) Math.round(cropRect.width() * cropScale);
    final int outHeight = (int) Math.round(cropRect.height() * cropScale);

    Runnable onEndCrop =
        new Runnable() {
          public void run() {
            updateWallpaperDimensions(outWidth, outHeight);
            if (finishActivityWhenDone) {
              setResult(Activity.RESULT_OK);
              finish();
            }
          }
        };
    BitmapCropTask cropTask =
        new BitmapCropTask(
            this, uri, cropRect, cropRotation, outWidth, outHeight, true, false, onEndCrop);
    if (onBitmapCroppedHandler != null) {
      cropTask.setOnBitmapCropped(onBitmapCroppedHandler);
    }
    cropTask.execute();
  }
  protected void cropImageAndSetWallpaper(
      Uri uri,
      OnBitmapCroppedHandler onBitmapCroppedHandler,
      final boolean finishActivityWhenDone) {
    // Get the crop
    boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;

    Point minDims = new Point();
    Point maxDims = new Point();
    Display d = getWindowManager().getDefaultDisplay();
    d.getCurrentSizeRange(minDims, maxDims);

    Point displaySize = new Point();
    d.getSize(displaySize);

    int maxDim = Math.max(maxDims.x, maxDims.y);
    final int minDim = Math.min(minDims.x, minDims.y);
    int defaultWallpaperWidth;
    if (isScreenLarge(getResources())) {
      defaultWallpaperWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim));
    } else {
      defaultWallpaperWidth = Math.max((int) (minDim * WALLPAPER_SCREENS_SPAN), maxDim);
    }

    boolean isPortrait = displaySize.x < displaySize.y;
    int portraitHeight;
    if (isPortrait) {
      portraitHeight = mCropView.getHeight();
    } else {
      // TODO: how to actually get the proper portrait height?
      // This is not quite right:
      portraitHeight = Math.max(maxDims.x, maxDims.y);
    }
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
      Point realSize = new Point();
      d.getRealSize(realSize);
      portraitHeight = Math.max(realSize.x, realSize.y);
    }
    // Get the crop
    RectF cropRect = mCropView.getCrop();
    int cropRotation = mCropView.getImageRotation();
    float cropScale = mCropView.getWidth() / (float) cropRect.width();

    Point inSize = mCropView.getSourceDimensions();
    Matrix rotateMatrix = new Matrix();
    rotateMatrix.setRotate(cropRotation);
    float[] rotatedInSize = new float[] {inSize.x, inSize.y};
    rotateMatrix.mapPoints(rotatedInSize);
    rotatedInSize[0] = Math.abs(rotatedInSize[0]);
    rotatedInSize[1] = Math.abs(rotatedInSize[1]);

    // ADJUST CROP WIDTH
    // Extend the crop all the way to the right, for parallax
    // (or all the way to the left, in RTL)
    float extraSpace = ltr ? rotatedInSize[0] - cropRect.right : cropRect.left;
    // Cap the amount of extra width
    float maxExtraSpace = defaultWallpaperWidth / cropScale - cropRect.width();
    extraSpace = Math.min(extraSpace, maxExtraSpace);

    if (ltr) {
      cropRect.right += extraSpace;
    } else {
      cropRect.left -= extraSpace;
    }

    // ADJUST CROP HEIGHT
    if (isPortrait) {
      cropRect.bottom = cropRect.top + portraitHeight / cropScale;
    } else { // LANDSCAPE
      float extraPortraitHeight = portraitHeight / cropScale - cropRect.height();
      float expandHeight =
          Math.min(
              Math.min(rotatedInSize[1] - cropRect.bottom, cropRect.top), extraPortraitHeight / 2);
      cropRect.top -= expandHeight;
      cropRect.bottom += expandHeight;
    }
    final int outWidth = (int) Math.round(cropRect.width() * cropScale);
    final int outHeight = (int) Math.round(cropRect.height() * cropScale);

    Runnable onEndCrop =
        new Runnable() {
          public void run() {
            updateWallpaperDimensions(outWidth, outHeight);
            if (finishActivityWhenDone) {
              setResult(Activity.RESULT_OK);
              finish();
            }
          }
        };
    BitmapCropTask cropTask =
        new BitmapCropTask(
            this, uri, cropRect, cropRotation, outWidth, outHeight, true, false, onEndCrop);
    if (onBitmapCroppedHandler != null) {
      cropTask.setOnBitmapCropped(onBitmapCroppedHandler);
    }
    cropTask.execute();
  }