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