1/*
2 * Copyright (C) 2007 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.content.pm;
18
19import android.content.res.XmlResourceParser;
20
21import android.graphics.drawable.Drawable;
22import android.os.Bundle;
23import android.os.Parcel;
24import android.os.UserHandle;
25import android.text.TextUtils;
26import android.util.Printer;
27
28import java.text.Collator;
29import java.util.Comparator;
30
31/**
32 * Base class containing information common to all package items held by
33 * the package manager.  This provides a very common basic set of attributes:
34 * a label, icon, and meta-data.  This class is not intended
35 * to be used by itself; it is simply here to share common definitions
36 * between all items returned by the package manager.  As such, it does not
37 * itself implement Parcelable, but does provide convenience methods to assist
38 * in the implementation of Parcelable in subclasses.
39 */
40public class PackageItemInfo {
41    /**
42     * Public name of this item. From the "android:name" attribute.
43     */
44    public String name;
45
46    /**
47     * Name of the package that this item is in.
48     */
49    public String packageName;
50
51    /**
52     * A string resource identifier (in the package's resources) of this
53     * component's label.  From the "label" attribute or, if not set, 0.
54     */
55    public int labelRes;
56
57    /**
58     * The string provided in the AndroidManifest file, if any.  You
59     * probably don't want to use this.  You probably want
60     * {@link PackageManager#getApplicationLabel}
61     */
62    public CharSequence nonLocalizedLabel;
63
64    /**
65     * A drawable resource identifier (in the package's resources) of this
66     * component's icon.  From the "icon" attribute or, if not set, 0.
67     */
68    public int icon;
69
70    /**
71     * A drawable resource identifier (in the package's resources) of this
72     * component's banner.  From the "banner" attribute or, if not set, 0.
73     */
74    public int banner;
75
76    /**
77     * A drawable resource identifier (in the package's resources) of this
78     * component's logo. Logos may be larger/wider than icons and are
79     * displayed by certain UI elements in place of a name or name/icon
80     * combination. From the "logo" attribute or, if not set, 0.
81     */
82    public int logo;
83
84    /**
85     * Additional meta-data associated with this component.  This field
86     * will only be filled in if you set the
87     * {@link PackageManager#GET_META_DATA} flag when requesting the info.
88     */
89    public Bundle metaData;
90
91    /**
92     * If different of UserHandle.USER_NULL, The icon of this item will be the one of that user.
93     * @hide
94     */
95    public int showUserIcon;
96
97    public PackageItemInfo() {
98        showUserIcon = UserHandle.USER_NULL;
99    }
100
101    public PackageItemInfo(PackageItemInfo orig) {
102        name = orig.name;
103        if (name != null) name = name.trim();
104        packageName = orig.packageName;
105        labelRes = orig.labelRes;
106        nonLocalizedLabel = orig.nonLocalizedLabel;
107        if (nonLocalizedLabel != null) nonLocalizedLabel = nonLocalizedLabel.toString().trim();
108        icon = orig.icon;
109        banner = orig.banner;
110        logo = orig.logo;
111        metaData = orig.metaData;
112        showUserIcon = orig.showUserIcon;
113    }
114
115    /**
116     * Retrieve the current textual label associated with this item.  This
117     * will call back on the given PackageManager to load the label from
118     * the application.
119     *
120     * @param pm A PackageManager from which the label can be loaded; usually
121     * the PackageManager from which you originally retrieved this item.
122     *
123     * @return Returns a CharSequence containing the item's label.  If the
124     * item does not have a label, its name is returned.
125     */
126    public CharSequence loadLabel(PackageManager pm) {
127        if (nonLocalizedLabel != null) {
128            return nonLocalizedLabel;
129        }
130        if (labelRes != 0) {
131            CharSequence label = pm.getText(packageName, labelRes, getApplicationInfo());
132            if (label != null) {
133                return label.toString().trim();
134            }
135        }
136        if (name != null) {
137            return name;
138        }
139        return packageName;
140    }
141
142    /**
143     * Retrieve the current graphical icon associated with this item.  This
144     * will call back on the given PackageManager to load the icon from
145     * the application.
146     *
147     * @param pm A PackageManager from which the icon can be loaded; usually
148     * the PackageManager from which you originally retrieved this item.
149     *
150     * @return Returns a Drawable containing the item's icon.  If the
151     * item does not have an icon, the item's default icon is returned
152     * such as the default activity icon.
153     */
154    public Drawable loadIcon(PackageManager pm) {
155        return pm.loadItemIcon(this, getApplicationInfo());
156    }
157
158    /**
159     * Retrieve the current graphical icon associated with this item without
160     * the addition of a work badge if applicable.
161     * This will call back on the given PackageManager to load the icon from
162     * the application.
163     *
164     * @param pm A PackageManager from which the icon can be loaded; usually
165     * the PackageManager from which you originally retrieved this item.
166     *
167     * @return Returns a Drawable containing the item's icon.  If the
168     * item does not have an icon, the item's default icon is returned
169     * such as the default activity icon.
170     */
171    public Drawable loadUnbadgedIcon(PackageManager pm) {
172        return pm.loadUnbadgedItemIcon(this, getApplicationInfo());
173    }
174
175    /**
176     * Retrieve the current graphical banner associated with this item.  This
177     * will call back on the given PackageManager to load the banner from
178     * the application.
179     *
180     * @param pm A PackageManager from which the banner can be loaded; usually
181     * the PackageManager from which you originally retrieved this item.
182     *
183     * @return Returns a Drawable containing the item's banner.  If the item
184     * does not have a banner, this method will return null.
185     */
186    public Drawable loadBanner(PackageManager pm) {
187        if (banner != 0) {
188            Drawable dr = pm.getDrawable(packageName, banner, getApplicationInfo());
189            if (dr != null) {
190                return dr;
191            }
192        }
193        return loadDefaultBanner(pm);
194    }
195
196    /**
197     * Retrieve the default graphical icon associated with this item.
198     *
199     * @param pm A PackageManager from which the icon can be loaded; usually
200     * the PackageManager from which you originally retrieved this item.
201     *
202     * @return Returns a Drawable containing the item's default icon
203     * such as the default activity icon.
204     *
205     * @hide
206     */
207    public Drawable loadDefaultIcon(PackageManager pm) {
208        return pm.getDefaultActivityIcon();
209    }
210
211    /**
212     * Retrieve the default graphical banner associated with this item.
213     *
214     * @param pm A PackageManager from which the banner can be loaded; usually
215     * the PackageManager from which you originally retrieved this item.
216     *
217     * @return Returns a Drawable containing the item's default banner
218     * or null if no default logo is available.
219     *
220     * @hide
221     */
222    protected Drawable loadDefaultBanner(PackageManager pm) {
223        return null;
224    }
225
226    /**
227     * Retrieve the current graphical logo associated with this item. This
228     * will call back on the given PackageManager to load the logo from
229     * the application.
230     *
231     * @param pm A PackageManager from which the logo can be loaded; usually
232     * the PackageManager from which you originally retrieved this item.
233     *
234     * @return Returns a Drawable containing the item's logo. If the item
235     * does not have a logo, this method will return null.
236     */
237    public Drawable loadLogo(PackageManager pm) {
238        if (logo != 0) {
239            Drawable d = pm.getDrawable(packageName, logo, getApplicationInfo());
240            if (d != null) {
241                return d;
242            }
243        }
244        return loadDefaultLogo(pm);
245    }
246
247    /**
248     * Retrieve the default graphical logo associated with this item.
249     *
250     * @param pm A PackageManager from which the logo can be loaded; usually
251     * the PackageManager from which you originally retrieved this item.
252     *
253     * @return Returns a Drawable containing the item's default logo
254     * or null if no default logo is available.
255     *
256     * @hide
257     */
258    protected Drawable loadDefaultLogo(PackageManager pm) {
259        return null;
260    }
261
262    /**
263     * Load an XML resource attached to the meta-data of this item.  This will
264     * retrieved the name meta-data entry, and if defined call back on the
265     * given PackageManager to load its XML file from the application.
266     *
267     * @param pm A PackageManager from which the XML can be loaded; usually
268     * the PackageManager from which you originally retrieved this item.
269     * @param name Name of the meta-date you would like to load.
270     *
271     * @return Returns an XmlPullParser you can use to parse the XML file
272     * assigned as the given meta-data.  If the meta-data name is not defined
273     * or the XML resource could not be found, null is returned.
274     */
275    public XmlResourceParser loadXmlMetaData(PackageManager pm, String name) {
276        if (metaData != null) {
277            int resid = metaData.getInt(name);
278            if (resid != 0) {
279                return pm.getXml(packageName, resid, getApplicationInfo());
280            }
281        }
282        return null;
283    }
284
285    protected void dumpFront(Printer pw, String prefix) {
286        if (name != null) {
287            pw.println(prefix + "name=" + name);
288        }
289        pw.println(prefix + "packageName=" + packageName);
290        if (labelRes != 0 || nonLocalizedLabel != null || icon != 0 || banner != 0) {
291            pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
292                    + " nonLocalizedLabel=" + nonLocalizedLabel
293                    + " icon=0x" + Integer.toHexString(icon)
294                    + " banner=0x" + Integer.toHexString(banner));
295        }
296    }
297
298    protected void dumpBack(Printer pw, String prefix) {
299        // no back here
300    }
301
302    public void writeToParcel(Parcel dest, int parcelableFlags) {
303        dest.writeString(name);
304        dest.writeString(packageName);
305        dest.writeInt(labelRes);
306        TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags);
307        dest.writeInt(icon);
308        dest.writeInt(logo);
309        dest.writeBundle(metaData);
310        dest.writeInt(banner);
311        dest.writeInt(showUserIcon);
312    }
313
314    protected PackageItemInfo(Parcel source) {
315        name = source.readString();
316        packageName = source.readString();
317        labelRes = source.readInt();
318        nonLocalizedLabel
319                = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
320        icon = source.readInt();
321        logo = source.readInt();
322        metaData = source.readBundle();
323        banner = source.readInt();
324        showUserIcon = source.readInt();
325    }
326
327    /**
328     * Get the ApplicationInfo for the application to which this item belongs,
329     * if available, otherwise returns null.
330     *
331     * @return Returns the ApplicationInfo of this item, or null if not known.
332     *
333     * @hide
334     */
335    protected ApplicationInfo getApplicationInfo() {
336        return null;
337    }
338
339    public static class DisplayNameComparator
340            implements Comparator<PackageItemInfo> {
341        public DisplayNameComparator(PackageManager pm) {
342            mPM = pm;
343        }
344
345        public final int compare(PackageItemInfo aa, PackageItemInfo ab) {
346            CharSequence  sa = aa.loadLabel(mPM);
347            if (sa == null) sa = aa.name;
348            CharSequence  sb = ab.loadLabel(mPM);
349            if (sb == null) sb = ab.name;
350            return sCollator.compare(sa.toString(), sb.toString());
351        }
352
353        private final Collator   sCollator = Collator.getInstance();
354        private PackageManager   mPM;
355    }
356}
357