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