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