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