ApplicationPackageManager.java revision 970417c7d3e33ccbd6918e28d9bc5da24651f5b3
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import android.content.ComponentName;
20import android.content.ContentResolver;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.content.IntentSender;
24import android.content.pm.ActivityInfo;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.ComponentInfo;
27import android.content.pm.ContainerEncryptionParams;
28import android.content.pm.FeatureInfo;
29import android.content.pm.IPackageDataObserver;
30import android.content.pm.IPackageDeleteObserver;
31import android.content.pm.IPackageInstallObserver;
32import android.content.pm.IPackageManager;
33import android.content.pm.IPackageMoveObserver;
34import android.content.pm.IPackageStatsObserver;
35import android.content.pm.InstrumentationInfo;
36import android.content.pm.PackageInfo;
37import android.content.pm.PackageManager;
38import android.content.pm.ParceledListSlice;
39import android.content.pm.PermissionGroupInfo;
40import android.content.pm.PermissionInfo;
41import android.content.pm.ProviderInfo;
42import android.content.pm.ResolveInfo;
43import android.content.pm.ServiceInfo;
44import android.content.pm.ManifestDigest;
45import android.content.pm.VerificationParams;
46import android.content.pm.VerifierDeviceIdentity;
47import android.content.res.Resources;
48import android.content.res.XmlResourceParser;
49import android.graphics.drawable.Drawable;
50import android.net.Uri;
51import android.os.Process;
52import android.os.RemoteException;
53import android.os.UserHandle;
54import android.util.ArrayMap;
55import android.util.Log;
56import android.view.Display;
57
58import java.lang.ref.WeakReference;
59import java.util.ArrayList;
60import java.util.HashMap;
61import java.util.Iterator;
62import java.util.List;
63
64/*package*/
65final class ApplicationPackageManager extends PackageManager {
66    private static final String TAG = "ApplicationPackageManager";
67    private final static boolean DEBUG = false;
68    private final static boolean DEBUG_ICONS = false;
69
70    @Override
71    public PackageInfo getPackageInfo(String packageName, int flags)
72            throws NameNotFoundException {
73        try {
74            PackageInfo pi = mPM.getPackageInfo(packageName, flags, mContext.getUserId());
75            if (pi != null) {
76                return pi;
77            }
78        } catch (RemoteException e) {
79            throw new RuntimeException("Package manager has died", e);
80        }
81
82        throw new NameNotFoundException(packageName);
83    }
84
85    @Override
86    public String[] currentToCanonicalPackageNames(String[] names) {
87        try {
88            return mPM.currentToCanonicalPackageNames(names);
89        } catch (RemoteException e) {
90            throw new RuntimeException("Package manager has died", e);
91        }
92    }
93
94    @Override
95    public String[] canonicalToCurrentPackageNames(String[] names) {
96        try {
97            return mPM.canonicalToCurrentPackageNames(names);
98        } catch (RemoteException e) {
99            throw new RuntimeException("Package manager has died", e);
100        }
101    }
102
103    @Override
104    public Intent getLaunchIntentForPackage(String packageName) {
105        // First see if the package has an INFO activity; the existence of
106        // such an activity is implied to be the desired front-door for the
107        // overall package (such as if it has multiple launcher entries).
108        Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
109        intentToResolve.addCategory(Intent.CATEGORY_INFO);
110        intentToResolve.setPackage(packageName);
111        List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
112
113        // Otherwise, try to find a main launcher activity.
114        if (ris == null || ris.size() <= 0) {
115            // reuse the intent instance
116            intentToResolve.removeCategory(Intent.CATEGORY_INFO);
117            intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
118            intentToResolve.setPackage(packageName);
119            ris = queryIntentActivities(intentToResolve, 0);
120        }
121        if (ris == null || ris.size() <= 0) {
122            return null;
123        }
124        Intent intent = new Intent(intentToResolve);
125        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
126        intent.setClassName(ris.get(0).activityInfo.packageName,
127                ris.get(0).activityInfo.name);
128        return intent;
129    }
130
131    @Override
132    public 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                        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.installPackage(packageURI, observer, 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.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
1108                    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.installPackageWithVerificationAndEncryption(packageURI, observer, flags,
1120                    installerPackageName, verificationParams, encryptionParams);
1121        } catch (RemoteException e) {
1122            // Should never happen!
1123        }
1124    }
1125
1126    @Override
1127    public int installExistingPackage(String packageName)
1128            throws NameNotFoundException {
1129        try {
1130            int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
1131            if (res == INSTALL_FAILED_INVALID_URI) {
1132                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1133            }
1134            return res;
1135        } catch (RemoteException e) {
1136            // Should never happen!
1137            throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1138        }
1139    }
1140
1141    @Override
1142    public void verifyPendingInstall(int id, int response) {
1143        try {
1144            mPM.verifyPendingInstall(id, response);
1145        } catch (RemoteException e) {
1146            // Should never happen!
1147        }
1148    }
1149
1150    @Override
1151    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1152            long millisecondsToDelay) {
1153        try {
1154            mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1155        } catch (RemoteException e) {
1156            // Should never happen!
1157        }
1158    }
1159
1160    @Override
1161    public void setInstallerPackageName(String targetPackage,
1162            String installerPackageName) {
1163        try {
1164            mPM.setInstallerPackageName(targetPackage, installerPackageName);
1165        } catch (RemoteException e) {
1166            // Should never happen!
1167        }
1168    }
1169
1170    @Override
1171    public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
1172        try {
1173            mPM.movePackage(packageName, observer, flags);
1174        } catch (RemoteException e) {
1175            // Should never happen!
1176        }
1177    }
1178
1179    @Override
1180    public String getInstallerPackageName(String packageName) {
1181        try {
1182            return mPM.getInstallerPackageName(packageName);
1183        } catch (RemoteException e) {
1184            // Should never happen!
1185        }
1186        return null;
1187    }
1188
1189    @Override
1190    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1191        try {
1192            mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
1193        } catch (RemoteException e) {
1194            // Should never happen!
1195        }
1196    }
1197    @Override
1198    public void clearApplicationUserData(String packageName,
1199                                         IPackageDataObserver observer) {
1200        try {
1201            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
1202        } catch (RemoteException e) {
1203            // Should never happen!
1204        }
1205    }
1206    @Override
1207    public void deleteApplicationCacheFiles(String packageName,
1208                                            IPackageDataObserver observer) {
1209        try {
1210            mPM.deleteApplicationCacheFiles(packageName, observer);
1211        } catch (RemoteException e) {
1212            // Should never happen!
1213        }
1214    }
1215    @Override
1216    public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
1217        try {
1218            mPM.freeStorageAndNotify(idealStorageSize, observer);
1219        } catch (RemoteException e) {
1220            // Should never happen!
1221        }
1222    }
1223
1224    @Override
1225    public void freeStorage(long freeStorageSize, IntentSender pi) {
1226        try {
1227            mPM.freeStorage(freeStorageSize, pi);
1228        } catch (RemoteException e) {
1229            // Should never happen!
1230        }
1231    }
1232
1233    @Override
1234    public void getPackageSizeInfo(String packageName, int userHandle,
1235            IPackageStatsObserver observer) {
1236        try {
1237            mPM.getPackageSizeInfo(packageName, userHandle, observer);
1238        } catch (RemoteException e) {
1239            // Should never happen!
1240        }
1241    }
1242    @Override
1243    public void addPackageToPreferred(String packageName) {
1244        try {
1245            mPM.addPackageToPreferred(packageName);
1246        } catch (RemoteException e) {
1247            // Should never happen!
1248        }
1249    }
1250
1251    @Override
1252    public void removePackageFromPreferred(String packageName) {
1253        try {
1254            mPM.removePackageFromPreferred(packageName);
1255        } catch (RemoteException e) {
1256            // Should never happen!
1257        }
1258    }
1259
1260    @Override
1261    public List<PackageInfo> getPreferredPackages(int flags) {
1262        try {
1263            return mPM.getPreferredPackages(flags);
1264        } catch (RemoteException e) {
1265            // Should never happen!
1266        }
1267        return new ArrayList<PackageInfo>();
1268    }
1269
1270    @Override
1271    public void addPreferredActivity(IntentFilter filter,
1272                                     int match, ComponentName[] set, ComponentName activity) {
1273        try {
1274            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
1275        } catch (RemoteException e) {
1276            // Should never happen!
1277        }
1278    }
1279
1280    @Override
1281    public void addPreferredActivity(IntentFilter filter, int match,
1282            ComponentName[] set, ComponentName activity, int userId) {
1283        try {
1284            mPM.addPreferredActivity(filter, match, set, activity, userId);
1285        } catch (RemoteException e) {
1286            // Should never happen!
1287        }
1288    }
1289
1290    @Override
1291    public void replacePreferredActivity(IntentFilter filter,
1292                                         int match, ComponentName[] set, ComponentName activity) {
1293        try {
1294            mPM.replacePreferredActivity(filter, match, set, activity);
1295        } catch (RemoteException e) {
1296            // Should never happen!
1297        }
1298    }
1299
1300    @Override
1301    public void clearPackagePreferredActivities(String packageName) {
1302        try {
1303            mPM.clearPackagePreferredActivities(packageName);
1304        } catch (RemoteException e) {
1305            // Should never happen!
1306        }
1307    }
1308
1309    @Override
1310    public int getPreferredActivities(List<IntentFilter> outFilters,
1311                                      List<ComponentName> outActivities, String packageName) {
1312        try {
1313            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1314        } catch (RemoteException e) {
1315            // Should never happen!
1316        }
1317        return 0;
1318    }
1319
1320    @Override
1321    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
1322        try {
1323            return mPM.getHomeActivities(outActivities);
1324        } catch (RemoteException e) {
1325            // Should never happen!
1326        }
1327        return null;
1328    }
1329
1330    @Override
1331    public void setComponentEnabledSetting(ComponentName componentName,
1332                                           int newState, int flags) {
1333        try {
1334            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
1335        } catch (RemoteException e) {
1336            // Should never happen!
1337        }
1338    }
1339
1340    @Override
1341    public int getComponentEnabledSetting(ComponentName componentName) {
1342        try {
1343            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
1344        } catch (RemoteException e) {
1345            // Should never happen!
1346        }
1347        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1348    }
1349
1350    @Override
1351    public void setApplicationEnabledSetting(String packageName,
1352                                             int newState, int flags) {
1353        try {
1354            mPM.setApplicationEnabledSetting(packageName, newState, flags,
1355                    mContext.getUserId(), mContext.getOpPackageName());
1356        } catch (RemoteException e) {
1357            // Should never happen!
1358        }
1359    }
1360
1361    @Override
1362    public int getApplicationEnabledSetting(String packageName) {
1363        try {
1364            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
1365        } catch (RemoteException e) {
1366            // Should never happen!
1367        }
1368        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1369    }
1370
1371    @Override
1372    public boolean setApplicationBlockedSettingAsUser(String packageName, boolean blocked,
1373            UserHandle user) {
1374        try {
1375            return mPM.setApplicationBlockedSettingAsUser(packageName, blocked,
1376                    user.getIdentifier());
1377        } catch (RemoteException re) {
1378            // Should never happen!
1379        }
1380        return false;
1381    }
1382
1383    @Override
1384    public boolean getApplicationBlockedSettingAsUser(String packageName, UserHandle user) {
1385        try {
1386            return mPM.getApplicationBlockedSettingAsUser(packageName, user.getIdentifier());
1387        } catch (RemoteException re) {
1388            // Should never happen!
1389        }
1390        return false;
1391    }
1392
1393    /**
1394     * @hide
1395     */
1396    @Override
1397    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1398        try {
1399            return mPM.getVerifierDeviceIdentity();
1400        } catch (RemoteException e) {
1401            // Should never happen!
1402        }
1403        return null;
1404    }
1405
1406    private final ContextImpl mContext;
1407    private final IPackageManager mPM;
1408
1409    private static final Object sSync = new Object();
1410    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
1411            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
1412    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
1413            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
1414}
1415