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