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