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