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