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