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