1 /* 2 * Copyright (C) 2017 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.wallpaper.asset; 17 18 import android.app.Activity; 19 import android.app.WallpaperManager; 20 import android.content.Context; 21 import android.graphics.Bitmap; 22 import android.graphics.Point; 23 import android.graphics.Rect; 24 import android.graphics.drawable.ColorDrawable; 25 import android.os.ParcelFileDescriptor; 26 import android.os.ParcelFileDescriptor.AutoCloseInputStream; 27 import android.util.Log; 28 import android.widget.ImageView; 29 30 import androidx.annotation.WorkerThread; 31 32 import com.android.wallpaper.compat.WallpaperManagerCompat; 33 import com.android.wallpaper.compat.WallpaperManagerCompat.WallpaperLocation; 34 import com.android.wallpaper.util.WallpaperCropUtils; 35 36 import com.bumptech.glide.Glide; 37 import com.bumptech.glide.load.Key; 38 import com.bumptech.glide.load.MultiTransformation; 39 import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; 40 import com.bumptech.glide.load.resource.bitmap.FitCenter; 41 import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; 42 import com.bumptech.glide.request.RequestOptions; 43 44 import java.io.InputStream; 45 import java.security.MessageDigest; 46 import java.util.concurrent.ExecutionException; 47 48 /** 49 * Asset representing the currently-set image wallpaper on N+ devices, including when daily rotation 50 * is set with a static wallpaper (but not when daily rotation uses a live wallpaper). 51 */ 52 public class CurrentWallpaperAssetVN extends StreamableAsset { 53 54 private static final String TAG = "CurrentWallpaperAssetVN"; 55 int mWallpaperId; 56 private WallpaperManager mWallpaperManager; 57 private WallpaperManagerCompat mWallpaperManagerCompat; 58 @WallpaperLocation 59 private int mWallpaperManagerFlag; 60 CurrentWallpaperAssetVN(Context context, @WallpaperLocation int wallpaperManagerFlag)61 public CurrentWallpaperAssetVN(Context context, @WallpaperLocation int wallpaperManagerFlag) { 62 mWallpaperManager = WallpaperManager.getInstance(context); 63 mWallpaperManagerCompat = WallpaperManagerCompat.getInstance(context); 64 mWallpaperManagerFlag = wallpaperManagerFlag; 65 mWallpaperId = mWallpaperManagerCompat.getWallpaperId(mWallpaperManagerFlag); 66 } 67 68 @Override openInputStream()69 protected InputStream openInputStream() { 70 ParcelFileDescriptor pfd = mWallpaperManagerCompat.getWallpaperFile(mWallpaperManagerFlag); 71 72 if (pfd == null) { 73 Log.e(TAG, "ParcelFileDescriptor for wallpaper " + mWallpaperManagerFlag + " is null, unable " 74 + "to open InputStream."); 75 return null; 76 } 77 78 return new AutoCloseInputStream(pfd); 79 } 80 81 @Override hashCode()82 public int hashCode() { 83 int result = 17; 84 result = result * 31 + mWallpaperManagerFlag; 85 result = result * 31 + mWallpaperId; 86 return result; 87 } 88 89 @Override equals(Object object)90 public boolean equals(Object object) { 91 if (object instanceof CurrentWallpaperAssetVN) { 92 CurrentWallpaperAssetVN otherAsset = (CurrentWallpaperAssetVN) object; 93 return otherAsset.mWallpaperManagerFlag == mWallpaperManagerFlag 94 && otherAsset.mWallpaperId == mWallpaperId; 95 96 } 97 return false; 98 } 99 100 101 @Override loadLowResDrawable(Activity activity, ImageView imageView, int placeholderColor, BitmapTransformation transformation)102 public void loadLowResDrawable(Activity activity, ImageView imageView, int placeholderColor, 103 BitmapTransformation transformation) { 104 MultiTransformation<Bitmap> multiTransformation = 105 new MultiTransformation<>(new FitCenter(), transformation); 106 Glide.with(activity) 107 .asDrawable() 108 .load(this) 109 .apply(RequestOptions.bitmapTransform(multiTransformation) 110 .placeholder(new ColorDrawable(placeholderColor))) 111 .into(imageView); 112 } 113 114 @Override 115 @WorkerThread getLowResBitmap(Context context)116 public Bitmap getLowResBitmap(Context context) { 117 try { 118 return Glide.with(context) 119 .asBitmap() 120 .load(this) 121 .submit() 122 .get(); 123 } catch (InterruptedException | ExecutionException e) { 124 Log.w(TAG, "Couldn't obtain low res bitmap", e); 125 } 126 return null; 127 } 128 129 @Override loadDrawable(Context context, ImageView imageView, int unusedPlaceholderColor)130 public void loadDrawable(Context context, ImageView imageView, 131 int unusedPlaceholderColor) { 132 Glide.with(context) 133 .asDrawable() 134 .load(CurrentWallpaperAssetVN.this) 135 .apply(RequestOptions.centerCropTransform()) 136 .transition(DrawableTransitionOptions.withCrossFade()) 137 .into(imageView); 138 } 139 140 @Override adjustCropRect(Context context, Point assetDimensions, Rect cropRect, boolean offsetToStart)141 protected void adjustCropRect(Context context, Point assetDimensions, Rect cropRect, 142 boolean offsetToStart) { 143 if (offsetToStart) { 144 cropRect.offsetTo(0, 0); 145 } 146 WallpaperCropUtils.adjustCurrentWallpaperCropRect(context, assetDimensions, cropRect); 147 } 148 getKey()149 public Key getKey() { 150 return new CurrentWallpaperVNKey(mWallpaperManager, mWallpaperManagerFlag); 151 } 152 getWallpaperPfd()153 ParcelFileDescriptor getWallpaperPfd() { 154 return mWallpaperManagerCompat.getWallpaperFile(mWallpaperManagerFlag); 155 } 156 157 /** 158 * Glide caching key for currently-set wallpapers on Android N or later using wallpaper IDs 159 * provided by WallpaperManager. 160 */ 161 private static final class CurrentWallpaperVNKey implements Key { 162 private WallpaperManager mWallpaperManager; 163 private int mWallpaperFlag; 164 CurrentWallpaperVNKey(WallpaperManager wallpaperManager, @WallpaperLocation int wallpaperFlag)165 public CurrentWallpaperVNKey(WallpaperManager wallpaperManager, 166 @WallpaperLocation int wallpaperFlag) { 167 mWallpaperManager = wallpaperManager; 168 mWallpaperFlag = wallpaperFlag; 169 } 170 171 @Override toString()172 public String toString() { 173 return getCacheKey(); 174 } 175 176 @Override hashCode()177 public int hashCode() { 178 return getCacheKey().hashCode(); 179 } 180 181 @Override equals(Object object)182 public boolean equals(Object object) { 183 if (object instanceof CurrentWallpaperVNKey) { 184 CurrentWallpaperVNKey otherKey = (CurrentWallpaperVNKey) object; 185 return getCacheKey().equals(otherKey.getCacheKey()); 186 187 } 188 return false; 189 } 190 191 @Override updateDiskCacheKey(MessageDigest messageDigest)192 public void updateDiskCacheKey(MessageDigest messageDigest) { 193 messageDigest.update(getCacheKey().getBytes(CHARSET)); 194 } 195 196 /** 197 * Returns an inexpensively calculated {@link String} suitable for use as a disk cache key. 198 */ getCacheKey()199 private String getCacheKey() { 200 return "CurrentWallpaperVNKey{" 201 + "flag=" + mWallpaperFlag 202 + ",id=" + mWallpaperManager.getWallpaperId(mWallpaperFlag) 203 + '}'; 204 } 205 } 206 } 207