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