ApplicationPackageManager.java revision e799175b6ba3aadd972f4b861758d675d1f93987
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.util.Log;
54import android.view.Display;
55
56import java.lang.ref.WeakReference;
57import java.util.ArrayList;
58import java.util.HashMap;
59import java.util.Iterator;
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            final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
430            PackageInfo lastItem = null;
431            ParceledListSlice<PackageInfo> slice;
432
433            do {
434                final String lastKey = lastItem != null ? lastItem.packageName : null;
435                slice = mPM.getInstalledPackages(flags, lastKey, userId);
436                lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
437            } while (!slice.isLastSlice());
438
439            return packageInfos;
440        } catch (RemoteException e) {
441            throw new RuntimeException("Package manager has died", e);
442        }
443    }
444
445    @SuppressWarnings("unchecked")
446    @Override
447    public List<PackageInfo> getPackagesHoldingPermissions(
448            String[] permissions, int flags) {
449        final int userId = mContext.getUserId();
450        try {
451            final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
452            PackageInfo lastItem = null;
453            ParceledListSlice<PackageInfo> slice;
454
455            do {
456                final String lastKey = lastItem != null ? lastItem.packageName : null;
457                slice = mPM.getPackagesHoldingPermissions(permissions, flags, lastKey, userId);
458                lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
459            } while (!slice.isLastSlice());
460
461            return packageInfos;
462        } catch (RemoteException e) {
463            throw new RuntimeException("Package manager has died", e);
464        }
465    }
466
467    @SuppressWarnings("unchecked")
468    @Override
469    public List<ApplicationInfo> getInstalledApplications(int flags) {
470        final int userId = mContext.getUserId();
471        try {
472            final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>();
473            ApplicationInfo lastItem = null;
474            ParceledListSlice<ApplicationInfo> slice;
475
476            do {
477                final String lastKey = lastItem != null ? lastItem.packageName : null;
478                slice = mPM.getInstalledApplications(flags, lastKey, userId);
479                lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR);
480            } while (!slice.isLastSlice());
481
482            return applicationInfos;
483        } catch (RemoteException e) {
484            throw new RuntimeException("Package manager has died", e);
485        }
486    }
487
488    @Override
489    public ResolveInfo resolveActivity(Intent intent, int flags) {
490        return resolveActivityAsUser(intent, flags, mContext.getUserId());
491    }
492
493    @Override
494    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
495        try {
496            return mPM.resolveIntent(
497                intent,
498                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
499                flags,
500                userId);
501        } catch (RemoteException e) {
502            throw new RuntimeException("Package manager has died", e);
503        }
504    }
505
506    @Override
507    public List<ResolveInfo> queryIntentActivities(Intent intent,
508                                                   int flags) {
509        return queryIntentActivitiesAsUser(intent, flags, mContext.getUserId());
510    }
511
512    /** @hide Same as above but for a specific user */
513    @Override
514    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
515                                                   int flags, int userId) {
516        try {
517            return mPM.queryIntentActivities(
518                intent,
519                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
520                flags,
521                userId);
522        } catch (RemoteException e) {
523            throw new RuntimeException("Package manager has died", e);
524        }
525    }
526
527    @Override
528    public List<ResolveInfo> queryIntentActivityOptions(
529        ComponentName caller, Intent[] specifics, Intent intent,
530        int flags) {
531        final ContentResolver resolver = mContext.getContentResolver();
532
533        String[] specificTypes = null;
534        if (specifics != null) {
535            final int N = specifics.length;
536            for (int i=0; i<N; i++) {
537                Intent sp = specifics[i];
538                if (sp != null) {
539                    String t = sp.resolveTypeIfNeeded(resolver);
540                    if (t != null) {
541                        if (specificTypes == null) {
542                            specificTypes = new String[N];
543                        }
544                        specificTypes[i] = t;
545                    }
546                }
547            }
548        }
549
550        try {
551            return mPM.queryIntentActivityOptions(caller, specifics,
552                                                  specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
553                                                  flags, mContext.getUserId());
554        } catch (RemoteException e) {
555            throw new RuntimeException("Package manager has died", e);
556        }
557    }
558
559    /**
560     * @hide
561     */
562    @Override
563    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags, int userId) {
564        try {
565            return mPM.queryIntentReceivers(
566                intent,
567                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
568                flags,
569                userId);
570        } catch (RemoteException e) {
571            throw new RuntimeException("Package manager has died", e);
572        }
573    }
574
575    @Override
576    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
577        return queryBroadcastReceivers(intent, flags, mContext.getUserId());
578    }
579
580    @Override
581    public ResolveInfo resolveService(Intent intent, int flags) {
582        try {
583            return mPM.resolveService(
584                intent,
585                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
586                flags,
587                mContext.getUserId());
588        } catch (RemoteException e) {
589            throw new RuntimeException("Package manager has died", e);
590        }
591    }
592
593    @Override
594    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
595        try {
596            return mPM.queryIntentServices(
597                intent,
598                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
599                flags,
600                userId);
601        } catch (RemoteException e) {
602            throw new RuntimeException("Package manager has died", e);
603        }
604    }
605
606    @Override
607    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
608        return queryIntentServicesAsUser(intent, flags, mContext.getUserId());
609    }
610
611    @Override
612    public ProviderInfo resolveContentProvider(String name,
613                                               int flags) {
614        try {
615            return mPM.resolveContentProvider(name, flags, mContext.getUserId());
616        } catch (RemoteException e) {
617            throw new RuntimeException("Package manager has died", e);
618        }
619    }
620
621    @Override
622    public List<ProviderInfo> queryContentProviders(String processName,
623                                                    int uid, int flags) {
624        try {
625            return mPM.queryContentProviders(processName, uid, flags);
626        } catch (RemoteException e) {
627            throw new RuntimeException("Package manager has died", e);
628        }
629    }
630
631    @Override
632    public InstrumentationInfo getInstrumentationInfo(
633        ComponentName className, int flags)
634            throws NameNotFoundException {
635        try {
636            InstrumentationInfo ii = mPM.getInstrumentationInfo(
637                className, flags);
638            if (ii != null) {
639                return ii;
640            }
641        } catch (RemoteException e) {
642            throw new RuntimeException("Package manager has died", e);
643        }
644
645        throw new NameNotFoundException(className.toString());
646    }
647
648    @Override
649    public List<InstrumentationInfo> queryInstrumentation(
650        String targetPackage, int flags) {
651        try {
652            return mPM.queryInstrumentation(targetPackage, flags);
653        } catch (RemoteException e) {
654            throw new RuntimeException("Package manager has died", e);
655        }
656    }
657
658    @Override public Drawable getDrawable(String packageName, int resid,
659                                          ApplicationInfo appInfo) {
660        ResourceName name = new ResourceName(packageName, resid);
661        Drawable dr = getCachedIcon(name);
662        if (dr != null) {
663            return dr;
664        }
665        if (appInfo == null) {
666            try {
667                appInfo = getApplicationInfo(packageName, 0);
668            } catch (NameNotFoundException e) {
669                return null;
670            }
671        }
672        try {
673            Resources r = getResourcesForApplication(appInfo);
674            dr = r.getDrawable(resid);
675            if (false) {
676                RuntimeException e = new RuntimeException("here");
677                e.fillInStackTrace();
678                Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
679                      + " from package " + packageName
680                      + ": app scale=" + r.getCompatibilityInfo().applicationScale
681                      + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
682                      e);
683            }
684            if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
685                                   + Integer.toHexString(resid) + " from " + r
686                                   + ": " + dr);
687            putCachedIcon(name, dr);
688            return dr;
689        } catch (NameNotFoundException e) {
690            Log.w("PackageManager", "Failure retrieving resources for"
691                  + appInfo.packageName);
692        } catch (Resources.NotFoundException e) {
693            Log.w("PackageManager", "Failure retrieving resources for"
694                  + appInfo.packageName + ": " + e.getMessage());
695        } catch (RuntimeException e) {
696            // If an exception was thrown, fall through to return
697            // default icon.
698            Log.w("PackageManager", "Failure retrieving icon 0x"
699                  + Integer.toHexString(resid) + " in package "
700                  + packageName, e);
701        }
702        return null;
703    }
704
705    @Override public Drawable getActivityIcon(ComponentName activityName)
706            throws NameNotFoundException {
707        return getActivityInfo(activityName, 0).loadIcon(this);
708    }
709
710    @Override public Drawable getActivityIcon(Intent intent)
711            throws NameNotFoundException {
712        if (intent.getComponent() != null) {
713            return getActivityIcon(intent.getComponent());
714        }
715
716        ResolveInfo info = resolveActivity(
717            intent, PackageManager.MATCH_DEFAULT_ONLY);
718        if (info != null) {
719            return info.activityInfo.loadIcon(this);
720        }
721
722        throw new NameNotFoundException(intent.toUri(0));
723    }
724
725    @Override public Drawable getDefaultActivityIcon() {
726        return Resources.getSystem().getDrawable(
727            com.android.internal.R.drawable.sym_def_app_icon);
728    }
729
730    @Override public Drawable getApplicationIcon(ApplicationInfo info) {
731        return info.loadIcon(this);
732    }
733
734    @Override public Drawable getApplicationIcon(String packageName)
735            throws NameNotFoundException {
736        return getApplicationIcon(getApplicationInfo(packageName, 0));
737    }
738
739    @Override
740    public Drawable getActivityLogo(ComponentName activityName)
741            throws NameNotFoundException {
742        return getActivityInfo(activityName, 0).loadLogo(this);
743    }
744
745    @Override
746    public Drawable getActivityLogo(Intent intent)
747            throws NameNotFoundException {
748        if (intent.getComponent() != null) {
749            return getActivityLogo(intent.getComponent());
750        }
751
752        ResolveInfo info = resolveActivity(
753            intent, PackageManager.MATCH_DEFAULT_ONLY);
754        if (info != null) {
755            return info.activityInfo.loadLogo(this);
756        }
757
758        throw new NameNotFoundException(intent.toUri(0));
759    }
760
761    @Override
762    public Drawable getApplicationLogo(ApplicationInfo info) {
763        return info.loadLogo(this);
764    }
765
766    @Override
767    public Drawable getApplicationLogo(String packageName)
768            throws NameNotFoundException {
769        return getApplicationLogo(getApplicationInfo(packageName, 0));
770    }
771
772    @Override public Resources getResourcesForActivity(
773        ComponentName activityName) throws NameNotFoundException {
774        return getResourcesForApplication(
775            getActivityInfo(activityName, 0).applicationInfo);
776    }
777
778    @Override public Resources getResourcesForApplication(
779        ApplicationInfo app) throws NameNotFoundException {
780        if (app.packageName.equals("system")) {
781            return mContext.mMainThread.getSystemContext().getResources();
782        }
783        Resources r = mContext.mMainThread.getTopLevelResources(
784                app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
785                        Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
786        if (r != null) {
787            return r;
788        }
789        throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
790    }
791
792    @Override public Resources getResourcesForApplication(
793        String appPackageName) throws NameNotFoundException {
794        return getResourcesForApplication(
795            getApplicationInfo(appPackageName, 0));
796    }
797
798    /** @hide */
799    @Override
800    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
801            throws NameNotFoundException {
802        if (userId < 0) {
803            throw new IllegalArgumentException(
804                    "Call does not support special user #" + userId);
805        }
806        if ("system".equals(appPackageName)) {
807            return mContext.mMainThread.getSystemContext().getResources();
808        }
809        try {
810            ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, 0, userId);
811            if (ai != null) {
812                return getResourcesForApplication(ai);
813            }
814        } catch (RemoteException e) {
815            throw new RuntimeException("Package manager has died", e);
816        }
817        throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
818    }
819
820    int mCachedSafeMode = -1;
821    @Override public boolean isSafeMode() {
822        try {
823            if (mCachedSafeMode < 0) {
824                mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
825            }
826            return mCachedSafeMode != 0;
827        } catch (RemoteException e) {
828            throw new RuntimeException("Package manager has died", e);
829        }
830    }
831
832    static void configurationChanged() {
833        synchronized (sSync) {
834            sIconCache.clear();
835            sStringCache.clear();
836        }
837    }
838
839    ApplicationPackageManager(ContextImpl context,
840                              IPackageManager pm) {
841        mContext = context;
842        mPM = pm;
843    }
844
845    private Drawable getCachedIcon(ResourceName name) {
846        synchronized (sSync) {
847            WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
848            if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
849                                   + name + ": " + wr);
850            if (wr != null) {   // we have the activity
851                Drawable.ConstantState state = wr.get();
852                if (state != null) {
853                    if (DEBUG_ICONS) {
854                        Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
855                    }
856                    // Note: It's okay here to not use the newDrawable(Resources) variant
857                    //       of the API. The ConstantState comes from a drawable that was
858                    //       originally created by passing the proper app Resources instance
859                    //       which means the state should already contain the proper
860                    //       resources specific information (like density.) See
861                    //       BitmapDrawable.BitmapState for instance.
862                    return state.newDrawable();
863                }
864                // our entry has been purged
865                sIconCache.remove(name);
866            }
867        }
868        return null;
869    }
870
871    private void putCachedIcon(ResourceName name, Drawable dr) {
872        synchronized (sSync) {
873            sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState()));
874            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
875        }
876    }
877
878    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
879        boolean immediateGc = false;
880        if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
881            immediateGc = true;
882        }
883        if (pkgList != null && (pkgList.length > 0)) {
884            boolean needCleanup = false;
885            for (String ssp : pkgList) {
886                synchronized (sSync) {
887                    if (sIconCache.size() > 0) {
888                        Iterator<ResourceName> it = sIconCache.keySet().iterator();
889                        while (it.hasNext()) {
890                            ResourceName nm = it.next();
891                            if (nm.packageName.equals(ssp)) {
892                                //Log.i(TAG, "Removing cached drawable for " + nm);
893                                it.remove();
894                                needCleanup = true;
895                            }
896                        }
897                    }
898                    if (sStringCache.size() > 0) {
899                        Iterator<ResourceName> it = sStringCache.keySet().iterator();
900                        while (it.hasNext()) {
901                            ResourceName nm = it.next();
902                            if (nm.packageName.equals(ssp)) {
903                                //Log.i(TAG, "Removing cached string for " + nm);
904                                it.remove();
905                                needCleanup = true;
906                            }
907                        }
908                    }
909                }
910            }
911            if (needCleanup || hasPkgInfo) {
912                if (immediateGc) {
913                    // Schedule an immediate gc.
914                    Runtime.getRuntime().gc();
915                } else {
916                    ActivityThread.currentActivityThread().scheduleGcIdler();
917                }
918            }
919        }
920    }
921
922    private static final class ResourceName {
923        final String packageName;
924        final int iconId;
925
926        ResourceName(String _packageName, int _iconId) {
927            packageName = _packageName;
928            iconId = _iconId;
929        }
930
931        ResourceName(ApplicationInfo aInfo, int _iconId) {
932            this(aInfo.packageName, _iconId);
933        }
934
935        ResourceName(ComponentInfo cInfo, int _iconId) {
936            this(cInfo.applicationInfo.packageName, _iconId);
937        }
938
939        ResourceName(ResolveInfo rInfo, int _iconId) {
940            this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
941        }
942
943        @Override
944        public boolean equals(Object o) {
945            if (this == o) return true;
946            if (o == null || getClass() != o.getClass()) return false;
947
948            ResourceName that = (ResourceName) o;
949
950            if (iconId != that.iconId) return false;
951            return !(packageName != null ?
952                     !packageName.equals(that.packageName) : that.packageName != null);
953
954        }
955
956        @Override
957        public int hashCode() {
958            int result;
959            result = packageName.hashCode();
960            result = 31 * result + iconId;
961            return result;
962        }
963
964        @Override
965        public String toString() {
966            return "{ResourceName " + packageName + " / " + iconId + "}";
967        }
968    }
969
970    private CharSequence getCachedString(ResourceName name) {
971        synchronized (sSync) {
972            WeakReference<CharSequence> wr = sStringCache.get(name);
973            if (wr != null) {   // we have the activity
974                CharSequence cs = wr.get();
975                if (cs != null) {
976                    return cs;
977                }
978                // our entry has been purged
979                sStringCache.remove(name);
980            }
981        }
982        return null;
983    }
984
985    private void putCachedString(ResourceName name, CharSequence cs) {
986        synchronized (sSync) {
987            sStringCache.put(name, new WeakReference<CharSequence>(cs));
988        }
989    }
990
991    @Override
992    public CharSequence getText(String packageName, int resid,
993                                ApplicationInfo appInfo) {
994        ResourceName name = new ResourceName(packageName, resid);
995        CharSequence text = getCachedString(name);
996        if (text != null) {
997            return text;
998        }
999        if (appInfo == null) {
1000            try {
1001                appInfo = getApplicationInfo(packageName, 0);
1002            } catch (NameNotFoundException e) {
1003                return null;
1004            }
1005        }
1006        try {
1007            Resources r = getResourcesForApplication(appInfo);
1008            text = r.getText(resid);
1009            putCachedString(name, text);
1010            return text;
1011        } catch (NameNotFoundException e) {
1012            Log.w("PackageManager", "Failure retrieving resources for"
1013                  + appInfo.packageName);
1014        } catch (RuntimeException e) {
1015            // If an exception was thrown, fall through to return
1016            // default icon.
1017            Log.w("PackageManager", "Failure retrieving text 0x"
1018                  + Integer.toHexString(resid) + " in package "
1019                  + packageName, e);
1020        }
1021        return null;
1022    }
1023
1024    @Override
1025    public XmlResourceParser getXml(String packageName, int resid,
1026                                    ApplicationInfo appInfo) {
1027        if (appInfo == null) {
1028            try {
1029                appInfo = getApplicationInfo(packageName, 0);
1030            } catch (NameNotFoundException e) {
1031                return null;
1032            }
1033        }
1034        try {
1035            Resources r = getResourcesForApplication(appInfo);
1036            return r.getXml(resid);
1037        } catch (RuntimeException e) {
1038            // If an exception was thrown, fall through to return
1039            // default icon.
1040            Log.w("PackageManager", "Failure retrieving xml 0x"
1041                  + Integer.toHexString(resid) + " in package "
1042                  + packageName, e);
1043        } catch (NameNotFoundException e) {
1044            Log.w("PackageManager", "Failure retrieving resources for "
1045                  + appInfo.packageName);
1046        }
1047        return null;
1048    }
1049
1050    @Override
1051    public CharSequence getApplicationLabel(ApplicationInfo info) {
1052        return info.loadLabel(this);
1053    }
1054
1055    @Override
1056    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1057                               String installerPackageName) {
1058        try {
1059            mPM.installPackage(packageURI, observer, flags, installerPackageName);
1060        } catch (RemoteException e) {
1061            // Should never happen!
1062        }
1063    }
1064
1065    @Override
1066    public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
1067            int flags, String installerPackageName, Uri verificationURI,
1068            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
1069        try {
1070            mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
1071                    verificationURI, manifestDigest, encryptionParams);
1072        } catch (RemoteException e) {
1073            // Should never happen!
1074        }
1075    }
1076
1077    @Override
1078	  public void installPackageWithVerificationAndEncryption(Uri packageURI,
1079            IPackageInstallObserver observer, int flags, String installerPackageName,
1080            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1081        try {
1082            mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags,
1083                    installerPackageName, verificationParams, encryptionParams);
1084        } catch (RemoteException e) {
1085            // Should never happen!
1086        }
1087    }
1088
1089    @Override
1090    public int installExistingPackage(String packageName)
1091            throws NameNotFoundException {
1092        try {
1093            int res = mPM.installExistingPackage(packageName);
1094            if (res == INSTALL_FAILED_INVALID_URI) {
1095                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1096            }
1097            return res;
1098        } catch (RemoteException e) {
1099            // Should never happen!
1100            throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1101        }
1102    }
1103
1104    @Override
1105    public void verifyPendingInstall(int id, int response) {
1106        try {
1107            mPM.verifyPendingInstall(id, response);
1108        } catch (RemoteException e) {
1109            // Should never happen!
1110        }
1111    }
1112
1113    @Override
1114    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1115            long millisecondsToDelay) {
1116        try {
1117            mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1118        } catch (RemoteException e) {
1119            // Should never happen!
1120        }
1121    }
1122
1123    @Override
1124    public void setInstallerPackageName(String targetPackage,
1125            String installerPackageName) {
1126        try {
1127            mPM.setInstallerPackageName(targetPackage, installerPackageName);
1128        } catch (RemoteException e) {
1129            // Should never happen!
1130        }
1131    }
1132
1133    @Override
1134    public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
1135        try {
1136            mPM.movePackage(packageName, observer, flags);
1137        } catch (RemoteException e) {
1138            // Should never happen!
1139        }
1140    }
1141
1142    @Override
1143    public String getInstallerPackageName(String packageName) {
1144        try {
1145            return mPM.getInstallerPackageName(packageName);
1146        } catch (RemoteException e) {
1147            // Should never happen!
1148        }
1149        return null;
1150    }
1151
1152    @Override
1153    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1154        try {
1155            mPM.deletePackage(packageName, observer, flags);
1156        } catch (RemoteException e) {
1157            // Should never happen!
1158        }
1159    }
1160    @Override
1161    public void clearApplicationUserData(String packageName,
1162                                         IPackageDataObserver observer) {
1163        try {
1164            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
1165        } catch (RemoteException e) {
1166            // Should never happen!
1167        }
1168    }
1169    @Override
1170    public void deleteApplicationCacheFiles(String packageName,
1171                                            IPackageDataObserver observer) {
1172        try {
1173            mPM.deleteApplicationCacheFiles(packageName, observer);
1174        } catch (RemoteException e) {
1175            // Should never happen!
1176        }
1177    }
1178    @Override
1179    public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
1180        try {
1181            mPM.freeStorageAndNotify(idealStorageSize, observer);
1182        } catch (RemoteException e) {
1183            // Should never happen!
1184        }
1185    }
1186
1187    @Override
1188    public void freeStorage(long freeStorageSize, IntentSender pi) {
1189        try {
1190            mPM.freeStorage(freeStorageSize, pi);
1191        } catch (RemoteException e) {
1192            // Should never happen!
1193        }
1194    }
1195
1196    @Override
1197    public void getPackageSizeInfo(String packageName, int userHandle,
1198            IPackageStatsObserver observer) {
1199        try {
1200            mPM.getPackageSizeInfo(packageName, userHandle, observer);
1201        } catch (RemoteException e) {
1202            // Should never happen!
1203        }
1204    }
1205    @Override
1206    public void addPackageToPreferred(String packageName) {
1207        try {
1208            mPM.addPackageToPreferred(packageName);
1209        } catch (RemoteException e) {
1210            // Should never happen!
1211        }
1212    }
1213
1214    @Override
1215    public void removePackageFromPreferred(String packageName) {
1216        try {
1217            mPM.removePackageFromPreferred(packageName);
1218        } catch (RemoteException e) {
1219            // Should never happen!
1220        }
1221    }
1222
1223    @Override
1224    public List<PackageInfo> getPreferredPackages(int flags) {
1225        try {
1226            return mPM.getPreferredPackages(flags);
1227        } catch (RemoteException e) {
1228            // Should never happen!
1229        }
1230        return new ArrayList<PackageInfo>();
1231    }
1232
1233    @Override
1234    public void addPreferredActivity(IntentFilter filter,
1235                                     int match, ComponentName[] set, ComponentName activity) {
1236        try {
1237            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
1238        } catch (RemoteException e) {
1239            // Should never happen!
1240        }
1241    }
1242
1243    @Override
1244    public void addPreferredActivity(IntentFilter filter, int match,
1245            ComponentName[] set, ComponentName activity, int userId) {
1246        try {
1247            mPM.addPreferredActivity(filter, match, set, activity, userId);
1248        } catch (RemoteException e) {
1249            // Should never happen!
1250        }
1251    }
1252
1253    @Override
1254    public void replacePreferredActivity(IntentFilter filter,
1255                                         int match, ComponentName[] set, ComponentName activity) {
1256        try {
1257            mPM.replacePreferredActivity(filter, match, set, activity);
1258        } catch (RemoteException e) {
1259            // Should never happen!
1260        }
1261    }
1262
1263    @Override
1264    public void clearPackagePreferredActivities(String packageName) {
1265        try {
1266            mPM.clearPackagePreferredActivities(packageName);
1267        } catch (RemoteException e) {
1268            // Should never happen!
1269        }
1270    }
1271
1272    @Override
1273    public int getPreferredActivities(List<IntentFilter> outFilters,
1274                                      List<ComponentName> outActivities, String packageName) {
1275        try {
1276            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1277        } catch (RemoteException e) {
1278            // Should never happen!
1279        }
1280        return 0;
1281    }
1282
1283    @Override
1284    public void setComponentEnabledSetting(ComponentName componentName,
1285                                           int newState, int flags) {
1286        try {
1287            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
1288        } catch (RemoteException e) {
1289            // Should never happen!
1290        }
1291    }
1292
1293    @Override
1294    public int getComponentEnabledSetting(ComponentName componentName) {
1295        try {
1296            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
1297        } catch (RemoteException e) {
1298            // Should never happen!
1299        }
1300        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1301    }
1302
1303    @Override
1304    public void setApplicationEnabledSetting(String packageName,
1305                                             int newState, int flags) {
1306        try {
1307            mPM.setApplicationEnabledSetting(packageName, newState, flags, mContext.getUserId());
1308        } catch (RemoteException e) {
1309            // Should never happen!
1310        }
1311    }
1312
1313    @Override
1314    public int getApplicationEnabledSetting(String packageName) {
1315        try {
1316            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
1317        } catch (RemoteException e) {
1318            // Should never happen!
1319        }
1320        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1321    }
1322
1323    /**
1324     * @hide
1325     */
1326    @Override
1327    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1328        try {
1329            return mPM.getVerifierDeviceIdentity();
1330        } catch (RemoteException e) {
1331            // Should never happen!
1332        }
1333        return null;
1334    }
1335
1336    private final ContextImpl mContext;
1337    private final IPackageManager mPM;
1338
1339    private static final Object sSync = new Object();
1340    private static HashMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
1341            = new HashMap<ResourceName, WeakReference<Drawable.ConstantState>>();
1342    private static HashMap<ResourceName, WeakReference<CharSequence>> sStringCache
1343            = new HashMap<ResourceName, WeakReference<CharSequence>>();
1344}
1345