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