1 /**
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.wallpaperpicker.common;
17 
18 import android.content.Context;
19 import android.graphics.Bitmap;
20 import android.graphics.Bitmap.CompressFormat;
21 import android.graphics.RectF;
22 import android.os.AsyncTask;
23 import android.util.Log;
24 import android.widget.Toast;
25 
26 import com.android.wallpaperpicker.R;
27 
28 import java.io.ByteArrayInputStream;
29 import java.io.ByteArrayOutputStream;
30 import java.io.IOException;
31 
32 public class CropAndSetWallpaperTask extends AsyncTask<Integer, Void, Boolean> {
33 
34     public interface OnBitmapCroppedHandler {
onBitmapCropped(byte[] imageBytes)35         void onBitmapCropped(byte[] imageBytes);
36     }
37 
38     public interface OnEndCropHandler {
run(boolean cropSucceeded)39         void run(boolean cropSucceeded);
40     }
41 
42     private static final int DEFAULT_COMPRESS_QUALITY = 90;
43     private static final String TAG = "CropAndSetWallpaperTask";
44 
45     private final InputStreamProvider mStreamProvider;
46     private final Context mContext;
47 
48     private final RectF mCropBounds;
49     private int mOutWidth, mOutHeight;
50     private int mRotation;
51     private CropAndSetWallpaperTask.OnEndCropHandler mOnEndCropHandler;
52     private CropAndSetWallpaperTask.OnBitmapCroppedHandler mOnBitmapCroppedHandler;
53 
CropAndSetWallpaperTask(InputStreamProvider streamProvider, Context context, RectF cropBounds, int rotation, int outWidth, int outHeight, OnEndCropHandler onEndCropHandler)54     public CropAndSetWallpaperTask(InputStreamProvider streamProvider, Context context,
55                                    RectF cropBounds, int rotation, int outWidth, int outHeight,
56                                    OnEndCropHandler onEndCropHandler) {
57         mStreamProvider = streamProvider;
58         mContext = context;
59 
60         mCropBounds = cropBounds;
61         mRotation = rotation;
62         mOutWidth = outWidth;
63         mOutHeight = outHeight;
64         mOnEndCropHandler = onEndCropHandler;
65     }
66 
setOnBitmapCropped(CropAndSetWallpaperTask.OnBitmapCroppedHandler handler)67     public void setOnBitmapCropped(CropAndSetWallpaperTask.OnBitmapCroppedHandler handler) {
68         mOnBitmapCroppedHandler = handler;
69     }
70 
cropBitmap(int whichWallpaper)71     public boolean cropBitmap(int whichWallpaper) {
72         Bitmap crop = mStreamProvider.readCroppedBitmap(
73                 mCropBounds, mOutWidth, mOutHeight, mRotation);
74         if (crop == null) {
75             return false;
76         }
77 
78         boolean failure = false;
79         // Compress to byte array
80         ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
81         if (crop.compress(CompressFormat.JPEG, DEFAULT_COMPRESS_QUALITY, tmpOut)) {
82             // Set the wallpaper
83             try {
84                 byte[] outByteArray = tmpOut.toByteArray();
85                 WallpaperManagerCompat.getInstance(mContext).setStream(
86                         new ByteArrayInputStream(outByteArray),
87                         null, true, whichWallpaper);
88                 if (mOnBitmapCroppedHandler != null) {
89                     mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
90                 }
91             } catch (IOException e) {
92                 Log.w(TAG, "cannot write stream to wallpaper", e);
93                 failure = true;
94             }
95         } else {
96             Log.w(TAG, "cannot compress bitmap");
97             failure = true;
98         }
99         return !failure; // True if any of the operations failed
100     }
101 
102     @Override
doInBackground(Integer... whichWallpaper)103     protected Boolean doInBackground(Integer... whichWallpaper) {
104         return cropBitmap(whichWallpaper[0]);
105     }
106 
107     @Override
onPostExecute(Boolean cropSucceeded)108     protected void onPostExecute(Boolean cropSucceeded) {
109         if (!cropSucceeded) {
110             Toast.makeText(mContext, R.string.wallpaper_set_fail, Toast.LENGTH_SHORT).show();
111         }
112         if (mOnEndCropHandler != null) {
113             mOnEndCropHandler.run(cropSucceeded);
114         }
115     }
116 }