package com.android.wallpaperpicker.tileinfo; import android.annotation.TargetApi; import android.app.Activity; import android.app.WallpaperManager; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Point; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Build; import android.util.Log; import com.android.wallpaperpicker.WallpaperCropActivity.CropViewScaleAndOffsetProvider; import com.android.wallpaperpicker.WallpaperFiles; import com.android.wallpaperpicker.WallpaperPickerActivity; import com.android.wallpaperpicker.common.CropAndSetWallpaperTask; import com.android.wallpaperpicker.common.DialogUtils; import com.android.wallpaperpicker.common.InputStreamProvider; import com.android.wallpaperpicker.common.WallpaperManagerCompat; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class DefaultWallpaperInfo extends DrawableThumbWallpaperInfo { private static final String TAG = "DefaultWallpaperInfo"; public DefaultWallpaperInfo(Drawable thumb) { super(thumb); } @Override public void onClick(WallpaperPickerActivity a) { a.setCropViewTileSource(null, false, false, new CropViewScaleAndOffsetProvider() { @Override public float getScale(Point wallpaperSize, RectF crop) { return 1f; } @Override public float getParallaxOffset() { return 0.5f; } }, null); } @Override public void onSave(final WallpaperPickerActivity a) { CropAndSetWallpaperTask.OnEndCropHandler onEndCropHandler = new CropAndSetWallpaperTask.OnEndCropHandler() { @Override public void run(boolean cropSucceeded) { if (cropSucceeded) { a.setResult(Activity.RESULT_OK); } a.finish(); } }; CropAndSetWallpaperTask setWallpaperTask = new CropAndSetWallpaperTask( null, a, null, -1, -1, -1, onEndCropHandler) { @Override protected Boolean doInBackground(Integer... params) { int whichWallpaper = params[0]; boolean succeeded; if (whichWallpaper == WallpaperManagerCompat.FLAG_SET_LOCK) { succeeded = setDefaultOnLock(a); } else { succeeded = clearWallpaper(a, whichWallpaper); } return succeeded; } }; DialogUtils.executeCropTaskAfterPrompt(a, setWallpaperTask, a.getOnDialogCancelListener()); } //TODO: @TargetApi(Build.VERSION_CODES.N) private boolean setDefaultOnLock(WallpaperPickerActivity a) { boolean succeeded = true; try { Bitmap defaultWallpaper = ((BitmapDrawable) WallpaperManager.getInstance( a.getApplicationContext()).getBuiltInDrawable()).getBitmap(); ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048); if (defaultWallpaper.compress(Bitmap.CompressFormat.PNG, 100, tmpOut)) { byte[] outByteArray = tmpOut.toByteArray(); WallpaperManagerCompat.getInstance(a.getApplicationContext()) .setStream(new ByteArrayInputStream(outByteArray), null, true, WallpaperManagerCompat.FLAG_SET_LOCK); } } catch (IOException e) { Log.w(TAG, "Setting wallpaper to default threw exception", e); succeeded = false; } return succeeded; } private boolean clearWallpaper(WallpaperPickerActivity a, int whichWallpaper) { boolean succeeded = true; try { WallpaperManagerCompat.getInstance(a.getApplicationContext()).clear(whichWallpaper); } catch (IOException e) { Log.w(TAG, "Setting wallpaper to default threw exception", e); succeeded = false; } catch (SecurityException e) { // Happens on Samsung S6, for instance: // "Permission denial: writing to settings requires android.permission.WRITE_SETTINGS" Log.w(TAG, "Setting wallpaper to default threw exception", e); // In this case, clearing worked even though the exception was thrown afterwards. succeeded = true; } return succeeded; } @Override public boolean isSelectable() { return true; } @Override public boolean isNamelessWallpaper() { return true; } /** * @return the system default wallpaper tile or null */ public static WallpaperTileInfo get(Context context) { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? getDefaultWallpaper(context) : getPreKKDefaultWallpaperInfo(context); } @TargetApi(Build.VERSION_CODES.KITKAT) private static DefaultWallpaperInfo getDefaultWallpaper(Context context) { File defaultThumbFile = getDefaultThumbFile(context); Bitmap thumb = null; boolean defaultWallpaperExists = false; Resources res = context.getResources(); if (defaultThumbFile.exists()) { thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath()); defaultWallpaperExists = true; } else { Point defaultThumbSize = getDefaultThumbSize(res); Drawable wallpaperDrawable = WallpaperManager.getInstance(context).getBuiltInDrawable( defaultThumbSize.x, defaultThumbSize.y, true, 0.5f, 0.5f); if (wallpaperDrawable != null) { thumb = Bitmap.createBitmap( defaultThumbSize.x, defaultThumbSize.y, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(thumb); wallpaperDrawable.setBounds(0, 0, defaultThumbSize.x, defaultThumbSize.y); wallpaperDrawable.draw(c); c.setBitmap(null); } if (thumb != null) { defaultWallpaperExists = saveDefaultWallpaperThumb(context, thumb); } } if (defaultWallpaperExists) { return new DefaultWallpaperInfo(new BitmapDrawable(res, thumb)); } return null; } private static ResourceWallpaperInfo getPreKKDefaultWallpaperInfo(Context context) { Resources sysRes = Resources.getSystem(); Resources res = context.getResources(); int resId = sysRes.getIdentifier("default_wallpaper", "drawable", "android"); File defaultThumbFile = getDefaultThumbFile(context); Bitmap thumb = null; boolean defaultWallpaperExists = false; if (defaultThumbFile.exists()) { thumb = BitmapFactory.decodeFile(defaultThumbFile.getAbsolutePath()); defaultWallpaperExists = true; } else { InputStreamProvider streamProvider = InputStreamProvider.fromResource(res, resId); thumb = createThumbnail( streamProvider, context, streamProvider.getRotationFromExif(context), false); if (thumb != null) { defaultWallpaperExists = saveDefaultWallpaperThumb(context, thumb); } } if (defaultWallpaperExists) { return new ResourceWallpaperInfo(sysRes, resId, new BitmapDrawable(res, thumb)); } return null; } private static File getDefaultThumbFile(Context context) { return new File(context.getFilesDir(), Build.VERSION.SDK_INT + "_" + WallpaperFiles.DEFAULT_WALLPAPER_THUMBNAIL); } private static boolean saveDefaultWallpaperThumb(Context c, Bitmap b) { // Delete old thumbnails. new File(c.getFilesDir(), WallpaperFiles.DEFAULT_WALLPAPER_THUMBNAIL_OLD).delete(); new File(c.getFilesDir(), WallpaperFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete(); for (int i = Build.VERSION_CODES.JELLY_BEAN; i < Build.VERSION.SDK_INT; i++) { new File(c.getFilesDir(), i + "_" + WallpaperFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete(); } File f = getDefaultThumbFile(c); try { f.createNewFile(); FileOutputStream thumbFileStream = c.openFileOutput(f.getName(), Context.MODE_PRIVATE); b.compress(Bitmap.CompressFormat.JPEG, 95, thumbFileStream); thumbFileStream.close(); return true; } catch (IOException e) { Log.e(TAG, "Error while writing bitmap to file " + e); f.delete(); return false; } } }