ApplicationPackageManager.java revision 8a4c9721a9e09d20c63381c13fa29bd9f7cbc3e3
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        final boolean sameUid = (app.uid == Process.myUid());
827        Resources r = mContext.mMainThread.getTopLevelResources(
828                sameUid ? app.sourceDir : app.publicSourceDir,
829                sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
830                app.resourceDirs, null, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
831        if (r != null) {
832            return r;
833        }
834        throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
835    }
836
837    @Override public Resources getResourcesForApplication(
838        String appPackageName) throws NameNotFoundException {
839        return getResourcesForApplication(
840            getApplicationInfo(appPackageName, 0));
841    }
842
843    /** @hide */
844    @Override
845    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
846            throws NameNotFoundException {
847        if (userId < 0) {
848            throw new IllegalArgumentException(
849                    "Call does not support special user #" + userId);
850        }
851        if ("system".equals(appPackageName)) {
852            return mContext.mMainThread.getSystemContext().getResources();
853        }
854        try {
855            ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, 0, userId);
856            if (ai != null) {
857                return getResourcesForApplication(ai);
858            }
859        } catch (RemoteException e) {
860            throw new RuntimeException("Package manager has died", e);
861        }
862        throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
863    }
864
865    int mCachedSafeMode = -1;
866    @Override public boolean isSafeMode() {
867        try {
868            if (mCachedSafeMode < 0) {
869                mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
870            }
871            return mCachedSafeMode != 0;
872        } catch (RemoteException e) {
873            throw new RuntimeException("Package manager has died", e);
874        }
875    }
876
877    static void configurationChanged() {
878        synchronized (sSync) {
879            sIconCache.clear();
880            sStringCache.clear();
881        }
882    }
883
884    ApplicationPackageManager(ContextImpl context,
885                              IPackageManager pm) {
886        mContext = context;
887        mPM = pm;
888    }
889
890    private Drawable getCachedIcon(ResourceName name) {
891        synchronized (sSync) {
892            WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
893            if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
894                                   + name + ": " + wr);
895            if (wr != null) {   // we have the activity
896                Drawable.ConstantState state = wr.get();
897                if (state != null) {
898                    if (DEBUG_ICONS) {
899                        Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
900                    }
901                    // Note: It's okay here to not use the newDrawable(Resources) variant
902                    //       of the API. The ConstantState comes from a drawable that was
903                    //       originally created by passing the proper app Resources instance
904                    //       which means the state should already contain the proper
905                    //       resources specific information (like density.) See
906                    //       BitmapDrawable.BitmapState for instance.
907                    return state.newDrawable();
908                }
909                // our entry has been purged
910                sIconCache.remove(name);
911            }
912        }
913        return null;
914    }
915
916    private void putCachedIcon(ResourceName name, Drawable dr) {
917        synchronized (sSync) {
918            sIconCache.put(name, new WeakReference<Drawable.ConstantState>(dr.getConstantState()));
919            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
920        }
921    }
922
923    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
924        boolean immediateGc = false;
925        if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
926            immediateGc = true;
927        }
928        if (pkgList != null && (pkgList.length > 0)) {
929            boolean needCleanup = false;
930            for (String ssp : pkgList) {
931                synchronized (sSync) {
932                    for (int i=sIconCache.size()-1; i>=0; i--) {
933                        ResourceName nm = sIconCache.keyAt(i);
934                        if (nm.packageName.equals(ssp)) {
935                            //Log.i(TAG, "Removing cached drawable for " + nm);
936                            sIconCache.removeAt(i);
937                            needCleanup = true;
938                        }
939                    }
940                    for (int i=sStringCache.size()-1; i>=0; i--) {
941                        ResourceName nm = sStringCache.keyAt(i);
942                        if (nm.packageName.equals(ssp)) {
943                            //Log.i(TAG, "Removing cached string for " + nm);
944                            sStringCache.removeAt(i);
945                            needCleanup = true;
946                        }
947                    }
948                }
949            }
950            if (needCleanup || hasPkgInfo) {
951                if (immediateGc) {
952                    // Schedule an immediate gc.
953                    Runtime.getRuntime().gc();
954                } else {
955                    ActivityThread.currentActivityThread().scheduleGcIdler();
956                }
957            }
958        }
959    }
960
961    private static final class ResourceName {
962        final String packageName;
963        final int iconId;
964
965        ResourceName(String _packageName, int _iconId) {
966            packageName = _packageName;
967            iconId = _iconId;
968        }
969
970        ResourceName(ApplicationInfo aInfo, int _iconId) {
971            this(aInfo.packageName, _iconId);
972        }
973
974        ResourceName(ComponentInfo cInfo, int _iconId) {
975            this(cInfo.applicationInfo.packageName, _iconId);
976        }
977
978        ResourceName(ResolveInfo rInfo, int _iconId) {
979            this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
980        }
981
982        @Override
983        public boolean equals(Object o) {
984            if (this == o) return true;
985            if (o == null || getClass() != o.getClass()) return false;
986
987            ResourceName that = (ResourceName) o;
988
989            if (iconId != that.iconId) return false;
990            return !(packageName != null ?
991                     !packageName.equals(that.packageName) : that.packageName != null);
992
993        }
994
995        @Override
996        public int hashCode() {
997            int result;
998            result = packageName.hashCode();
999            result = 31 * result + iconId;
1000            return result;
1001        }
1002
1003        @Override
1004        public String toString() {
1005            return "{ResourceName " + packageName + " / " + iconId + "}";
1006        }
1007    }
1008
1009    private CharSequence getCachedString(ResourceName name) {
1010        synchronized (sSync) {
1011            WeakReference<CharSequence> wr = sStringCache.get(name);
1012            if (wr != null) {   // we have the activity
1013                CharSequence cs = wr.get();
1014                if (cs != null) {
1015                    return cs;
1016                }
1017                // our entry has been purged
1018                sStringCache.remove(name);
1019            }
1020        }
1021        return null;
1022    }
1023
1024    private void putCachedString(ResourceName name, CharSequence cs) {
1025        synchronized (sSync) {
1026            sStringCache.put(name, new WeakReference<CharSequence>(cs));
1027        }
1028    }
1029
1030    @Override
1031    public CharSequence getText(String packageName, int resid,
1032                                ApplicationInfo appInfo) {
1033        ResourceName name = new ResourceName(packageName, resid);
1034        CharSequence text = getCachedString(name);
1035        if (text != null) {
1036            return text;
1037        }
1038        if (appInfo == null) {
1039            try {
1040                appInfo = getApplicationInfo(packageName, 0);
1041            } catch (NameNotFoundException e) {
1042                return null;
1043            }
1044        }
1045        try {
1046            Resources r = getResourcesForApplication(appInfo);
1047            text = r.getText(resid);
1048            putCachedString(name, text);
1049            return text;
1050        } catch (NameNotFoundException e) {
1051            Log.w("PackageManager", "Failure retrieving resources for"
1052                  + appInfo.packageName);
1053        } catch (RuntimeException e) {
1054            // If an exception was thrown, fall through to return
1055            // default icon.
1056            Log.w("PackageManager", "Failure retrieving text 0x"
1057                  + Integer.toHexString(resid) + " in package "
1058                  + packageName, e);
1059        }
1060        return null;
1061    }
1062
1063    @Override
1064    public XmlResourceParser getXml(String packageName, int resid,
1065                                    ApplicationInfo appInfo) {
1066        if (appInfo == null) {
1067            try {
1068                appInfo = getApplicationInfo(packageName, 0);
1069            } catch (NameNotFoundException e) {
1070                return null;
1071            }
1072        }
1073        try {
1074            Resources r = getResourcesForApplication(appInfo);
1075            return r.getXml(resid);
1076        } catch (RuntimeException e) {
1077            // If an exception was thrown, fall through to return
1078            // default icon.
1079            Log.w("PackageManager", "Failure retrieving xml 0x"
1080                  + Integer.toHexString(resid) + " in package "
1081                  + packageName, e);
1082        } catch (NameNotFoundException e) {
1083            Log.w("PackageManager", "Failure retrieving resources for "
1084                  + appInfo.packageName);
1085        }
1086        return null;
1087    }
1088
1089    @Override
1090    public CharSequence getApplicationLabel(ApplicationInfo info) {
1091        return info.loadLabel(this);
1092    }
1093
1094    @Override
1095    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1096                               String installerPackageName) {
1097        try {
1098            mPM.installPackageEtc(packageURI, observer, null, flags, installerPackageName);
1099        } catch (RemoteException e) {
1100            // Should never happen!
1101        }
1102    }
1103
1104    @Override
1105    public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
1106            int flags, String installerPackageName, Uri verificationURI,
1107            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
1108        try {
1109            mPM.installPackageWithVerificationEtc(packageURI, observer, null, flags,
1110                    installerPackageName, verificationURI, manifestDigest, encryptionParams);
1111        } catch (RemoteException e) {
1112            // Should never happen!
1113        }
1114    }
1115
1116    @Override
1117    public void installPackageWithVerificationAndEncryption(Uri packageURI,
1118            IPackageInstallObserver observer, int flags, String installerPackageName,
1119            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1120        try {
1121            mPM.installPackageWithVerificationAndEncryptionEtc(packageURI, observer, null,
1122                    flags, installerPackageName, verificationParams, encryptionParams);
1123        } catch (RemoteException e) {
1124            // Should never happen!
1125        }
1126    }
1127
1128    // Expanded observer-API versions
1129    @Override
1130    public void installPackage(Uri packageURI, PackageInstallObserver observer,
1131            int flags, String installerPackageName) {
1132        try {
1133            mPM.installPackageEtc(packageURI, null, observer.getBinder(),
1134                    flags, installerPackageName);
1135        } catch (RemoteException e) {
1136            // Should never happen!
1137        }
1138    }
1139
1140    @Override
1141    public void installPackageWithVerification(Uri packageURI,
1142            PackageInstallObserver observer, int flags, String installerPackageName,
1143            Uri verificationURI, ManifestDigest manifestDigest,
1144            ContainerEncryptionParams encryptionParams) {
1145        try {
1146            mPM.installPackageWithVerificationEtc(packageURI, null, observer.getBinder(), flags,
1147                    installerPackageName, verificationURI, manifestDigest, encryptionParams);
1148        } catch (RemoteException e) {
1149            // Should never happen!
1150        }
1151    }
1152
1153    @Override
1154    public void installPackageWithVerificationAndEncryption(Uri packageURI,
1155            PackageInstallObserver observer, int flags, String installerPackageName,
1156            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1157        try {
1158            mPM.installPackageWithVerificationAndEncryptionEtc(packageURI, null,
1159                    observer.getBinder(), flags, installerPackageName, verificationParams,
1160                    encryptionParams);
1161        } catch (RemoteException e) {
1162            // Should never happen!
1163        }
1164    }
1165
1166    @Override
1167    public int installExistingPackage(String packageName)
1168            throws NameNotFoundException {
1169        try {
1170            int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
1171            if (res == INSTALL_FAILED_INVALID_URI) {
1172                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1173            }
1174            return res;
1175        } catch (RemoteException e) {
1176            // Should never happen!
1177            throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1178        }
1179    }
1180
1181    @Override
1182    public void verifyPendingInstall(int id, int response) {
1183        try {
1184            mPM.verifyPendingInstall(id, response);
1185        } catch (RemoteException e) {
1186            // Should never happen!
1187        }
1188    }
1189
1190    @Override
1191    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1192            long millisecondsToDelay) {
1193        try {
1194            mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1195        } catch (RemoteException e) {
1196            // Should never happen!
1197        }
1198    }
1199
1200    @Override
1201    public void setInstallerPackageName(String targetPackage,
1202            String installerPackageName) {
1203        try {
1204            mPM.setInstallerPackageName(targetPackage, installerPackageName);
1205        } catch (RemoteException e) {
1206            // Should never happen!
1207        }
1208    }
1209
1210    @Override
1211    public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
1212        try {
1213            mPM.movePackage(packageName, observer, flags);
1214        } catch (RemoteException e) {
1215            // Should never happen!
1216        }
1217    }
1218
1219    @Override
1220    public String getInstallerPackageName(String packageName) {
1221        try {
1222            return mPM.getInstallerPackageName(packageName);
1223        } catch (RemoteException e) {
1224            // Should never happen!
1225        }
1226        return null;
1227    }
1228
1229    @Override
1230    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1231        try {
1232            mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
1233        } catch (RemoteException e) {
1234            // Should never happen!
1235        }
1236    }
1237    @Override
1238    public void clearApplicationUserData(String packageName,
1239                                         IPackageDataObserver observer) {
1240        try {
1241            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
1242        } catch (RemoteException e) {
1243            // Should never happen!
1244        }
1245    }
1246    @Override
1247    public void deleteApplicationCacheFiles(String packageName,
1248                                            IPackageDataObserver observer) {
1249        try {
1250            mPM.deleteApplicationCacheFiles(packageName, observer);
1251        } catch (RemoteException e) {
1252            // Should never happen!
1253        }
1254    }
1255    @Override
1256    public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
1257        try {
1258            mPM.freeStorageAndNotify(idealStorageSize, observer);
1259        } catch (RemoteException e) {
1260            // Should never happen!
1261        }
1262    }
1263
1264    @Override
1265    public void freeStorage(long freeStorageSize, IntentSender pi) {
1266        try {
1267            mPM.freeStorage(freeStorageSize, pi);
1268        } catch (RemoteException e) {
1269            // Should never happen!
1270        }
1271    }
1272
1273    @Override
1274    public void getPackageSizeInfo(String packageName, int userHandle,
1275            IPackageStatsObserver observer) {
1276        try {
1277            mPM.getPackageSizeInfo(packageName, userHandle, observer);
1278        } catch (RemoteException e) {
1279            // Should never happen!
1280        }
1281    }
1282    @Override
1283    public void addPackageToPreferred(String packageName) {
1284        try {
1285            mPM.addPackageToPreferred(packageName);
1286        } catch (RemoteException e) {
1287            // Should never happen!
1288        }
1289    }
1290
1291    @Override
1292    public void removePackageFromPreferred(String packageName) {
1293        try {
1294            mPM.removePackageFromPreferred(packageName);
1295        } catch (RemoteException e) {
1296            // Should never happen!
1297        }
1298    }
1299
1300    @Override
1301    public List<PackageInfo> getPreferredPackages(int flags) {
1302        try {
1303            return mPM.getPreferredPackages(flags);
1304        } catch (RemoteException e) {
1305            // Should never happen!
1306        }
1307        return new ArrayList<PackageInfo>();
1308    }
1309
1310    @Override
1311    public void addPreferredActivity(IntentFilter filter,
1312                                     int match, ComponentName[] set, ComponentName activity) {
1313        try {
1314            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
1315        } catch (RemoteException e) {
1316            // Should never happen!
1317        }
1318    }
1319
1320    @Override
1321    public void addPreferredActivity(IntentFilter filter, int match,
1322            ComponentName[] set, ComponentName activity, int userId) {
1323        try {
1324            mPM.addPreferredActivity(filter, match, set, activity, userId);
1325        } catch (RemoteException e) {
1326            // Should never happen!
1327        }
1328    }
1329
1330    @Override
1331    public void replacePreferredActivity(IntentFilter filter,
1332                                         int match, ComponentName[] set, ComponentName activity) {
1333        try {
1334            mPM.replacePreferredActivity(filter, match, set, activity);
1335        } catch (RemoteException e) {
1336            // Should never happen!
1337        }
1338    }
1339
1340    @Override
1341    public void clearPackagePreferredActivities(String packageName) {
1342        try {
1343            mPM.clearPackagePreferredActivities(packageName);
1344        } catch (RemoteException e) {
1345            // Should never happen!
1346        }
1347    }
1348
1349    @Override
1350    public int getPreferredActivities(List<IntentFilter> outFilters,
1351                                      List<ComponentName> outActivities, String packageName) {
1352        try {
1353            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1354        } catch (RemoteException e) {
1355            // Should never happen!
1356        }
1357        return 0;
1358    }
1359
1360    @Override
1361    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
1362        try {
1363            return mPM.getHomeActivities(outActivities);
1364        } catch (RemoteException e) {
1365            // Should never happen!
1366        }
1367        return null;
1368    }
1369
1370    @Override
1371    public void setComponentEnabledSetting(ComponentName componentName,
1372                                           int newState, int flags) {
1373        try {
1374            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
1375        } catch (RemoteException e) {
1376            // Should never happen!
1377        }
1378    }
1379
1380    @Override
1381    public int getComponentEnabledSetting(ComponentName componentName) {
1382        try {
1383            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
1384        } catch (RemoteException e) {
1385            // Should never happen!
1386        }
1387        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1388    }
1389
1390    @Override
1391    public void setApplicationEnabledSetting(String packageName,
1392                                             int newState, int flags) {
1393        try {
1394            mPM.setApplicationEnabledSetting(packageName, newState, flags,
1395                    mContext.getUserId(), mContext.getOpPackageName());
1396        } catch (RemoteException e) {
1397            // Should never happen!
1398        }
1399    }
1400
1401    @Override
1402    public int getApplicationEnabledSetting(String packageName) {
1403        try {
1404            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
1405        } catch (RemoteException e) {
1406            // Should never happen!
1407        }
1408        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1409    }
1410
1411    @Override
1412    public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
1413            UserHandle user) {
1414        try {
1415            return mPM.setApplicationBlockedSettingAsUser(packageName, blocked,
1416                    user.getIdentifier());
1417        } catch (RemoteException re) {
1418            // Should never happen!
1419        }
1420        return false;
1421    }
1422
1423    @Override
1424    public boolean getApplicationBlockedSettingAsUser(String packageName, UserHandle user) {
1425        try {
1426            return mPM.getApplicationBlockedSettingAsUser(packageName, user.getIdentifier());
1427        } catch (RemoteException re) {
1428            // Should never happen!
1429        }
1430        return false;
1431    }
1432
1433    /**
1434     * @hide
1435     */
1436    @Override
1437    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1438        try {
1439            return mPM.getVerifierDeviceIdentity();
1440        } catch (RemoteException e) {
1441            // Should never happen!
1442        }
1443        return null;
1444    }
1445
1446    @Override
1447    public PackageInstaller getPackageInstaller() {
1448        try {
1449            return new PackageInstaller(this, mPM.getPackageInstaller(), mContext.getUserId(),
1450                    mContext.getPackageName());
1451        } catch (RemoteException e) {
1452            throw e.rethrowAsRuntimeException();
1453        }
1454    }
1455
1456    /**
1457     * @hide
1458     */
1459    @Override
1460    public void addCrossProfileIntentFilter(IntentFilter filter, boolean removable,
1461            int sourceUserId, int targetUserId) {
1462        try {
1463            mPM.addCrossProfileIntentFilter(filter, removable, sourceUserId, targetUserId);
1464        } catch (RemoteException e) {
1465            // Should never happen!
1466        }
1467    }
1468
1469    /**
1470     * @hide
1471     */
1472    @Override
1473    public void addForwardingIntentFilter(IntentFilter filter, boolean removable, int sourceUserId,
1474            int targetUserId) {
1475        addCrossProfileIntentFilter(filter, removable, sourceUserId, targetUserId);
1476    }
1477
1478    /**
1479     * @hide
1480     */
1481    @Override
1482    public void clearCrossProfileIntentFilters(int sourceUserId) {
1483        try {
1484            mPM.clearCrossProfileIntentFilters(sourceUserId);
1485        } catch (RemoteException e) {
1486            // Should never happen!
1487        }
1488    }
1489
1490    /**
1491     * @hide
1492     */
1493    @Override
1494    public void clearForwardingIntentFilters(int sourceUserId) {
1495        clearCrossProfileIntentFilters(sourceUserId);
1496    }
1497
1498    private final ContextImpl mContext;
1499    private final IPackageManager mPM;
1500
1501    private static final Object sSync = new Object();
1502    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
1503            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
1504    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
1505            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
1506}
1507