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();
  }