ApplicationPackageManager.java revision ecd585a8fd2ae17479ae698193d5b04b602c5b70
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            } catch (NameNotFoundException e) {
779                Log.w("PackageManager", "Failure retrieving resources for "
780                        + appInfo.packageName);
781            } catch (Resources.NotFoundException e) {
782                Log.w("PackageManager", "Failure retrieving resources for "
783                        + appInfo.packageName + ": " + e.getMessage());
784            } catch (Exception e) {
785                // If an exception was thrown, fall through to return
786                // default icon.
787                Log.w("PackageManager", "Failure retrieving icon 0x"
788                        + Integer.toHexString(resId) + " in package "
789                        + packageName, e);
790            }
791        }
792
793        return null;
794    }
795
796    @Override public Drawable getActivityIcon(ComponentName activityName)
797            throws NameNotFoundException {
798        return getActivityInfo(activityName, sDefaultFlags).loadIcon(this);
799    }
800
801    @Override public Drawable getActivityIcon(Intent intent)
802            throws NameNotFoundException {
803        if (intent.getComponent() != null) {
804            return getActivityIcon(intent.getComponent());
805        }
806
807        ResolveInfo info = resolveActivity(
808            intent, PackageManager.MATCH_DEFAULT_ONLY);
809        if (info != null) {
810            return info.activityInfo.loadIcon(this);
811        }
812
813        throw new NameNotFoundException(intent.toUri(0));
814    }
815
816    @Override public Drawable getDefaultActivityIcon() {
817        return Resources.getSystem().getDrawable(
818            com.android.internal.R.drawable.sym_def_app_icon);
819    }
820
821    @Override public Drawable getApplicationIcon(ApplicationInfo info) {
822        return info.loadIcon(this);
823    }
824
825    @Override public Drawable getApplicationIcon(String packageName)
826            throws NameNotFoundException {
827        return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags));
828    }
829
830    @Override
831    public Drawable getActivityBanner(ComponentName activityName)
832            throws NameNotFoundException {
833        return getActivityInfo(activityName, sDefaultFlags).loadBanner(this);
834    }
835
836    @Override
837    public Drawable getActivityBanner(Intent intent)
838            throws NameNotFoundException {
839        if (intent.getComponent() != null) {
840            return getActivityBanner(intent.getComponent());
841        }
842
843        ResolveInfo info = resolveActivity(
844                intent, PackageManager.MATCH_DEFAULT_ONLY);
845        if (info != null) {
846            return info.activityInfo.loadBanner(this);
847        }
848
849        throw new NameNotFoundException(intent.toUri(0));
850    }
851
852    @Override
853    public Drawable getApplicationBanner(ApplicationInfo info) {
854        return info.loadBanner(this);
855    }
856
857    @Override
858    public Drawable getApplicationBanner(String packageName)
859            throws NameNotFoundException {
860        return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags));
861    }
862
863    @Override
864    public Drawable getActivityLogo(ComponentName activityName)
865            throws NameNotFoundException {
866        return getActivityInfo(activityName, sDefaultFlags).loadLogo(this);
867    }
868
869    @Override
870    public Drawable getActivityLogo(Intent intent)
871            throws NameNotFoundException {
872        if (intent.getComponent() != null) {
873            return getActivityLogo(intent.getComponent());
874        }
875
876        ResolveInfo info = resolveActivity(
877            intent, PackageManager.MATCH_DEFAULT_ONLY);
878        if (info != null) {
879            return info.activityInfo.loadLogo(this);
880        }
881
882        throw new NameNotFoundException(intent.toUri(0));
883    }
884
885    @Override
886    public Drawable getApplicationLogo(ApplicationInfo info) {
887        return info.loadLogo(this);
888    }
889
890    @Override
891    public Drawable getApplicationLogo(String packageName)
892            throws NameNotFoundException {
893        return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags));
894    }
895
896    @Override
897    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
898        final int badgeResId = getBadgeResIdForUser(user.getIdentifier());
899        if (badgeResId == 0) {
900            return icon;
901        }
902        Drawable badgeIcon = getDrawable("system", badgeResId, null);
903        return getBadgedDrawable(icon, badgeIcon, null, true);
904    }
905
906    @Override
907    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
908            Rect badgeLocation, int badgeDensity) {
909        Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity);
910        if (badgeDrawable == null) {
911            return drawable;
912        }
913        return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
914    }
915
916    @Override
917    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
918        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
919        if (userInfo != null && userInfo.isManagedProfile()) {
920            if (density <= 0) {
921                density = mContext.getResources().getDisplayMetrics().densityDpi;
922            }
923            return Resources.getSystem().getDrawableForDensity(
924                    com.android.internal.R.drawable.ic_corp_badge, density);
925        }
926        return null;
927    }
928
929    @Override
930    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
931        UserInfo userInfo = getUserIfProfile(user.getIdentifier());
932        if (userInfo != null && userInfo.isManagedProfile()) {
933            return Resources.getSystem().getString(
934                    com.android.internal.R.string.managed_profile_label_badge, label);
935        }
936        return label;
937    }
938
939    @Override
940    public Resources getResourcesForActivity(ComponentName activityName)
941            throws NameNotFoundException {
942        return getResourcesForApplication(
943            getActivityInfo(activityName, sDefaultFlags).applicationInfo);
944    }
945
946    @Override
947    public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
948            throws NameNotFoundException {
949        if (app.packageName.equals("system")) {
950            return mContext.mMainThread.getSystemContext().getResources();
951        }
952        final boolean sameUid = (app.uid == Process.myUid());
953        final Resources r = mContext.mMainThread.getTopLevelResources(
954                sameUid ? app.sourceDir : app.publicSourceDir,
955                sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
956                app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
957                null, mContext.mPackageInfo);
958        if (r != null) {
959            return r;
960        }
961        throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
962    }
963
964    @Override
965    public Resources getResourcesForApplication(String appPackageName)
966            throws NameNotFoundException {
967        return getResourcesForApplication(
968            getApplicationInfo(appPackageName, sDefaultFlags));
969    }
970
971    /** @hide */
972    @Override
973    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
974            throws NameNotFoundException {
975        if (userId < 0) {
976            throw new IllegalArgumentException(
977                    "Call does not support special user #" + userId);
978        }
979        if ("system".equals(appPackageName)) {
980            return mContext.mMainThread.getSystemContext().getResources();
981        }
982        try {
983            ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
984            if (ai != null) {
985                return getResourcesForApplication(ai);
986            }
987        } catch (RemoteException e) {
988            throw new RuntimeException("Package manager has died", e);
989        }
990        throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
991    }
992
993    int mCachedSafeMode = -1;
994    @Override public boolean isSafeMode() {
995        try {
996            if (mCachedSafeMode < 0) {
997                mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
998            }
999            return mCachedSafeMode != 0;
1000        } catch (RemoteException e) {
1001            throw new RuntimeException("Package manager has died", e);
1002        }
1003    }
1004
1005    static void configurationChanged() {
1006        synchronized (sSync) {
1007            sIconCache.clear();
1008            sStringCache.clear();
1009        }
1010    }
1011
1012    ApplicationPackageManager(ContextImpl context,
1013                              IPackageManager pm) {
1014        mContext = context;
1015        mPM = pm;
1016    }
1017
1018    @Nullable
1019    private Drawable getCachedIcon(@NonNull ResourceName name) {
1020        synchronized (sSync) {
1021            final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
1022            if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
1023                                   + name + ": " + wr);
1024            if (wr != null) {   // we have the activity
1025                final Drawable.ConstantState state = wr.get();
1026                if (state != null) {
1027                    if (DEBUG_ICONS) {
1028                        Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
1029                    }
1030                    // Note: It's okay here to not use the newDrawable(Resources) variant
1031                    //       of the API. The ConstantState comes from a drawable that was
1032                    //       originally created by passing the proper app Resources instance
1033                    //       which means the state should already contain the proper
1034                    //       resources specific information (like density.) See
1035                    //       BitmapDrawable.BitmapState for instance.
1036                    return state.newDrawable();
1037                }
1038                // our entry has been purged
1039                sIconCache.remove(name);
1040            }
1041        }
1042        return null;
1043    }
1044
1045    private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) {
1046        synchronized (sSync) {
1047            sIconCache.put(name, new WeakReference<>(dr.getConstantState()));
1048            if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
1049        }
1050    }
1051
1052    static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
1053        boolean immediateGc = false;
1054        if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
1055            immediateGc = true;
1056        }
1057        if (pkgList != null && (pkgList.length > 0)) {
1058            boolean needCleanup = false;
1059            for (String ssp : pkgList) {
1060                synchronized (sSync) {
1061                    for (int i=sIconCache.size()-1; i>=0; i--) {
1062                        ResourceName nm = sIconCache.keyAt(i);
1063                        if (nm.packageName.equals(ssp)) {
1064                            //Log.i(TAG, "Removing cached drawable for " + nm);
1065                            sIconCache.removeAt(i);
1066                            needCleanup = true;
1067                        }
1068                    }
1069                    for (int i=sStringCache.size()-1; i>=0; i--) {
1070                        ResourceName nm = sStringCache.keyAt(i);
1071                        if (nm.packageName.equals(ssp)) {
1072                            //Log.i(TAG, "Removing cached string for " + nm);
1073                            sStringCache.removeAt(i);
1074                            needCleanup = true;
1075                        }
1076                    }
1077                }
1078            }
1079            if (needCleanup || hasPkgInfo) {
1080                if (immediateGc) {
1081                    // Schedule an immediate gc.
1082                    Runtime.getRuntime().gc();
1083                } else {
1084                    ActivityThread.currentActivityThread().scheduleGcIdler();
1085                }
1086            }
1087        }
1088    }
1089
1090    private static final class ResourceName {
1091        final String packageName;
1092        final int iconId;
1093
1094        ResourceName(String _packageName, int _iconId) {
1095            packageName = _packageName;
1096            iconId = _iconId;
1097        }
1098
1099        ResourceName(ApplicationInfo aInfo, int _iconId) {
1100            this(aInfo.packageName, _iconId);
1101        }
1102
1103        ResourceName(ComponentInfo cInfo, int _iconId) {
1104            this(cInfo.applicationInfo.packageName, _iconId);
1105        }
1106
1107        ResourceName(ResolveInfo rInfo, int _iconId) {
1108            this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
1109        }
1110
1111        @Override
1112        public boolean equals(Object o) {
1113            if (this == o) return true;
1114            if (o == null || getClass() != o.getClass()) return false;
1115
1116            ResourceName that = (ResourceName) o;
1117
1118            if (iconId != that.iconId) return false;
1119            return !(packageName != null ?
1120                     !packageName.equals(that.packageName) : that.packageName != null);
1121
1122        }
1123
1124        @Override
1125        public int hashCode() {
1126            int result;
1127            result = packageName.hashCode();
1128            result = 31 * result + iconId;
1129            return result;
1130        }
1131
1132        @Override
1133        public String toString() {
1134            return "{ResourceName " + packageName + " / " + iconId + "}";
1135        }
1136    }
1137
1138    private CharSequence getCachedString(ResourceName name) {
1139        synchronized (sSync) {
1140            WeakReference<CharSequence> wr = sStringCache.get(name);
1141            if (wr != null) {   // we have the activity
1142                CharSequence cs = wr.get();
1143                if (cs != null) {
1144                    return cs;
1145                }
1146                // our entry has been purged
1147                sStringCache.remove(name);
1148            }
1149        }
1150        return null;
1151    }
1152
1153    private void putCachedString(ResourceName name, CharSequence cs) {
1154        synchronized (sSync) {
1155            sStringCache.put(name, new WeakReference<CharSequence>(cs));
1156        }
1157    }
1158
1159    @Override
1160    public CharSequence getText(String packageName, @StringRes int resid,
1161                                ApplicationInfo appInfo) {
1162        ResourceName name = new ResourceName(packageName, resid);
1163        CharSequence text = getCachedString(name);
1164        if (text != null) {
1165            return text;
1166        }
1167        if (appInfo == null) {
1168            try {
1169                appInfo = getApplicationInfo(packageName, sDefaultFlags);
1170            } catch (NameNotFoundException e) {
1171                return null;
1172            }
1173        }
1174        try {
1175            Resources r = getResourcesForApplication(appInfo);
1176            text = r.getText(resid);
1177            putCachedString(name, text);
1178            return text;
1179        } catch (NameNotFoundException e) {
1180            Log.w("PackageManager", "Failure retrieving resources for "
1181                  + appInfo.packageName);
1182        } catch (RuntimeException e) {
1183            // If an exception was thrown, fall through to return
1184            // default icon.
1185            Log.w("PackageManager", "Failure retrieving text 0x"
1186                  + Integer.toHexString(resid) + " in package "
1187                  + packageName, e);
1188        }
1189        return null;
1190    }
1191
1192    @Override
1193    public XmlResourceParser getXml(String packageName, @XmlRes int resid,
1194                                    ApplicationInfo appInfo) {
1195        if (appInfo == null) {
1196            try {
1197                appInfo = getApplicationInfo(packageName, sDefaultFlags);
1198            } catch (NameNotFoundException e) {
1199                return null;
1200            }
1201        }
1202        try {
1203            Resources r = getResourcesForApplication(appInfo);
1204            return r.getXml(resid);
1205        } catch (RuntimeException e) {
1206            // If an exception was thrown, fall through to return
1207            // default icon.
1208            Log.w("PackageManager", "Failure retrieving xml 0x"
1209                  + Integer.toHexString(resid) + " in package "
1210                  + packageName, e);
1211        } catch (NameNotFoundException e) {
1212            Log.w("PackageManager", "Failure retrieving resources for "
1213                  + appInfo.packageName);
1214        }
1215        return null;
1216    }
1217
1218    @Override
1219    public CharSequence getApplicationLabel(ApplicationInfo info) {
1220        return info.loadLabel(this);
1221    }
1222
1223    @Override
1224    public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
1225                               String installerPackageName) {
1226        final VerificationParams verificationParams = new VerificationParams(null, null,
1227                null, VerificationParams.NO_UID, null);
1228        installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1229                installerPackageName, verificationParams, null);
1230    }
1231
1232    @Override
1233    public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
1234            int flags, String installerPackageName, Uri verificationURI,
1235            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
1236        final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
1237                null, VerificationParams.NO_UID, manifestDigest);
1238        installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1239                installerPackageName, verificationParams, encryptionParams);
1240    }
1241
1242    @Override
1243    public void installPackageWithVerificationAndEncryption(Uri packageURI,
1244            IPackageInstallObserver observer, int flags, String installerPackageName,
1245            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1246        installCommon(packageURI, new LegacyPackageInstallObserver(observer), flags,
1247                installerPackageName, verificationParams, encryptionParams);
1248    }
1249
1250    @Override
1251    public void installPackage(Uri packageURI, PackageInstallObserver observer,
1252            int flags, String installerPackageName) {
1253        final VerificationParams verificationParams = new VerificationParams(null, null,
1254                null, VerificationParams.NO_UID, null);
1255        installCommon(packageURI, observer, flags, installerPackageName, verificationParams, null);
1256    }
1257
1258    @Override
1259    public void installPackageWithVerification(Uri packageURI,
1260            PackageInstallObserver observer, int flags, String installerPackageName,
1261            Uri verificationURI, ManifestDigest manifestDigest,
1262            ContainerEncryptionParams encryptionParams) {
1263        final VerificationParams verificationParams = new VerificationParams(verificationURI, null,
1264                null, VerificationParams.NO_UID, manifestDigest);
1265        installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
1266                encryptionParams);
1267    }
1268
1269    @Override
1270    public void installPackageWithVerificationAndEncryption(Uri packageURI,
1271            PackageInstallObserver observer, int flags, String installerPackageName,
1272            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1273        installCommon(packageURI, observer, flags, installerPackageName, verificationParams,
1274                encryptionParams);
1275    }
1276
1277    private void installCommon(Uri packageURI,
1278            PackageInstallObserver observer, int flags, String installerPackageName,
1279            VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
1280        if (!"file".equals(packageURI.getScheme())) {
1281            throw new UnsupportedOperationException("Only file:// URIs are supported");
1282        }
1283        if (encryptionParams != null) {
1284            throw new UnsupportedOperationException("ContainerEncryptionParams not supported");
1285        }
1286
1287        final String originPath = packageURI.getPath();
1288        try {
1289            mPM.installPackage(originPath, observer.getBinder(), flags, installerPackageName,
1290                    verificationParams, null);
1291        } catch (RemoteException ignored) {
1292        }
1293    }
1294
1295    @Override
1296    public int installExistingPackage(String packageName)
1297            throws NameNotFoundException {
1298        try {
1299            int res = mPM.installExistingPackageAsUser(packageName, UserHandle.myUserId());
1300            if (res == INSTALL_FAILED_INVALID_URI) {
1301                throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1302            }
1303            return res;
1304        } catch (RemoteException e) {
1305            // Should never happen!
1306            throw new NameNotFoundException("Package " + packageName + " doesn't exist");
1307        }
1308    }
1309
1310    @Override
1311    public void verifyPendingInstall(int id, int response) {
1312        try {
1313            mPM.verifyPendingInstall(id, response);
1314        } catch (RemoteException e) {
1315            // Should never happen!
1316        }
1317    }
1318
1319    @Override
1320    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
1321            long millisecondsToDelay) {
1322        try {
1323            mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
1324        } catch (RemoteException e) {
1325            // Should never happen!
1326        }
1327    }
1328
1329    @Override
1330    public void verifyIntentFilter(int id, int verificationCode, List<String> outFailedDomains) {
1331        try {
1332            mPM.verifyIntentFilter(id, verificationCode, outFailedDomains);
1333        } catch (RemoteException e) {
1334            // Should never happen!
1335        }
1336    }
1337
1338    @Override
1339    public int getIntentVerificationStatus(String packageName, int userId) {
1340        try {
1341            return mPM.getIntentVerificationStatus(packageName, userId);
1342        } catch (RemoteException e) {
1343            // Should never happen!
1344            return PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1345        }
1346    }
1347
1348    @Override
1349    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
1350        try {
1351            return mPM.updateIntentVerificationStatus(packageName, status, userId);
1352        } catch (RemoteException e) {
1353            // Should never happen!
1354            return false;
1355        }
1356    }
1357
1358    @Override
1359    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
1360        try {
1361            return mPM.getIntentFilterVerifications(packageName);
1362        } catch (RemoteException e) {
1363            // Should never happen!
1364            return null;
1365        }
1366    }
1367
1368    @Override
1369    public List<IntentFilter> getAllIntentFilters(String packageName) {
1370        try {
1371            return mPM.getAllIntentFilters(packageName);
1372        } catch (RemoteException e) {
1373            // Should never happen!
1374            return null;
1375        }
1376    }
1377
1378    @Override
1379    public String getDefaultBrowserPackageName(int userId) {
1380        try {
1381            return mPM.getDefaultBrowserPackageName(userId);
1382        } catch (RemoteException e) {
1383            // Should never happen!
1384            return null;
1385        }
1386    }
1387
1388    @Override
1389    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
1390        try {
1391            return mPM.setDefaultBrowserPackageName(packageName, userId);
1392        } catch (RemoteException e) {
1393            // Should never happen!
1394            return false;
1395        }
1396    }
1397
1398    @Override
1399    public void setInstallerPackageName(String targetPackage,
1400            String installerPackageName) {
1401        try {
1402            mPM.setInstallerPackageName(targetPackage, installerPackageName);
1403        } catch (RemoteException e) {
1404            // Should never happen!
1405        }
1406    }
1407
1408    @Override
1409    public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
1410        try {
1411            mPM.movePackage(packageName, observer, flags);
1412        } catch (RemoteException e) {
1413            throw e.rethrowAsRuntimeException();
1414        }
1415    }
1416
1417    @Override
1418    public void movePackageAndData(String packageName, String volumeUuid,
1419            IPackageMoveObserver observer) {
1420        try {
1421            mPM.movePackageAndData(packageName, volumeUuid, observer);
1422        } catch (RemoteException e) {
1423            throw e.rethrowAsRuntimeException();
1424        }
1425    }
1426
1427    @Override
1428    public String getInstallerPackageName(String packageName) {
1429        try {
1430            return mPM.getInstallerPackageName(packageName);
1431        } catch (RemoteException e) {
1432            // Should never happen!
1433        }
1434        return null;
1435    }
1436
1437    @Override
1438    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1439        try {
1440            mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags);
1441        } catch (RemoteException e) {
1442            // Should never happen!
1443        }
1444    }
1445
1446    @Override
1447    public void clearApplicationUserData(String packageName,
1448                                         IPackageDataObserver observer) {
1449        try {
1450            mPM.clearApplicationUserData(packageName, observer, mContext.getUserId());
1451        } catch (RemoteException e) {
1452            // Should never happen!
1453        }
1454    }
1455    @Override
1456    public void deleteApplicationCacheFiles(String packageName,
1457                                            IPackageDataObserver observer) {
1458        try {
1459            mPM.deleteApplicationCacheFiles(packageName, observer);
1460        } catch (RemoteException e) {
1461            // Should never happen!
1462        }
1463    }
1464    @Override
1465    public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
1466        try {
1467            mPM.freeStorageAndNotify(idealStorageSize, observer);
1468        } catch (RemoteException e) {
1469            // Should never happen!
1470        }
1471    }
1472
1473    @Override
1474    public void freeStorage(long freeStorageSize, IntentSender pi) {
1475        try {
1476            mPM.freeStorage(freeStorageSize, pi);
1477        } catch (RemoteException e) {
1478            // Should never happen!
1479        }
1480    }
1481
1482    @Override
1483    public void getPackageSizeInfo(String packageName, int userHandle,
1484            IPackageStatsObserver observer) {
1485        try {
1486            mPM.getPackageSizeInfo(packageName, userHandle, observer);
1487        } catch (RemoteException e) {
1488            // Should never happen!
1489        }
1490    }
1491    @Override
1492    public void addPackageToPreferred(String packageName) {
1493        try {
1494            mPM.addPackageToPreferred(packageName);
1495        } catch (RemoteException e) {
1496            // Should never happen!
1497        }
1498    }
1499
1500    @Override
1501    public void removePackageFromPreferred(String packageName) {
1502        try {
1503            mPM.removePackageFromPreferred(packageName);
1504        } catch (RemoteException e) {
1505            // Should never happen!
1506        }
1507    }
1508
1509    @Override
1510    public List<PackageInfo> getPreferredPackages(int flags) {
1511        try {
1512            return mPM.getPreferredPackages(flags);
1513        } catch (RemoteException e) {
1514            // Should never happen!
1515        }
1516        return new ArrayList<PackageInfo>();
1517    }
1518
1519    @Override
1520    public void addPreferredActivity(IntentFilter filter,
1521                                     int match, ComponentName[] set, ComponentName activity) {
1522        try {
1523            mPM.addPreferredActivity(filter, match, set, activity, mContext.getUserId());
1524        } catch (RemoteException e) {
1525            // Should never happen!
1526        }
1527    }
1528
1529    @Override
1530    public void addPreferredActivity(IntentFilter filter, int match,
1531            ComponentName[] set, ComponentName activity, int userId) {
1532        try {
1533            mPM.addPreferredActivity(filter, match, set, activity, userId);
1534        } catch (RemoteException e) {
1535            // Should never happen!
1536        }
1537    }
1538
1539    @Override
1540    public void replacePreferredActivity(IntentFilter filter,
1541                                         int match, ComponentName[] set, ComponentName activity) {
1542        try {
1543            mPM.replacePreferredActivity(filter, match, set, activity, UserHandle.myUserId());
1544        } catch (RemoteException e) {
1545            // Should never happen!
1546        }
1547    }
1548
1549    @Override
1550    public void replacePreferredActivityAsUser(IntentFilter filter,
1551                                         int match, ComponentName[] set, ComponentName activity,
1552                                         int userId) {
1553        try {
1554            mPM.replacePreferredActivity(filter, match, set, activity, userId);
1555        } catch (RemoteException e) {
1556            // Should never happen!
1557        }
1558    }
1559
1560    @Override
1561    public void clearPackagePreferredActivities(String packageName) {
1562        try {
1563            mPM.clearPackagePreferredActivities(packageName);
1564        } catch (RemoteException e) {
1565            // Should never happen!
1566        }
1567    }
1568
1569    @Override
1570    public int getPreferredActivities(List<IntentFilter> outFilters,
1571                                      List<ComponentName> outActivities, String packageName) {
1572        try {
1573            return mPM.getPreferredActivities(outFilters, outActivities, packageName);
1574        } catch (RemoteException e) {
1575            // Should never happen!
1576        }
1577        return 0;
1578    }
1579
1580    @Override
1581    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
1582        try {
1583            return mPM.getHomeActivities(outActivities);
1584        } catch (RemoteException e) {
1585            // Should never happen!
1586        }
1587        return null;
1588    }
1589
1590    @Override
1591    public void setComponentEnabledSetting(ComponentName componentName,
1592                                           int newState, int flags) {
1593        try {
1594            mPM.setComponentEnabledSetting(componentName, newState, flags, mContext.getUserId());
1595        } catch (RemoteException e) {
1596            // Should never happen!
1597        }
1598    }
1599
1600    @Override
1601    public int getComponentEnabledSetting(ComponentName componentName) {
1602        try {
1603            return mPM.getComponentEnabledSetting(componentName, mContext.getUserId());
1604        } catch (RemoteException e) {
1605            // Should never happen!
1606        }
1607        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1608    }
1609
1610    @Override
1611    public void setApplicationEnabledSetting(String packageName,
1612                                             int newState, int flags) {
1613        try {
1614            mPM.setApplicationEnabledSetting(packageName, newState, flags,
1615                    mContext.getUserId(), mContext.getOpPackageName());
1616        } catch (RemoteException e) {
1617            // Should never happen!
1618        }
1619    }
1620
1621    @Override
1622    public int getApplicationEnabledSetting(String packageName) {
1623        try {
1624            return mPM.getApplicationEnabledSetting(packageName, mContext.getUserId());
1625        } catch (RemoteException e) {
1626            // Should never happen!
1627        }
1628        return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
1629    }
1630
1631    @Override
1632    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
1633            UserHandle user) {
1634        try {
1635            return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
1636                    user.getIdentifier());
1637        } catch (RemoteException re) {
1638            // Should never happen!
1639        }
1640        return false;
1641    }
1642
1643    @Override
1644    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
1645        try {
1646            return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
1647        } catch (RemoteException re) {
1648            // Should never happen!
1649        }
1650        return false;
1651    }
1652
1653    /** @hide */
1654    @Override
1655    public KeySet getKeySetByAlias(String packageName, String alias) {
1656        Preconditions.checkNotNull(packageName);
1657        Preconditions.checkNotNull(alias);
1658        KeySet ks;
1659        try {
1660            ks = mPM.getKeySetByAlias(packageName, alias);
1661        } catch (RemoteException e) {
1662            return null;
1663        }
1664        return ks;
1665    }
1666
1667    /** @hide */
1668    @Override
1669    public KeySet getSigningKeySet(String packageName) {
1670        Preconditions.checkNotNull(packageName);
1671        KeySet ks;
1672        try {
1673            ks = mPM.getSigningKeySet(packageName);
1674        } catch (RemoteException e) {
1675            return null;
1676        }
1677        return ks;
1678    }
1679
1680    /** @hide */
1681    @Override
1682    public boolean isSignedBy(String packageName, KeySet ks) {
1683        Preconditions.checkNotNull(packageName);
1684        Preconditions.checkNotNull(ks);
1685        try {
1686            return mPM.isPackageSignedByKeySet(packageName, ks);
1687        } catch (RemoteException e) {
1688            return false;
1689        }
1690    }
1691
1692    /** @hide */
1693    @Override
1694    public boolean isSignedByExactly(String packageName, KeySet ks) {
1695        Preconditions.checkNotNull(packageName);
1696        Preconditions.checkNotNull(ks);
1697        try {
1698            return mPM.isPackageSignedByKeySetExactly(packageName, ks);
1699        } catch (RemoteException e) {
1700            return false;
1701        }
1702    }
1703
1704    /**
1705     * @hide
1706     */
1707    @Override
1708    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
1709        try {
1710            return mPM.getVerifierDeviceIdentity();
1711        } catch (RemoteException e) {
1712            // Should never happen!
1713        }
1714        return null;
1715    }
1716
1717    /**
1718     * @hide
1719     */
1720    @Override
1721    public boolean isUpgrade() {
1722        try {
1723            return mPM.isUpgrade();
1724        } catch (RemoteException e) {
1725            return false;
1726        }
1727    }
1728
1729    @Override
1730    public PackageInstaller getPackageInstaller() {
1731        synchronized (mLock) {
1732            if (mInstaller == null) {
1733                try {
1734                    mInstaller = new PackageInstaller(mContext, this, mPM.getPackageInstaller(),
1735                            mContext.getPackageName(), mContext.getUserId());
1736                } catch (RemoteException e) {
1737                    throw e.rethrowAsRuntimeException();
1738                }
1739            }
1740            return mInstaller;
1741        }
1742    }
1743
1744    @Override
1745    public boolean isPackageAvailable(String packageName) {
1746        try {
1747            return mPM.isPackageAvailable(packageName, mContext.getUserId());
1748        } catch (RemoteException e) {
1749            throw e.rethrowAsRuntimeException();
1750        }
1751    }
1752
1753    /**
1754     * @hide
1755     */
1756    @Override
1757    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
1758            int flags) {
1759        try {
1760            mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
1761                    sourceUserId, targetUserId, flags);
1762        } catch (RemoteException e) {
1763            // Should never happen!
1764        }
1765    }
1766
1767    /**
1768     * @hide
1769     */
1770    @Override
1771    public void clearCrossProfileIntentFilters(int sourceUserId) {
1772        try {
1773            mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
1774        } catch (RemoteException e) {
1775            // Should never happen!
1776        }
1777    }
1778
1779    /**
1780     * @hide
1781     */
1782    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
1783        Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
1784        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
1785            return dr;
1786        }
1787        return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
1788    }
1789
1790    /**
1791     * @hide
1792     */
1793    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
1794        if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
1795            Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
1796            if (bitmap == null) {
1797                return UserIcons.getDefaultUserIcon(itemInfo.showUserIcon, /* light= */ false);
1798            }
1799            return new BitmapDrawable(bitmap);
1800        }
1801        Drawable dr = null;
1802        if (itemInfo.packageName != null) {
1803            dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
1804        }
1805        if (dr == null) {
1806            dr = itemInfo.loadDefaultIcon(this);
1807        }
1808        return dr;
1809    }
1810
1811    private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
1812            Rect badgeLocation, boolean tryBadgeInPlace) {
1813        final int badgedWidth = drawable.getIntrinsicWidth();
1814        final int badgedHeight = drawable.getIntrinsicHeight();
1815        final boolean canBadgeInPlace = tryBadgeInPlace
1816                && (drawable instanceof BitmapDrawable)
1817                && ((BitmapDrawable) drawable).getBitmap().isMutable();
1818
1819        final Bitmap bitmap;
1820        if (canBadgeInPlace) {
1821            bitmap = ((BitmapDrawable) drawable).getBitmap();
1822        } else {
1823            bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
1824        }
1825        Canvas canvas = new Canvas(bitmap);
1826
1827        if (!canBadgeInPlace) {
1828            drawable.setBounds(0, 0, badgedWidth, badgedHeight);
1829            drawable.draw(canvas);
1830        }
1831
1832        if (badgeLocation != null) {
1833            if (badgeLocation.left < 0 || badgeLocation.top < 0
1834                    || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
1835                throw new IllegalArgumentException("Badge location " + badgeLocation
1836                        + " not in badged drawable bounds "
1837                        + new Rect(0, 0, badgedWidth, badgedHeight));
1838            }
1839            badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
1840
1841            canvas.save();
1842            canvas.translate(badgeLocation.left, badgeLocation.top);
1843            badgeDrawable.draw(canvas);
1844            canvas.restore();
1845        } else {
1846            badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
1847            badgeDrawable.draw(canvas);
1848        }
1849
1850        if (!canBadgeInPlace) {
1851            BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
1852
1853            if (drawable instanceof BitmapDrawable) {
1854                BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
1855                mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
1856            }
1857
1858            return mergedDrawable;
1859        }
1860
1861        return drawable;
1862    }
1863
1864    private int getBadgeResIdForUser(int userHandle) {
1865        // Return the framework-provided badge.
1866        UserInfo userInfo = getUserIfProfile(userHandle);
1867        if (userInfo != null && userInfo.isManagedProfile()) {
1868            return com.android.internal.R.drawable.ic_corp_icon_badge;
1869        }
1870        return 0;
1871    }
1872
1873    private UserInfo getUserIfProfile(int userHandle) {
1874        List<UserInfo> userProfiles = getUserManager().getProfiles(UserHandle.myUserId());
1875        for (UserInfo user : userProfiles) {
1876            if (user.id == userHandle) {
1877                return user;
1878            }
1879        }
1880        return null;
1881    }
1882
1883    private final ContextImpl mContext;
1884    private final IPackageManager mPM;
1885
1886    private static final Object sSync = new Object();
1887    private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
1888            = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
1889    private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
1890            = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
1891}
1892