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