1 /* 2 * Copyright (C) 2020 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.content.Context; 20 import android.content.pm.PackageManager; 21 import android.content.res.Resources; 22 import android.os.Parcel; 23 import android.text.TextUtils; 24 import android.util.AttributeSet; 25 import android.util.Log; 26 27 import androidx.annotation.Nullable; 28 29 import com.android.wallpaper.asset.Asset; 30 import com.android.wallpaper.asset.ResourceAsset; 31 import com.android.wallpaper.asset.SystemStaticAsset; 32 33 import java.util.ArrayList; 34 import java.util.List; 35 36 /** 37 * Represents a wallpaper coming from the resources of the partner static wallpaper 38 * container APK. 39 */ 40 public class SystemStaticWallpaperInfo extends WallpaperInfo { 41 public static final Creator<SystemStaticWallpaperInfo> CREATOR = 42 new Creator<SystemStaticWallpaperInfo>() { 43 @Override 44 public SystemStaticWallpaperInfo createFromParcel(Parcel in) { 45 return new SystemStaticWallpaperInfo(in); 46 } 47 48 @Override 49 public SystemStaticWallpaperInfo[] newArray(int size) { 50 return new SystemStaticWallpaperInfo[size]; 51 } 52 }; 53 public static final String TAG_NAME = "static-wallpaper"; 54 55 private static final String TAG = "PartnerStaticWPInfo"; 56 private static final String DRAWABLE_DEF_TYPE = "drawable"; 57 private static final String STRING_DEF_TYPE = "string"; 58 private static final String INTEGER_DEF_TYPE = "integer"; 59 private static final String ARRAY_DEF_TYPE = "array"; 60 private static final String WALLPAPERS_RES_SUFFIX = "_wallpapers"; 61 private static final String TITLE_RES_SUFFIX = "_title"; 62 private static final String SUBTITLE1_RES_SUFFIX = "_subtitle1"; 63 private static final String SUBTITLE2_RES_SUFFIX = "_subtitle2"; 64 private static final String ACTION_TYPE_RES_SUFFIX = "_action_type"; 65 private static final String ACTION_URL_RES_SUFFIX = "_action_url"; 66 private static final String THUMBNAIL_RES_SUFFIX = "_thumbnail"; 67 68 // Xml parsing attribute names 69 public static final String ATTR_ID = "id"; 70 public static final String ATTR_SRC = "src"; 71 public static final String ATTR_TITLE_RES = "title"; 72 public static final String ATTR_SUBTITLE1_RES = "subtitle1"; 73 public static final String ATTR_SUBTITLE2_RES = "subtitle2"; 74 public static final String ATTR_ACTION_URL_RES = "actionUrl"; 75 public static final String ATTR_THUMBNAIL = "thumbnail"; 76 77 private final int mDrawableResId; 78 private final String mWallpaperId; 79 private final String mCollectionId; 80 private final int mTitleResId; 81 private final int mSubtitle1ResId; 82 private final int mSubtitle2ResId; 83 private final int mActionTypeResId; 84 private final int mActionUrlResId; 85 private ResourceAsset mAsset; 86 private Resources mResources; 87 private final String mPackageName; 88 private List<String> mAttributions; 89 private String mActionUrl; 90 private int mActionType; 91 private final int mThumbnailResId; 92 private ResourceAsset mThumbnailAsset; 93 94 /** 95 * Create and return a new {@link SystemStaticWallpaperInfo} from the information in the given 96 * XML's {@link AttributeSet} 97 * @param packageName name of the package where the resources are read from 98 * @param categoryId id of the category the new wallpaper will belong to 99 * @param attrs {@link AttributeSet} from the XML with the information for the new wallpaper 100 * info 101 * @return a new {@link SystemStaticWallpaperInfo} or {@code null} if no id could be found in 102 * the given {@link AttributeSet} 103 */ 104 @Nullable fromAttributeSet(String packageName, String categoryId, AttributeSet attrs)105 public static SystemStaticWallpaperInfo fromAttributeSet(String packageName, 106 String categoryId, AttributeSet attrs) { 107 String wallpaperId = attrs.getAttributeValue(null, ATTR_ID); 108 if (TextUtils.isEmpty(wallpaperId)) { 109 return null; 110 } 111 int drawableResId = attrs.getAttributeResourceValue(null, ATTR_SRC, 0); 112 int wallpaperTitleResId = attrs.getAttributeResourceValue(null, ATTR_TITLE_RES, 0); 113 int wallpaperSubtitle1ResId = attrs.getAttributeResourceValue(null, ATTR_SUBTITLE1_RES, 0); 114 int wallpaperSubtitle2ResId = attrs.getAttributeResourceValue(null, ATTR_SUBTITLE2_RES, 0); 115 int actionUrlResId = attrs.getAttributeResourceValue(null, ATTR_ACTION_URL_RES, 0); 116 int thumbnailResId = attrs.getAttributeResourceValue(null, ATTR_THUMBNAIL, 0); 117 118 return new SystemStaticWallpaperInfo(packageName, wallpaperId, 119 categoryId, drawableResId, wallpaperTitleResId, wallpaperSubtitle1ResId, 120 wallpaperSubtitle2ResId, 0, actionUrlResId, thumbnailResId); 121 } 122 123 /** 124 * Read from the given stub apk the available static categories and wallpapers 125 * @deprecated this is left for backwards compatibility with legacy stub format, 126 * use {@link #fromAttributeSet(String, String, AttributeSet)} instead for 127 * the new stub format. 128 */ 129 @Deprecated getAll(String partnerStubPackageName, Resources stubApkResources, String categoryId)130 public static List<WallpaperInfo> getAll(String partnerStubPackageName, 131 Resources stubApkResources, String categoryId) { 132 ArrayList<WallpaperInfo> wallpapers = new ArrayList<>(); 133 134 int listResId = stubApkResources.getIdentifier(categoryId + WALLPAPERS_RES_SUFFIX, 135 ARRAY_DEF_TYPE, partnerStubPackageName); 136 String[] wallpaperResNames = stubApkResources.getStringArray(listResId); 137 138 for (String wallpaperResName : wallpaperResNames) { 139 int drawableResId = stubApkResources.getIdentifier(wallpaperResName, DRAWABLE_DEF_TYPE, 140 partnerStubPackageName); 141 int wallpaperTitleResId = stubApkResources.getIdentifier( 142 wallpaperResName + TITLE_RES_SUFFIX, STRING_DEF_TYPE, partnerStubPackageName); 143 int wallpaperSubtitle1ResId = stubApkResources.getIdentifier( 144 wallpaperResName + SUBTITLE1_RES_SUFFIX, STRING_DEF_TYPE, 145 partnerStubPackageName); 146 int wallpaperSubtitle2ResId = stubApkResources.getIdentifier( 147 wallpaperResName + SUBTITLE2_RES_SUFFIX, STRING_DEF_TYPE, 148 partnerStubPackageName); 149 int actionTypeResId = stubApkResources.getIdentifier( 150 wallpaperResName + ACTION_TYPE_RES_SUFFIX, INTEGER_DEF_TYPE, 151 partnerStubPackageName); 152 int actionUrlResId = stubApkResources.getIdentifier( 153 wallpaperResName + ACTION_URL_RES_SUFFIX, STRING_DEF_TYPE, 154 partnerStubPackageName); 155 int thumbnailResId = stubApkResources.getIdentifier( 156 wallpaperResName + THUMBNAIL_RES_SUFFIX, STRING_DEF_TYPE, 157 partnerStubPackageName); 158 159 SystemStaticWallpaperInfo wallpaperInfo = new SystemStaticWallpaperInfo( 160 partnerStubPackageName, wallpaperResName, categoryId, 161 drawableResId, wallpaperTitleResId, wallpaperSubtitle1ResId, 162 wallpaperSubtitle2ResId, actionTypeResId, actionUrlResId, thumbnailResId); 163 wallpapers.add(wallpaperInfo); 164 } 165 166 return wallpapers; 167 } 168 169 /** 170 * Constructs a new Nexus static wallpaper model object. 171 * 172 * @param resName The unique name of the wallpaper resource, e.g. "z_wp001". 173 * @param collectionId Unique name of the collection this wallpaper belongs in; 174 * used for logging. 175 * @param drawableResId Resource ID of the raw wallpaper image. 176 * @param titleResId Resource ID of the string for the title attribution. 177 * @param subtitle1ResId Resource ID of the string for the first subtitle attribution. 178 * @param subtitle2ResId Resource ID of the string for the second subtitle attribution. 179 * @param thumbnailResId Resource ID of the thumbnail image. 180 */ SystemStaticWallpaperInfo(String packageName, String resName, String collectionId, int drawableResId, int titleResId, int subtitle1ResId, int subtitle2ResId, int actionTypeResId, int actionUrlResId, int thumbnailResId)181 public SystemStaticWallpaperInfo(String packageName, String resName, String collectionId, 182 int drawableResId, int titleResId, int subtitle1ResId, int subtitle2ResId, 183 int actionTypeResId, int actionUrlResId, int thumbnailResId) { 184 mPackageName = packageName; 185 mWallpaperId = resName; 186 mCollectionId = collectionId; 187 mDrawableResId = drawableResId; 188 mTitleResId = titleResId; 189 mSubtitle1ResId = subtitle1ResId; 190 mSubtitle2ResId = subtitle2ResId; 191 mActionTypeResId = actionTypeResId; 192 mActionUrlResId = actionUrlResId; 193 mThumbnailResId = thumbnailResId; 194 } 195 SystemStaticWallpaperInfo(Parcel in)196 private SystemStaticWallpaperInfo(Parcel in) { 197 super(in); 198 mPackageName = in.readString(); 199 mWallpaperId = in.readString(); 200 mCollectionId = in.readString(); 201 mDrawableResId = in.readInt(); 202 mTitleResId = in.readInt(); 203 mSubtitle1ResId = in.readInt(); 204 mSubtitle2ResId = in.readInt(); 205 mActionTypeResId = in.readInt(); 206 mActionUrlResId = in.readInt(); 207 mThumbnailResId = in.readInt(); 208 } 209 210 @Override getAsset(Context context)211 public Asset getAsset(Context context) { 212 if (mAsset == null) { 213 Resources res = getPackageResources(context); 214 mAsset = new SystemStaticAsset(res, mDrawableResId, mWallpaperId, false); 215 } 216 217 return mAsset; 218 } 219 220 @Override getThumbAsset(Context context)221 public Asset getThumbAsset(Context context) { 222 if (mThumbnailResId != 0) { 223 if (mThumbnailAsset == null) { 224 Resources res = getPackageResources(context); 225 mThumbnailAsset = new SystemStaticAsset(res, mThumbnailResId, mWallpaperId, true); 226 } 227 return mThumbnailAsset; 228 } 229 return getAsset(context); 230 } 231 232 @Override getAttributions(Context context)233 public List<String> getAttributions(Context context) { 234 if (mAttributions == null) { 235 Resources res = getPackageResources(context); 236 mAttributions = new ArrayList<>(); 237 if (mTitleResId != 0) { 238 mAttributions.add(res.getString(mTitleResId)); 239 } 240 if (mSubtitle1ResId != 0) { 241 mAttributions.add(res.getString(mSubtitle1ResId)); 242 } 243 if (mSubtitle2ResId != 0) { 244 mAttributions.add(res.getString(mSubtitle2ResId)); 245 } 246 } 247 248 return mAttributions; 249 } 250 251 @Override getActionUrl(Context context)252 public String getActionUrl(Context context) { 253 if (mActionUrl == null && mActionUrlResId != 0) { 254 mActionUrl = getPackageResources(context).getString(mActionUrlResId); 255 } 256 return mActionUrl; 257 } 258 259 @Override showPreview(Activity srcActivity, InlinePreviewIntentFactory factory, int requestCode, boolean isAssetIdPresent)260 public void showPreview(Activity srcActivity, InlinePreviewIntentFactory factory, 261 int requestCode, boolean isAssetIdPresent) { 262 srcActivity.startActivityForResult(factory.newIntent(srcActivity, this, 263 isAssetIdPresent), requestCode); 264 } 265 266 @Override getCollectionId(Context unused)267 public String getCollectionId(Context unused) { 268 return mCollectionId; 269 } 270 271 @Override getWallpaperId()272 public String getWallpaperId() { 273 return mWallpaperId; 274 } 275 getResName()276 public String getResName() { 277 return mWallpaperId; 278 } 279 getActionType(Context context)280 private int getActionType(Context context) { 281 if (mActionType == 0 && mActionTypeResId != 0) { 282 mActionType = getPackageResources(context).getInteger(mActionTypeResId); 283 } 284 return mActionType; 285 } 286 287 /** 288 * Returns the {@link Resources} instance for the Nexus static wallpapers stub APK. 289 */ getPackageResources(Context context)290 private Resources getPackageResources(Context context) { 291 if (mResources != null) { 292 return mResources; 293 } 294 295 try { 296 mResources = context.getPackageManager().getResourcesForApplication(mPackageName); 297 } catch (PackageManager.NameNotFoundException e) { 298 Log.e(TAG, "Could not get app resources"); 299 } 300 return mResources; 301 } 302 303 @Override writeToParcel(Parcel dest, int flags)304 public void writeToParcel(Parcel dest, int flags) { 305 super.writeToParcel(dest, flags); 306 dest.writeString(mPackageName); 307 dest.writeString(mWallpaperId); 308 dest.writeString(mCollectionId); 309 dest.writeInt(mDrawableResId); 310 dest.writeInt(mTitleResId); 311 dest.writeInt(mSubtitle1ResId); 312 dest.writeInt(mSubtitle2ResId); 313 dest.writeInt(mActionTypeResId); 314 dest.writeInt(mActionUrlResId); 315 dest.writeInt(mThumbnailResId); 316 } 317 } 318