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