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