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