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