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