ApplicationPackageManager.java revision 8a985d24ce9a38f40ed88fecbdcd0e75e3a68f44
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 getActivityLogo(ComponentName activityName)
731            throws NameNotFoundException {
732        return getActivityInfo(activityName, 0).loadLogo(this);
733    }
734
735    @Override
736    public Drawable getActivityLogo(Intent intent)
737            throws NameNotFoundException {
738        if (intent.getComponent() != null) {
739            return getActivityLogo(intent.getComponent());
740        }
741
742        ResolveInfo info = resolveActivity(
743            intent, PackageManager.MATCH_DEFAULT_ONLY);
744        if (info != null) {
745            return info.activityInfo.loadLogo(this);
746        }
747
748        throw new NameNotFoundException(intent.toUri(0));
749    }
750
751    @Override
752    public Drawable getApplicationLogo(ApplicationInfo info) {
753        return info.loadLogo(this);
754    }
755
756    @Override
757    public Drawable getApplicationLogo(String packageName)
758            throws NameNotFoundException {
759        return getApplicationLogo(getApplicationInfo(packageName, 0));
760    }
761
762    @Override public Resources getResourcesForActivity(
763        ComponentName activityName) throws NameNotFoundException {
764        return getResourcesForApplication(
765            getActivityInfo(activityName, 0).applicationInfo);
766    }
767
768    @Override public Resources getResourcesForApplication(
769        ApplicationInfo app) throws NameNotFoundException {
770        if (app.packageName.equals("system")) {
771            return mContext.mMainThread.getSystemContext().getResources();
772        }
773        Resources r = mContext.mMainThread.getTopLevelResources(
774                app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
775                app.resourceDirs, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
776        if (r != null) {
777            return r;
778        }
779        throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
780    }
781
782    @Override public Resources getResourcesForApplication(
783        String appPackageName) throws NameNotFoundException {
784        return getResourcesForApplication(
785            getApplicationInfo(appPackageName, 0));
786    }
787
788    /** @hide */
789    @Override
790    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
791            throws NameNotFoundException {
792        if (userId < 0) {
793            throw new IllegalArgumentException(
794                    "Call does not support special user #" + userId);
795        }
796        if ("system".equals(appPackageName)) {
797            return mContext.mMainThread.getSystemContext().getResources();
798        }
799        try {
800            ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, 0, userId);
801            if (ai != null) {
802                return getResourcesForApplication(ai);
803            }
804        } catch (RemoteException e) {
805            throw new RuntimeException("Package manager has died", e);
806        }
807        throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
808    }
809
810    int mCachedSafeMode = -1;
811    @Override public boolean isSafeMode() {
812        try {
813            if (mCachedSafeMode < 0) {
814                mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
815            }
816            return mCachedSafeMode != 0;
817        } catch (RemoteException e) {
818            throw new RuntimeException("Package manager has died", e);
819        }
820    }
821
822    static void configurationChanged() {
823        synchronized (sSync) {
824            sIconCache.clear();
825            sStringCache.clear();
826        }
827    }
828
829    ApplicationPackageManager(ContextImpl context,
830                              IPackageManager pm) {
831        mContext = context;
832        mPM = pm;
833    }
834
835    private Drawable getCachedIcon(ResourceName name) {
836        synchronized (sSync) {
837            WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
838            if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
839                                   + name + ": " + wr);
840            if (wr != null) {   // we have the activity
841                Drawable.ConstantState state = wr.get();
842                if (state != null) {
843                    if (DEBUG_ICONS) {
844                        Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
845                    }
846                    // Note: It's okay here to not use the newDrawable(Resources) variant
847                    //       of the API. The ConstantState comes from a drawable that was
848                    //       originally created by passing the proper app Resources instance
849                    //       which means the state should already contain the proper
850                    //       resources specific information (like density.) See
851                    //       BitmapDrawable.BitmapState for instance.
852                    return state.newDrawable();
853                }
854                // our entry has been purged
855                sIconCache.remove(name);
856            }
857        }
858        return null;
859    }
860
861    private void putCachedIcon(ResourceName name, Drawable dr) {
862        synchronized (sSync) {
863            sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState()));
864            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
865        }
866    }
867
868    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
869        boolean immediateGc = false;
870        if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
871            immediateGc = true;
872        }
873        if (pkgList != null && (pkgList.length > 0)) {
874            boolean needCleanup = false;
875            for (String ssp : pkgList) {
876                synchronized (sSync) {
877                    for (int i=sIconCache.size()-1; i>=0; i--) {
878                        ResourceName nm = sIconCache.keyAt(i);
879                        if (nm.packageName.equals(ssp)) {
880                            //Log.i(TAG, "Removing cached drawable for " + nm);
881                            sIconCache.removeAt(i);
882                            needCleanup = true;
883                        }
884                    }
885                    for (int i=sStringCache.size()-1; i>=0; i--) {
886                        ResourceName nm = sStringCache.keyAt(i);
887                        if (nm.packageName.equals(ssp)) {
888                            //Log.i(TAG, "Removing cached string for " + nm);
889                            sStringCache.removeAt(i);
890                            needCleanup = true;
891                        }
892                    }
893                }
894            }
895            if (needCleanup || hasPkgInfo) {
896                if (immediateGc) {
897                    // Schedule an immediate gc.
898                    Runtime.getRuntime().gc();
899                } else {
900                    ActivityThread.currentActivityThread().scheduleGcIdler();
901                }
902            }
903        }
904    }
905
906    private static final class ResourceName {
907        final String packageName;
908        final int iconId;
909
910        ResourceName(String _packageName, int _iconId) {
911            packageName = _packageName;
912            iconId = _iconId;
913        }
914
915        ResourceName(ApplicationInfo aInfo, int _iconId) {
916            this(aInfo.packageName, _iconId);
917        }
918
919        ResourceName(ComponentInfo cInfo, int _iconId) {
920            this(cInfo.applicationInfo.packageName, _iconId);
921        }
922
923        ResourceName(ResolveInfo rInfo, int _iconId) {
924            this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
925        }
926
927        @Override
928        public boolean equals(Object o) {
929            if (this == o) return true;
930            if (o == null || getClass() != o.getClass()) return false;
931
932            ResourceName that = (ResourceName) o;
933
934            if (iconId != that.iconId) return false;
935            return !(packageName != null ?
936                     !packageName.equals(that.packageName) : that.packageName != null);
937
938        }
939
940        @Override
941        public int hashCode() {
942            int result;
943            result = packageName.hashCode();
944            result = 31 * result + iconId;
945            return result;
946        }
947
948        @Override
949        public String toString() {
950            return "{ResourceName " + packageName + " / " + iconId + "}";
951        }
952    }
953
954    private CharSequence getCachedString(ResourceName name) {
955        synchronized (sSync) {
956            WeakReference<CharSequence> wr = sStringCache.get(name);
957            if (wr != null) {   // we have the activity
958                CharSequence cs = wr.get();
959                if (cs != null) {
960                    return cs;
961                }
962                // our entry has been purged
963                sStringCache.remove(name);
964            }
965        }
966        return null;
967    }
968
969    private void putCachedString(ResourceName name, CharSequence cs) {
970        synchronized (sSync) {
971            sStringCache.put(name, new WeakReference<CharSequence>(cs));
972        }
973    }
974
975    @Override
976    public CharSequence getText(String packageName, int resid,
977                                ApplicationInfo appInfo) {
978        ResourceName name = new ResourceName(packageName, resid);
979        CharSequence text = getCachedString(name);
980        if (text != null) {
981            return text;
982        }
983        if (appInfo == null) {
984            try {
985                appInfo = getApplicationInfo(packageName, 0);
986            } catch (NameNotFoundException e) {
987                return null;
988            }
989        }
990        try {
991            Resources r = getResourcesForApplication(appInfo);
992            text = r.getText(resid);
993            putCachedString(name, text);
994            return text;
995        } catch (NameNotFoundException e) {
996            Log.w("PackageManager", "Failure retrieving resources for"
997                  + appInfo.packageName);
998        } catch (RuntimeException e) {
999            // If an exception was thrown, fall through to return
1000            // default icon.
1001            Log.w("PackageManager", "Failure retrieving text 0x"
1002                  + Integer.toHexString(resid) + " in package "
1003                  + packageName, e);
1004        }
1005        return null;
1006    }
1007
1008    @Override
1009    public XmlResourceParser getXml(String packageName, int resid,
1010                                    ApplicationInfo appInfo) {
1011        if (appInfo == null) {
1012            try {
1013                appInfo = getApplicationInfo(packageName, 0);
1014            } catch (NameNotFoundException e) {
1015                return null;
1016            }
1017        }
1018        try {
1019            Resources r = getResourcesForApplication(appInfo);
1020            return r.getXml(resid);
1021        } catch (RuntimeException e) {
1022            // If an exception was thrown, fall through to return
1023            // default icon.
1024            Log.w("PackageManager", "Failure retrieving xml 0x"
1025                  + Integer.toHexString(resid) + " in package "
1026                  + packageName, e);
1027        } catch (NameNotFoundException e) {
1028            Log.w("PackageManager", "Failure retrieving resources for "
1029                  + appInfo.packageName);
1030        }
1031        return null;
1032    }
1033
1034    @Override
1035    public CharSequence getApplicationLabel(ApplicationInfo info) {
1036        return info.loadLabel(this);
1037    }
1038
1039    @Override
1040    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1041                               String installerPackageName) {
1042        try {
1043            mPM.installPackage(packageURI, observer, flags, installerPackageName);
1044        } catch (RemoteException e) {
1045            // Should never happen!
1046        }
1047    }
1048
1049    @Override
1050    public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
1051            int flags, String installerPackageName, Uri verificationURI,
1052            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
1053        try {
1054            mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
1055                    verificationURI, manifestDigest, encryptionParams);
1056        } catch (RemoteException e) {
1057            // Should never happen!
1058        }
1059    }
1060
1061    @Override
1062    public void installPackageWithVerificationAndEncryption(Uri packageURI,
1063            IPackageInstallObserver observer, int flags, String installerPackageName,
1064            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1065        try {
1066            mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags,
1067                    installerPackageName, verificationParams, encryptionParams);
1068        } catch (RemoteException e) {
1069            // Should never happen!
1070        }
1071    }
1072
1073    @Override
1074    public int installExistingPackage(String packageName)
1075            throws NameNotFoundException {
1076        try {
1077            int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
1078            if (res == INSTALL_FAILED_INVALID_URI) {
1079                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1080            }
1081            return res;
1082        } catch (RemoteException e) {
1083            // Should never happen!
1084            throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1085        }
1086    }
1087
1088    @Override
1089    public void verifyPendingInstall(int id, int response) {
1090        try {
1091            mPM.verifyPendingInstall(id, response);
1092        } catch (RemoteException e) {
1093            // Should never happen!
1094        }
1095    }
1096
1097    @Override
1098    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1099            long millisecondsToDelay) {
1100        try {
1101            mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1102        } catch (RemoteException e) {
1103            // Should never happen!
1104        }
1105    }
1106
1107    @Override
1108    public void setInstallerPackageName(String targetPackage,
1109            String installerPackageName) {
1110        try {
1111            mPM.setInstallerPackageName(targetPackage, installerPackageName);
1112        } catch (RemoteException e) {
1113            // Should never happen!
1114        }
1115    }
1116
1117    @Override
1118    public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
1119        try {
1120            mPM.movePackage(packageName, observer, flags);
1121        } catch (RemoteException e) {
1122            // Should never happen!
1123        }
1124    }
1125
1126    @Override
1127    public String getInstallerPackageName(String packageName) {
1128        try {
1129            return mPM.getInstallerPackageName(packageName);
1130        } catch (RemoteException e) {
1131            // Should never happen!
1132        }
1133        return null;
1134    }
1135
1136    @Override
1137    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1138        try {
1139            mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
1140        } catch (RemoteException e) {
1141            // Should never happen!
1142        }
1143    }
1144    @Override
1145    public void clearApplicationUserData(String packageName,
1146                                         IPackageDataObserver observer) {
1147        try {
1148            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
1149        } catch (RemoteException e) {
1150            // Should never happen!
1151        }
1152    }
1153    @Override
1154    public void deleteApplicationCacheFiles(String packageName,
1155                                            IPackageDataObserver observer) {
1156        try {
1157            mPM.deleteApplicationCacheFiles(packageName, observer);
1158        } catch (RemoteException e) {
1159            // Should never happen!
1160        }
1161    }
1162    @Override
1163    public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
1164        try {
1165            mPM.freeStorageAndNotify(idealStorageSize, observer);
1166        } catch (RemoteException e) {
1167            // Should never happen!
1168        }
1169    }
1170
1171    @Override
1172    public void freeStorage(long freeStorageSize, IntentSender pi) {
1173        try {
1174            mPM.freeStorage(freeStorageSize, pi);
1175        } catch (RemoteException e) {
1176            // Should never happen!
1177        }
1178    }
1179
1180    @Override
1181    public void getPackageSizeInfo(String packageName, int userHandle,
1182            IPackageStatsObserver observer) {
1183        try {
1184            mPM.getPackageSizeInfo(packageName, userHandle, observer);
1185        } catch (RemoteException e) {
1186            // Should never happen!
1187        }
1188    }
1189    @Override
1190    public void addPackageToPreferred(String packageName) {
1191        try {
1192            mPM.addPackageToPreferred(packageName);
1193        } catch (RemoteException e) {
1194            // Should never happen!
1195        }
1196    }
1197
1198    @Override
1199    public void removePackageFromPreferred(String packageName) {
1200        try {
1201            mPM.removePackageFromPreferred(packageName);
1202        } catch (RemoteException e) {
1203            // Should never happen!
1204        }
1205    }
1206
1207    @Override
1208    public List<PackageInfo> getPreferredPackages(int flags) {
1209        try {
1210            return mPM.getPreferredPackages(flags);
1211        } catch (RemoteException e) {
1212            // Should never happen!
1213        }
1214        return new ArrayList<PackageInfo>();
1215    }
1216
1217    @Override
1218    public void addPreferredActivity(IntentFilter filter,
1219                                     int match, ComponentName[] set, ComponentName activity) {
1220        try {
1221            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
1222        } catch (RemoteException e) {
1223            // Should never happen!
1224        }
1225    }
1226
1227    @Override
1228    public void addPreferredActivity(IntentFilter filter, int match,
1229            ComponentName[] set, ComponentName activity, int userId) {
1230        try {
1231            mPM.addPreferredActivity(filter, match, set, activity, userId);
1232        } catch (RemoteException e) {
1233            // Should never happen!
1234        }
1235    }
1236
1237    @Override
1238    public void replacePreferredActivity(IntentFilter filter,
1239                                         int match, ComponentName[] set, ComponentName activity) {
1240        try {
1241            mPM.replacePreferredActivity(filter, match, set, activity);
1242        } catch (RemoteException e) {
1243            // Should never happen!
1244        }
1245    }
1246
1247    @Override
1248    public void clearPackagePreferredActivities(String packageName) {
1249        try {
1250            mPM.clearPackagePreferredActivities(packageName);
1251        } catch (RemoteException e) {
1252            // Should never happen!
1253        }
1254    }
1255
1256    @Override
1257    public int getPreferredActivities(List<IntentFilter> outFilters,
1258                                      List<ComponentName> outActivities, String packageName) {
1259        try {
1260            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1261        } catch (RemoteException e) {
1262            // Should never happen!
1263        }
1264        return 0;
1265    }
1266
1267    @Override
1268    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
1269        try {
1270            return mPM.getHomeActivities(outActivities);
1271        } catch (RemoteException e) {
1272            // Should never happen!
1273        }
1274        return null;
1275    }
1276
1277    @Override
1278    public void setComponentEnabledSetting(ComponentName componentName,
1279                                           int newState, int flags) {
1280        try {
1281            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
1282        } catch (RemoteException e) {
1283            // Should never happen!
1284        }
1285    }
1286
1287    @Override
1288    public int getComponentEnabledSetting(ComponentName componentName) {
1289        try {
1290            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
1291        } catch (RemoteException e) {
1292            // Should never happen!
1293        }
1294        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1295    }
1296
1297    @Override
1298    public void setApplicationEnabledSetting(String packageName,
1299                                             int newState, int flags) {
1300        try {
1301            mPM.setApplicationEnabledSetting(packageName, newState, flags,
1302                    mContext.getUserId(), mContext.getOpPackageName());
1303        } catch (RemoteException e) {
1304            // Should never happen!
1305        }
1306    }
1307
1308    @Override
1309    public int getApplicationEnabledSetting(String packageName) {
1310        try {
1311            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
1312        } catch (RemoteException e) {
1313            // Should never happen!
1314        }
1315        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1316    }
1317
1318    @Override
1319    public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
1320            UserHandle user) {
1321        try {
1322            return mPM.setApplicationBlockedSettingAsUser(packageName, blocked,
1323                    user.getIdentifier());
1324        } catch (RemoteException re) {
1325            // Should never happen!
1326        }
1327        return false;
1328    }
1329
1330    @Override
1331    public boolean getApplicationBlockedSettingAsUser(String packageName, UserHandle user) {
1332        try {
1333            return mPM.getApplicationBlockedSettingAsUser(packageName, user.getIdentifier());
1334        } catch (RemoteException re) {
1335            // Should never happen!
1336        }
1337        return false;
1338    }
1339
1340    /**
1341     * @hide
1342     */
1343    @Override
1344    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1345        try {
1346            return mPM.getVerifierDeviceIdentity();
1347        } catch (RemoteException e) {
1348            // Should never happen!
1349        }
1350        return null;
1351    }
1352
1353    private final ContextImpl mContext;
1354    private final IPackageManager mPM;
1355
1356    private static final Object sSync = new Object();
1357    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
1358            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
1359    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
1360            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
1361}
1362