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