ApplicationPackageManager.java revision 7f7b0c759e2970178ef68805b21f06a26e24eb76
1/*
2 * Copyright (C) 2010 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.app;
18
19import android.content.ComponentName;
20import android.content.ContentResolver;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.content.IntentSender;
24import android.content.pm.ActivityInfo;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.ComponentInfo;
27import android.content.pm.ContainerEncryptionParams;
28import android.content.pm.FeatureInfo;
29import android.content.pm.IPackageDataObserver;
30import android.content.pm.IPackageDeleteObserver;
31import android.content.pm.IPackageInstallObserver;
32import android.content.pm.IPackageInstallObserver2;
33import android.content.pm.IPackageManager;
34import android.content.pm.IPackageMoveObserver;
35import android.content.pm.IPackageStatsObserver;
36import android.content.pm.InstrumentationInfo;
37import android.content.pm.PackageInfo;
38import android.content.pm.PackageInstaller;
39import android.content.pm.PackageItemInfo;
40import android.content.pm.PackageManager;
41import android.content.pm.ParceledListSlice;
42import android.content.pm.PermissionGroupInfo;
43import android.content.pm.PermissionInfo;
44import android.content.pm.ProviderInfo;
45import android.content.pm.ResolveInfo;
46import android.content.pm.ServiceInfo;
47import android.content.pm.ManifestDigest;
48import android.content.pm.VerificationParams;
49import android.content.pm.VerifierDeviceIdentity;
50import android.content.res.Resources;
51import android.content.res.XmlResourceParser;
52import android.graphics.Bitmap;
53import android.graphics.drawable.BitmapDrawable;
54import android.graphics.drawable.Drawable;
55import android.net.Uri;
56import android.os.Process;
57import android.os.RemoteException;
58import android.os.UserHandle;
59import android.os.UserManager;
60import android.util.ArrayMap;
61import android.util.Log;
62import android.view.Display;
63
64import java.lang.ref.WeakReference;
65import java.util.ArrayList;
66import java.util.List;
67
68/*package*/
69final class ApplicationPackageManager extends PackageManager {
70    private static final String TAG = "ApplicationPackageManager";
71    private final static boolean DEBUG = false;
72    private final static boolean DEBUG_ICONS = false;
73
74    UserManager mUserManager;
75
76    UserManager getUserManager() {
77        if (mUserManager == null) {
78            mUserManager = UserManager.get(mContext);
79        }
80        return mUserManager;
81    }
82
83    @Override
84    public PackageInfo getPackageInfo(String packageName, int flags)
85            throws NameNotFoundException {
86        try {
87            PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId());
88            if (pi != null) {
89                return pi;
90            }
91        } catch (RemoteException e) {
92            throw new RuntimeException("Package manager has died", e);
93        }
94
95        throw new NameNotFoundException(packageName);
96    }
97
98    @Override
99    public String[] currentToCanonicalPackageNames(String[] names) {
100        try {
101            return mPM.currentToCanonicalPackageNames(names);
102        } catch (RemoteException e) {
103            throw new RuntimeException("Package manager has died", e);
104        }
105    }
106
107    @Override
108    public String[] canonicalToCurrentPackageNames(String[] names) {
109        try {
110            return mPM.canonicalToCurrentPackageNames(names);
111        } catch (RemoteException e) {
112            throw new RuntimeException("Package manager has died", e);
113        }
114    }
115
116    @Override
117    public Intent getLaunchIntentForPackage(String packageName) {
118        // First see if the package has an INFO activity; the existence of
119        // such an activity is implied to be the desired front-door for the
120        // overall package (such as if it has multiple launcher entries).
121        Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
122        intentToResolve.addCategory(Intent.CATEGORY_INFO);
123        intentToResolve.setPackage(packageName);
124        List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
125
126        // Otherwise, try to find a main launcher activity.
127        if (ris == null || ris.size() <= 0) {
128            // reuse the intent instance
129            intentToResolve.removeCategory(Intent.CATEGORY_INFO);
130            intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
131            intentToResolve.setPackage(packageName);
132            ris = queryIntentActivities(intentToResolve, 0);
133        }
134        if (ris == null || ris.size() <= 0) {
135            return null;
136        }
137        Intent intent = new Intent(intentToResolve);
138        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
139        intent.setClassName(ris.get(0).activityInfo.packageName,
140                ris.get(0).activityInfo.name);
141        return intent;
142    }
143
144    @Override
145    public Intent getLeanbackLaunchIntentForPackage(String packageName) {
146        // Try to find a main leanback_launcher activity.
147        Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
148        intentToResolve.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER);
149        intentToResolve.setPackage(packageName);
150        List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
151
152        if (ris == null || ris.size() <= 0) {
153            return null;
154        }
155        Intent intent = new Intent(intentToResolve);
156        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
157        intent.setClassName(ris.get(0).activityInfo.packageName,
158                ris.get(0).activityInfo.name);
159        return intent;
160    }
161
162    @Override
163    public int[] getPackageGids(String packageName)
164            throws NameNotFoundException {
165        try {
166            int[] gids = mPM.getPackageGids(packageName);
167            if (gids == null || gids.length > 0) {
168                return gids;
169            }
170        } catch (RemoteException e) {
171            throw new RuntimeException("Package manager has died", e);
172        }
173
174        throw new NameNotFoundException(packageName);
175    }
176
177    @Override
178    public int getPackageUid(String packageName, int userHandle)
179            throws NameNotFoundException {
180        try {
181            int uid = mPM.getPackageUid(packageName, userHandle);
182            if (uid >= 0) {
183                return uid;
184            }
185        } catch (RemoteException e) {
186            throw new RuntimeException("Package manager has died", e);
187        }
188
189        throw new NameNotFoundException(packageName);
190    }
191
192    @Override
193    public PermissionInfo getPermissionInfo(String name, int flags)
194            throws NameNotFoundException {
195        try {
196            PermissionInfo pi = mPM.getPermissionInfo(name, flags);
197            if (pi != null) {
198                return pi;
199            }
200        } catch (RemoteException e) {
201            throw new RuntimeException("Package manager has died", e);
202        }
203
204        throw new NameNotFoundException(name);
205    }
206
207    @Override
208    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
209            throws NameNotFoundException {
210        try {
211            List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
212            if (pi != null) {
213                return pi;
214            }
215        } catch (RemoteException e) {
216            throw new RuntimeException("Package manager has died", e);
217        }
218
219        throw new NameNotFoundException(group);
220    }
221
222    @Override
223    public PermissionGroupInfo getPermissionGroupInfo(String name,
224                                                      int flags) throws NameNotFoundException {
225        try {
226            PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
227            if (pgi != null) {
228                return pgi;
229            }
230        } catch (RemoteException e) {
231            throw new RuntimeException("Package manager has died", e);
232        }
233
234        throw new NameNotFoundException(name);
235    }
236
237    @Override
238    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
239        try {
240            return mPM.getAllPermissionGroups(flags);
241        } catch (RemoteException e) {
242            throw new RuntimeException("Package manager has died", e);
243        }
244    }
245
246    @Override
247    public ApplicationInfo getApplicationInfo(String packageName, int flags)
248            throws NameNotFoundException {
249        try {
250            ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags, mContext.getUserId());
251            if (ai != null) {
252                return ai;
253            }
254        } catch (RemoteException e) {
255            throw new RuntimeException("Package manager has died", e);
256        }
257
258        throw new NameNotFoundException(packageName);
259    }
260
261    @Override
262    public ActivityInfo getActivityInfo(ComponentName className, int flags)
263            throws NameNotFoundException {
264        try {
265            ActivityInfo ai = mPM.getActivityInfo(className, flags, mContext.getUserId());
266            if (ai != null) {
267                return ai;
268            }
269        } catch (RemoteException e) {
270            throw new RuntimeException("Package manager has died", e);
271        }
272
273        throw new NameNotFoundException(className.toString());
274    }
275
276    @Override
277    public ActivityInfo getReceiverInfo(ComponentName className, int flags)
278            throws NameNotFoundException {
279        try {
280            ActivityInfo ai = mPM.getReceiverInfo(className, flags, mContext.getUserId());
281            if (ai != null) {
282                return ai;
283            }
284        } catch (RemoteException e) {
285            throw new RuntimeException("Package manager has died", e);
286        }
287
288        throw new NameNotFoundException(className.toString());
289    }
290
291    @Override
292    public ServiceInfo getServiceInfo(ComponentName className, int flags)
293            throws NameNotFoundException {
294        try {
295            ServiceInfo si = mPM.getServiceInfo(className, flags, mContext.getUserId());
296            if (si != null) {
297                return si;
298            }
299        } catch (RemoteException e) {
300            throw new RuntimeException("Package manager has died", e);
301        }
302
303        throw new NameNotFoundException(className.toString());
304    }
305
306    @Override
307    public ProviderInfo getProviderInfo(ComponentName className, int flags)
308            throws NameNotFoundException {
309        try {
310            ProviderInfo pi = mPM.getProviderInfo(className, flags, mContext.getUserId());
311            if (pi != null) {
312                return pi;
313            }
314        } catch (RemoteException e) {
315            throw new RuntimeException("Package manager has died", e);
316        }
317
318        throw new NameNotFoundException(className.toString());
319    }
320
321    @Override
322    public String[] getSystemSharedLibraryNames() {
323        try {
324            return mPM.getSystemSharedLibraryNames();
325        } catch (RemoteException e) {
326            throw new RuntimeException("Package manager has died", e);
327        }
328    }
329
330    @Override
331    public FeatureInfo[] getSystemAvailableFeatures() {
332        try {
333            return mPM.getSystemAvailableFeatures();
334        } catch (RemoteException e) {
335            throw new RuntimeException("Package manager has died", e);
336        }
337    }
338
339    @Override
340    public boolean hasSystemFeature(String name) {
341        try {
342            return mPM.hasSystemFeature(name);
343        } catch (RemoteException e) {
344            throw new RuntimeException("Package manager has died", e);
345        }
346    }
347
348    @Override
349    public int checkPermission(String permName, String pkgName) {
350        try {
351            return mPM.checkPermission(permName, pkgName);
352        } catch (RemoteException e) {
353            throw new RuntimeException("Package manager has died", e);
354        }
355    }
356
357    @Override
358    public boolean addPermission(PermissionInfo info) {
359        try {
360            return mPM.addPermission(info);
361        } catch (RemoteException e) {
362            throw new RuntimeException("Package manager has died", e);
363        }
364    }
365
366    @Override
367    public boolean addPermissionAsync(PermissionInfo info) {
368        try {
369            return mPM.addPermissionAsync(info);
370        } catch (RemoteException e) {
371            throw new RuntimeException("Package manager has died", e);
372        }
373    }
374
375    @Override
376    public void removePermission(String name) {
377        try {
378            mPM.removePermission(name);
379        } catch (RemoteException e) {
380            throw new RuntimeException("Package manager has died", e);
381        }
382    }
383
384    @Override
385    public void grantPermission(String packageName, String permissionName) {
386        try {
387            mPM.grantPermission(packageName, permissionName);
388        } catch (RemoteException e) {
389            throw new RuntimeException("Package manager has died", e);
390        }
391    }
392
393    @Override
394    public void revokePermission(String packageName, String permissionName) {
395        try {
396            mPM.revokePermission(packageName, permissionName);
397        } catch (RemoteException e) {
398            throw new RuntimeException("Package manager has died", e);
399        }
400    }
401
402    @Override
403    public int checkSignatures(String pkg1, String pkg2) {
404        try {
405            return mPM.checkSignatures(pkg1, pkg2);
406        } catch (RemoteException e) {
407            throw new RuntimeException("Package manager has died", e);
408        }
409    }
410
411    @Override
412    public int checkSignatures(int uid1, int uid2) {
413        try {
414            return mPM.checkUidSignatures(uid1, uid2);
415        } catch (RemoteException e) {
416            throw new RuntimeException("Package manager has died", e);
417        }
418    }
419
420    @Override
421    public String[] getPackagesForUid(int uid) {
422        try {
423            return mPM.getPackagesForUid(uid);
424        } catch (RemoteException e) {
425            throw new RuntimeException("Package manager has died", e);
426        }
427    }
428
429    @Override
430    public String getNameForUid(int uid) {
431        try {
432            return mPM.getNameForUid(uid);
433        } catch (RemoteException e) {
434            throw new RuntimeException("Package manager has died", e);
435        }
436    }
437
438    @Override
439    public int getUidForSharedUser(String sharedUserName)
440            throws NameNotFoundException {
441        try {
442            int uid = mPM.getUidForSharedUser(sharedUserName);
443            if(uid != -1) {
444                return uid;
445            }
446        } catch (RemoteException e) {
447            throw new RuntimeException("Package manager has died", e);
448        }
449        throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
450    }
451
452    @SuppressWarnings("unchecked")
453    @Override
454    public List<PackageInfo> getInstalledPackages(int flags) {
455        return getInstalledPackages(flags, mContext.getUserId());
456    }
457
458    /** @hide */
459    @Override
460    public List<PackageInfo> getInstalledPackages(int flags, int userId) {
461        try {
462            ParceledListSlice<PackageInfo> slice = mPM.getInstalledPackages(flags, userId);
463            return slice.getList();
464        } catch (RemoteException e) {
465            throw new RuntimeException("Package manager has died", e);
466        }
467    }
468
469    @SuppressWarnings("unchecked")
470    @Override
471    public List<PackageInfo> getPackagesHoldingPermissions(
472            String[] permissions, int flags) {
473        final int userId = mContext.getUserId();
474        try {
475            ParceledListSlice<PackageInfo> slice = mPM.getPackagesHoldingPermissions(
476                    permissions, flags, userId);
477            return slice.getList();
478        } catch (RemoteException e) {
479            throw new RuntimeException("Package manager has died", e);
480        }
481    }
482
483    @SuppressWarnings("unchecked")
484    @Override
485    public List<ApplicationInfo> getInstalledApplications(int flags) {
486        final int userId = mContext.getUserId();
487        try {
488            ParceledListSlice<ApplicationInfo> slice = mPM.getInstalledApplications(flags, userId);
489            return slice.getList();
490        } catch (RemoteException e) {
491            throw new RuntimeException("Package manager has died", e);
492        }
493    }
494
495    @Override
496    public ResolveInfo resolveActivity(Intent intent, int flags) {
497        return resolveActivityAsUser(intent, flags, mContext.getUserId());
498    }
499
500    @Override
501    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
502        try {
503            return mPM.resolveIntent(
504                intent,
505                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
506                flags,
507                userId);
508        } catch (RemoteException e) {
509            throw new RuntimeException("Package manager has died", e);
510        }
511    }
512
513    @Override
514    public List<ResolveInfo> queryIntentActivities(Intent intent,
515                                                   int flags) {
516        return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId());
517    }
518
519    /** @hide Same as above but for a specific user */
520    @Override
521    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
522                                                   int flags, int userId) {
523        try {
524            return mPM.queryIntentActivities(
525                intent,
526                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
527                flags,
528                userId);
529        } catch (RemoteException e) {
530            throw new RuntimeException("Package manager has died", e);
531        }
532    }
533
534    @Override
535    public List<ResolveInfo> queryIntentActivityOptions(
536        ComponentName caller, Intent[] specifics, Intent intent,
537        int flags) {
538        final ContentResolver resolver = mContext.getContentResolver();
539
540        String[] specificTypes = null;
541        if (specifics != null) {
542            final int N = specifics.length;
543            for (int i=0; i<N; i++) {
544                Intent sp = specifics[i];
545                if (sp != null) {
546                    String t = sp.resolveTypeIfNeeded(resolver);
547                    if (t != null) {
548                        if (specificTypes == null) {
549                            specificTypes = new String[N];
550                        }
551                        specificTypes[i] = t;
552                    }
553                }
554            }
555        }
556
557        try {
558            return mPM.queryIntentActivityOptions(caller, specifics,
559                                                  specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
560                                                  flags, mContext.getUserId());
561        } catch (RemoteException e) {
562            throw new RuntimeException("Package manager has died", e);
563        }
564    }
565
566    /**
567     * @hide
568     */
569    @Override
570    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags, int userId) {
571        try {
572            return mPM.queryIntentReceivers(
573                intent,
574                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
575                flags,
576                userId);
577        } catch (RemoteException e) {
578            throw new RuntimeException("Package manager has died", e);
579        }
580    }
581
582    @Override
583    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
584        return queryBroadcastReceivers(intent, flags, mContext.getUserId());
585    }
586
587    @Override
588    public ResolveInfo resolveService(Intent intent, int flags) {
589        try {
590            return mPM.resolveService(
591                intent,
592                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
593                flags,
594                mContext.getUserId());
595        } catch (RemoteException e) {
596            throw new RuntimeException("Package manager has died", e);
597        }
598    }
599
600    @Override
601    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
602        try {
603            return mPM.queryIntentServices(
604                intent,
605                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
606                flags,
607                userId);
608        } catch (RemoteException e) {
609            throw new RuntimeException("Package manager has died", e);
610        }
611    }
612
613    @Override
614    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
615        return queryIntentServicesAsUser(intent, flags, mContext.getUserId());
616    }
617
618    @Override
619    public List<ResolveInfo> queryIntentContentProvidersAsUser(
620            Intent intent, int flags, int userId) {
621        try {
622            return mPM.queryIntentContentProviders(intent,
623                    intent.resolveTypeIfNeeded(mContext.getContentResolver()), flags, userId);
624        } catch (RemoteException e) {
625            throw new RuntimeException("Package manager has died", e);
626        }
627    }
628
629    @Override
630    public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
631        return queryIntentContentProvidersAsUser(intent, flags, mContext.getUserId());
632    }
633
634    @Override
635    public ProviderInfo resolveContentProvider(String name, int flags) {
636        return resolveContentProviderAsUser(name, flags, mContext.getUserId());
637    }
638
639    /** @hide **/
640    @Override
641    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
642        try {
643            return mPM.resolveContentProvider(name, flags, userId);
644        } catch (RemoteException e) {
645            throw new RuntimeException("Package manager has died", e);
646        }
647    }
648
649    @Override
650    public List<ProviderInfo> queryContentProviders(String processName,
651                                                    int uid, int flags) {
652        try {
653            return mPM.queryContentProviders(processName, uid, flags);
654        } catch (RemoteException e) {
655            throw new RuntimeException("Package manager has died", e);
656        }
657    }
658
659    @Override
660    public InstrumentationInfo getInstrumentationInfo(
661        ComponentName className, int flags)
662            throws NameNotFoundException {
663        try {
664            InstrumentationInfo ii = mPM.getInstrumentationInfo(
665                className, flags);
666            if (ii != null) {
667                return ii;
668            }
669        } catch (RemoteException e) {
670            throw new RuntimeException("Package manager has died", e);
671        }
672
673        throw new NameNotFoundException(className.toString());
674    }
675
676    @Override
677    public List<InstrumentationInfo> queryInstrumentation(
678        String targetPackage, int flags) {
679        try {
680            return mPM.queryInstrumentation(targetPackage, flags);
681        } catch (RemoteException e) {
682            throw new RuntimeException("Package manager has died", e);
683        }
684    }
685
686    @Override public Drawable getDrawable(String packageName, int resid,
687                                          ApplicationInfo appInfo) {
688        ResourceName name = new ResourceName(packageName, resid);
689        Drawable dr = getCachedIcon(name);
690        if (dr != null) {
691            return dr;
692        }
693        if (appInfo == null) {
694            try {
695                appInfo = getApplicationInfo(packageName, 0);
696            } catch (NameNotFoundException e) {
697                return null;
698            }
699        }
700        try {
701            Resources r = getResourcesForApplication(appInfo);
702            dr = r.getDrawable(resid);
703            if (false) {
704                RuntimeException e = new RuntimeException("here");
705                e.fillInStackTrace();
706                Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
707                      + " from package " + packageName
708                      + ": app scale=" + r.getCompatibilityInfo().applicationScale
709                      + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
710                      e);
711            }
712            if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
713                                   + Integer.toHexString(resid) + " from " + r
714                                   + ": " + dr);
715            putCachedIcon(name, dr);
716            return dr;
717        } catch (NameNotFoundException e) {
718            Log.w("PackageManager", "Failure retrieving resources for"
719                  + appInfo.packageName);
720        } catch (Resources.NotFoundException e) {
721            Log.w("PackageManager", "Failure retrieving resources for"
722                  + appInfo.packageName + ": " + e.getMessage());
723        } catch (RuntimeException e) {
724            // If an exception was thrown, fall through to return
725            // default icon.
726            Log.w("PackageManager", "Failure retrieving icon 0x"
727                  + Integer.toHexString(resid) + " in package "
728                  + packageName, e);
729        }
730        return null;
731    }
732
733    @Override public Drawable getActivityIcon(ComponentName activityName)
734            throws NameNotFoundException {
735        return getActivityInfo(activityName, 0).loadIcon(this);
736    }
737
738    @Override public Drawable getActivityIcon(Intent intent)
739            throws NameNotFoundException {
740        if (intent.getComponent() != null) {
741            return getActivityIcon(intent.getComponent());
742        }
743
744        ResolveInfo info = resolveActivity(
745            intent, PackageManager.MATCH_DEFAULT_ONLY);
746        if (info != null) {
747            return info.activityInfo.loadIcon(this);
748        }
749
750        throw new NameNotFoundException(intent.toUri(0));
751    }
752
753    @Override public Drawable getDefaultActivityIcon() {
754        return Resources.getSystem().getDrawable(
755            com.android.internal.R.drawable.sym_def_app_icon);
756    }
757
758    @Override public Drawable getApplicationIcon(ApplicationInfo info) {
759        return info.loadIcon(this);
760    }
761
762    @Override public Drawable getApplicationIcon(String packageName)
763            throws NameNotFoundException {
764        return getApplicationIcon(getApplicationInfo(packageName, 0));
765    }
766
767    @Override
768    public Drawable getActivityBanner(ComponentName activityName)
769            throws NameNotFoundException {
770        return getActivityInfo(activityName, 0).loadBanner(this);
771    }
772
773    @Override
774    public Drawable getActivityBanner(Intent intent)
775            throws NameNotFoundException {
776        if (intent.getComponent() != null) {
777            return getActivityBanner(intent.getComponent());
778        }
779
780        ResolveInfo info = resolveActivity(
781                intent, PackageManager.MATCH_DEFAULT_ONLY);
782        if (info != null) {
783            return info.activityInfo.loadBanner(this);
784        }
785
786        throw new NameNotFoundException(intent.toUri(0));
787    }
788
789    @Override
790    public Drawable getApplicationBanner(ApplicationInfo info) {
791        return info.loadBanner(this);
792    }
793
794    @Override
795    public Drawable getApplicationBanner(String packageName)
796            throws NameNotFoundException {
797        return getApplicationBanner(getApplicationInfo(packageName, 0));
798    }
799
800    @Override
801    public Drawable getActivityLogo(ComponentName activityName)
802            throws NameNotFoundException {
803        return getActivityInfo(activityName, 0).loadLogo(this);
804    }
805
806    @Override
807    public Drawable getActivityLogo(Intent intent)
808            throws NameNotFoundException {
809        if (intent.getComponent() != null) {
810            return getActivityLogo(intent.getComponent());
811        }
812
813        ResolveInfo info = resolveActivity(
814            intent, PackageManager.MATCH_DEFAULT_ONLY);
815        if (info != null) {
816            return info.activityInfo.loadLogo(this);
817        }
818
819        throw new NameNotFoundException(intent.toUri(0));
820    }
821
822    @Override
823    public Drawable getApplicationLogo(ApplicationInfo info) {
824        return info.loadLogo(this);
825    }
826
827    @Override
828    public Drawable getApplicationLogo(String packageName)
829            throws NameNotFoundException {
830        return getApplicationLogo(getApplicationInfo(packageName, 0));
831    }
832
833    @Override public Resources getResourcesForActivity(
834        ComponentName activityName) throws NameNotFoundException {
835        return getResourcesForApplication(
836            getActivityInfo(activityName, 0).applicationInfo);
837    }
838
839    @Override public Resources getResourcesForApplication(
840        ApplicationInfo app) throws NameNotFoundException {
841        if (app.packageName.equals("system")) {
842            return mContext.mMainThread.getSystemContext().getResources();
843        }
844        final boolean sameUid = (app.uid == Process.myUid());
845        Resources r = mContext.mMainThread.getTopLevelResources(
846                sameUid ? app.sourceDir : app.publicSourceDir,
847                sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
848                app.resourceDirs, null, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
849        if (r != null) {
850            return r;
851        }
852        throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
853    }
854
855    @Override public Resources getResourcesForApplication(
856        String appPackageName) throws NameNotFoundException {
857        return getResourcesForApplication(
858            getApplicationInfo(appPackageName, 0));
859    }
860
861    /** @hide */
862    @Override
863    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
864            throws NameNotFoundException {
865        if (userId < 0) {
866            throw new IllegalArgumentException(
867                    "Call does not support special user #" + userId);
868        }
869        if ("system".equals(appPackageName)) {
870            return mContext.mMainThread.getSystemContext().getResources();
871        }
872        try {
873            ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, 0, userId);
874            if (ai != null) {
875                return getResourcesForApplication(ai);
876            }
877        } catch (RemoteException e) {
878            throw new RuntimeException("Package manager has died", e);
879        }
880        throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
881    }
882
883    int mCachedSafeMode = -1;
884    @Override public boolean isSafeMode() {
885        try {
886            if (mCachedSafeMode < 0) {
887                mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
888            }
889            return mCachedSafeMode != 0;
890        } catch (RemoteException e) {
891            throw new RuntimeException("Package manager has died", e);
892        }
893    }
894
895    static void configurationChanged() {
896        synchronized (sSync) {
897            sIconCache.clear();
898            sStringCache.clear();
899        }
900    }
901
902    ApplicationPackageManager(ContextImpl context,
903                              IPackageManager pm) {
904        mContext = context;
905        mPM = pm;
906    }
907
908    private Drawable getCachedIcon(ResourceName name) {
909        synchronized (sSync) {
910            WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
911            if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
912                                   + name + ": " + wr);
913            if (wr != null) {   // we have the activity
914                Drawable.ConstantState state = wr.get();
915                if (state != null) {
916                    if (DEBUG_ICONS) {
917                        Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
918                    }
919                    // Note: It's okay here to not use the newDrawable(Resources) variant
920                    //       of the API. The ConstantState comes from a drawable that was
921                    //       originally created by passing the proper app Resources instance
922                    //       which means the state should already contain the proper
923                    //       resources specific information (like density.) See
924                    //       BitmapDrawable.BitmapState for instance.
925                    return state.newDrawable();
926                }
927                // our entry has been purged
928                sIconCache.remove(name);
929            }
930        }
931        return null;
932    }
933
934    private void putCachedIcon(ResourceName name, Drawable dr) {
935        synchronized (sSync) {
936            sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState()));
937            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
938        }
939    }
940
941    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
942        boolean immediateGc = false;
943        if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
944            immediateGc = true;
945        }
946        if (pkgList != null && (pkgList.length > 0)) {
947            boolean needCleanup = false;
948            for (String ssp : pkgList) {
949                synchronized (sSync) {
950                    for (int i=sIconCache.size()-1; i>=0; i--) {
951                        ResourceName nm = sIconCache.keyAt(i);
952                        if (nm.packageName.equals(ssp)) {
953                            //Log.i(TAG, "Removing cached drawable for " + nm);
954                            sIconCache.removeAt(i);
955                            needCleanup = true;
956                        }
957                    }
958                    for (int i=sStringCache.size()-1; i>=0; i--) {
959                        ResourceName nm = sStringCache.keyAt(i);
960                        if (nm.packageName.equals(ssp)) {
961                            //Log.i(TAG, "Removing cached string for " + nm);
962                            sStringCache.removeAt(i);
963                            needCleanup = true;
964                        }
965                    }
966                }
967            }
968            if (needCleanup || hasPkgInfo) {
969                if (immediateGc) {
970                    // Schedule an immediate gc.
971                    Runtime.getRuntime().gc();
972                } else {
973                    ActivityThread.currentActivityThread().scheduleGcIdler();
974                }
975            }
976        }
977    }
978
979    private static final class ResourceName {
980        final String packageName;
981        final int iconId;
982
983        ResourceName(String _packageName, int _iconId) {
984            packageName = _packageName;
985            iconId = _iconId;
986        }
987
988        ResourceName(ApplicationInfo aInfo, int _iconId) {
989            this(aInfo.packageName, _iconId);
990        }
991
992        ResourceName(ComponentInfo cInfo, int _iconId) {
993            this(cInfo.applicationInfo.packageName, _iconId);
994        }
995
996        ResourceName(ResolveInfo rInfo, int _iconId) {
997            this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
998        }
999
1000        @Override
1001        public boolean equals(Object o) {
1002            if (this == o) return true;
1003            if (o == null || getClass() != o.getClass()) return false;
1004
1005            ResourceName that = (ResourceName) o;
1006
1007            if (iconId != that.iconId) return false;
1008            return !(packageName != null ?
1009                     !packageName.equals(that.packageName) : that.packageName != null);
1010
1011        }
1012
1013        @Override
1014        public int hashCode() {
1015            int result;
1016            result = packageName.hashCode();
1017            result = 31 * result + iconId;
1018            return result;
1019        }
1020
1021        @Override
1022        public String toString() {
1023            return "{ResourceName " + packageName + " / " + iconId + "}";
1024        }
1025    }
1026
1027    private CharSequence getCachedString(ResourceName name) {
1028        synchronized (sSync) {
1029            WeakReference<CharSequence> wr = sStringCache.get(name);
1030            if (wr != null) {   // we have the activity
1031                CharSequence cs = wr.get();
1032                if (cs != null) {
1033                    return cs;
1034                }
1035                // our entry has been purged
1036                sStringCache.remove(name);
1037            }
1038        }
1039        return null;
1040    }
1041
1042    private void putCachedString(ResourceName name, CharSequence cs) {
1043        synchronized (sSync) {
1044            sStringCache.put(name, new WeakReference<CharSequence>(cs));
1045        }
1046    }
1047
1048    @Override
1049    public CharSequence getText(String packageName, int resid,
1050                                ApplicationInfo appInfo) {
1051        ResourceName name = new ResourceName(packageName, resid);
1052        CharSequence text = getCachedString(name);
1053        if (text != null) {
1054            return text;
1055        }
1056        if (appInfo == null) {
1057            try {
1058                appInfo = getApplicationInfo(packageName, 0);
1059            } catch (NameNotFoundException e) {
1060                return null;
1061            }
1062        }
1063        try {
1064            Resources r = getResourcesForApplication(appInfo);
1065            text = r.getText(resid);
1066            putCachedString(name, text);
1067            return text;
1068        } catch (NameNotFoundException e) {
1069            Log.w("PackageManager", "Failure retrieving resources for"
1070                  + appInfo.packageName);
1071        } catch (RuntimeException e) {
1072            // If an exception was thrown, fall through to return
1073            // default icon.
1074            Log.w("PackageManager", "Failure retrieving text 0x"
1075                  + Integer.toHexString(resid) + " in package "
1076                  + packageName, e);
1077        }
1078        return null;
1079    }
1080
1081    @Override
1082    public XmlResourceParser getXml(String packageName, int resid,
1083                                    ApplicationInfo appInfo) {
1084        if (appInfo == null) {
1085            try {
1086                appInfo = getApplicationInfo(packageName, 0);
1087            } catch (NameNotFoundException e) {
1088                return null;
1089            }
1090        }
1091        try {
1092            Resources r = getResourcesForApplication(appInfo);
1093            return r.getXml(resid);
1094        } catch (RuntimeException e) {
1095            // If an exception was thrown, fall through to return
1096            // default icon.
1097            Log.w("PackageManager", "Failure retrieving xml 0x"
1098                  + Integer.toHexString(resid) + " in package "
1099                  + packageName, e);
1100        } catch (NameNotFoundException e) {
1101            Log.w("PackageManager", "Failure retrieving resources for "
1102                  + appInfo.packageName);
1103        }
1104        return null;
1105    }
1106
1107    @Override
1108    public CharSequence getApplicationLabel(ApplicationInfo info) {
1109        return info.loadLabel(this);
1110    }
1111
1112    @Override
1113    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1114                               String installerPackageName) {
1115        try {
1116            mPM.installPackageEtc(packageURI, observer, null, flags, installerPackageName);
1117        } catch (RemoteException e) {
1118            // Should never happen!
1119        }
1120    }
1121
1122    @Override
1123    public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
1124            int flags, String installerPackageName, Uri verificationURI,
1125            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
1126        try {
1127            mPM.installPackageWithVerificationEtc(packageURI, observer, null, flags,
1128                    installerPackageName, verificationURI, manifestDigest, encryptionParams);
1129        } catch (RemoteException e) {
1130            // Should never happen!
1131        }
1132    }
1133
1134    @Override
1135    public void installPackageWithVerificationAndEncryption(Uri packageURI,
1136            IPackageInstallObserver observer, int flags, String installerPackageName,
1137            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1138        try {
1139            mPM.installPackageWithVerificationAndEncryptionEtc(packageURI, observer, null,
1140                    flags, installerPackageName, verificationParams, encryptionParams);
1141        } catch (RemoteException e) {
1142            // Should never happen!
1143        }
1144    }
1145
1146    // Expanded observer-API versions
1147    @Override
1148    public void installPackage(Uri packageURI, PackageInstallObserver observer,
1149            int flags, String installerPackageName) {
1150        try {
1151            mPM.installPackageEtc(packageURI, null, observer.getBinder(),
1152                    flags, installerPackageName);
1153        } catch (RemoteException e) {
1154            // Should never happen!
1155        }
1156    }
1157
1158    @Override
1159    public void installPackageWithVerification(Uri packageURI,
1160            PackageInstallObserver observer, int flags, String installerPackageName,
1161            Uri verificationURI, ManifestDigest manifestDigest,
1162            ContainerEncryptionParams encryptionParams) {
1163        try {
1164            mPM.installPackageWithVerificationEtc(packageURI, null, observer.getBinder(), flags,
1165                    installerPackageName, verificationURI, manifestDigest, encryptionParams);
1166        } catch (RemoteException e) {
1167            // Should never happen!
1168        }
1169    }
1170
1171    @Override
1172    public void installPackageWithVerificationAndEncryption(Uri packageURI,
1173            PackageInstallObserver observer, int flags, String installerPackageName,
1174            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1175        try {
1176            mPM.installPackageWithVerificationAndEncryptionEtc(packageURI, null,
1177                    observer.getBinder(), flags, installerPackageName, verificationParams,
1178                    encryptionParams);
1179        } catch (RemoteException e) {
1180            // Should never happen!
1181        }
1182    }
1183
1184    @Override
1185    public int installExistingPackage(String packageName)
1186            throws NameNotFoundException {
1187        try {
1188            int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
1189            if (res == INSTALL_FAILED_INVALID_URI) {
1190                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1191            }
1192            return res;
1193        } catch (RemoteException e) {
1194            // Should never happen!
1195            throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1196        }
1197    }
1198
1199    @Override
1200    public void verifyPendingInstall(int id, int response) {
1201        try {
1202            mPM.verifyPendingInstall(id, response);
1203        } catch (RemoteException e) {
1204            // Should never happen!
1205        }
1206    }
1207
1208    @Override
1209    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1210            long millisecondsToDelay) {
1211        try {
1212            mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1213        } catch (RemoteException e) {
1214            // Should never happen!
1215        }
1216    }
1217
1218    @Override
1219    public void setInstallerPackageName(String targetPackage,
1220            String installerPackageName) {
1221        try {
1222            mPM.setInstallerPackageName(targetPackage, installerPackageName);
1223        } catch (RemoteException e) {
1224            // Should never happen!
1225        }
1226    }
1227
1228    @Override
1229    public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
1230        try {
1231            mPM.movePackage(packageName, observer, flags);
1232        } catch (RemoteException e) {
1233            // Should never happen!
1234        }
1235    }
1236
1237    @Override
1238    public String getInstallerPackageName(String packageName) {
1239        try {
1240            return mPM.getInstallerPackageName(packageName);
1241        } catch (RemoteException e) {
1242            // Should never happen!
1243        }
1244        return null;
1245    }
1246
1247    @Override
1248    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1249        try {
1250            mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
1251        } catch (RemoteException e) {
1252            // Should never happen!
1253        }
1254    }
1255    @Override
1256    public void clearApplicationUserData(String packageName,
1257                                         IPackageDataObserver observer) {
1258        try {
1259            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
1260        } catch (RemoteException e) {
1261            // Should never happen!
1262        }
1263    }
1264    @Override
1265    public void deleteApplicationCacheFiles(String packageName,
1266                                            IPackageDataObserver observer) {
1267        try {
1268            mPM.deleteApplicationCacheFiles(packageName, observer);
1269        } catch (RemoteException e) {
1270            // Should never happen!
1271        }
1272    }
1273    @Override
1274    public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
1275        try {
1276            mPM.freeStorageAndNotify(idealStorageSize, observer);
1277        } catch (RemoteException e) {
1278            // Should never happen!
1279        }
1280    }
1281
1282    @Override
1283    public void freeStorage(long freeStorageSize, IntentSender pi) {
1284        try {
1285            mPM.freeStorage(freeStorageSize, pi);
1286        } catch (RemoteException e) {
1287            // Should never happen!
1288        }
1289    }
1290
1291    @Override
1292    public void getPackageSizeInfo(String packageName, int userHandle,
1293            IPackageStatsObserver observer) {
1294        try {
1295            mPM.getPackageSizeInfo(packageName, userHandle, observer);
1296        } catch (RemoteException e) {
1297            // Should never happen!
1298        }
1299    }
1300    @Override
1301    public void addPackageToPreferred(String packageName) {
1302        try {
1303            mPM.addPackageToPreferred(packageName);
1304        } catch (RemoteException e) {
1305            // Should never happen!
1306        }
1307    }
1308
1309    @Override
1310    public void removePackageFromPreferred(String packageName) {
1311        try {
1312            mPM.removePackageFromPreferred(packageName);
1313        } catch (RemoteException e) {
1314            // Should never happen!
1315        }
1316    }
1317
1318    @Override
1319    public List<PackageInfo> getPreferredPackages(int flags) {
1320        try {
1321            return mPM.getPreferredPackages(flags);
1322        } catch (RemoteException e) {
1323            // Should never happen!
1324        }
1325        return new ArrayList<PackageInfo>();
1326    }
1327
1328    @Override
1329    public void addPreferredActivity(IntentFilter filter,
1330                                     int match, ComponentName[] set, ComponentName activity) {
1331        try {
1332            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
1333        } catch (RemoteException e) {
1334            // Should never happen!
1335        }
1336    }
1337
1338    @Override
1339    public void addPreferredActivity(IntentFilter filter, int match,
1340            ComponentName[] set, ComponentName activity, int userId) {
1341        try {
1342            mPM.addPreferredActivity(filter, match, set, activity, userId);
1343        } catch (RemoteException e) {
1344            // Should never happen!
1345        }
1346    }
1347
1348    @Override
1349    public void replacePreferredActivity(IntentFilter filter,
1350                                         int match, ComponentName[] set, ComponentName activity) {
1351        try {
1352            mPM.replacePreferredActivity(filter, match, set, activity);
1353        } catch (RemoteException e) {
1354            // Should never happen!
1355        }
1356    }
1357
1358    @Override
1359    public void clearPackagePreferredActivities(String packageName) {
1360        try {
1361            mPM.clearPackagePreferredActivities(packageName);
1362        } catch (RemoteException e) {
1363            // Should never happen!
1364        }
1365    }
1366
1367    @Override
1368    public int getPreferredActivities(List<IntentFilter> outFilters,
1369                                      List<ComponentName> outActivities, String packageName) {
1370        try {
1371            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1372        } catch (RemoteException e) {
1373            // Should never happen!
1374        }
1375        return 0;
1376    }
1377
1378    @Override
1379    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
1380        try {
1381            return mPM.getHomeActivities(outActivities);
1382        } catch (RemoteException e) {
1383            // Should never happen!
1384        }
1385        return null;
1386    }
1387
1388    @Override
1389    public void setComponentEnabledSetting(ComponentName componentName,
1390                                           int newState, int flags) {
1391        try {
1392            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
1393        } catch (RemoteException e) {
1394            // Should never happen!
1395        }
1396    }
1397
1398    @Override
1399    public int getComponentEnabledSetting(ComponentName componentName) {
1400        try {
1401            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
1402        } catch (RemoteException e) {
1403            // Should never happen!
1404        }
1405        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1406    }
1407
1408    @Override
1409    public void setApplicationEnabledSetting(String packageName,
1410                                             int newState, int flags) {
1411        try {
1412            mPM.setApplicationEnabledSetting(packageName, newState, flags,
1413                    mContext.getUserId(), mContext.getOpPackageName());
1414        } catch (RemoteException e) {
1415            // Should never happen!
1416        }
1417    }
1418
1419    @Override
1420    public int getApplicationEnabledSetting(String packageName) {
1421        try {
1422            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
1423        } catch (RemoteException e) {
1424            // Should never happen!
1425        }
1426        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1427    }
1428
1429    @Override
1430    public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
1431            UserHandle user) {
1432        try {
1433            return mPM.setApplicationBlockedSettingAsUser(packageName, blocked,
1434                    user.getIdentifier());
1435        } catch (RemoteException re) {
1436            // Should never happen!
1437        }
1438        return false;
1439    }
1440
1441    @Override
1442    public boolean getApplicationBlockedSettingAsUser(String packageName, UserHandle user) {
1443        try {
1444            return mPM.getApplicationBlockedSettingAsUser(packageName, user.getIdentifier());
1445        } catch (RemoteException re) {
1446            // Should never happen!
1447        }
1448        return false;
1449    }
1450
1451    /**
1452     * @hide
1453     */
1454    @Override
1455    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1456        try {
1457            return mPM.getVerifierDeviceIdentity();
1458        } catch (RemoteException e) {
1459            // Should never happen!
1460        }
1461        return null;
1462    }
1463
1464    @Override
1465    public PackageInstaller getPackageInstaller() {
1466        try {
1467            return new PackageInstaller(this, mPM.getPackageInstaller(), mContext.getUserId(),
1468                    mContext.getPackageName());
1469        } catch (RemoteException e) {
1470            throw e.rethrowAsRuntimeException();
1471        }
1472    }
1473
1474    /**
1475     * @hide
1476     */
1477    @Override
1478    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
1479            int flags) {
1480        try {
1481            mPM.addCrossProfileIntentFilter(filter, sourceUserId, targetUserId, flags);
1482        } catch (RemoteException e) {
1483            // Should never happen!
1484        }
1485    }
1486
1487    /**
1488     * @hide
1489     */
1490    public void addCrossProfileIntentsForPackage(String packageName,
1491            int sourceUserId, int targetUserId) {
1492        try {
1493            mPM.addCrossProfileIntentsForPackage(packageName, sourceUserId, targetUserId);
1494        } catch (RemoteException e) {
1495            // Should never happen!
1496        }
1497    }
1498
1499    /**
1500     * @hide
1501     */
1502    @Override
1503    public void clearCrossProfileIntentFilters(int sourceUserId) {
1504        try {
1505            mPM.clearCrossProfileIntentFilters(sourceUserId);
1506        } catch (RemoteException e) {
1507            // Should never happen!
1508        }
1509    }
1510
1511    /**
1512     * @hide
1513     */
1514    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
1515        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
1516            return new BitmapDrawable(getUserManager().getUserIcon(itemInfo.showUserIcon));
1517        }
1518        Drawable dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
1519        if (dr != null) {
1520            dr = getUserManager().getBadgedDrawableForUser(dr,
1521                    new UserHandle(mContext.getUserId()));
1522        }
1523        return dr;
1524    }
1525
1526    private final ContextImpl mContext;
1527    private final IPackageManager mPM;
1528
1529    private static final Object sSync = new Object();
1530    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
1531            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
1532    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
1533            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
1534}
1535