ApplicationInfo.java revision 7767eac3232ba2fb9828766813cdb481d6a97584
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}: Set to true if the application has been
312     * installed using the forward lock option.
313     *
314     * NOTE: DO NOT CHANGE THIS VALUE!  It is saved in packages.xml.
315     *
316     * {@hide}
317     */
318    public static final int FLAG_FORWARD_LOCK = 1<<29;
319
320    /**
321     * Value for {@link #flags}: set to <code>true</code> if the application
322     * has reported that it is heavy-weight, and thus can not participate in
323     * the normal application lifecycle.
324     *
325     * <p>Comes from the
326     * {@link android.R.styleable#AndroidManifestApplication_cantSaveState android:cantSaveState}
327     * attribute of the &lt;application&gt; tag.
328     *
329     * {@hide}
330     */
331    public static final int FLAG_CANT_SAVE_STATE = 1<<28;
332
333    /**
334     * Flags associated with the application.  Any combination of
335     * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
336     * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
337     * {@link #FLAG_ALLOW_TASK_REPARENTING}
338     * {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
339     * {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
340     * {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
341     * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_SUPPORTS_XLARGE_SCREENS},
342     * {@link #FLAG_RESIZEABLE_FOR_SCREENS},
343     * {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}, {@link #FLAG_VM_SAFE_MODE},
344     * {@link #FLAG_INSTALLED}.
345     */
346    public int flags = 0;
347
348    /**
349     * The required smallest screen width the application can run on.  If 0,
350     * nothing has been specified.  Comes from
351     * {@link android.R.styleable#AndroidManifestSupportsScreens_requiresSmallestWidthDp
352     * android:requiresSmallestWidthDp} attribute of the &lt;supports-screens&gt; tag.
353     */
354    public int requiresSmallestWidthDp = 0;
355
356    /**
357     * The maximum smallest screen width the application is designed for.  If 0,
358     * nothing has been specified.  Comes from
359     * {@link android.R.styleable#AndroidManifestSupportsScreens_compatibleWidthLimitDp
360     * android:compatibleWidthLimitDp} attribute of the &lt;supports-screens&gt; tag.
361     */
362    public int compatibleWidthLimitDp = 0;
363
364    /**
365     * The maximum smallest screen width the application will work on.  If 0,
366     * nothing has been specified.  Comes from
367     * {@link android.R.styleable#AndroidManifestSupportsScreens_largestWidthLimitDp
368     * android:largestWidthLimitDp} attribute of the &lt;supports-screens&gt; tag.
369     */
370    public int largestWidthLimitDp = 0;
371
372    /**
373     * Full path to the location of this package.
374     */
375    public String sourceDir;
376
377    /**
378     * Full path to the location of the publicly available parts of this
379     * package (i.e. the primary resource package and manifest).  For
380     * non-forward-locked apps this will be the same as {@link #sourceDir).
381     */
382    public String publicSourceDir;
383
384    /**
385     * Full paths to the locations of extra resource packages this application
386     * uses. This field is only used if there are extra resource packages,
387     * otherwise it is null.
388     *
389     * {@hide}
390     */
391    public String[] resourceDirs;
392
393    /**
394     * Paths to all shared libraries this application is linked against.  This
395     * field is only set if the {@link PackageManager#GET_SHARED_LIBRARY_FILES
396     * PackageManager.GET_SHARED_LIBRARY_FILES} flag was used when retrieving
397     * the structure.
398     */
399    public String[] sharedLibraryFiles;
400
401    /**
402     * Full path to a directory assigned to the package for its persistent
403     * data.
404     */
405    public String dataDir;
406
407    /**
408     * Full path to the directory where native JNI libraries are stored.
409     */
410    public String nativeLibraryDir;
411
412    /**
413     * The kernel user-ID that has been assigned to this application;
414     * currently this is not a unique ID (multiple applications can have
415     * the same uid).
416     */
417    public int uid;
418
419    /**
420     * The minimum SDK version this application targets.  It may run on earlier
421     * versions, but it knows how to work with any new behavior added at this
422     * version.  Will be {@link android.os.Build.VERSION_CODES#CUR_DEVELOPMENT}
423     * if this is a development build and the app is targeting that.  You should
424     * compare that this number is >= the SDK version number at which your
425     * behavior was introduced.
426     */
427    public int targetSdkVersion;
428
429    /**
430     * When false, indicates that all components within this application are
431     * considered disabled, regardless of their individually set enabled status.
432     */
433    public boolean enabled = true;
434
435    /**
436     * For convenient access to the current enabled setting of this app.
437     * @hide
438     */
439    public int enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
440
441    /**
442     * For convenient access to package's install location.
443     * @hide
444     */
445    public int installLocation = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
446
447    public void dump(Printer pw, String prefix) {
448        super.dumpFront(pw, prefix);
449        if (className != null) {
450            pw.println(prefix + "className=" + className);
451        }
452        if (permission != null) {
453            pw.println(prefix + "permission=" + permission);
454        }
455        pw.println(prefix + "processName=" + processName);
456        pw.println(prefix + "taskAffinity=" + taskAffinity);
457        pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags)
458                + " theme=0x" + Integer.toHexString(theme));
459        pw.println(prefix + "requiresSmallestWidthDp=" + requiresSmallestWidthDp
460                + " compatibleWidthLimitDp=" + compatibleWidthLimitDp
461                + " largestWidthLimitDp=" + largestWidthLimitDp);
462        pw.println(prefix + "sourceDir=" + sourceDir);
463        if (sourceDir == null) {
464            if (publicSourceDir != null) {
465                pw.println(prefix + "publicSourceDir=" + publicSourceDir);
466            }
467        } else if (!sourceDir.equals(publicSourceDir)) {
468            pw.println(prefix + "publicSourceDir=" + publicSourceDir);
469        }
470        if (resourceDirs != null) {
471            pw.println(prefix + "resourceDirs=" + resourceDirs);
472        }
473        pw.println(prefix + "dataDir=" + dataDir);
474        if (sharedLibraryFiles != null) {
475            pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
476        }
477        pw.println(prefix + "enabled=" + enabled + " targetSdkVersion=" + targetSdkVersion);
478        if (manageSpaceActivityName != null) {
479            pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
480        }
481        if (descriptionRes != 0) {
482            pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes));
483        }
484        if (uiOptions != 0) {
485            pw.println(prefix + "uiOptions=0x" + Integer.toHexString(uiOptions));
486        }
487        pw.println(prefix + "supportsRtl=" + (hasRtlSupport() ? "true" : "false"));
488        super.dumpBack(pw, prefix);
489    }
490
491    /**
492     * @return true if "supportsRtl" has been set to true in the AndroidManifest
493     * @hide
494     */
495    public boolean hasRtlSupport() {
496        return (flags & FLAG_SUPPORTS_RTL) == FLAG_SUPPORTS_RTL;
497    }
498
499    public static class DisplayNameComparator
500            implements Comparator<ApplicationInfo> {
501        public DisplayNameComparator(PackageManager pm) {
502            mPM = pm;
503        }
504
505        public final int compare(ApplicationInfo aa, ApplicationInfo ab) {
506            CharSequence  sa = mPM.getApplicationLabel(aa);
507            if (sa == null) {
508                sa = aa.packageName;
509            }
510            CharSequence  sb = mPM.getApplicationLabel(ab);
511            if (sb == null) {
512                sb = ab.packageName;
513            }
514
515            return sCollator.compare(sa.toString(), sb.toString());
516        }
517
518        private final Collator   sCollator = Collator.getInstance();
519        private PackageManager   mPM;
520    }
521
522    public ApplicationInfo() {
523    }
524
525    public ApplicationInfo(ApplicationInfo orig) {
526        super(orig);
527        taskAffinity = orig.taskAffinity;
528        permission = orig.permission;
529        processName = orig.processName;
530        className = orig.className;
531        theme = orig.theme;
532        flags = orig.flags;
533        requiresSmallestWidthDp = orig.requiresSmallestWidthDp;
534        compatibleWidthLimitDp = orig.compatibleWidthLimitDp;
535        largestWidthLimitDp = orig.largestWidthLimitDp;
536        sourceDir = orig.sourceDir;
537        publicSourceDir = orig.publicSourceDir;
538        nativeLibraryDir = orig.nativeLibraryDir;
539        resourceDirs = orig.resourceDirs;
540        sharedLibraryFiles = orig.sharedLibraryFiles;
541        dataDir = orig.dataDir;
542        uid = orig.uid;
543        targetSdkVersion = orig.targetSdkVersion;
544        enabled = orig.enabled;
545        enabledSetting = orig.enabledSetting;
546        installLocation = orig.installLocation;
547        manageSpaceActivityName = orig.manageSpaceActivityName;
548        descriptionRes = orig.descriptionRes;
549        uiOptions = orig.uiOptions;
550    }
551
552
553    public String toString() {
554        return "ApplicationInfo{"
555            + Integer.toHexString(System.identityHashCode(this))
556            + " " + packageName + "}";
557    }
558
559    public int describeContents() {
560        return 0;
561    }
562
563    public void writeToParcel(Parcel dest, int parcelableFlags) {
564        super.writeToParcel(dest, parcelableFlags);
565        dest.writeString(taskAffinity);
566        dest.writeString(permission);
567        dest.writeString(processName);
568        dest.writeString(className);
569        dest.writeInt(theme);
570        dest.writeInt(flags);
571        dest.writeInt(requiresSmallestWidthDp);
572        dest.writeInt(compatibleWidthLimitDp);
573        dest.writeInt(largestWidthLimitDp);
574        dest.writeString(sourceDir);
575        dest.writeString(publicSourceDir);
576        dest.writeString(nativeLibraryDir);
577        dest.writeStringArray(resourceDirs);
578        dest.writeStringArray(sharedLibraryFiles);
579        dest.writeString(dataDir);
580        dest.writeInt(uid);
581        dest.writeInt(targetSdkVersion);
582        dest.writeInt(enabled ? 1 : 0);
583        dest.writeInt(enabledSetting);
584        dest.writeInt(installLocation);
585        dest.writeString(manageSpaceActivityName);
586        dest.writeString(backupAgentName);
587        dest.writeInt(descriptionRes);
588        dest.writeInt(uiOptions);
589    }
590
591    public static final Parcelable.Creator<ApplicationInfo> CREATOR
592            = new Parcelable.Creator<ApplicationInfo>() {
593        public ApplicationInfo createFromParcel(Parcel source) {
594            return new ApplicationInfo(source);
595        }
596        public ApplicationInfo[] newArray(int size) {
597            return new ApplicationInfo[size];
598        }
599    };
600
601    private ApplicationInfo(Parcel source) {
602        super(source);
603        taskAffinity = source.readString();
604        permission = source.readString();
605        processName = source.readString();
606        className = source.readString();
607        theme = source.readInt();
608        flags = source.readInt();
609        requiresSmallestWidthDp = source.readInt();
610        compatibleWidthLimitDp = source.readInt();
611        largestWidthLimitDp = source.readInt();
612        sourceDir = source.readString();
613        publicSourceDir = source.readString();
614        nativeLibraryDir = source.readString();
615        resourceDirs = source.readStringArray();
616        sharedLibraryFiles = source.readStringArray();
617        dataDir = source.readString();
618        uid = source.readInt();
619        targetSdkVersion = source.readInt();
620        enabled = source.readInt() != 0;
621        enabledSetting = source.readInt();
622        installLocation = source.readInt();
623        manageSpaceActivityName = source.readString();
624        backupAgentName = source.readString();
625        descriptionRes = source.readInt();
626        uiOptions = source.readInt();
627    }
628
629    /**
630     * Retrieve the textual description of the application.  This
631     * will call back on the given PackageManager to load the description from
632     * the application.
633     *
634     * @param pm A PackageManager from which the label can be loaded; usually
635     * the PackageManager from which you originally retrieved this item.
636     *
637     * @return Returns a CharSequence containing the application's description.
638     * If there is no description, null is returned.
639     */
640    public CharSequence loadDescription(PackageManager pm) {
641        if (descriptionRes != 0) {
642            CharSequence label = pm.getText(packageName, descriptionRes, this);
643            if (label != null) {
644                return label;
645            }
646        }
647        return null;
648    }
649
650    /**
651     * Disable compatibility mode
652     *
653     * @hide
654     */
655    public void disableCompatibilityMode() {
656        flags |= (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS |
657                FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS |
658                FLAG_SUPPORTS_SCREEN_DENSITIES | FLAG_SUPPORTS_XLARGE_SCREENS);
659    }
660
661    /**
662     * @hide
663     */
664    @Override protected Drawable loadDefaultIcon(PackageManager pm) {
665        if ((flags & FLAG_EXTERNAL_STORAGE) != 0
666                && isPackageUnavailable(pm)) {
667            return Resources.getSystem().getDrawable(
668                    com.android.internal.R.drawable.sym_app_on_sd_unavailable_icon);
669        }
670        return pm.getDefaultActivityIcon();
671    }
672
673    private boolean isPackageUnavailable(PackageManager pm) {
674        try {
675            return pm.getPackageInfo(packageName, 0) == null;
676        } catch (NameNotFoundException ex) {
677            return true;
678        }
679    }
680
681    /**
682     * @hide
683     */
684    @Override protected ApplicationInfo getApplicationInfo() {
685        return this;
686    }
687}
688