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