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