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