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.pm.PackageManager.NameNotFoundException;
20import android.content.res.Resources;
21import android.graphics.drawable.Drawable;
22import android.os.Parcel;
23import android.os.Parcelable;
24import android.util.Printer;
25
26import java.text.Collator;
27import java.util.Comparator;
28
29/**
30 * Information you can retrieve about a particular application.  This
31 * corresponds to information collected from the AndroidManifest.xml's
32 * <application> tag.
33 */
34public class ApplicationInfo extends PackageItemInfo implements Parcelable {
35
36    /**
37     * Default task affinity of all activities in this application. See
38     * {@link ActivityInfo#taskAffinity} for more information.  This comes
39     * from the "taskAffinity" attribute.
40     */
41    public String taskAffinity;
42
43    /**
44     * Optional name of a permission required to be able to access this
45     * application's components.  From the "permission" attribute.
46     */
47    public String permission;
48
49    /**
50     * The name of the process this application should run in.  From the
51     * "process" attribute or, if not set, the same as
52     * <var>packageName</var>.
53     */
54    public String processName;
55
56    /**
57     * Class implementing the Application object.  From the "class"
58     * attribute.
59     */
60    public String className;
61
62    /**
63     * A style resource identifier (in the package's resources) of the
64     * description of an application.  From the "description" attribute
65     * or, if not set, 0.
66     */
67    public int descriptionRes;
68
69    /**
70     * A style resource identifier (in the package's resources) of the
71     * default visual theme of the application.  From the "theme" attribute
72     * or, if not set, 0.
73     */
74    public int theme;
75
76    /**
77     * Class implementing the Application's manage space
78     * functionality.  From the "manageSpaceActivity"
79     * attribute. This is an optional attribute and will be null if
80     * applications don't specify it in their manifest
81     */
82    public String manageSpaceActivityName;
83
84    /**
85     * Class implementing the Application's backup functionality.  From
86     * the "backupAgent" attribute.  This is an optional attribute and
87     * will be null if the application does not specify it in its manifest.
88     *
89     * <p>If android:allowBackup is set to false, this attribute is ignored.
90     */
91    public String backupAgentName;
92
93    /**
94     * The default extra UI options for activities in this application.
95     * Set from the {@link android.R.attr#uiOptions} attribute in the
96     * activity's manifest.
97     */
98    public int uiOptions = 0;
99
100    /**
101     * Value for {@link #flags}: if set, this application is installed in the
102     * device's system image.
103     */
104    public static final int FLAG_SYSTEM = 1<<0;
105
106    /**
107     * Value for {@link #flags}: set to true if this application would like to
108     * allow debugging of its
109     * code, even when installed on a non-development system.  Comes
110     * from {@link android.R.styleable#AndroidManifestApplication_debuggable
111     * android:debuggable} of the &lt;application&gt; tag.
112     */
113    public static final int FLAG_DEBUGGABLE = 1<<1;
114
115    /**
116     * Value for {@link #flags}: set to true if this application has code
117     * associated with it.  Comes
118     * from {@link android.R.styleable#AndroidManifestApplication_hasCode
119     * android:hasCode} of the &lt;application&gt; tag.
120     */
121    public static final int FLAG_HAS_CODE = 1<<2;
122
123    /**
124     * Value for {@link #flags}: set to true if this application is persistent.
125     * Comes from {@link android.R.styleable#AndroidManifestApplication_persistent
126     * android:persistent} of the &lt;application&gt; tag.
127     */
128    public static final int FLAG_PERSISTENT = 1<<3;
129
130    /**
131     * Value for {@link #flags}: set to true if this application holds the
132     * {@link android.Manifest.permission#FACTORY_TEST} permission and the
133     * device is running in factory test mode.
134     */
135    public static final int FLAG_FACTORY_TEST = 1<<4;
136
137    /**
138     * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
139     * Comes from {@link android.R.styleable#AndroidManifestApplication_allowTaskReparenting
140     * android:allowTaskReparenting} of the &lt;application&gt; tag.
141     */
142    public static final int FLAG_ALLOW_TASK_REPARENTING = 1<<5;
143
144    /**
145     * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
146     * Comes from {@link android.R.styleable#AndroidManifestApplication_allowClearUserData
147     * android:allowClearUserData} of the &lt;application&gt; tag.
148     */
149    public static final int FLAG_ALLOW_CLEAR_USER_DATA = 1<<6;
150
151    /**
152     * Value for {@link #flags}: this is set if this application has been
153     * install as an update to a built-in system application.
154     */
155    public static final int FLAG_UPDATED_SYSTEM_APP = 1<<7;
156
157    /**
158     * Value for {@link #flags}: this is set of the application has specified
159     * {@link android.R.styleable#AndroidManifestApplication_testOnly
160     * android:testOnly} to be true.
161     */
162    public static final int FLAG_TEST_ONLY = 1<<8;
163
164    /**
165     * Value for {@link #flags}: true when the application's window can be
166     * reduced in size for smaller screens.  Corresponds to
167     * {@link android.R.styleable#AndroidManifestSupportsScreens_smallScreens
168     * android:smallScreens}.
169     */
170    public static final int FLAG_SUPPORTS_SMALL_SCREENS = 1<<9;
171
172    /**
173     * Value for {@link #flags}: true when the application's window can be
174     * displayed on normal screens.  Corresponds to
175     * {@link android.R.styleable#AndroidManifestSupportsScreens_normalScreens
176     * android:normalScreens}.
177     */
178    public static final int FLAG_SUPPORTS_NORMAL_SCREENS = 1<<10;
179
180    /**
181     * Value for {@link #flags}: true when the application's window can be
182     * increased in size for larger screens.  Corresponds to
183     * {@link android.R.styleable#AndroidManifestSupportsScreens_largeScreens
184     * android:largeScreens}.
185     */
186    public static final int FLAG_SUPPORTS_LARGE_SCREENS = 1<<11;
187
188    /**
189     * Value for {@link #flags}: true when the application knows how to adjust
190     * its UI for different screen sizes.  Corresponds to
191     * {@link android.R.styleable#AndroidManifestSupportsScreens_resizeable
192     * android:resizeable}.
193     */
194    public static final int FLAG_RESIZEABLE_FOR_SCREENS = 1<<12;
195
196    /**
197     * Value for {@link #flags}: true when the application knows how to
198     * accomodate different screen densities.  Corresponds to
199     * {@link android.R.styleable#AndroidManifestSupportsScreens_anyDensity
200     * android:anyDensity}.
201     */
202    public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 1<<13;
203
204    /**
205     * Value for {@link #flags}: set to true if this application would like to
206     * request the VM to operate under the safe mode. Comes from
207     * {@link android.R.styleable#AndroidManifestApplication_vmSafeMode
208     * android:vmSafeMode} of the &lt;application&gt; tag.
209     */
210    public static final int FLAG_VM_SAFE_MODE = 1<<14;
211
212    /**
213     * Value for {@link #flags}: set to <code>false</code> if the application does not wish
214     * to permit any OS-driven backups of its data; <code>true</code> otherwise.
215     *
216     * <p>Comes from the
217     * {@link android.R.styleable#AndroidManifestApplication_allowBackup android:allowBackup}
218     * attribute of the &lt;application&gt; tag.
219     */
220    public static final int FLAG_ALLOW_BACKUP = 1<<15;
221
222    /**
223     * Value for {@link #flags}: set to <code>false</code> if the application must be kept
224     * in memory following a full-system restore operation; <code>true</code> otherwise.
225     * Ordinarily, during a full system restore operation each application is shut down
226     * following execution of its agent's onRestore() method.  Setting this attribute to
227     * <code>false</code> prevents this.  Most applications will not need to set this attribute.
228     *
229     * <p>If
230     * {@link android.R.styleable#AndroidManifestApplication_allowBackup android:allowBackup}
231     * is set to <code>false</code> or no
232     * {@link android.R.styleable#AndroidManifestApplication_backupAgent android:backupAgent}
233     * is specified, this flag will be ignored.
234     *
235     * <p>Comes from the
236     * {@link android.R.styleable#AndroidManifestApplication_killAfterRestore android:killAfterRestore}
237     * attribute of the &lt;application&gt; tag.
238     */
239    public static final int FLAG_KILL_AFTER_RESTORE = 1<<16;
240
241    /**
242     * Value for {@link #flags}: Set to <code>true</code> if the application's backup
243     * agent claims to be able to handle restore data even "from the future,"
244     * i.e. from versions of the application with a versionCode greater than
245     * the one currently installed on the device.  <i>Use with caution!</i>  By default
246     * this attribute is <code>false</code> and the Backup Manager will ensure that data
247     * from "future" versions of the application are never supplied during a restore operation.
248     *
249     * <p>If
250     * {@link android.R.styleable#AndroidManifestApplication_allowBackup android:allowBackup}
251     * is set to <code>false</code> or no
252     * {@link android.R.styleable#AndroidManifestApplication_backupAgent android:backupAgent}
253     * is specified, this flag will be ignored.
254     *
255     * <p>Comes from the
256     * {@link android.R.styleable#AndroidManifestApplication_restoreAnyVersion android:restoreAnyVersion}
257     * attribute of the &lt;application&gt; tag.
258     */
259    public static final int FLAG_RESTORE_ANY_VERSION = 1<<17;
260
261    /**
262     * Value for {@link #flags}: Set to true if the application is
263     * currently installed on external/removable/unprotected storage.  Such
264     * applications may not be available if their storage is not currently
265     * mounted.  When the storage it is on is not available, it will look like
266     * the application has been uninstalled (its .apk is no longer available)
267     * but its persistent data is not removed.
268     */
269    public static final int FLAG_EXTERNAL_STORAGE = 1<<18;
270
271    /**
272     * Value for {@link #flags}: true when the application's window can be
273     * increased in size for extra large screens.  Corresponds to
274     * {@link android.R.styleable#AndroidManifestSupportsScreens_xlargeScreens
275     * android:xlargeScreens}.
276     */
277    public static final int FLAG_SUPPORTS_XLARGE_SCREENS = 1<<19;
278
279    /**
280     * Value for {@link #flags}: true when the application has requested a
281     * large heap for its processes.  Corresponds to
282     * {@link android.R.styleable#AndroidManifestApplication_largeHeap
283     * android:largeHeap}.
284     */
285    public static final int FLAG_LARGE_HEAP = 1<<20;
286
287    /**
288     * Value for {@link #flags}: true if this application's package is in
289     * the stopped state.
290     */
291    public static final int FLAG_STOPPED = 1<<21;
292
293    /**
294     * Value for {@link #flags}: true  when the application is willing to support
295     * RTL (right to left). All activities will inherit this value.
296     *
297     * Set from the {@link android.R.attr#supportsRtl} attribute in the
298     * activity's manifest.
299     *
300     * Default value is false (no support for RTL).
301     */
302    public static final int FLAG_SUPPORTS_RTL = 1<<22;
303
304    /**
305     * Value for {@link #flags}: true if the application is currently
306     * installed for the calling user.
307     */
308    public static final int FLAG_INSTALLED = 1<<23;
309
310    /**
311     * Value for {@link #flags}: true if the application only has its
312     * data installed; the application package itself does not currently
313     * exist on the device.
314     */
315    public static final int FLAG_IS_DATA_ONLY = 1<<24;
316
317    /**
318     * Value for {@link #flags}: Set to true if the application has been
319     * installed using the forward lock option.
320     *
321     * NOTE: DO NOT CHANGE THIS VALUE!  It is saved in packages.xml.
322     *
323     * {@hide}
324     */
325    public static final int FLAG_FORWARD_LOCK = 1<<29;
326
327    /**
328     * Value for {@link #flags}: set to <code>true</code> if the application
329     * has reported that it is heavy-weight, and thus can not participate in
330     * the normal application lifecycle.
331     *
332     * <p>Comes from the
333     * {@link android.R.styleable#AndroidManifestApplication_cantSaveState android:cantSaveState}
334     * attribute of the &lt;application&gt; tag.
335     *
336     * {@hide}
337     */
338    public static final int FLAG_CANT_SAVE_STATE = 1<<28;
339
340    /**
341     * Flags associated with the application.  Any combination of
342     * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
343     * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
344     * {@link #FLAG_ALLOW_TASK_REPARENTING}
345     * {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
346     * {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
347     * {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
348     * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_SUPPORTS_XLARGE_SCREENS},
349     * {@link #FLAG_RESIZEABLE_FOR_SCREENS},
350     * {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}, {@link #FLAG_VM_SAFE_MODE},
351     * {@link #FLAG_INSTALLED}.
352     */
353    public int flags = 0;
354
355    /**
356     * The required smallest screen width the application can run on.  If 0,
357     * nothing has been specified.  Comes from
358     * {@link android.R.styleable#AndroidManifestSupportsScreens_requiresSmallestWidthDp
359     * android:requiresSmallestWidthDp} attribute of the &lt;supports-screens&gt; tag.
360     */
361    public int requiresSmallestWidthDp = 0;
362
363    /**
364     * The maximum smallest screen width the application is designed for.  If 0,
365     * nothing has been specified.  Comes from
366     * {@link android.R.styleable#AndroidManifestSupportsScreens_compatibleWidthLimitDp
367     * android:compatibleWidthLimitDp} attribute of the &lt;supports-screens&gt; tag.
368     */
369    public int compatibleWidthLimitDp = 0;
370
371    /**
372     * The maximum smallest screen width the application will work on.  If 0,
373     * nothing has been specified.  Comes from
374     * {@link android.R.styleable#AndroidManifestSupportsScreens_largestWidthLimitDp
375     * android:largestWidthLimitDp} attribute of the &lt;supports-screens&gt; tag.
376     */
377    public int largestWidthLimitDp = 0;
378
379    /**
380     * Full path to the location of this package.
381     */
382    public String sourceDir;
383
384    /**
385     * Full path to the location of the publicly available parts of this
386     * package (i.e. the primary resource package and manifest).  For
387     * non-forward-locked apps this will be the same as {@link #sourceDir).
388     */
389    public String publicSourceDir;
390
391    /**
392     * Full paths to the locations of extra resource packages this application
393     * uses. This field is only used if there are extra resource packages,
394     * otherwise it is null.
395     *
396     * {@hide}
397     */
398    public String[] resourceDirs;
399
400    /**
401     * Paths to all shared libraries this application is linked against.  This
402     * field is only set if the {@link PackageManager#GET_SHARED_LIBRARY_FILES
403     * PackageManager.GET_SHARED_LIBRARY_FILES} flag was used when retrieving
404     * the structure.
405     */
406    public String[] sharedLibraryFiles;
407
408    /**
409     * Full path to a directory assigned to the package for its persistent
410     * data.
411     */
412    public String dataDir;
413
414    /**
415     * Full path to the directory where native JNI libraries are stored.
416     */
417    public String nativeLibraryDir;
418
419    /**
420     * The kernel user-ID that has been assigned to this application;
421     * currently this is not a unique ID (multiple applications can have
422     * the same uid).
423     */
424    public int uid;
425
426    /**
427     * The minimum SDK version this application targets.  It may run on earlier
428     * versions, but it knows how to work with any new behavior added at this
429     * version.  Will be {@link android.os.Build.VERSION_CODES#CUR_DEVELOPMENT}
430     * if this is a development build and the app is targeting that.  You should
431     * compare that this number is >= the SDK version number at which your
432     * behavior was introduced.
433     */
434    public int targetSdkVersion;
435
436    /**
437     * When false, indicates that all components within this application are
438     * considered disabled, regardless of their individually set enabled status.
439     */
440    public boolean enabled = true;
441
442    /**
443     * For convenient access to the current enabled setting of this app.
444     * @hide
445     */
446    public int enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
447
448    /**
449     * For convenient access to package's install location.
450     * @hide
451     */
452    public int installLocation = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
453
454    public void dump(Printer pw, String prefix) {
455        super.dumpFront(pw, prefix);
456        if (className != null) {
457            pw.println(prefix + "className=" + className);
458        }
459        if (permission != null) {
460            pw.println(prefix + "permission=" + permission);
461        }
462        pw.println(prefix + "processName=" + processName);
463        pw.println(prefix + "taskAffinity=" + taskAffinity);
464        pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags)
465                + " theme=0x" + Integer.toHexString(theme));
466        pw.println(prefix + "requiresSmallestWidthDp=" + requiresSmallestWidthDp
467                + " compatibleWidthLimitDp=" + compatibleWidthLimitDp
468                + " largestWidthLimitDp=" + largestWidthLimitDp);
469        pw.println(prefix + "sourceDir=" + sourceDir);
470        if (sourceDir == null) {
471            if (publicSourceDir != null) {
472                pw.println(prefix + "publicSourceDir=" + publicSourceDir);
473            }
474        } else if (!sourceDir.equals(publicSourceDir)) {
475            pw.println(prefix + "publicSourceDir=" + publicSourceDir);
476        }
477        if (resourceDirs != null) {
478            pw.println(prefix + "resourceDirs=" + resourceDirs);
479        }
480        pw.println(prefix + "dataDir=" + dataDir);
481        if (sharedLibraryFiles != null) {
482            pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
483        }
484        pw.println(prefix + "enabled=" + enabled + " targetSdkVersion=" + targetSdkVersion);
485        if (manageSpaceActivityName != null) {
486            pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
487        }
488        if (descriptionRes != 0) {
489            pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes));
490        }
491        if (uiOptions != 0) {
492            pw.println(prefix + "uiOptions=0x" + Integer.toHexString(uiOptions));
493        }
494        pw.println(prefix + "supportsRtl=" + (hasRtlSupport() ? "true" : "false"));
495        super.dumpBack(pw, prefix);
496    }
497
498    /**
499     * @return true if "supportsRtl" has been set to true in the AndroidManifest
500     * @hide
501     */
502    public boolean hasRtlSupport() {
503        return (flags & FLAG_SUPPORTS_RTL) == FLAG_SUPPORTS_RTL;
504    }
505
506    public static class DisplayNameComparator
507            implements Comparator<ApplicationInfo> {
508        public DisplayNameComparator(PackageManager pm) {
509            mPM = pm;
510        }
511
512        public final int compare(ApplicationInfo aa, ApplicationInfo ab) {
513            CharSequence  sa = mPM.getApplicationLabel(aa);
514            if (sa == null) {
515                sa = aa.packageName;
516            }
517            CharSequence  sb = mPM.getApplicationLabel(ab);
518            if (sb == null) {
519                sb = ab.packageName;
520            }
521
522            return sCollator.compare(sa.toString(), sb.toString());
523        }
524
525        private final Collator   sCollator = Collator.getInstance();
526        private PackageManager   mPM;
527    }
528
529    public ApplicationInfo() {
530    }
531
532    public ApplicationInfo(ApplicationInfo orig) {
533        super(orig);
534        taskAffinity = orig.taskAffinity;
535        permission = orig.permission;
536        processName = orig.processName;
537        className = orig.className;
538        theme = orig.theme;
539        flags = orig.flags;
540        requiresSmallestWidthDp = orig.requiresSmallestWidthDp;
541        compatibleWidthLimitDp = orig.compatibleWidthLimitDp;
542        largestWidthLimitDp = orig.largestWidthLimitDp;
543        sourceDir = orig.sourceDir;
544        publicSourceDir = orig.publicSourceDir;
545        nativeLibraryDir = orig.nativeLibraryDir;
546        resourceDirs = orig.resourceDirs;
547        sharedLibraryFiles = orig.sharedLibraryFiles;
548        dataDir = orig.dataDir;
549        uid = orig.uid;
550        targetSdkVersion = orig.targetSdkVersion;
551        enabled = orig.enabled;
552        enabledSetting = orig.enabledSetting;
553        installLocation = orig.installLocation;
554        manageSpaceActivityName = orig.manageSpaceActivityName;
555        descriptionRes = orig.descriptionRes;
556        uiOptions = orig.uiOptions;
557        backupAgentName = orig.backupAgentName;
558    }
559
560
561    public String toString() {
562        return "ApplicationInfo{"
563            + Integer.toHexString(System.identityHashCode(this))
564            + " " + packageName + "}";
565    }
566
567    public int describeContents() {
568        return 0;
569    }
570
571    public void writeToParcel(Parcel dest, int parcelableFlags) {
572        super.writeToParcel(dest, parcelableFlags);
573        dest.writeString(taskAffinity);
574        dest.writeString(permission);
575        dest.writeString(processName);
576        dest.writeString(className);
577        dest.writeInt(theme);
578        dest.writeInt(flags);
579        dest.writeInt(requiresSmallestWidthDp);
580        dest.writeInt(compatibleWidthLimitDp);
581        dest.writeInt(largestWidthLimitDp);
582        dest.writeString(sourceDir);
583        dest.writeString(publicSourceDir);
584        dest.writeString(nativeLibraryDir);
585        dest.writeStringArray(resourceDirs);
586        dest.writeStringArray(sharedLibraryFiles);
587        dest.writeString(dataDir);
588        dest.writeInt(uid);
589        dest.writeInt(targetSdkVersion);
590        dest.writeInt(enabled ? 1 : 0);
591        dest.writeInt(enabledSetting);
592        dest.writeInt(installLocation);
593        dest.writeString(manageSpaceActivityName);
594        dest.writeString(backupAgentName);
595        dest.writeInt(descriptionRes);
596        dest.writeInt(uiOptions);
597    }
598
599    public static final Parcelable.Creator<ApplicationInfo> CREATOR
600            = new Parcelable.Creator<ApplicationInfo>() {
601        public ApplicationInfo createFromParcel(Parcel source) {
602            return new ApplicationInfo(source);
603        }
604        public ApplicationInfo[] newArray(int size) {
605            return new ApplicationInfo[size];
606        }
607    };
608
609    private ApplicationInfo(Parcel source) {
610        super(source);
611        taskAffinity = source.readString();
612        permission = source.readString();
613        processName = source.readString();
614        className = source.readString();
615        theme = source.readInt();
616        flags = source.readInt();
617        requiresSmallestWidthDp = source.readInt();
618        compatibleWidthLimitDp = source.readInt();
619        largestWidthLimitDp = source.readInt();
620        sourceDir = source.readString();
621        publicSourceDir = source.readString();
622        nativeLibraryDir = source.readString();
623        resourceDirs = source.readStringArray();
624        sharedLibraryFiles = source.readStringArray();
625        dataDir = source.readString();
626        uid = source.readInt();
627        targetSdkVersion = source.readInt();
628        enabled = source.readInt() != 0;
629        enabledSetting = source.readInt();
630        installLocation = source.readInt();
631        manageSpaceActivityName = source.readString();
632        backupAgentName = source.readString();
633        descriptionRes = source.readInt();
634        uiOptions = source.readInt();
635    }
636
637    /**
638     * Retrieve the textual description of the application.  This
639     * will call back on the given PackageManager to load the description from
640     * the application.
641     *
642     * @param pm A PackageManager from which the label can be loaded; usually
643     * the PackageManager from which you originally retrieved this item.
644     *
645     * @return Returns a CharSequence containing the application's description.
646     * If there is no description, null is returned.
647     */
648    public CharSequence loadDescription(PackageManager pm) {
649        if (descriptionRes != 0) {
650            CharSequence label = pm.getText(packageName, descriptionRes, this);
651            if (label != null) {
652                return label;
653            }
654        }
655        return null;
656    }
657
658    /**
659     * Disable compatibility mode
660     *
661     * @hide
662     */
663    public void disableCompatibilityMode() {
664        flags |= (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS |
665                FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS |
666                FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
667    }
668
669    /**
670     * @hide
671     */
672    @Override protected Drawable loadDefaultIcon(PackageManager pm) {
673        if ((flags & FLAG_EXTERNAL_STORAGE) != 0
674                && isPackageUnavailable(pm)) {
675            return Resources.getSystem().getDrawable(
676                    com.android.internal.R.drawable.sym_app_on_sd_unavailable_icon);
677        }
678        return pm.getDefaultActivityIcon();
679    }
680
681    private boolean isPackageUnavailable(PackageManager pm) {
682        try {
683            return pm.getPackageInfo(packageName, 0) == null;
684        } catch (NameNotFoundException ex) {
685            return true;
686        }
687    }
688
689    /**
690     * @hide
691     */
692    @Override protected ApplicationInfo getApplicationInfo() {
693        return this;
694    }
695}
696