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