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