1 package com.android.wallpaperpicker.tileinfo; 2 3 import android.annotation.TargetApi; 4 import android.app.Activity; 5 import android.app.WallpaperManager; 6 import android.content.Context; 7 import android.content.res.Resources; 8 import android.graphics.Bitmap; 9 import android.graphics.BitmapFactory; 10 import android.graphics.Canvas; 11 import android.graphics.Point; 12 import android.graphics.RectF; 13 import android.graphics.drawable.BitmapDrawable; 14 import android.graphics.drawable.Drawable; 15 import android.os.Build; 16 import android.util.Log; 17 18 import com.android.wallpaperpicker.WallpaperCropActivity.CropViewScaleAndOffsetProvider; 19 import com.android.wallpaperpicker.WallpaperFiles; 20 import com.android.wallpaperpicker.WallpaperPickerActivity; 21 import com.android.wallpaperpicker.common.CropAndSetWallpaperTask; 22 import com.android.wallpaperpicker.common.DialogUtils; 23 import com.android.wallpaperpicker.common.InputStreamProvider; 24 import com.android.wallpaperpicker.common.WallpaperManagerCompat; 25 26 import java.io.ByteArrayInputStream; 27 import java.io.ByteArrayOutputStream; 28 import java.io.File; 29 import java.io.FileOutputStream; 30 import java.io.IOException; 31 32 public class DefaultWallpaperInfo extends DrawableThumbWallpaperInfo { 33 34 private static final String TAG = "DefaultWallpaperInfo"; 35 DefaultWallpaperInfo(Drawable thumb)36 public DefaultWallpaperInfo(Drawable thumb) { 37 super(thumb); 38 } 39 40 @Override onClick(WallpaperPickerActivity a)41 public void onClick(WallpaperPickerActivity a) { 42 a.setCropViewTileSource(null, false, false, new CropViewScaleAndOffsetProvider() { 43 44 @Override 45 public float getScale(Point wallpaperSize, RectF crop) { 46 return 1f; 47 } 48 49 @Override 50 public float getParallaxOffset() { 51 return 0.5f; 52 } 53 }, null); 54 } 55 56 @Override onSave(final WallpaperPickerActivity a)57 public void onSave(final WallpaperPickerActivity a) { 58 CropAndSetWallpaperTask.OnEndCropHandler onEndCropHandler 59 = new CropAndSetWallpaperTask.OnEndCropHandler() { 60 @Override 61 public void run(boolean cropSucceeded) { 62 if (cropSucceeded) { 63 a.setResult(Activity.RESULT_OK); 64 } 65 a.finish(); 66 } 67 }; 68 CropAndSetWallpaperTask setWallpaperTask = new CropAndSetWallpaperTask( 69 null, a, null, -1, -1, -1, onEndCropHandler) { 70 @Override 71 protected Boolean doInBackground(Integer... params) { 72 int whichWallpaper = params[0]; 73 boolean succeeded; 74 if (whichWallpaper == WallpaperManagerCompat.FLAG_SET_LOCK) { 75 succeeded = setDefaultOnLock(a); 76 } else { 77 succeeded = clearWallpaper(a, whichWallpaper); 78 } 79 return succeeded; 80 } 81 }; 82 83 DialogUtils.executeCropTaskAfterPrompt(a, setWallpaperTask, a.getOnDialogCancelListener()); 84 } 85 86 //TODO: @TargetApi(Build.VERSION_CODES.N) setDefaultOnLock(WallpaperPickerActivity a)87 private boolean setDefaultOnLock(WallpaperPickerActivity a) { 88 boolean succeeded = true; 89 try { 90 Bitmap defaultWallpaper = ((BitmapDrawable) WallpaperManager.getInstance( 91 a.getApplicationContext()).getBuiltInDrawable()).getBitmap(); 92 ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048); 93 if (defaultWallpaper.compress(Bitmap.CompressFormat.PNG, 100, tmpOut)) { 94 byte[] outByteArray = tmpOut.toByteArray(); 95 WallpaperManagerCompat.getInstance(a.getApplicationContext()) 96 .setStream(new ByteArrayInputStream(outByteArray), null, 97 true, WallpaperManagerCompat.FLAG_SET_LOCK); 98 } 99 } catch (IOException e) { 100 Log.w(TAG, "Setting wallpaper to default threw exception", e); 101 succeeded = false; 102 } 103 return succeeded; 104 } 105 clearWallpaper(WallpaperPickerActivity a, int whichWallpaper)106 private boolean clearWallpaper(WallpaperPickerActivity a, int whichWallpaper) { 107 boolean succeeded = true; 108 try { 109 WallpaperManagerCompat.getInstance(a.getApplicationContext()).clear(whichWallpaper); 110 } catch (IOException e) { 111 Log.w(TAG, "Setting wallpaper to default threw exception", e); 112 succeeded = false; 113 } catch (SecurityException e) { 114 // Happens on Samsung S6, for instance: 115 // "Permission denial: writing to settings requires android.permission.WRITE_SETTINGS" 116 Log.w(TAG, "Setting wallpaper to default threw exception", e); 117 // In this case, clearing worked even though the exception was thrown afterwards. 118 succeeded = true; 119 } 120 return succeeded; 121 } 122 123 @Override isSelectable()124 public boolean isSelectable() { 125 return true; 126 } 127 128 @Override isNamelessWallpaper()129 public boolean isNamelessWallpaper() { 130 return true; 131 } 132 133 /** 134 * @return the system default wallpaper tile or null 135 */ get(Context context)136 public static WallpaperTileInfo get(Context context) { 137 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT 138 ? getDefaultWallpaper(context) : getPreKKDefaultWallpaperInfo(context); 139 } 140 141 @TargetApi(Build.VERSION_CODES.KITKAT) getDefaultWallpaper(Context context)142 private static DefaultWallpaperInfo getDefaultWallpaper(Context context) { 143 File defaultThumbFile = getDefaultThumbFile(context); 144 Bitmap thumb = null; 145 boolean defaultWallpaperExists = false; 146 Resources res = context.getResources(); 147 148 if (defaultThumbFile.exists()) { 149 thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath()); 150 defaultWallpaperExists = true; 151 } else { 152 Point defaultThumbSize = getDefaultThumbSize(res); 153 Drawable wallpaperDrawable = WallpaperManager.getInstance(context).getBuiltInDrawable( 154 defaultThumbSize.x, defaultThumbSize.y, true, 0.5f, 0.5f); 155 if (wallpaperDrawable != null) { 156 thumb = Bitmap.createBitmap( 157 defaultThumbSize.x, defaultThumbSize.y, Bitmap.Config.ARGB_8888); 158 Canvas c = new Canvas(thumb); 159 wallpaperDrawable.setBounds(0, 0, defaultThumbSize.x, defaultThumbSize.y); 160 wallpaperDrawable.draw(c); 161 c.setBitmap(null); 162 } 163 if (thumb != null) { 164 defaultWallpaperExists = saveDefaultWallpaperThumb(context, thumb); 165 } 166 } 167 if (defaultWallpaperExists) { 168 return new DefaultWallpaperInfo(new BitmapDrawable(res, thumb)); 169 } 170 return null; 171 } 172 getPreKKDefaultWallpaperInfo(Context context)173 private static ResourceWallpaperInfo getPreKKDefaultWallpaperInfo(Context context) { 174 Resources sysRes = Resources.getSystem(); 175 Resources res = context.getResources(); 176 177 int resId = sysRes.getIdentifier("default_wallpaper", "drawable", "android"); 178 179 File defaultThumbFile = getDefaultThumbFile(context); 180 Bitmap thumb = null; 181 boolean defaultWallpaperExists = false; 182 if (defaultThumbFile.exists()) { 183 thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath()); 184 defaultWallpaperExists = true; 185 } else { 186 InputStreamProvider streamProvider = InputStreamProvider.fromResource(res, resId); 187 thumb = createThumbnail( 188 streamProvider, context, streamProvider.getRotationFromExif(context), false); 189 if (thumb != null) { 190 defaultWallpaperExists = saveDefaultWallpaperThumb(context, thumb); 191 } 192 } 193 if (defaultWallpaperExists) { 194 return new ResourceWallpaperInfo(sysRes, resId, new BitmapDrawable(res, thumb)); 195 } 196 return null; 197 } 198 getDefaultThumbFile(Context context)199 private static File getDefaultThumbFile(Context context) { 200 return new File(context.getFilesDir(), Build.VERSION.SDK_INT 201 + "_" + WallpaperFiles.DEFAULT_WALLPAPER_THUMBNAIL); 202 } 203 saveDefaultWallpaperThumb(Context c, Bitmap b)204 private static boolean saveDefaultWallpaperThumb(Context c, Bitmap b) { 205 // Delete old thumbnails. 206 new File(c.getFilesDir(), WallpaperFiles.DEFAULT_WALLPAPER_THUMBNAIL_OLD).delete(); 207 new File(c.getFilesDir(), WallpaperFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete(); 208 209 for (int i = Build.VERSION_CODES.JELLY_BEAN; i < Build.VERSION.SDK_INT; i++) { 210 new File(c.getFilesDir(), i + "_" + WallpaperFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete(); 211 } 212 File f = getDefaultThumbFile(c); 213 try { 214 f.createNewFile(); 215 FileOutputStream thumbFileStream = c.openFileOutput(f.getName(), Context.MODE_PRIVATE); 216 b.compress(Bitmap.CompressFormat.JPEG, 95, thumbFileStream); 217 thumbFileStream.close(); 218 return true; 219 } catch (IOException e) { 220 Log.e(TAG, "Error while writing bitmap to file " + e); 221 f.delete(); 222 return false; 223 } 224 } 225 }