1/* 2 * Copyright (C) 2009 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 17package android.app; 18 19import org.xmlpull.v1.XmlPullParser; 20import org.xmlpull.v1.XmlPullParserException; 21 22import android.content.ComponentName; 23import android.content.Context; 24import android.content.pm.ApplicationInfo; 25import android.content.pm.PackageManager; 26import android.content.pm.ResolveInfo; 27import android.content.pm.ServiceInfo; 28import android.content.pm.PackageManager.NameNotFoundException; 29import android.content.res.Resources.NotFoundException; 30import android.content.res.Resources; 31import android.content.res.TypedArray; 32import android.content.res.XmlResourceParser; 33import android.graphics.drawable.Drawable; 34import android.net.Uri; 35import android.os.Parcel; 36import android.os.Parcelable; 37import android.service.wallpaper.WallpaperService; 38import android.util.AttributeSet; 39import android.util.Printer; 40import android.util.Xml; 41 42import java.io.IOException; 43 44/** 45 * This class is used to specify meta information of a wallpaper service. 46 */ 47public final class WallpaperInfo implements Parcelable { 48 static final String TAG = "WallpaperInfo"; 49 50 /** 51 * The Service that implements this wallpaper component. 52 */ 53 final ResolveInfo mService; 54 55 /** 56 * The wallpaper setting activity's name, to 57 * launch the setting activity of this wallpaper. 58 */ 59 final String mSettingsActivityName; 60 61 /** 62 * Resource identifier for this wallpaper's thumbnail image. 63 */ 64 final int mThumbnailResource; 65 66 /** 67 * Resource identifier for a string indicating the author of the wallpaper. 68 */ 69 final int mAuthorResource; 70 71 /** 72 * Resource identifier for a string containing a short description of the wallpaper. 73 */ 74 final int mDescriptionResource; 75 76 final int mContextUriResource; 77 final int mContextDescriptionResource; 78 final boolean mShowMetadataInPreview; 79 80 /** 81 * Constructor. 82 * 83 * @param context The Context in which we are parsing the wallpaper. 84 * @param service The ResolveInfo returned from the package manager about 85 * this wallpaper's component. 86 */ 87 public WallpaperInfo(Context context, ResolveInfo service) 88 throws XmlPullParserException, IOException { 89 mService = service; 90 ServiceInfo si = service.serviceInfo; 91 92 PackageManager pm = context.getPackageManager(); 93 String settingsActivityComponent = null; 94 int thumbnailRes = -1; 95 int authorRes = -1; 96 int descriptionRes = -1; 97 int contextUriRes = -1; 98 int contextDescriptionRes = -1; 99 boolean showMetadataInPreview = false; 100 101 XmlResourceParser parser = null; 102 try { 103 parser = si.loadXmlMetaData(pm, WallpaperService.SERVICE_META_DATA); 104 if (parser == null) { 105 throw new XmlPullParserException("No " 106 + WallpaperService.SERVICE_META_DATA + " meta-data"); 107 } 108 109 Resources res = pm.getResourcesForApplication(si.applicationInfo); 110 111 AttributeSet attrs = Xml.asAttributeSet(parser); 112 113 int type; 114 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 115 && type != XmlPullParser.START_TAG) { 116 } 117 118 String nodeName = parser.getName(); 119 if (!"wallpaper".equals(nodeName)) { 120 throw new XmlPullParserException( 121 "Meta-data does not start with wallpaper tag"); 122 } 123 124 TypedArray sa = res.obtainAttributes(attrs, 125 com.android.internal.R.styleable.Wallpaper); 126 settingsActivityComponent = sa.getString( 127 com.android.internal.R.styleable.Wallpaper_settingsActivity); 128 129 thumbnailRes = sa.getResourceId( 130 com.android.internal.R.styleable.Wallpaper_thumbnail, 131 -1); 132 authorRes = sa.getResourceId( 133 com.android.internal.R.styleable.Wallpaper_author, 134 -1); 135 descriptionRes = sa.getResourceId( 136 com.android.internal.R.styleable.Wallpaper_description, 137 -1); 138 contextUriRes = sa.getResourceId( 139 com.android.internal.R.styleable.Wallpaper_contextUri, 140 -1); 141 contextDescriptionRes = sa.getResourceId( 142 com.android.internal.R.styleable.Wallpaper_contextDescription, 143 -1); 144 showMetadataInPreview = sa.getBoolean( 145 com.android.internal.R.styleable.Wallpaper_showMetadataInPreview, 146 false); 147 148 sa.recycle(); 149 } catch (NameNotFoundException e) { 150 throw new XmlPullParserException( 151 "Unable to create context for: " + si.packageName); 152 } finally { 153 if (parser != null) parser.close(); 154 } 155 156 mSettingsActivityName = settingsActivityComponent; 157 mThumbnailResource = thumbnailRes; 158 mAuthorResource = authorRes; 159 mDescriptionResource = descriptionRes; 160 mContextUriResource = contextUriRes; 161 mContextDescriptionResource = contextDescriptionRes; 162 mShowMetadataInPreview = showMetadataInPreview; 163 } 164 165 WallpaperInfo(Parcel source) { 166 mSettingsActivityName = source.readString(); 167 mThumbnailResource = source.readInt(); 168 mAuthorResource = source.readInt(); 169 mDescriptionResource = source.readInt(); 170 mContextUriResource = source.readInt(); 171 mContextDescriptionResource = source.readInt(); 172 mShowMetadataInPreview = source.readInt() != 0; 173 mService = ResolveInfo.CREATOR.createFromParcel(source); 174 } 175 176 /** 177 * Return the .apk package that implements this wallpaper. 178 */ 179 public String getPackageName() { 180 return mService.serviceInfo.packageName; 181 } 182 183 /** 184 * Return the class name of the service component that implements 185 * this wallpaper. 186 */ 187 public String getServiceName() { 188 return mService.serviceInfo.name; 189 } 190 191 /** 192 * Return the raw information about the Service implementing this 193 * wallpaper. Do not modify the returned object. 194 */ 195 public ServiceInfo getServiceInfo() { 196 return mService.serviceInfo; 197 } 198 199 /** 200 * Return the component of the service that implements this wallpaper. 201 */ 202 public ComponentName getComponent() { 203 return new ComponentName(mService.serviceInfo.packageName, 204 mService.serviceInfo.name); 205 } 206 207 /** 208 * Load the user-displayed label for this wallpaper. 209 * 210 * @param pm Supply a PackageManager used to load the wallpaper's 211 * resources. 212 */ 213 public CharSequence loadLabel(PackageManager pm) { 214 return mService.loadLabel(pm); 215 } 216 217 /** 218 * Load the user-displayed icon for this wallpaper. 219 * 220 * @param pm Supply a PackageManager used to load the wallpaper's 221 * resources. 222 */ 223 public Drawable loadIcon(PackageManager pm) { 224 return mService.loadIcon(pm); 225 } 226 227 /** 228 * Load the thumbnail image for this wallpaper. 229 * 230 * @param pm Supply a PackageManager used to load the wallpaper's 231 * resources. 232 */ 233 public Drawable loadThumbnail(PackageManager pm) { 234 if (mThumbnailResource < 0) return null; 235 236 return pm.getDrawable(mService.serviceInfo.packageName, 237 mThumbnailResource, 238 mService.serviceInfo.applicationInfo); 239 } 240 241 /** 242 * Return a string indicating the author(s) of this wallpaper. 243 */ 244 public CharSequence loadAuthor(PackageManager pm) throws NotFoundException { 245 if (mAuthorResource <= 0) throw new NotFoundException(); 246 String packageName = mService.resolvePackageName; 247 ApplicationInfo applicationInfo = null; 248 if (packageName == null) { 249 packageName = mService.serviceInfo.packageName; 250 applicationInfo = mService.serviceInfo.applicationInfo; 251 } 252 return pm.getText(packageName, mAuthorResource, applicationInfo); 253 } 254 255 /** 256 * Return a brief summary of this wallpaper's behavior. 257 */ 258 public CharSequence loadDescription(PackageManager pm) throws NotFoundException { 259 String packageName = mService.resolvePackageName; 260 ApplicationInfo applicationInfo = null; 261 if (packageName == null) { 262 packageName = mService.serviceInfo.packageName; 263 applicationInfo = mService.serviceInfo.applicationInfo; 264 } 265 if (mService.serviceInfo.descriptionRes != 0) { 266 return pm.getText(packageName, mService.serviceInfo.descriptionRes, 267 applicationInfo); 268 269 } 270 if (mDescriptionResource <= 0) throw new NotFoundException(); 271 return pm.getText(packageName, mDescriptionResource, 272 mService.serviceInfo.applicationInfo); 273 } 274 275 /** 276 * Returns an URI that specifies a link for further context about this wallpaper. 277 * 278 * @param pm An instance of {@link PackageManager} to retrieve the URI. 279 * @return The URI. 280 */ 281 public Uri loadContextUri(PackageManager pm) throws NotFoundException { 282 if (mContextUriResource <= 0) throw new NotFoundException(); 283 String packageName = mService.resolvePackageName; 284 ApplicationInfo applicationInfo = null; 285 if (packageName == null) { 286 packageName = mService.serviceInfo.packageName; 287 applicationInfo = mService.serviceInfo.applicationInfo; 288 } 289 String contextUriString = pm.getText( 290 packageName, mContextUriResource, applicationInfo).toString(); 291 if (contextUriString == null) { 292 return null; 293 } 294 return Uri.parse(contextUriString); 295 } 296 297 /** 298 * Retrieves a title of the URI that specifies a link for further context about this wallpaper. 299 * 300 * @param pm An instance of {@link PackageManager} to retrieve the title. 301 * @return The title. 302 */ 303 public CharSequence loadContextDescription(PackageManager pm) throws NotFoundException { 304 if (mContextDescriptionResource <= 0) throw new NotFoundException(); 305 String packageName = mService.resolvePackageName; 306 ApplicationInfo applicationInfo = null; 307 if (packageName == null) { 308 packageName = mService.serviceInfo.packageName; 309 applicationInfo = mService.serviceInfo.applicationInfo; 310 } 311 return pm.getText(packageName, mContextDescriptionResource, applicationInfo).toString(); 312 } 313 314 /** 315 * Queries whether any metadata should be shown when previewing the wallpaper. If this value is 316 * set to true, any component that shows a preview of this live wallpaper should also show 317 * accompanying information like {@link #loadLabel}, 318 * {@link #loadDescription}, {@link #loadAuthor} and 319 * {@link #loadContextDescription(PackageManager)}, so the user gets to know further information 320 * about this wallpaper. 321 * 322 * @return Whether any metadata should be shown when previewing the wallpaper. 323 */ 324 public boolean getShowMetadataInPreview() { 325 return mShowMetadataInPreview; 326 } 327 328 /** 329 * Return the class name of an activity that provides a settings UI for 330 * the wallpaper. You can launch this activity be starting it with 331 * an {@link android.content.Intent} whose action is MAIN and with an 332 * explicit {@link android.content.ComponentName} 333 * composed of {@link #getPackageName} and the class name returned here. 334 * 335 * <p>A null will be returned if there is no settings activity associated 336 * with the wallpaper. 337 */ 338 public String getSettingsActivity() { 339 return mSettingsActivityName; 340 } 341 342 public void dump(Printer pw, String prefix) { 343 pw.println(prefix + "Service:"); 344 mService.dump(pw, prefix + " "); 345 pw.println(prefix + "mSettingsActivityName=" + mSettingsActivityName); 346 } 347 348 @Override 349 public String toString() { 350 return "WallpaperInfo{" + mService.serviceInfo.name 351 + ", settings: " 352 + mSettingsActivityName + "}"; 353 } 354 355 /** 356 * Used to package this object into a {@link Parcel}. 357 * 358 * @param dest The {@link Parcel} to be written. 359 * @param flags The flags used for parceling. 360 */ 361 public void writeToParcel(Parcel dest, int flags) { 362 dest.writeString(mSettingsActivityName); 363 dest.writeInt(mThumbnailResource); 364 dest.writeInt(mAuthorResource); 365 dest.writeInt(mDescriptionResource); 366 dest.writeInt(mContextUriResource); 367 dest.writeInt(mContextDescriptionResource); 368 dest.writeInt(mShowMetadataInPreview ? 1 : 0); 369 mService.writeToParcel(dest, flags); 370 } 371 372 /** 373 * Used to make this class parcelable. 374 */ 375 public static final Parcelable.Creator<WallpaperInfo> CREATOR = new Parcelable.Creator<WallpaperInfo>() { 376 public WallpaperInfo createFromParcel(Parcel source) { 377 return new WallpaperInfo(source); 378 } 379 380 public WallpaperInfo[] newArray(int size) { 381 return new WallpaperInfo[size]; 382 } 383 }; 384 385 public int describeContents() { 386 return 0; 387 } 388} 389