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.model; 17 18 import android.app.Activity; 19 import android.app.WallpaperColors; 20 import android.content.Context; 21 import android.graphics.Bitmap; 22 import android.graphics.Color; 23 import android.graphics.drawable.Drawable; 24 import android.net.Uri; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 28 import androidx.annotation.DrawableRes; 29 import androidx.annotation.IntDef; 30 import androidx.annotation.StringRes; 31 32 import com.android.wallpaper.R; 33 import com.android.wallpaper.asset.Asset; 34 35 import java.util.List; 36 import java.util.concurrent.CompletableFuture; 37 import java.util.concurrent.ExecutorService; 38 import java.util.concurrent.Executors; 39 import java.util.concurrent.Future; 40 41 /** 42 * Interface for wallpaper info model. 43 */ 44 public abstract class WallpaperInfo implements Parcelable { 45 46 private static final ExecutorService sExecutor = Executors.newCachedThreadPool(); 47 48 private int mPlaceholderColor = Color.TRANSPARENT; 49 WallpaperInfo()50 public WallpaperInfo() {} 51 WallpaperInfo(Parcel in)52 protected WallpaperInfo(Parcel in) { 53 mPlaceholderColor = in.readInt(); 54 } 55 56 @Override writeToParcel(Parcel parcel, int flags)57 public void writeToParcel(Parcel parcel, int flags) { 58 parcel.writeInt(mPlaceholderColor); 59 } 60 61 @DrawableRes getDefaultActionIcon()62 public static int getDefaultActionIcon() { 63 return R.drawable.ic_explore_24px; 64 } 65 66 @StringRes getDefaultActionLabel()67 public static int getDefaultActionLabel() { 68 return R.string.explore; 69 } 70 71 public static final int BACKUP_NOT_ALLOWED = 0; 72 public static final int BACKUP_ALLOWED = 1; 73 74 /** 75 * @param context 76 * @return The title for this wallpaper, if applicable (as in a wallpaper "app" or live 77 * wallpaper), or null if not applicable. 78 */ getTitle(Context context)79 public String getTitle(Context context) { 80 return null; 81 } 82 83 /** 84 * @return The available attributions for this wallpaper, as a list of strings. These represent 85 * the author / website or any other attribution required to be displayed for this wallpaper 86 * regarding authorship, ownership, etc. 87 */ getAttributions(Context context)88 public abstract List<String> getAttributions(Context context); 89 90 /** 91 * Returns the base (remote) image URL for this wallpaper, or null if none exists. 92 */ getBaseImageUrl()93 public String getBaseImageUrl() { 94 return null; 95 } 96 97 /** 98 * Returns the action or "explore" URL for the wallpaper, or null if none exists. 99 */ getActionUrl(Context unused)100 public String getActionUrl(Context unused) { 101 return null; 102 } 103 104 /** Returns the URI corresponding to the wallpaper, or null if none exists. */ getUri()105 public Uri getUri() { 106 return null; 107 } 108 109 /** 110 * Returns the icon to use to represent the action link corresponding to 111 * {@link #getActionUrl(Context)} 112 */ 113 @DrawableRes getActionIconRes(Context context)114 public int getActionIconRes(Context context) { 115 return getDefaultActionIcon(); 116 } 117 118 /** 119 * Returns the label to use for the action link corresponding to 120 * {@link #getActionUrl(Context)} 121 */ 122 @StringRes getActionLabelRes(Context context)123 public int getActionLabelRes(Context context) { 124 return getDefaultActionLabel(); 125 } 126 127 /** 128 * @param context 129 * @return An overlay icon to be used instead of a thumbnail, if appropriate, or null if not 130 * applicable. 131 */ getOverlayIcon(Context context)132 public Drawable getOverlayIcon(Context context) { 133 return null; 134 } 135 136 ; 137 138 @Override describeContents()139 public int describeContents() { 140 return 0; 141 } 142 143 /** 144 * @param context The client application's context. 145 * @return The {@link Asset} representing the wallpaper image. 146 */ getAsset(Context context)147 public abstract Asset getAsset(Context context); 148 149 /** 150 * @param context The client application's context. 151 * @return The {@link Asset} representing the wallpaper's thumbnail. 152 */ getThumbAsset(Context context)153 public abstract Asset getThumbAsset(Context context); 154 155 /** 156 * @param context The client application's context. 157 * @return An {@link Asset} that is appropriately sized to be directly set to the desktop. By 158 * default, this just the full wallpaper image asset (#getAsset) but subclasses may provide an 159 * Asset sized exactly for the device's primary display (i.e., cropped prior to providing a 160 * bitmap or input stream). 161 */ getDesktopAsset(Context context)162 public Asset getDesktopAsset(Context context) { 163 return getAsset(context); 164 } 165 166 /** 167 * @return the {@link android.app.WallpaperInfo} associated with this wallpaper, which is 168 * generally present for live wallpapers, or null if there is none. 169 */ getWallpaperComponent()170 public android.app.WallpaperInfo getWallpaperComponent() { 171 return null; 172 } 173 174 /** 175 * Returns the ID of the collection this image is associated with, if any. 176 */ getCollectionId(Context context)177 public abstract String getCollectionId(Context context); 178 179 /** 180 * Returns the ID of this wallpaper or null if there is no ID. 181 */ getWallpaperId()182 public String getWallpaperId() { 183 return null; 184 } 185 186 /** 187 * Returns whether backup is allowed for this wallpaper. 188 */ 189 @BackupPermission getBackupPermission()190 public int getBackupPermission() { 191 return BACKUP_ALLOWED; 192 } 193 194 /** 195 * Shows the appropriate preview activity for this WallpaperInfo. 196 * 197 * @param srcActivity 198 * @param factory A factory for showing the inline preview activity for within this app. 199 * Only used for certain WallpaperInfo implementations that require an inline preview 200 * (as opposed to some external preview activity). 201 * @param requestCode Request code to pass in when starting the inline preview activity. 202 */ showPreview(Activity srcActivity, InlinePreviewIntentFactory factory, int requestCode)203 public abstract void showPreview(Activity srcActivity, InlinePreviewIntentFactory factory, 204 int requestCode); 205 206 207 /** 208 * Returns a Future to obtain a placeholder color calculated in a background thread for this 209 * wallpaper's thumbnail. 210 * If it's already available, the Future will return the color immediately. 211 * This is intended to be a "best effort" attempt and might not obtain a color if no low res 212 * thumbnail is available. 213 */ computePlaceholderColor(Context context)214 public Future<Integer> computePlaceholderColor(Context context) { 215 if (mPlaceholderColor != Color.TRANSPARENT) { 216 return CompletableFuture.completedFuture(mPlaceholderColor); 217 } 218 final Context appContext = context.getApplicationContext(); 219 return sExecutor.submit(() -> { 220 synchronized (WallpaperInfo.this) { 221 if (mPlaceholderColor != Color.TRANSPARENT) { 222 return mPlaceholderColor; 223 } 224 Asset thumbAsset = getThumbAsset(appContext); 225 Bitmap lowResBitmap = thumbAsset.getLowResBitmap(appContext); 226 if (lowResBitmap == null) { 227 return Color.TRANSPARENT; 228 } 229 mPlaceholderColor = WallpaperColors.fromBitmap( 230 lowResBitmap).getPrimaryColor().toArgb(); 231 return mPlaceholderColor; 232 } 233 }); 234 } 235 236 /** 237 * Whether backup is allowed for this type of wallpaper. 238 */ 239 @IntDef({ 240 BACKUP_NOT_ALLOWED, 241 BACKUP_ALLOWED 242 }) 243 public @interface BackupPermission { 244 } 245 } 246