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