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