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.UserIdInt;
24 import android.annotation.XmlRes;
25 import android.compat.annotation.UnsupportedAppUsage;
26 import android.content.ComponentName;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.IntentFilter;
31 import android.content.IntentSender;
32 import android.content.pm.ActivityInfo;
33 import android.content.pm.ApplicationInfo;
34 import android.content.pm.ChangedPackages;
35 import android.content.pm.ComponentInfo;
36 import android.content.pm.FeatureInfo;
37 import android.content.pm.IPackageDataObserver;
38 import android.content.pm.IPackageDeleteObserver;
39 import android.content.pm.IPackageManager;
40 import android.content.pm.IPackageMoveObserver;
41 import android.content.pm.IPackageStatsObserver;
42 import android.content.pm.InstallSourceInfo;
43 import android.content.pm.InstantAppInfo;
44 import android.content.pm.InstrumentationInfo;
45 import android.content.pm.IntentFilterVerificationInfo;
46 import android.content.pm.KeySet;
47 import android.content.pm.ModuleInfo;
48 import android.content.pm.PackageInfo;
49 import android.content.pm.PackageInstaller;
50 import android.content.pm.PackageItemInfo;
51 import android.content.pm.PackageManager;
52 import android.content.pm.ParceledListSlice;
53 import android.content.pm.PermissionGroupInfo;
54 import android.content.pm.PermissionInfo;
55 import android.content.pm.ProviderInfo;
56 import android.content.pm.ResolveInfo;
57 import android.content.pm.ServiceInfo;
58 import android.content.pm.SharedLibraryInfo;
59 import android.content.pm.SuspendDialogInfo;
60 import android.content.pm.VerifierDeviceIdentity;
61 import android.content.pm.VersionedPackage;
62 import android.content.pm.dex.ArtManager;
63 import android.content.res.Resources;
64 import android.content.res.XmlResourceParser;
65 import android.graphics.Bitmap;
66 import android.graphics.Canvas;
67 import android.graphics.Rect;
68 import android.graphics.drawable.BitmapDrawable;
69 import android.graphics.drawable.Drawable;
70 import android.graphics.drawable.LayerDrawable;
71 import android.os.Build;
72 import android.os.Bundle;
73 import android.os.Handler;
74 import android.os.Looper;
75 import android.os.Message;
76 import android.os.PersistableBundle;
77 import android.os.Process;
78 import android.os.RemoteException;
79 import android.os.StrictMode;
80 import android.os.SystemProperties;
81 import android.os.UserHandle;
82 import android.os.UserManager;
83 import android.os.storage.StorageManager;
84 import android.os.storage.VolumeInfo;
85 import android.permission.IOnPermissionsChangeListener;
86 import android.permission.IPermissionManager;
87 import android.permission.PermissionManager;
88 import android.provider.Settings;
89 import android.system.ErrnoException;
90 import android.system.Os;
91 import android.system.OsConstants;
92 import android.system.StructStat;
93 import android.text.TextUtils;
94 import android.util.ArrayMap;
95 import android.util.ArraySet;
96 import android.util.DebugUtils;
97 import android.util.LauncherIcons;
98 import android.util.Log;
99 import android.view.Display;
100 
101 import com.android.internal.annotations.GuardedBy;
102 import com.android.internal.annotations.Immutable;
103 import com.android.internal.annotations.VisibleForTesting;
104 import com.android.internal.os.SomeArgs;
105 import com.android.internal.util.UserIcons;
106 
107 import dalvik.system.VMRuntime;
108 
109 import libcore.util.EmptyArray;
110 
111 import java.lang.ref.WeakReference;
112 import java.util.ArrayList;
113 import java.util.Collections;
114 import java.util.Iterator;
115 import java.util.List;
116 import java.util.Map;
117 import java.util.Objects;
118 import java.util.Set;
119 
120 /** @hide */
121 public class ApplicationPackageManager extends PackageManager {
122     private static final String TAG = "ApplicationPackageManager";
123     private static final boolean DEBUG_ICONS = false;
124     /**
125      * Note: Changing this won't do anything on it's own - you should also change the filtering in
126      * {@link #shouldTraceGrant}
127      *
128      * @hide
129      */
130     public static final boolean DEBUG_TRACE_GRANTS = false;
131     public static final boolean DEBUG_TRACE_PERMISSION_UPDATES = false;
132 
133     private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384; // 16KB
134 
135     // Default flags to use with PackageManager when no flags are given.
136     private static final int sDefaultFlags = GET_SHARED_LIBRARY_FILES;
137 
138     // Name of the resource which provides background permission button string
139     public static final String APP_PERMISSION_BUTTON_ALLOW_ALWAYS =
140             "app_permission_button_allow_always";
141 
142     // Name of the package which the permission controller's resources are in.
143     public static final String PERMISSION_CONTROLLER_RESOURCE_PACKAGE =
144             "com.android.permissioncontroller";
145 
146     private final Object mLock = new Object();
147 
148     @GuardedBy("mLock")
149     private UserManager mUserManager;
150     @GuardedBy("mLock")
151     private PackageInstaller mInstaller;
152     @GuardedBy("mLock")
153     private ArtManager mArtManager;
154 
155     @GuardedBy("mDelegates")
156     private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();
157 
158     @GuardedBy("mLock")
159     private String mPermissionsControllerPackageName;
160 
getUserManager()161     UserManager getUserManager() {
162         synchronized (mLock) {
163             if (mUserManager == null) {
164                 mUserManager = UserManager.get(mContext);
165             }
166             return mUserManager;
167         }
168     }
169 
170     @Override
getUserId()171     public int getUserId() {
172         return mContext.getUserId();
173     }
174 
175     @Override
getPackageInfo(String packageName, int flags)176     public PackageInfo getPackageInfo(String packageName, int flags)
177             throws NameNotFoundException {
178         return getPackageInfoAsUser(packageName, flags, getUserId());
179     }
180 
181     @Override
getPackageInfo(VersionedPackage versionedPackage, int flags)182     public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags)
183             throws NameNotFoundException {
184         final int userId = getUserId();
185         try {
186             PackageInfo pi = mPM.getPackageInfoVersioned(versionedPackage,
187                     updateFlagsForPackage(flags, userId), userId);
188             if (pi != null) {
189                 return pi;
190             }
191         } catch (RemoteException e) {
192             throw e.rethrowFromSystemServer();
193         }
194         throw new NameNotFoundException(versionedPackage.toString());
195     }
196 
197     @Override
getPackageInfoAsUser(String packageName, int flags, int userId)198     public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
199             throws NameNotFoundException {
200         PackageInfo pi =
201                 getPackageInfoAsUserCached(
202                         packageName,
203                         updateFlagsForPackage(flags, userId),
204                         userId);
205         if (pi == null) {
206             throw new NameNotFoundException(packageName);
207         }
208         return pi;
209     }
210 
211     @Override
currentToCanonicalPackageNames(String[] names)212     public String[] currentToCanonicalPackageNames(String[] names) {
213         try {
214             return mPM.currentToCanonicalPackageNames(names);
215         } catch (RemoteException e) {
216             throw e.rethrowFromSystemServer();
217         }
218     }
219 
220     @Override
canonicalToCurrentPackageNames(String[] names)221     public String[] canonicalToCurrentPackageNames(String[] names) {
222         try {
223             return mPM.canonicalToCurrentPackageNames(names);
224         } catch (RemoteException e) {
225             throw e.rethrowFromSystemServer();
226         }
227     }
228 
229     @Override
getLaunchIntentForPackage(String packageName)230     public Intent getLaunchIntentForPackage(String packageName) {
231         // First see if the package has an INFO activity; the existence of
232         // such an activity is implied to be the desired front-door for the
233         // overall package (such as if it has multiple launcher entries).
234         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
235         intentToResolve.addCategory(Intent.CATEGORY_INFO);
236         intentToResolve.setPackage(packageName);
237         List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
238 
239         // Otherwise, try to find a main launcher activity.
240         if (ris == null || ris.size() <= 0) {
241             // reuse the intent instance
242             intentToResolve.removeCategory(Intent.CATEGORY_INFO);
243             intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
244             intentToResolve.setPackage(packageName);
245             ris = queryIntentActivities(intentToResolve, 0);
246         }
247         if (ris == null || ris.size() <= 0) {
248             return null;
249         }
250         Intent intent = new Intent(intentToResolve);
251         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
252         intent.setClassName(ris.get(0).activityInfo.packageName,
253                 ris.get(0).activityInfo.name);
254         return intent;
255     }
256 
257     @Override
getLeanbackLaunchIntentForPackage(String packageName)258     public Intent getLeanbackLaunchIntentForPackage(String packageName) {
259         return getLaunchIntentForPackageAndCategory(packageName, Intent.CATEGORY_LEANBACK_LAUNCHER);
260     }
261 
262     @Override
getCarLaunchIntentForPackage(String packageName)263     public Intent getCarLaunchIntentForPackage(String packageName) {
264         return getLaunchIntentForPackageAndCategory(packageName, Intent.CATEGORY_CAR_LAUNCHER);
265     }
266 
getLaunchIntentForPackageAndCategory(String packageName, String category)267     private Intent getLaunchIntentForPackageAndCategory(String packageName, String category) {
268         // Try to find a main launcher activity for the given categories.
269         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
270         intentToResolve.addCategory(category);
271         intentToResolve.setPackage(packageName);
272         List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
273 
274         if (ris == null || ris.size() <= 0) {
275             return null;
276         }
277         Intent intent = new Intent(intentToResolve);
278         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
279         intent.setClassName(ris.get(0).activityInfo.packageName,
280                 ris.get(0).activityInfo.name);
281         return intent;
282     }
283 
284     @Override
getPackageGids(String packageName)285     public int[] getPackageGids(String packageName) throws NameNotFoundException {
286         return getPackageGids(packageName, 0);
287     }
288 
289     @Override
getPackageGids(String packageName, int flags)290     public int[] getPackageGids(String packageName, int flags)
291             throws NameNotFoundException {
292         final int userId = getUserId();
293         try {
294             int[] gids = mPM.getPackageGids(packageName,
295                     updateFlagsForPackage(flags, userId), userId);
296             if (gids != null) {
297                 return gids;
298             }
299         } catch (RemoteException e) {
300             throw e.rethrowFromSystemServer();
301         }
302 
303         throw new NameNotFoundException(packageName);
304     }
305 
306     @Override
getPackageUid(String packageName, int flags)307     public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
308         return getPackageUidAsUser(packageName, flags, getUserId());
309     }
310 
311     @Override
getPackageUidAsUser(String packageName, int userId)312     public int getPackageUidAsUser(String packageName, int userId) throws NameNotFoundException {
313         return getPackageUidAsUser(packageName, 0, userId);
314     }
315 
316     @Override
getPackageUidAsUser(String packageName, int flags, int userId)317     public int getPackageUidAsUser(String packageName, int flags, int userId)
318             throws NameNotFoundException {
319         try {
320             int uid = mPM.getPackageUid(packageName,
321                     updateFlagsForPackage(flags, userId), userId);
322             if (uid >= 0) {
323                 return uid;
324             }
325         } catch (RemoteException e) {
326             throw e.rethrowFromSystemServer();
327         }
328 
329         throw new NameNotFoundException(packageName);
330     }
331 
332     @Override
333     @SuppressWarnings("unchecked")
getAllPermissionGroups(int flags)334     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
335         try {
336             final ParceledListSlice<PermissionGroupInfo> parceledList =
337                     mPermissionManager.getAllPermissionGroups(flags);
338             if (parceledList == null) {
339                 return Collections.emptyList();
340             }
341             return parceledList.getList();
342         } catch (RemoteException e) {
343             throw e.rethrowFromSystemServer();
344         }
345     }
346 
347     @Override
getPermissionGroupInfo(String groupName, int flags)348     public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags)
349             throws NameNotFoundException {
350         try {
351             final PermissionGroupInfo pgi =
352                     mPermissionManager.getPermissionGroupInfo(groupName, flags);
353             if (pgi != null) {
354                 return pgi;
355             }
356         } catch (RemoteException e) {
357             throw e.rethrowFromSystemServer();
358         }
359         throw new NameNotFoundException(groupName);
360     }
361 
362     @Override
getPermissionInfo(String permName, int flags)363     public PermissionInfo getPermissionInfo(String permName, int flags)
364             throws NameNotFoundException {
365         try {
366             final String packageName = mContext.getOpPackageName();
367             final PermissionInfo pi =
368                     mPermissionManager.getPermissionInfo(permName, packageName, flags);
369             if (pi != null) {
370                 return pi;
371             }
372         } catch (RemoteException e) {
373             throw e.rethrowFromSystemServer();
374         }
375         throw new NameNotFoundException(permName);
376     }
377 
378     @Override
379     @SuppressWarnings("unchecked")
queryPermissionsByGroup(String groupName, int flags)380     public List<PermissionInfo> queryPermissionsByGroup(String groupName, int flags)
381             throws NameNotFoundException {
382         try {
383             final ParceledListSlice<PermissionInfo> parceledList =
384                     mPermissionManager.queryPermissionsByGroup(groupName, flags);
385             if (parceledList != null) {
386                 final List<PermissionInfo> pi = parceledList.getList();
387                 if (pi != null) {
388                     return pi;
389                 }
390             }
391         } catch (RemoteException e) {
392             throw e.rethrowFromSystemServer();
393         }
394         throw new NameNotFoundException(groupName);
395     }
396 
397     @Override
arePermissionsIndividuallyControlled()398     public boolean arePermissionsIndividuallyControlled() {
399         return mContext.getResources().getBoolean(
400                 com.android.internal.R.bool.config_permissionsIndividuallyControlled);
401     }
402 
403     @Override
isWirelessConsentModeEnabled()404     public boolean isWirelessConsentModeEnabled() {
405         return mContext.getResources().getBoolean(
406                 com.android.internal.R.bool.config_wirelessConsentRequired);
407     }
408 
409     @Override
getApplicationInfo(String packageName, int flags)410     public ApplicationInfo getApplicationInfo(String packageName, int flags)
411             throws NameNotFoundException {
412         return getApplicationInfoAsUser(packageName, flags, getUserId());
413     }
414 
415     @Override
getApplicationInfoAsUser(String packageName, int flags, int userId)416     public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
417             throws NameNotFoundException {
418         ApplicationInfo ai = getApplicationInfoAsUserCached(
419                         packageName,
420                         updateFlagsForApplication(flags, userId),
421                         userId);
422         if (ai == null) {
423             throw new NameNotFoundException(packageName);
424         }
425         return maybeAdjustApplicationInfo(ai);
426     }
427 
maybeAdjustApplicationInfo(ApplicationInfo info)428     private static ApplicationInfo maybeAdjustApplicationInfo(ApplicationInfo info) {
429         // If we're dealing with a multi-arch application that has both
430         // 32 and 64 bit shared libraries, we might need to choose the secondary
431         // depending on what the current runtime's instruction set is.
432         if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
433             final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
434 
435             // Get the instruction set that the libraries of secondary Abi is supported.
436             // In presence of a native bridge this might be different than the one secondary Abi used.
437             String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
438             final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
439             secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
440 
441             // If the runtimeIsa is the same as the primary isa, then we do nothing.
442             // Everything will be set up correctly because info.nativeLibraryDir will
443             // correspond to the right ISA.
444             if (runtimeIsa.equals(secondaryIsa)) {
445                 ApplicationInfo modified = new ApplicationInfo(info);
446                 modified.nativeLibraryDir = info.secondaryNativeLibraryDir;
447                 return modified;
448             }
449         }
450         return info;
451     }
452 
453     @Override
getActivityInfo(ComponentName className, int flags)454     public ActivityInfo getActivityInfo(ComponentName className, int flags)
455             throws NameNotFoundException {
456         final int userId = getUserId();
457         try {
458             ActivityInfo ai = mPM.getActivityInfo(className,
459                     updateFlagsForComponent(flags, userId, null), userId);
460             if (ai != null) {
461                 return ai;
462             }
463         } catch (RemoteException e) {
464             throw e.rethrowFromSystemServer();
465         }
466 
467         throw new NameNotFoundException(className.toString());
468     }
469 
470     @Override
getReceiverInfo(ComponentName className, int flags)471     public ActivityInfo getReceiverInfo(ComponentName className, int flags)
472             throws NameNotFoundException {
473         final int userId = getUserId();
474         try {
475             ActivityInfo ai = mPM.getReceiverInfo(className,
476                     updateFlagsForComponent(flags, userId, null), userId);
477             if (ai != null) {
478                 return ai;
479             }
480         } catch (RemoteException e) {
481             throw e.rethrowFromSystemServer();
482         }
483 
484         throw new NameNotFoundException(className.toString());
485     }
486 
487     @Override
getServiceInfo(ComponentName className, int flags)488     public ServiceInfo getServiceInfo(ComponentName className, int flags)
489             throws NameNotFoundException {
490         final int userId = getUserId();
491         try {
492             ServiceInfo si = mPM.getServiceInfo(className,
493                     updateFlagsForComponent(flags, userId, null), userId);
494             if (si != null) {
495                 return si;
496             }
497         } catch (RemoteException e) {
498             throw e.rethrowFromSystemServer();
499         }
500 
501         throw new NameNotFoundException(className.toString());
502     }
503 
504     @Override
getProviderInfo(ComponentName className, int flags)505     public ProviderInfo getProviderInfo(ComponentName className, int flags)
506             throws NameNotFoundException {
507         final int userId = getUserId();
508         try {
509             ProviderInfo pi = mPM.getProviderInfo(className,
510                     updateFlagsForComponent(flags, userId, null), userId);
511             if (pi != null) {
512                 return pi;
513             }
514         } catch (RemoteException e) {
515             throw e.rethrowFromSystemServer();
516         }
517 
518         throw new NameNotFoundException(className.toString());
519     }
520 
521     @Override
getSystemSharedLibraryNames()522     public String[] getSystemSharedLibraryNames() {
523         try {
524             return mPM.getSystemSharedLibraryNames();
525         } catch (RemoteException e) {
526             throw e.rethrowFromSystemServer();
527         }
528     }
529 
530     /** @hide */
531     @Override
getSharedLibraries(int flags)532     public @NonNull List<SharedLibraryInfo> getSharedLibraries(int flags) {
533         return getSharedLibrariesAsUser(flags, getUserId());
534     }
535 
536     /** @hide */
537     @Override
538     @SuppressWarnings("unchecked")
getSharedLibrariesAsUser(int flags, int userId)539     public @NonNull List<SharedLibraryInfo> getSharedLibrariesAsUser(int flags, int userId) {
540         try {
541             ParceledListSlice<SharedLibraryInfo> sharedLibs = mPM.getSharedLibraries(
542                     mContext.getOpPackageName(), flags, userId);
543             if (sharedLibs == null) {
544                 return Collections.emptyList();
545             }
546             return sharedLibs.getList();
547         } catch (RemoteException e) {
548             throw e.rethrowFromSystemServer();
549         }
550     }
551 
552     @NonNull
553     @Override
getDeclaredSharedLibraries(@onNull String packageName, @InstallFlags int flags)554     public List<SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String packageName,
555             @InstallFlags int flags) {
556         try {
557             ParceledListSlice<SharedLibraryInfo> sharedLibraries = mPM.getDeclaredSharedLibraries(
558                     packageName, flags, mContext.getUserId());
559             return sharedLibraries != null ? sharedLibraries.getList() : Collections.emptyList();
560         } catch (RemoteException e) {
561             throw e.rethrowFromSystemServer();
562         }
563     }
564 
565     /** @hide */
566     @Override
getServicesSystemSharedLibraryPackageName()567     public @NonNull String getServicesSystemSharedLibraryPackageName() {
568         try {
569             return mPM.getServicesSystemSharedLibraryPackageName();
570         } catch (RemoteException e) {
571             throw e.rethrowFromSystemServer();
572         }
573     }
574 
575     /**
576      * @hide
577      */
getSharedSystemSharedLibraryPackageName()578     public @NonNull String getSharedSystemSharedLibraryPackageName() {
579         try {
580             return mPM.getSharedSystemSharedLibraryPackageName();
581         } catch (RemoteException e) {
582             throw e.rethrowFromSystemServer();
583         }
584     }
585 
586     @Override
getChangedPackages(int sequenceNumber)587     public ChangedPackages getChangedPackages(int sequenceNumber) {
588         try {
589             return mPM.getChangedPackages(sequenceNumber, getUserId());
590         } catch (RemoteException e) {
591             throw e.rethrowFromSystemServer();
592         }
593     }
594 
595     @Override
596     @SuppressWarnings("unchecked")
getSystemAvailableFeatures()597     public FeatureInfo[] getSystemAvailableFeatures() {
598         try {
599             ParceledListSlice<FeatureInfo> parceledList =
600                     mPM.getSystemAvailableFeatures();
601             if (parceledList == null) {
602                 return new FeatureInfo[0];
603             }
604             final List<FeatureInfo> list = parceledList.getList();
605             final FeatureInfo[] res = new FeatureInfo[list.size()];
606             for (int i = 0; i < res.length; i++) {
607                 res[i] = list.get(i);
608             }
609             return res;
610         } catch (RemoteException e) {
611             throw e.rethrowFromSystemServer();
612         }
613     }
614 
615     @Override
hasSystemFeature(String name)616     public boolean hasSystemFeature(String name) {
617         return hasSystemFeature(name, 0);
618     }
619 
620     /**
621      * Identifies a single hasSystemFeature query.
622      */
623     @Immutable
624     private static final class HasSystemFeatureQuery {
625         public final String name;
626         public final int version;
HasSystemFeatureQuery(String n, int v)627         public HasSystemFeatureQuery(String n, int v) {
628             name = n;
629             version = v;
630         }
631         @Override
toString()632         public String toString() {
633             return String.format("HasSystemFeatureQuery(name=\"%s\", version=%d)",
634                     name, version);
635         }
636         @Override
equals(Object o)637         public boolean equals(Object o) {
638             if (o instanceof HasSystemFeatureQuery) {
639                 HasSystemFeatureQuery r = (HasSystemFeatureQuery) o;
640                 return Objects.equals(name, r.name) &&  version == r.version;
641             } else {
642                 return false;
643             }
644         }
645         @Override
hashCode()646         public int hashCode() {
647             return Objects.hashCode(name) * 13 + version;
648         }
649     }
650 
651     // Make this cache relatively large.  There are many system features and
652     // none are ever invalidated.  MPTS tests suggests that the cache should
653     // hold at least 150 entries.
654     private final static PropertyInvalidatedCache<HasSystemFeatureQuery, Boolean>
655             mHasSystemFeatureCache =
656             new PropertyInvalidatedCache<HasSystemFeatureQuery, Boolean>(
657                 256, "cache_key.has_system_feature") {
658                 @Override
659                 protected Boolean recompute(HasSystemFeatureQuery query) {
660                     try {
661                         return ActivityThread.currentActivityThread().getPackageManager().
662                             hasSystemFeature(query.name, query.version);
663                     } catch (RemoteException e) {
664                         throw e.rethrowFromSystemServer();
665                     }
666                 }
667             };
668 
669     @Override
hasSystemFeature(String name, int version)670     public boolean hasSystemFeature(String name, int version) {
671         return mHasSystemFeatureCache.query(new HasSystemFeatureQuery(name, version));
672     }
673 
674     /** @hide */
disableHasSystemFeatureCache()675     public void disableHasSystemFeatureCache() {
676         mHasSystemFeatureCache.disableLocal();
677     }
678 
679     /** @hide */
invalidateHasSystemFeatureCache()680     public static void invalidateHasSystemFeatureCache() {
681         mHasSystemFeatureCache.invalidateCache();
682     }
683 
684     @Override
checkPermission(String permName, String pkgName)685     public int checkPermission(String permName, String pkgName) {
686         return PermissionManager
687                 .checkPackageNamePermission(permName, pkgName, getUserId());
688     }
689 
690     @Override
isPermissionRevokedByPolicy(String permName, String pkgName)691     public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
692         try {
693             return mPermissionManager.isPermissionRevokedByPolicy(permName, pkgName, getUserId());
694         } catch (RemoteException e) {
695             throw e.rethrowFromSystemServer();
696         }
697     }
698 
699     /**
700      * @hide
701      */
702     @Override
getPermissionControllerPackageName()703     public String getPermissionControllerPackageName() {
704         synchronized (mLock) {
705             if (mPermissionsControllerPackageName == null) {
706                 try {
707                     mPermissionsControllerPackageName = mPM.getPermissionControllerPackageName();
708                 } catch (RemoteException e) {
709                     throw e.rethrowFromSystemServer();
710                 }
711             }
712             return mPermissionsControllerPackageName;
713         }
714     }
715 
716     @Override
addPermission(PermissionInfo info)717     public boolean addPermission(PermissionInfo info) {
718         try {
719             return mPermissionManager.addPermission(info, false);
720         } catch (RemoteException e) {
721             throw e.rethrowFromSystemServer();
722         }
723     }
724 
725     @Override
addPermissionAsync(PermissionInfo info)726     public boolean addPermissionAsync(PermissionInfo info) {
727         try {
728             return mPermissionManager.addPermission(info, true);
729         } catch (RemoteException e) {
730             throw e.rethrowFromSystemServer();
731         }
732     }
733 
734     @Override
removePermission(String name)735     public void removePermission(String name) {
736         try {
737             mPermissionManager.removePermission(name);
738         } catch (RemoteException e) {
739             throw e.rethrowFromSystemServer();
740         }
741     }
742 
743     @Override
grantRuntimePermission(String packageName, String permissionName, UserHandle user)744     public void grantRuntimePermission(String packageName, String permissionName,
745             UserHandle user) {
746         if (DEBUG_TRACE_GRANTS
747                 && shouldTraceGrant(packageName, permissionName, user.getIdentifier())) {
748             Log.i(TAG, "App " + mContext.getPackageName() + " is granting " + packageName + " "
749                     + permissionName + " for user " + user.getIdentifier(), new RuntimeException());
750         }
751         try {
752             mPM.grantRuntimePermission(packageName, permissionName, user.getIdentifier());
753         } catch (RemoteException e) {
754             throw e.rethrowFromSystemServer();
755         }
756     }
757 
758     /** @hide */
shouldTraceGrant(String packageName, String permissionName, int userId)759     public static boolean shouldTraceGrant(String packageName, String permissionName, int userId) {
760         // To be modified when debugging
761         return false;
762     }
763 
764     @Override
revokeRuntimePermission(String packageName, String permName, UserHandle user)765     public void revokeRuntimePermission(String packageName, String permName, UserHandle user) {
766         revokeRuntimePermission(packageName, permName, user, null);
767     }
768 
769     @Override
revokeRuntimePermission(String packageName, String permName, UserHandle user, String reason)770     public void revokeRuntimePermission(String packageName, String permName, UserHandle user,
771             String reason) {
772         if (DEBUG_TRACE_PERMISSION_UPDATES
773                 && shouldTraceGrant(packageName, permName, user.getIdentifier())) {
774             Log.i(TAG, "App " + mContext.getPackageName() + " is revoking " + packageName + " "
775                     + permName + " for user " + user.getIdentifier() + " with reason " + reason,
776                     new RuntimeException());
777         }
778         try {
779             mPermissionManager
780                     .revokeRuntimePermission(packageName, permName, user.getIdentifier(), reason);
781         } catch (RemoteException e) {
782             throw e.rethrowFromSystemServer();
783         }
784     }
785 
786     @Override
getPermissionFlags(String permName, String packageName, UserHandle user)787     public int getPermissionFlags(String permName, String packageName, UserHandle user) {
788         try {
789             return mPermissionManager
790                     .getPermissionFlags(permName, packageName, user.getIdentifier());
791         } catch (RemoteException e) {
792             throw e.rethrowFromSystemServer();
793         }
794     }
795 
796     @Override
updatePermissionFlags(String permName, String packageName, int flagMask, int flagValues, UserHandle user)797     public void updatePermissionFlags(String permName, String packageName,
798             int flagMask, int flagValues, UserHandle user) {
799         if (DEBUG_TRACE_PERMISSION_UPDATES
800                 && shouldTraceGrant(packageName, permName, user.getIdentifier())) {
801             Log.i(TAG, "App " + mContext.getPackageName() + " is updating flags for "
802                     + packageName + " "
803                     + permName + " for user " + user.getIdentifier() + ": "
804                     + DebugUtils.flagsToString(PackageManager.class, "FLAG_PERMISSION_", flagMask)
805                     + " := " + DebugUtils.flagsToString(
806                             PackageManager.class, "FLAG_PERMISSION_", flagValues),
807                     new RuntimeException());
808         }
809         try {
810             final boolean checkAdjustPolicyFlagPermission =
811                     mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q;
812             mPermissionManager.updatePermissionFlags(permName, packageName, flagMask,
813                     flagValues, checkAdjustPolicyFlagPermission, user.getIdentifier());
814         } catch (RemoteException e) {
815             throw e.rethrowFromSystemServer();
816         }
817     }
818 
819     @Override
getWhitelistedRestrictedPermissions( @onNull String packageName, @PermissionWhitelistFlags int flags)820     public @NonNull Set<String> getWhitelistedRestrictedPermissions(
821             @NonNull String packageName, @PermissionWhitelistFlags int flags) {
822         try {
823             final int userId = getUserId();
824             final List<String> whitelist = mPermissionManager
825                     .getWhitelistedRestrictedPermissions(packageName, flags, userId);
826             if (whitelist != null) {
827                 return new ArraySet<>(whitelist);
828             }
829             return Collections.emptySet();
830         } catch (RemoteException e) {
831             throw e.rethrowFromSystemServer();
832         }
833     }
834 
835     @Override
addWhitelistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PermissionWhitelistFlags int flags)836     public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
837             @NonNull String permName, @PermissionWhitelistFlags int flags) {
838         try {
839             final int userId = getUserId();
840             return mPermissionManager
841                     .addWhitelistedRestrictedPermission(packageName, permName, flags, userId);
842         } catch (RemoteException e) {
843             throw e.rethrowFromSystemServer();
844         }
845     }
846 
847     @Override
setAutoRevokeWhitelisted( @onNull String packageName, boolean whitelisted)848     public boolean setAutoRevokeWhitelisted(
849             @NonNull String packageName, boolean whitelisted) {
850         try {
851             final int userId = getUserId();
852             return mPermissionManager.setAutoRevokeWhitelisted(packageName, whitelisted, userId);
853         } catch (RemoteException e) {
854             throw e.rethrowFromSystemServer();
855         }
856     }
857 
858     @Override
isAutoRevokeWhitelisted(@onNull String packageName)859     public boolean isAutoRevokeWhitelisted(@NonNull String packageName) {
860         try {
861             final int userId = getUserId();
862             return mPermissionManager.isAutoRevokeWhitelisted(packageName, userId);
863         } catch (RemoteException e) {
864             throw e.rethrowFromSystemServer();
865         }
866     }
867 
868     @Override
removeWhitelistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PermissionWhitelistFlags int flags)869     public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
870             @NonNull String permName, @PermissionWhitelistFlags int flags) {
871         try {
872             final int userId = getUserId();
873             return mPermissionManager
874                     .removeWhitelistedRestrictedPermission(packageName, permName, flags, userId);
875         } catch (RemoteException e) {
876             throw e.rethrowFromSystemServer();
877         }
878     }
879 
880     @Override
881     @UnsupportedAppUsage
shouldShowRequestPermissionRationale(String permName)882     public boolean shouldShowRequestPermissionRationale(String permName) {
883         try {
884             final String packageName = mContext.getPackageName();
885             return mPermissionManager
886                     .shouldShowRequestPermissionRationale(permName, packageName, getUserId());
887         } catch (RemoteException e) {
888             throw e.rethrowFromSystemServer();
889         }
890     }
891 
892     @Override
getBackgroundPermissionOptionLabel()893     public CharSequence getBackgroundPermissionOptionLabel() {
894         try {
895 
896             String permissionController = getPermissionControllerPackageName();
897             Context context =
898                     mContext.createPackageContext(permissionController, 0);
899 
900             int textId = context.getResources().getIdentifier(APP_PERMISSION_BUTTON_ALLOW_ALWAYS,
901                     "string", PERMISSION_CONTROLLER_RESOURCE_PACKAGE);
902             if (textId != 0) {
903                 return context.getText(textId);
904             }
905         } catch (NameNotFoundException e) {
906             Log.e(TAG, "Permission controller not found.", e);
907         }
908         return "";
909     }
910 
911     @Override
checkSignatures(String pkg1, String pkg2)912     public int checkSignatures(String pkg1, String pkg2) {
913         try {
914             return mPM.checkSignatures(pkg1, pkg2);
915         } catch (RemoteException e) {
916             throw e.rethrowFromSystemServer();
917         }
918     }
919 
920     @Override
checkSignatures(int uid1, int uid2)921     public int checkSignatures(int uid1, int uid2) {
922         try {
923             return mPM.checkUidSignatures(uid1, uid2);
924         } catch (RemoteException e) {
925             throw e.rethrowFromSystemServer();
926         }
927     }
928 
929     @Override
hasSigningCertificate( String packageName, byte[] certificate, @CertificateInputType int type)930     public boolean hasSigningCertificate(
931             String packageName, byte[] certificate, @CertificateInputType int type) {
932         try {
933             return mPM.hasSigningCertificate(packageName, certificate, type);
934         } catch (RemoteException e) {
935             throw e.rethrowFromSystemServer();
936         }
937     }
938 
939     @Override
hasSigningCertificate( int uid, byte[] certificate, @CertificateInputType int type)940     public boolean hasSigningCertificate(
941             int uid, byte[] certificate, @CertificateInputType int type) {
942         try {
943             return mPM.hasUidSigningCertificate(uid, certificate, type);
944         } catch (RemoteException e) {
945             throw e.rethrowFromSystemServer();
946         }
947     }
948 
949     @Override
getPackagesForUid(int uid)950     public String[] getPackagesForUid(int uid) {
951         try {
952             return mPM.getPackagesForUid(uid);
953         } catch (RemoteException e) {
954             throw e.rethrowFromSystemServer();
955         }
956     }
957 
958     @Override
getNameForUid(int uid)959     public String getNameForUid(int uid) {
960         try {
961             return mPM.getNameForUid(uid);
962         } catch (RemoteException e) {
963             throw e.rethrowFromSystemServer();
964         }
965     }
966 
967     @Override
getNamesForUids(int[] uids)968     public String[] getNamesForUids(int[] uids) {
969         try {
970             return mPM.getNamesForUids(uids);
971         } catch (RemoteException e) {
972             throw e.rethrowFromSystemServer();
973         }
974     }
975 
976     @Override
getUidForSharedUser(String sharedUserName)977     public int getUidForSharedUser(String sharedUserName)
978             throws NameNotFoundException {
979         try {
980             int uid = mPM.getUidForSharedUser(sharedUserName);
981             if(uid != -1) {
982                 return uid;
983             }
984         } catch (RemoteException e) {
985             throw e.rethrowFromSystemServer();
986         }
987         throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
988     }
989 
990     @Override
getInstalledModules(int flags)991     public List<ModuleInfo> getInstalledModules(int flags) {
992         try {
993             return mPM.getInstalledModules(flags);
994         } catch (RemoteException e) {
995             throw e.rethrowFromSystemServer();
996         }
997     }
998 
999     @Override
getModuleInfo(String packageName, int flags)1000     public ModuleInfo getModuleInfo(String packageName, int flags) throws NameNotFoundException {
1001         try {
1002             ModuleInfo mi = mPM.getModuleInfo(packageName, flags);
1003             if (mi != null) {
1004                 return mi;
1005             }
1006         } catch (RemoteException e) {
1007             throw e.rethrowFromSystemServer();
1008         }
1009 
1010         throw new NameNotFoundException("No module info for package: " + packageName);
1011     }
1012 
1013     @SuppressWarnings("unchecked")
1014     @Override
getInstalledPackages(int flags)1015     public List<PackageInfo> getInstalledPackages(int flags) {
1016         return getInstalledPackagesAsUser(flags, getUserId());
1017     }
1018 
1019     /** @hide */
1020     @Override
1021     @SuppressWarnings("unchecked")
getInstalledPackagesAsUser(int flags, int userId)1022     public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
1023         try {
1024             ParceledListSlice<PackageInfo> parceledList =
1025                     mPM.getInstalledPackages(updateFlagsForPackage(flags, userId), userId);
1026             if (parceledList == null) {
1027                 return Collections.emptyList();
1028             }
1029             return parceledList.getList();
1030         } catch (RemoteException e) {
1031             throw e.rethrowFromSystemServer();
1032         }
1033     }
1034 
1035     @SuppressWarnings("unchecked")
1036     @Override
getPackagesHoldingPermissions( String[] permissions, int flags)1037     public List<PackageInfo> getPackagesHoldingPermissions(
1038             String[] permissions, int flags) {
1039         final int userId = getUserId();
1040         try {
1041             ParceledListSlice<PackageInfo> parceledList =
1042                     mPM.getPackagesHoldingPermissions(permissions,
1043                             updateFlagsForPackage(flags, userId), userId);
1044             if (parceledList == null) {
1045                 return Collections.emptyList();
1046             }
1047             return parceledList.getList();
1048         } catch (RemoteException e) {
1049             throw e.rethrowFromSystemServer();
1050         }
1051     }
1052 
1053     @SuppressWarnings("unchecked")
1054     @Override
getInstalledApplications(int flags)1055     public List<ApplicationInfo> getInstalledApplications(int flags) {
1056         return getInstalledApplicationsAsUser(flags, getUserId());
1057     }
1058 
1059     /** @hide */
1060     @SuppressWarnings("unchecked")
1061     @Override
getInstalledApplicationsAsUser(int flags, int userId)1062     public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
1063         try {
1064             ParceledListSlice<ApplicationInfo> parceledList =
1065                     mPM.getInstalledApplications(updateFlagsForApplication(flags, userId), userId);
1066             if (parceledList == null) {
1067                 return Collections.emptyList();
1068             }
1069             return parceledList.getList();
1070         } catch (RemoteException e) {
1071             throw e.rethrowFromSystemServer();
1072         }
1073     }
1074 
1075     /** @hide */
1076     @SuppressWarnings("unchecked")
1077     @Override
getInstantApps()1078     public List<InstantAppInfo> getInstantApps() {
1079         try {
1080             ParceledListSlice<InstantAppInfo> slice = mPM.getInstantApps(getUserId());
1081             if (slice != null) {
1082                 return slice.getList();
1083             }
1084             return Collections.emptyList();
1085         } catch (RemoteException e) {
1086             throw e.rethrowFromSystemServer();
1087         }
1088     }
1089 
1090     /** @hide */
1091     @Override
getInstantAppIcon(String packageName)1092     public Drawable getInstantAppIcon(String packageName) {
1093         try {
1094             Bitmap bitmap = mPM.getInstantAppIcon(packageName, getUserId());
1095             if (bitmap != null) {
1096                 return new BitmapDrawable(null, bitmap);
1097             }
1098             return null;
1099         } catch (RemoteException e) {
1100             throw e.rethrowFromSystemServer();
1101         }
1102     }
1103 
1104     @Override
isInstantApp()1105     public boolean isInstantApp() {
1106         return isInstantApp(mContext.getPackageName());
1107     }
1108 
1109     @Override
isInstantApp(String packageName)1110     public boolean isInstantApp(String packageName) {
1111         try {
1112             return mPM.isInstantApp(packageName, getUserId());
1113         } catch (RemoteException e) {
1114             throw e.rethrowFromSystemServer();
1115         }
1116     }
1117 
getInstantAppCookieMaxBytes()1118     public int getInstantAppCookieMaxBytes() {
1119         return Settings.Global.getInt(mContext.getContentResolver(),
1120                 Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
1121                 DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES);
1122     }
1123 
1124     @Override
getInstantAppCookieMaxSize()1125     public int getInstantAppCookieMaxSize() {
1126         return getInstantAppCookieMaxBytes();
1127     }
1128 
1129     @Override
getInstantAppCookie()1130     public @NonNull byte[] getInstantAppCookie() {
1131         try {
1132             final byte[] cookie = mPM.getInstantAppCookie(mContext.getPackageName(), getUserId());
1133             if (cookie != null) {
1134                 return cookie;
1135             } else {
1136                 return EmptyArray.BYTE;
1137             }
1138         } catch (RemoteException e) {
1139             throw e.rethrowFromSystemServer();
1140         }
1141     }
1142 
1143     @Override
clearInstantAppCookie()1144     public void clearInstantAppCookie() {
1145         updateInstantAppCookie(null);
1146     }
1147 
1148     @Override
updateInstantAppCookie(@onNull byte[] cookie)1149     public void updateInstantAppCookie(@NonNull byte[] cookie) {
1150         if (cookie != null && cookie.length > getInstantAppCookieMaxBytes()) {
1151             throw new IllegalArgumentException("instant cookie longer than "
1152                     + getInstantAppCookieMaxBytes());
1153         }
1154         try {
1155             mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId());
1156         } catch (RemoteException e) {
1157             throw e.rethrowFromSystemServer();
1158         }
1159     }
1160 
1161     @UnsupportedAppUsage
1162     @Override
setInstantAppCookie(@onNull byte[] cookie)1163     public boolean setInstantAppCookie(@NonNull byte[] cookie) {
1164         try {
1165             return mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId());
1166         } catch (RemoteException e) {
1167             throw e.rethrowFromSystemServer();
1168         }
1169     }
1170 
1171     @Override
resolveActivity(Intent intent, int flags)1172     public ResolveInfo resolveActivity(Intent intent, int flags) {
1173         return resolveActivityAsUser(intent, flags, getUserId());
1174     }
1175 
1176     @Override
resolveActivityAsUser(Intent intent, int flags, int userId)1177     public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
1178         try {
1179             return mPM.resolveIntent(
1180                 intent,
1181                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1182                 updateFlagsForComponent(flags, userId, intent),
1183                 userId);
1184         } catch (RemoteException e) {
1185             throw e.rethrowFromSystemServer();
1186         }
1187     }
1188 
1189     @Override
queryIntentActivities(Intent intent, int flags)1190     public List<ResolveInfo> queryIntentActivities(Intent intent,
1191                                                    int flags) {
1192         return queryIntentActivitiesAsUser(intent, flags, getUserId());
1193     }
1194 
1195     /** @hide Same as above but for a specific user */
1196     @Override
1197     @SuppressWarnings("unchecked")
queryIntentActivitiesAsUser(Intent intent, int flags, int userId)1198     public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
1199             int flags, int userId) {
1200         try {
1201             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivities(
1202                     intent,
1203                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1204                     updateFlagsForComponent(flags, userId, intent),
1205                     userId);
1206             if (parceledList == null) {
1207                 return Collections.emptyList();
1208             }
1209             return parceledList.getList();
1210         } catch (RemoteException e) {
1211             throw e.rethrowFromSystemServer();
1212         }
1213     }
1214 
1215     @Override
1216     @SuppressWarnings("unchecked")
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, Intent intent, int flags)1217     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics,
1218             Intent intent, int flags) {
1219         final int userId = getUserId();
1220         final ContentResolver resolver = mContext.getContentResolver();
1221 
1222         String[] specificTypes = null;
1223         if (specifics != null) {
1224             final int N = specifics.length;
1225             for (int i=0; i<N; i++) {
1226                 Intent sp = specifics[i];
1227                 if (sp != null) {
1228                     String t = sp.resolveTypeIfNeeded(resolver);
1229                     if (t != null) {
1230                         if (specificTypes == null) {
1231                             specificTypes = new String[N];
1232                         }
1233                         specificTypes[i] = t;
1234                     }
1235                 }
1236             }
1237         }
1238 
1239         try {
1240             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivityOptions(
1241                     caller,
1242                     specifics,
1243                     specificTypes,
1244                     intent,
1245                     intent.resolveTypeIfNeeded(resolver),
1246                     updateFlagsForComponent(flags, userId, intent),
1247                     userId);
1248             if (parceledList == null) {
1249                 return Collections.emptyList();
1250             }
1251             return parceledList.getList();
1252         } catch (RemoteException e) {
1253             throw e.rethrowFromSystemServer();
1254         }
1255     }
1256 
1257     /**
1258      * @hide
1259      */
1260     @Override
1261     @SuppressWarnings("unchecked")
queryBroadcastReceiversAsUser(Intent intent, int flags, int userId)1262     public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
1263         try {
1264             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentReceivers(
1265                     intent,
1266                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1267                     updateFlagsForComponent(flags, userId, intent),
1268                     userId);
1269             if (parceledList == null) {
1270                 return Collections.emptyList();
1271             }
1272             return parceledList.getList();
1273         } catch (RemoteException e) {
1274             throw e.rethrowFromSystemServer();
1275         }
1276     }
1277 
1278     @Override
queryBroadcastReceivers(Intent intent, int flags)1279     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
1280         return queryBroadcastReceiversAsUser(intent, flags, getUserId());
1281     }
1282 
1283     @Override
resolveServiceAsUser(Intent intent, @ResolveInfoFlags int flags, @UserIdInt int userId)1284     public ResolveInfo resolveServiceAsUser(Intent intent, @ResolveInfoFlags int flags,
1285             @UserIdInt int userId) {
1286         try {
1287             return mPM.resolveService(
1288                 intent,
1289                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1290                 updateFlagsForComponent(flags, userId, intent),
1291                 userId);
1292         } catch (RemoteException e) {
1293             throw e.rethrowFromSystemServer();
1294         }
1295     }
1296 
1297     @Override
resolveService(Intent intent, int flags)1298     public ResolveInfo resolveService(Intent intent, int flags) {
1299         return resolveServiceAsUser(intent, flags, getUserId());
1300     }
1301 
1302     @Override
1303     @SuppressWarnings("unchecked")
queryIntentServicesAsUser(Intent intent, int flags, int userId)1304     public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
1305         try {
1306             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentServices(
1307                     intent,
1308                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1309                     updateFlagsForComponent(flags, userId, intent),
1310                     userId);
1311             if (parceledList == null) {
1312                 return Collections.emptyList();
1313             }
1314             return parceledList.getList();
1315         } catch (RemoteException e) {
1316             throw e.rethrowFromSystemServer();
1317         }
1318     }
1319 
1320     @Override
queryIntentServices(Intent intent, int flags)1321     public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
1322         return queryIntentServicesAsUser(intent, flags, getUserId());
1323     }
1324 
1325     @Override
1326     @SuppressWarnings("unchecked")
queryIntentContentProvidersAsUser( Intent intent, int flags, int userId)1327     public List<ResolveInfo> queryIntentContentProvidersAsUser(
1328             Intent intent, int flags, int userId) {
1329         try {
1330             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentContentProviders(
1331                     intent,
1332                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1333                     updateFlagsForComponent(flags, userId, intent),
1334                     userId);
1335             if (parceledList == null) {
1336                 return Collections.emptyList();
1337             }
1338             return parceledList.getList();
1339         } catch (RemoteException e) {
1340             throw e.rethrowFromSystemServer();
1341         }
1342     }
1343 
1344     @Override
queryIntentContentProviders(Intent intent, int flags)1345     public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
1346         return queryIntentContentProvidersAsUser(intent, flags, getUserId());
1347     }
1348 
1349     @Override
resolveContentProvider(String name, int flags)1350     public ProviderInfo resolveContentProvider(String name, int flags) {
1351         return resolveContentProviderAsUser(name, flags, getUserId());
1352     }
1353 
1354     /** @hide **/
1355     @Override
resolveContentProviderAsUser(String name, int flags, int userId)1356     public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
1357         try {
1358             return mPM.resolveContentProvider(name,
1359                     updateFlagsForComponent(flags, userId, null), userId);
1360         } catch (RemoteException e) {
1361             throw e.rethrowFromSystemServer();
1362         }
1363     }
1364 
1365     @Override
queryContentProviders(String processName, int uid, int flags)1366     public List<ProviderInfo> queryContentProviders(String processName,
1367             int uid, int flags) {
1368         return queryContentProviders(processName, uid, flags, null);
1369     }
1370 
1371     @Override
1372     @SuppressWarnings("unchecked")
queryContentProviders(String processName, int uid, int flags, String metaDataKey)1373     public List<ProviderInfo> queryContentProviders(String processName,
1374             int uid, int flags, String metaDataKey) {
1375         try {
1376             ParceledListSlice<ProviderInfo> slice = mPM.queryContentProviders(processName, uid,
1377                     updateFlagsForComponent(flags, UserHandle.getUserId(uid), null), metaDataKey);
1378             return slice != null ? slice.getList() : Collections.<ProviderInfo>emptyList();
1379         } catch (RemoteException e) {
1380             throw e.rethrowFromSystemServer();
1381         }
1382     }
1383 
1384     @Override
getInstrumentationInfo( ComponentName className, int flags)1385     public InstrumentationInfo getInstrumentationInfo(
1386         ComponentName className, int flags)
1387             throws NameNotFoundException {
1388         try {
1389             InstrumentationInfo ii = mPM.getInstrumentationInfo(
1390                 className, flags);
1391             if (ii != null) {
1392                 return ii;
1393             }
1394         } catch (RemoteException e) {
1395             throw e.rethrowFromSystemServer();
1396         }
1397 
1398         throw new NameNotFoundException(className.toString());
1399     }
1400 
1401     @Override
1402     @SuppressWarnings("unchecked")
queryInstrumentation( String targetPackage, int flags)1403     public List<InstrumentationInfo> queryInstrumentation(
1404         String targetPackage, int flags) {
1405         try {
1406             ParceledListSlice<InstrumentationInfo> parceledList =
1407                     mPM.queryInstrumentation(targetPackage, flags);
1408             if (parceledList == null) {
1409                 return Collections.emptyList();
1410             }
1411             return parceledList.getList();
1412         } catch (RemoteException e) {
1413             throw e.rethrowFromSystemServer();
1414         }
1415     }
1416 
1417     @Nullable
1418     @Override
getDrawable(String packageName, @DrawableRes int resId, @Nullable ApplicationInfo appInfo)1419     public Drawable getDrawable(String packageName, @DrawableRes int resId,
1420             @Nullable ApplicationInfo appInfo) {
1421         final ResourceName name = new ResourceName(packageName, resId);
1422         final Drawable cachedIcon = getCachedIcon(name);
1423         if (cachedIcon != null) {
1424             return cachedIcon;
1425         }
1426 
1427         if (appInfo == null) {
1428             try {
1429                 appInfo = getApplicationInfo(packageName, sDefaultFlags);
1430             } catch (NameNotFoundException e) {
1431                 return null;
1432             }
1433         }
1434 
1435         if (resId != 0) {
1436             try {
1437                 final Resources r = getResourcesForApplication(appInfo);
1438                 final Drawable dr = r.getDrawable(resId, null);
1439                 if (dr != null) {
1440                     putCachedIcon(name, dr);
1441                 }
1442 
1443                 if (false) {
1444                     RuntimeException e = new RuntimeException("here");
1445                     e.fillInStackTrace();
1446                     Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resId)
1447                                     + " from package " + packageName
1448                                     + ": app scale=" + r.getCompatibilityInfo().applicationScale
1449                                     + ", caller scale=" + mContext.getResources()
1450                                     .getCompatibilityInfo().applicationScale,
1451                             e);
1452                 }
1453                 if (DEBUG_ICONS) {
1454                     Log.v(TAG, "Getting drawable 0x"
1455                             + Integer.toHexString(resId) + " from " + r
1456                             + ": " + dr);
1457                 }
1458                 return dr;
1459             } catch (NameNotFoundException e) {
1460                 Log.w("PackageManager", "Failure retrieving resources for "
1461                         + appInfo.packageName);
1462             } catch (Resources.NotFoundException e) {
1463                 Log.w("PackageManager", "Failure retrieving resources for "
1464                         + appInfo.packageName + ": " + e.getMessage());
1465             } catch (Exception e) {
1466                 // If an exception was thrown, fall through to return
1467                 // default icon.
1468                 Log.w("PackageManager", "Failure retrieving icon 0x"
1469                         + Integer.toHexString(resId) + " in package "
1470                         + packageName, e);
1471             }
1472         }
1473 
1474         return null;
1475     }
1476 
getActivityIcon(ComponentName activityName)1477     @Override public Drawable getActivityIcon(ComponentName activityName)
1478             throws NameNotFoundException {
1479         return getActivityInfo(activityName, sDefaultFlags).loadIcon(this);
1480     }
1481 
getActivityIcon(Intent intent)1482     @Override public Drawable getActivityIcon(Intent intent)
1483             throws NameNotFoundException {
1484         if (intent.getComponent() != null) {
1485             return getActivityIcon(intent.getComponent());
1486         }
1487 
1488         ResolveInfo info = resolveActivity(intent, MATCH_DEFAULT_ONLY);
1489         if (info != null) {
1490             return info.activityInfo.loadIcon(this);
1491         }
1492 
1493         throw new NameNotFoundException(intent.toUri(0));
1494     }
1495 
getDefaultActivityIcon()1496     @Override public Drawable getDefaultActivityIcon() {
1497         return mContext.getDrawable(com.android.internal.R.drawable.sym_def_app_icon);
1498     }
1499 
getApplicationIcon(ApplicationInfo info)1500     @Override public Drawable getApplicationIcon(ApplicationInfo info) {
1501         return info.loadIcon(this);
1502     }
1503 
getApplicationIcon(String packageName)1504     @Override public Drawable getApplicationIcon(String packageName)
1505             throws NameNotFoundException {
1506         return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags));
1507     }
1508 
1509     @Override
getActivityBanner(ComponentName activityName)1510     public Drawable getActivityBanner(ComponentName activityName)
1511             throws NameNotFoundException {
1512         return getActivityInfo(activityName, sDefaultFlags).loadBanner(this);
1513     }
1514 
1515     @Override
getActivityBanner(Intent intent)1516     public Drawable getActivityBanner(Intent intent)
1517             throws NameNotFoundException {
1518         if (intent.getComponent() != null) {
1519             return getActivityBanner(intent.getComponent());
1520         }
1521 
1522         ResolveInfo info = resolveActivity(
1523                 intent, MATCH_DEFAULT_ONLY);
1524         if (info != null) {
1525             return info.activityInfo.loadBanner(this);
1526         }
1527 
1528         throw new NameNotFoundException(intent.toUri(0));
1529     }
1530 
1531     @Override
getApplicationBanner(ApplicationInfo info)1532     public Drawable getApplicationBanner(ApplicationInfo info) {
1533         return info.loadBanner(this);
1534     }
1535 
1536     @Override
getApplicationBanner(String packageName)1537     public Drawable getApplicationBanner(String packageName)
1538             throws NameNotFoundException {
1539         return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags));
1540     }
1541 
1542     @Override
getActivityLogo(ComponentName activityName)1543     public Drawable getActivityLogo(ComponentName activityName)
1544             throws NameNotFoundException {
1545         return getActivityInfo(activityName, sDefaultFlags).loadLogo(this);
1546     }
1547 
1548     @Override
getActivityLogo(Intent intent)1549     public Drawable getActivityLogo(Intent intent)
1550             throws NameNotFoundException {
1551         if (intent.getComponent() != null) {
1552             return getActivityLogo(intent.getComponent());
1553         }
1554 
1555         ResolveInfo info = resolveActivity(intent, MATCH_DEFAULT_ONLY);
1556         if (info != null) {
1557             return info.activityInfo.loadLogo(this);
1558         }
1559 
1560         throw new NameNotFoundException(intent.toUri(0));
1561     }
1562 
1563     @Override
getApplicationLogo(ApplicationInfo info)1564     public Drawable getApplicationLogo(ApplicationInfo info) {
1565         return info.loadLogo(this);
1566     }
1567 
1568     @Override
getApplicationLogo(String packageName)1569     public Drawable getApplicationLogo(String packageName)
1570             throws NameNotFoundException {
1571         return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags));
1572     }
1573 
1574     @Override
getUserBadgedIcon(Drawable icon, UserHandle user)1575     public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
1576         if (!hasUserBadge(user.getIdentifier())) {
1577             return icon;
1578         }
1579         Drawable badge = new LauncherIcons(mContext).getBadgeDrawable(
1580                 getUserManager().getUserIconBadgeResId(user.getIdentifier()),
1581                 getUserBadgeColor(user, false));
1582         return getBadgedDrawable(icon, badge, null, true);
1583     }
1584 
1585     @Override
getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user, Rect badgeLocation, int badgeDensity)1586     public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
1587             Rect badgeLocation, int badgeDensity) {
1588         Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity);
1589         if (badgeDrawable == null) {
1590             return drawable;
1591         }
1592         return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
1593     }
1594 
1595     /**
1596      * Returns the color of the user's actual badge (not the badge's shadow).
1597      * @param checkTheme whether to check the theme to determine the badge color. This should be
1598      *                   true if the background is determined by the theme. Otherwise, if
1599      *                   checkTheme is false, returns the color assuming a light background.
1600      */
getUserBadgeColor(UserHandle user, boolean checkTheme)1601     private int getUserBadgeColor(UserHandle user, boolean checkTheme) {
1602         if (checkTheme && mContext.getResources().getConfiguration().isNightModeActive()) {
1603             return getUserManager().getUserBadgeDarkColor(user.getIdentifier());
1604         }
1605         return getUserManager().getUserBadgeColor(user.getIdentifier());
1606     }
1607 
1608     @Override
getUserBadgeForDensity(UserHandle user, int density)1609     public Drawable getUserBadgeForDensity(UserHandle user, int density) {
1610         // This is part of the shadow, not the main color, and is not actually corp-specific.
1611         Drawable badgeColor = getProfileIconForDensity(user,
1612                 com.android.internal.R.drawable.ic_corp_badge_color, density);
1613         if (badgeColor == null) {
1614             return null;
1615         }
1616         Drawable badgeForeground = getDrawableForDensity(
1617                 getUserManager().getUserBadgeResId(user.getIdentifier()), density);
1618         badgeForeground.setTint(getUserBadgeColor(user, false));
1619         Drawable badge = new LayerDrawable(new Drawable[] {badgeColor, badgeForeground });
1620         return badge;
1621     }
1622 
1623     /**
1624      * Returns the badge color based on whether device has dark theme enabled or not.
1625      */
1626     @Override
getUserBadgeForDensityNoBackground(UserHandle user, int density)1627     public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
1628         if (!hasUserBadge(user.getIdentifier())) {
1629             return null;
1630         }
1631         Drawable badge = getDrawableForDensity(
1632                 getUserManager().getUserBadgeNoBackgroundResId(user.getIdentifier()), density);
1633         if (badge != null) {
1634             badge.setTint(getUserBadgeColor(user, true));
1635         }
1636         return badge;
1637     }
1638 
getDrawableForDensity(int drawableId, int density)1639     private Drawable getDrawableForDensity(int drawableId, int density) {
1640         if (density <= 0) {
1641             density = mContext.getResources().getDisplayMetrics().densityDpi;
1642         }
1643         return mContext.getResources().getDrawableForDensity(drawableId, density);
1644     }
1645 
getProfileIconForDensity(UserHandle user, int drawableId, int density)1646     private Drawable getProfileIconForDensity(UserHandle user, int drawableId, int density) {
1647         if (hasUserBadge(user.getIdentifier())) {
1648             return getDrawableForDensity(drawableId, density);
1649         }
1650         return null;
1651     }
1652 
1653     @Override
getUserBadgedLabel(CharSequence label, UserHandle user)1654     public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
1655         return getUserManager().getBadgedLabelForUser(label, user);
1656     }
1657 
1658     @Override
getResourcesForActivity(ComponentName activityName)1659     public Resources getResourcesForActivity(ComponentName activityName)
1660             throws NameNotFoundException {
1661         return getResourcesForApplication(
1662             getActivityInfo(activityName, sDefaultFlags).applicationInfo);
1663     }
1664 
1665     @Override
getResourcesForApplication(@onNull ApplicationInfo app)1666     public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
1667             throws NameNotFoundException {
1668         if (app.packageName.equals("system")) {
1669             return mContext.mMainThread.getSystemUiContext().getResources();
1670         }
1671         final boolean sameUid = (app.uid == Process.myUid());
1672         final Resources r = mContext.mMainThread.getTopLevelResources(
1673                     sameUid ? app.sourceDir : app.publicSourceDir,
1674                     sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
1675                     app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
1676                     mContext.mPackageInfo);
1677         if (r != null) {
1678             return r;
1679         }
1680         throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
1681 
1682     }
1683 
1684     @Override
getResourcesForApplication(String appPackageName)1685     public Resources getResourcesForApplication(String appPackageName)
1686             throws NameNotFoundException {
1687         return getResourcesForApplication(
1688             getApplicationInfo(appPackageName, sDefaultFlags));
1689     }
1690 
1691     /** @hide */
1692     @Override
getResourcesForApplicationAsUser(String appPackageName, int userId)1693     public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
1694             throws NameNotFoundException {
1695         if (userId < 0) {
1696             throw new IllegalArgumentException(
1697                     "Call does not support special user #" + userId);
1698         }
1699         if ("system".equals(appPackageName)) {
1700             return mContext.mMainThread.getSystemUiContext().getResources();
1701         }
1702         try {
1703             ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
1704             if (ai != null) {
1705                 return getResourcesForApplication(ai);
1706             }
1707         } catch (RemoteException e) {
1708             throw e.rethrowFromSystemServer();
1709         }
1710         throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
1711     }
1712 
1713     volatile int mCachedSafeMode = -1;
1714 
1715     @Override
isSafeMode()1716     public boolean isSafeMode() {
1717         try {
1718             if (mCachedSafeMode < 0) {
1719                 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
1720             }
1721             return mCachedSafeMode != 0;
1722         } catch (RemoteException e) {
1723             throw e.rethrowFromSystemServer();
1724         }
1725     }
1726 
1727     @Override
addOnPermissionsChangeListener(OnPermissionsChangedListener listener)1728     public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
1729         synchronized (mPermissionListeners) {
1730             if (mPermissionListeners.get(listener) != null) {
1731                 return;
1732             }
1733             OnPermissionsChangeListenerDelegate delegate =
1734                     new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper());
1735             try {
1736                 mPermissionManager.addOnPermissionsChangeListener(delegate);
1737                 mPermissionListeners.put(listener, delegate);
1738             } catch (RemoteException e) {
1739                 throw e.rethrowFromSystemServer();
1740             }
1741         }
1742     }
1743 
1744     @Override
removeOnPermissionsChangeListener(OnPermissionsChangedListener listener)1745     public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
1746         synchronized (mPermissionListeners) {
1747             IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener);
1748             if (delegate != null) {
1749                 try {
1750                     mPermissionManager.removeOnPermissionsChangeListener(delegate);
1751                     mPermissionListeners.remove(listener);
1752                 } catch (RemoteException e) {
1753                     throw e.rethrowFromSystemServer();
1754                 }
1755             }
1756         }
1757     }
1758 
1759     @UnsupportedAppUsage
configurationChanged()1760     static void configurationChanged() {
1761         synchronized (sSync) {
1762             sIconCache.clear();
1763             sStringCache.clear();
1764         }
1765     }
1766 
1767     @UnsupportedAppUsage
ApplicationPackageManager(ContextImpl context, IPackageManager pm)1768     protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
1769         this(context, pm, ActivityThread.getPermissionManager());
1770     }
1771 
ApplicationPackageManager(ContextImpl context, IPackageManager pm, IPermissionManager permissionManager)1772     protected ApplicationPackageManager(ContextImpl context, IPackageManager pm,
1773             IPermissionManager permissionManager) {
1774         mContext = context;
1775         mPM = pm;
1776         mPermissionManager = permissionManager;
1777     }
1778 
1779     /**
1780      * Update given flags when being used to request {@link PackageInfo}.
1781      */
updateFlagsForPackage(int flags, int userId)1782     private int updateFlagsForPackage(int flags, int userId) {
1783         if ((flags & (GET_ACTIVITIES | GET_RECEIVERS | GET_SERVICES | GET_PROVIDERS)) != 0) {
1784             // Caller is asking for component details, so they'd better be
1785             // asking for specific Direct Boot matching behavior
1786             if ((flags & (MATCH_DIRECT_BOOT_UNAWARE
1787                     | MATCH_DIRECT_BOOT_AWARE
1788                     | MATCH_DIRECT_BOOT_AUTO)) == 0) {
1789                 onImplicitDirectBoot(userId);
1790             }
1791         }
1792         return flags;
1793     }
1794 
1795     /**
1796      * Update given flags when being used to request {@link ApplicationInfo}.
1797      */
updateFlagsForApplication(int flags, int userId)1798     private int updateFlagsForApplication(int flags, int userId) {
1799         return updateFlagsForPackage(flags, userId);
1800     }
1801 
1802     /**
1803      * Update given flags when being used to request {@link ComponentInfo}.
1804      */
updateFlagsForComponent(int flags, int userId, Intent intent)1805     private int updateFlagsForComponent(int flags, int userId, Intent intent) {
1806         if (intent != null) {
1807             if ((intent.getFlags() & Intent.FLAG_DIRECT_BOOT_AUTO) != 0) {
1808                 flags |= MATCH_DIRECT_BOOT_AUTO;
1809             }
1810         }
1811 
1812         // Caller is asking for component details, so they'd better be
1813         // asking for specific Direct Boot matching behavior
1814         if ((flags & (MATCH_DIRECT_BOOT_UNAWARE
1815                 | MATCH_DIRECT_BOOT_AWARE
1816                 | MATCH_DIRECT_BOOT_AUTO)) == 0) {
1817             onImplicitDirectBoot(userId);
1818         }
1819         return flags;
1820     }
1821 
onImplicitDirectBoot(int userId)1822     private void onImplicitDirectBoot(int userId) {
1823         // Only report if someone is relying on implicit behavior while the user
1824         // is locked; code running when unlocked is going to see both aware and
1825         // unaware components.
1826         if (StrictMode.vmImplicitDirectBootEnabled()) {
1827             // We can cache the unlocked state for the userId we're running as,
1828             // since any relocking of that user will always result in our
1829             // process being killed to release any CE FDs we're holding onto.
1830             if (userId == UserHandle.myUserId()) {
1831                 if (mUserUnlocked) {
1832                     return;
1833                 } else if (mContext.getSystemService(UserManager.class)
1834                         .isUserUnlockingOrUnlocked(userId)) {
1835                     mUserUnlocked = true;
1836                 } else {
1837                     StrictMode.onImplicitDirectBoot();
1838                 }
1839             } else if (!mContext.getSystemService(UserManager.class)
1840                     .isUserUnlockingOrUnlocked(userId)) {
1841                 StrictMode.onImplicitDirectBoot();
1842             }
1843         }
1844     }
1845 
1846     @Nullable
getCachedIcon(@onNull ResourceName name)1847     private Drawable getCachedIcon(@NonNull ResourceName name) {
1848         synchronized (sSync) {
1849             final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
1850             if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
1851                                    + name + ": " + wr);
1852             if (wr != null) {   // we have the activity
1853                 final Drawable.ConstantState state = wr.get();
1854                 if (state != null) {
1855                     if (DEBUG_ICONS) {
1856                         Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
1857                     }
1858                     // Note: It's okay here to not use the newDrawable(Resources) variant
1859                     //       of the API. The ConstantState comes from a drawable that was
1860                     //       originally created by passing the proper app Resources instance
1861                     //       which means the state should already contain the proper
1862                     //       resources specific information (like density.) See
1863                     //       BitmapDrawable.BitmapState for instance.
1864                     return state.newDrawable();
1865                 }
1866                 // our entry has been purged
1867                 sIconCache.remove(name);
1868             }
1869         }
1870         return null;
1871     }
1872 
putCachedIcon(@onNull ResourceName name, @NonNull Drawable dr)1873     private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) {
1874         synchronized (sSync) {
1875             sIconCache.put(name, new WeakReference<>(dr.getConstantState()));
1876             if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
1877         }
1878     }
1879 
handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo)1880     static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
1881         boolean immediateGc = false;
1882         if (cmd == ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE) {
1883             immediateGc = true;
1884         }
1885         if (pkgList != null && (pkgList.length > 0)) {
1886             boolean needCleanup = false;
1887             for (String ssp : pkgList) {
1888                 synchronized (sSync) {
1889                     for (int i=sIconCache.size()-1; i>=0; i--) {
1890                         ResourceName nm = sIconCache.keyAt(i);
1891                         if (nm.packageName.equals(ssp)) {
1892                             //Log.i(TAG, "Removing cached drawable for " + nm);
1893                             sIconCache.removeAt(i);
1894                             needCleanup = true;
1895                         }
1896                     }
1897                     for (int i=sStringCache.size()-1; i>=0; i--) {
1898                         ResourceName nm = sStringCache.keyAt(i);
1899                         if (nm.packageName.equals(ssp)) {
1900                             //Log.i(TAG, "Removing cached string for " + nm);
1901                             sStringCache.removeAt(i);
1902                             needCleanup = true;
1903                         }
1904                     }
1905                 }
1906             }
1907             if (needCleanup || hasPkgInfo) {
1908                 if (immediateGc) {
1909                     // Schedule an immediate gc.
1910                     Runtime.getRuntime().gc();
1911                 } else {
1912                     ActivityThread.currentActivityThread().scheduleGcIdler();
1913                 }
1914             }
1915         }
1916     }
1917 
1918     private static final class ResourceName {
1919         final String packageName;
1920         final int iconId;
1921 
ResourceName(String _packageName, int _iconId)1922         ResourceName(String _packageName, int _iconId) {
1923             packageName = _packageName;
1924             iconId = _iconId;
1925         }
1926 
ResourceName(ApplicationInfo aInfo, int _iconId)1927         ResourceName(ApplicationInfo aInfo, int _iconId) {
1928             this(aInfo.packageName, _iconId);
1929         }
1930 
ResourceName(ComponentInfo cInfo, int _iconId)1931         ResourceName(ComponentInfo cInfo, int _iconId) {
1932             this(cInfo.applicationInfo.packageName, _iconId);
1933         }
1934 
ResourceName(ResolveInfo rInfo, int _iconId)1935         ResourceName(ResolveInfo rInfo, int _iconId) {
1936             this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
1937         }
1938 
1939         @Override
equals(Object o)1940         public boolean equals(Object o) {
1941             if (this == o) return true;
1942             if (o == null || getClass() != o.getClass()) return false;
1943 
1944             ResourceName that = (ResourceName) o;
1945 
1946             if (iconId != that.iconId) return false;
1947             return !(packageName != null ?
1948                      !packageName.equals(that.packageName) : that.packageName != null);
1949 
1950         }
1951 
1952         @Override
hashCode()1953         public int hashCode() {
1954             int result;
1955             result = packageName.hashCode();
1956             result = 31 * result + iconId;
1957             return result;
1958         }
1959 
1960         @Override
toString()1961         public String toString() {
1962             return "{ResourceName " + packageName + " / " + iconId + "}";
1963         }
1964     }
1965 
getCachedString(ResourceName name)1966     private CharSequence getCachedString(ResourceName name) {
1967         synchronized (sSync) {
1968             WeakReference<CharSequence> wr = sStringCache.get(name);
1969             if (wr != null) {   // we have the activity
1970                 CharSequence cs = wr.get();
1971                 if (cs != null) {
1972                     return cs;
1973                 }
1974                 // our entry has been purged
1975                 sStringCache.remove(name);
1976             }
1977         }
1978         return null;
1979     }
1980 
putCachedString(ResourceName name, CharSequence cs)1981     private void putCachedString(ResourceName name, CharSequence cs) {
1982         synchronized (sSync) {
1983             sStringCache.put(name, new WeakReference<CharSequence>(cs));
1984         }
1985     }
1986 
1987     @Override
getText(String packageName, @StringRes int resid, ApplicationInfo appInfo)1988     public CharSequence getText(String packageName, @StringRes int resid,
1989                                 ApplicationInfo appInfo) {
1990         ResourceName name = new ResourceName(packageName, resid);
1991         CharSequence text = getCachedString(name);
1992         if (text != null) {
1993             return text;
1994         }
1995         if (appInfo == null) {
1996             try {
1997                 appInfo = getApplicationInfo(packageName, sDefaultFlags);
1998             } catch (NameNotFoundException e) {
1999                 return null;
2000             }
2001         }
2002         try {
2003             Resources r = getResourcesForApplication(appInfo);
2004             text = r.getText(resid);
2005             putCachedString(name, text);
2006             return text;
2007         } catch (NameNotFoundException e) {
2008             Log.w("PackageManager", "Failure retrieving resources for "
2009                   + appInfo.packageName);
2010         } catch (RuntimeException e) {
2011             // If an exception was thrown, fall through to return
2012             // default icon.
2013             Log.w("PackageManager", "Failure retrieving text 0x"
2014                   + Integer.toHexString(resid) + " in package "
2015                   + packageName, e);
2016         }
2017         return null;
2018     }
2019 
2020     @Override
getXml(String packageName, @XmlRes int resid, ApplicationInfo appInfo)2021     public XmlResourceParser getXml(String packageName, @XmlRes int resid,
2022                                     ApplicationInfo appInfo) {
2023         if (appInfo == null) {
2024             try {
2025                 appInfo = getApplicationInfo(packageName, sDefaultFlags);
2026             } catch (NameNotFoundException e) {
2027                 return null;
2028             }
2029         }
2030         try {
2031             Resources r = getResourcesForApplication(appInfo);
2032             return r.getXml(resid);
2033         } catch (RuntimeException e) {
2034             // If an exception was thrown, fall through to return
2035             // default icon.
2036             Log.w("PackageManager", "Failure retrieving xml 0x"
2037                   + Integer.toHexString(resid) + " in package "
2038                   + packageName, e);
2039         } catch (NameNotFoundException e) {
2040             Log.w("PackageManager", "Failure retrieving resources for "
2041                   + appInfo.packageName);
2042         }
2043         return null;
2044     }
2045 
2046     @Override
getApplicationLabel(ApplicationInfo info)2047     public CharSequence getApplicationLabel(ApplicationInfo info) {
2048         return info.loadLabel(this);
2049     }
2050 
2051     @Override
installExistingPackage(String packageName)2052     public int installExistingPackage(String packageName) throws NameNotFoundException {
2053         return installExistingPackage(packageName, INSTALL_REASON_UNKNOWN);
2054     }
2055 
2056     @Override
installExistingPackage(String packageName, int installReason)2057     public int installExistingPackage(String packageName, int installReason)
2058             throws NameNotFoundException {
2059         return installExistingPackageAsUser(packageName, installReason, getUserId());
2060     }
2061 
2062     @Override
installExistingPackageAsUser(String packageName, int userId)2063     public int installExistingPackageAsUser(String packageName, int userId)
2064             throws NameNotFoundException {
2065         return installExistingPackageAsUser(packageName, INSTALL_REASON_UNKNOWN,
2066                 userId);
2067     }
2068 
installExistingPackageAsUser(String packageName, int installReason, int userId)2069     private int installExistingPackageAsUser(String packageName, int installReason, int userId)
2070             throws NameNotFoundException {
2071         try {
2072             int res = mPM.installExistingPackageAsUser(packageName, userId,
2073                     INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS, installReason, null);
2074             if (res == INSTALL_FAILED_INVALID_URI) {
2075                 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
2076             }
2077             return res;
2078         } catch (RemoteException e) {
2079             throw e.rethrowFromSystemServer();
2080         }
2081     }
2082 
2083     @Override
verifyPendingInstall(int id, int response)2084     public void verifyPendingInstall(int id, int response) {
2085         try {
2086             mPM.verifyPendingInstall(id, response);
2087         } catch (RemoteException e) {
2088             throw e.rethrowFromSystemServer();
2089         }
2090     }
2091 
2092     @Override
extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)2093     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
2094             long millisecondsToDelay) {
2095         try {
2096             mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
2097         } catch (RemoteException e) {
2098             throw e.rethrowFromSystemServer();
2099         }
2100     }
2101 
2102     @Override
verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)2103     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
2104         try {
2105             mPM.verifyIntentFilter(id, verificationCode, failedDomains);
2106         } catch (RemoteException e) {
2107             throw e.rethrowFromSystemServer();
2108         }
2109     }
2110 
2111     @Override
getIntentVerificationStatusAsUser(String packageName, int userId)2112     public int getIntentVerificationStatusAsUser(String packageName, int userId) {
2113         try {
2114             return mPM.getIntentVerificationStatus(packageName, userId);
2115         } catch (RemoteException e) {
2116             throw e.rethrowFromSystemServer();
2117         }
2118     }
2119 
2120     @Override
updateIntentVerificationStatusAsUser(String packageName, int status, int userId)2121     public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
2122         try {
2123             return mPM.updateIntentVerificationStatus(packageName, status, userId);
2124         } catch (RemoteException e) {
2125             throw e.rethrowFromSystemServer();
2126         }
2127     }
2128 
2129     @Override
2130     @SuppressWarnings("unchecked")
getIntentFilterVerifications(String packageName)2131     public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
2132         try {
2133             ParceledListSlice<IntentFilterVerificationInfo> parceledList =
2134                     mPM.getIntentFilterVerifications(packageName);
2135             if (parceledList == null) {
2136                 return Collections.emptyList();
2137             }
2138             return parceledList.getList();
2139         } catch (RemoteException e) {
2140             throw e.rethrowFromSystemServer();
2141         }
2142     }
2143 
2144     @Override
2145     @SuppressWarnings("unchecked")
getAllIntentFilters(String packageName)2146     public List<IntentFilter> getAllIntentFilters(String packageName) {
2147         try {
2148             ParceledListSlice<IntentFilter> parceledList =
2149                     mPM.getAllIntentFilters(packageName);
2150             if (parceledList == null) {
2151                 return Collections.emptyList();
2152             }
2153             return parceledList.getList();
2154         } catch (RemoteException e) {
2155             throw e.rethrowFromSystemServer();
2156         }
2157     }
2158 
2159     @Override
getDefaultBrowserPackageNameAsUser(int userId)2160     public String getDefaultBrowserPackageNameAsUser(int userId) {
2161         try {
2162             return mPermissionManager.getDefaultBrowser(userId);
2163         } catch (RemoteException e) {
2164             throw e.rethrowFromSystemServer();
2165         }
2166     }
2167 
2168     @Override
setDefaultBrowserPackageNameAsUser(String packageName, int userId)2169     public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
2170         try {
2171             return mPermissionManager.setDefaultBrowser(packageName, userId);
2172         } catch (RemoteException e) {
2173             throw e.rethrowFromSystemServer();
2174         }
2175     }
2176 
2177     @Override
setInstallerPackageName(String targetPackage, String installerPackageName)2178     public void setInstallerPackageName(String targetPackage,
2179             String installerPackageName) {
2180         try {
2181             mPM.setInstallerPackageName(targetPackage, installerPackageName);
2182         } catch (RemoteException e) {
2183             throw e.rethrowFromSystemServer();
2184         }
2185     }
2186 
2187     @Override
setUpdateAvailable(String packageName, boolean updateAvailable)2188     public void setUpdateAvailable(String packageName, boolean updateAvailable) {
2189         try {
2190             mPM.setUpdateAvailable(packageName, updateAvailable);
2191         } catch (RemoteException e) {
2192             throw e.rethrowFromSystemServer();
2193         }
2194     }
2195 
2196     @Override
getInstallerPackageName(String packageName)2197     public String getInstallerPackageName(String packageName) {
2198         try {
2199             return mPM.getInstallerPackageName(packageName);
2200         } catch (RemoteException e) {
2201             throw e.rethrowFromSystemServer();
2202         }
2203     }
2204 
2205     @Override
2206     @NonNull
getInstallSourceInfo(String packageName)2207     public InstallSourceInfo getInstallSourceInfo(String packageName) throws NameNotFoundException {
2208         final InstallSourceInfo installSourceInfo;
2209         try {
2210             installSourceInfo = mPM.getInstallSourceInfo(packageName);
2211         } catch (RemoteException e) {
2212             throw e.rethrowFromSystemServer();
2213         }
2214         if (installSourceInfo == null) {
2215             throw new NameNotFoundException(packageName);
2216         }
2217         return installSourceInfo;
2218     }
2219 
2220     @Override
getMoveStatus(int moveId)2221     public int getMoveStatus(int moveId) {
2222         try {
2223             return mPM.getMoveStatus(moveId);
2224         } catch (RemoteException e) {
2225             throw e.rethrowFromSystemServer();
2226         }
2227     }
2228 
2229     @Override
registerMoveCallback(MoveCallback callback, Handler handler)2230     public void registerMoveCallback(MoveCallback callback, Handler handler) {
2231         synchronized (mDelegates) {
2232             final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback,
2233                     handler.getLooper());
2234             try {
2235                 mPM.registerMoveCallback(delegate);
2236             } catch (RemoteException e) {
2237                 throw e.rethrowFromSystemServer();
2238             }
2239             mDelegates.add(delegate);
2240         }
2241     }
2242 
2243     @Override
unregisterMoveCallback(MoveCallback callback)2244     public void unregisterMoveCallback(MoveCallback callback) {
2245         synchronized (mDelegates) {
2246             for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
2247                 final MoveCallbackDelegate delegate = i.next();
2248                 if (delegate.mCallback == callback) {
2249                     try {
2250                         mPM.unregisterMoveCallback(delegate);
2251                     } catch (RemoteException e) {
2252                         throw e.rethrowFromSystemServer();
2253                     }
2254                     i.remove();
2255                 }
2256             }
2257         }
2258     }
2259 
2260     @Override
movePackage(String packageName, VolumeInfo vol)2261     public int movePackage(String packageName, VolumeInfo vol) {
2262         try {
2263             final String volumeUuid;
2264             if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
2265                 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
2266             } else if (vol.isPrimaryPhysical()) {
2267                 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
2268             } else {
2269                 volumeUuid = Objects.requireNonNull(vol.fsUuid);
2270             }
2271 
2272             return mPM.movePackage(packageName, volumeUuid);
2273         } catch (RemoteException e) {
2274             throw e.rethrowFromSystemServer();
2275         }
2276     }
2277 
2278     @Override
2279     @UnsupportedAppUsage
getPackageCurrentVolume(ApplicationInfo app)2280     public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
2281         final StorageManager storage = mContext.getSystemService(StorageManager.class);
2282         return getPackageCurrentVolume(app, storage);
2283     }
2284 
2285     @VisibleForTesting
getPackageCurrentVolume(ApplicationInfo app, StorageManager storage)2286     protected @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app,
2287             StorageManager storage) {
2288         if (app.isInternal()) {
2289             return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
2290         } else {
2291             return storage.findVolumeByUuid(app.volumeUuid);
2292         }
2293     }
2294 
2295     @Override
getPackageCandidateVolumes(ApplicationInfo app)2296     public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
2297         final StorageManager storageManager = mContext.getSystemService(StorageManager.class);
2298         return getPackageCandidateVolumes(app, storageManager, mPM);
2299     }
2300 
2301     @VisibleForTesting
getPackageCandidateVolumes(ApplicationInfo app, StorageManager storageManager, IPackageManager pm)2302     protected @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app,
2303             StorageManager storageManager, IPackageManager pm) {
2304         final VolumeInfo currentVol = getPackageCurrentVolume(app, storageManager);
2305         final List<VolumeInfo> vols = storageManager.getVolumes();
2306         final List<VolumeInfo> candidates = new ArrayList<>();
2307         for (VolumeInfo vol : vols) {
2308             if (Objects.equals(vol, currentVol)
2309                     || isPackageCandidateVolume(mContext, app, vol, pm)) {
2310                 candidates.add(vol);
2311             }
2312         }
2313         return candidates;
2314     }
2315 
2316     @VisibleForTesting
isForceAllowOnExternal(Context context)2317     protected boolean isForceAllowOnExternal(Context context) {
2318         return Settings.Global.getInt(
2319                 context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0;
2320     }
2321 
2322     @VisibleForTesting
isAllow3rdPartyOnInternal(Context context)2323     protected boolean isAllow3rdPartyOnInternal(Context context) {
2324         return context.getResources().getBoolean(
2325                 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
2326     }
2327 
isPackageCandidateVolume( ContextImpl context, ApplicationInfo app, VolumeInfo vol, IPackageManager pm)2328     private boolean isPackageCandidateVolume(
2329             ContextImpl context, ApplicationInfo app, VolumeInfo vol, IPackageManager pm) {
2330         final boolean forceAllowOnExternal = isForceAllowOnExternal(context);
2331 
2332         if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
2333             return app.isSystemApp() || isAllow3rdPartyOnInternal(context);
2334         }
2335 
2336         // System apps and apps demanding internal storage can't be moved
2337         // anywhere else
2338         if (app.isSystemApp()) {
2339             return false;
2340         }
2341         if (!forceAllowOnExternal
2342                 && (app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY
2343                         || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED)) {
2344             return false;
2345         }
2346 
2347         // Gotta be able to write there
2348         if (!vol.isMountedWritable()) {
2349             return false;
2350         }
2351 
2352         // Moving into an ASEC on public primary is only option internal
2353         if (vol.isPrimaryPhysical()) {
2354             return app.isInternal();
2355         }
2356 
2357         // Some apps can't be moved. (e.g. device admins)
2358         try {
2359             if (pm.isPackageDeviceAdminOnAnyUser(app.packageName)) {
2360                 return false;
2361             }
2362         } catch (RemoteException e) {
2363             throw e.rethrowFromSystemServer();
2364         }
2365 
2366         // Otherwise we can move to any private volume
2367         return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
2368     }
2369 
2370     @Override
movePrimaryStorage(VolumeInfo vol)2371     public int movePrimaryStorage(VolumeInfo vol) {
2372         try {
2373             final String volumeUuid;
2374             if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
2375                 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
2376             } else if (vol.isPrimaryPhysical()) {
2377                 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
2378             } else {
2379                 volumeUuid = Objects.requireNonNull(vol.fsUuid);
2380             }
2381 
2382             return mPM.movePrimaryStorage(volumeUuid);
2383         } catch (RemoteException e) {
2384             throw e.rethrowFromSystemServer();
2385         }
2386     }
2387 
2388     @Override
getPrimaryStorageCurrentVolume()2389     public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
2390         final StorageManager storage = mContext.getSystemService(StorageManager.class);
2391         final String volumeUuid = storage.getPrimaryStorageUuid();
2392         return storage.findVolumeByQualifiedUuid(volumeUuid);
2393     }
2394 
2395     @Override
getPrimaryStorageCandidateVolumes()2396     public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
2397         final StorageManager storage = mContext.getSystemService(StorageManager.class);
2398         final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
2399         final List<VolumeInfo> vols = storage.getVolumes();
2400         final List<VolumeInfo> candidates = new ArrayList<>();
2401         if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL,
2402                 storage.getPrimaryStorageUuid()) && currentVol != null) {
2403             // TODO: support moving primary physical to emulated volume
2404             candidates.add(currentVol);
2405         } else {
2406             for (VolumeInfo vol : vols) {
2407                 if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
2408                     candidates.add(vol);
2409                 }
2410             }
2411         }
2412         return candidates;
2413     }
2414 
isPrimaryStorageCandidateVolume(VolumeInfo vol)2415     private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) {
2416         // Private internal is always an option
2417         if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
2418             return true;
2419         }
2420 
2421         // Gotta be able to write there
2422         if (!vol.isMountedWritable()) {
2423             return false;
2424         }
2425 
2426         // We can move to any private volume
2427         return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
2428     }
2429 
2430     @Override
2431     @UnsupportedAppUsage
deletePackage(String packageName, IPackageDeleteObserver observer, int flags)2432     public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2433         deletePackageAsUser(packageName, observer, flags, getUserId());
2434     }
2435 
2436     @Override
deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags, int userId)2437     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer,
2438             int flags, int userId) {
2439         try {
2440             mPM.deletePackageAsUser(packageName, VERSION_CODE_HIGHEST,
2441                     observer, userId, flags);
2442         } catch (RemoteException e) {
2443             throw e.rethrowFromSystemServer();
2444         }
2445     }
2446 
2447     @Override
clearApplicationUserData(String packageName, IPackageDataObserver observer)2448     public void clearApplicationUserData(String packageName,
2449                                          IPackageDataObserver observer) {
2450         try {
2451             mPM.clearApplicationUserData(packageName, observer, getUserId());
2452         } catch (RemoteException e) {
2453             throw e.rethrowFromSystemServer();
2454         }
2455     }
2456     @Override
deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer)2457     public void deleteApplicationCacheFiles(String packageName,
2458                                             IPackageDataObserver observer) {
2459         try {
2460             mPM.deleteApplicationCacheFiles(packageName, observer);
2461         } catch (RemoteException e) {
2462             throw e.rethrowFromSystemServer();
2463         }
2464     }
2465 
2466     @Override
deleteApplicationCacheFilesAsUser(String packageName, int userId, IPackageDataObserver observer)2467     public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
2468             IPackageDataObserver observer) {
2469         try {
2470             mPM.deleteApplicationCacheFilesAsUser(packageName, userId, observer);
2471         } catch (RemoteException e) {
2472             throw e.rethrowFromSystemServer();
2473         }
2474     }
2475 
2476     @Override
freeStorageAndNotify(String volumeUuid, long idealStorageSize, IPackageDataObserver observer)2477     public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
2478             IPackageDataObserver observer) {
2479         try {
2480             mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, 0, observer);
2481         } catch (RemoteException e) {
2482             throw e.rethrowFromSystemServer();
2483         }
2484     }
2485 
2486     @Override
freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi)2487     public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
2488         try {
2489             mPM.freeStorage(volumeUuid, freeStorageSize, 0, pi);
2490         } catch (RemoteException e) {
2491             throw e.rethrowFromSystemServer();
2492         }
2493     }
2494 
2495     @Override
setDistractingPackageRestrictions(String[] packages, int distractionFlags)2496     public String[] setDistractingPackageRestrictions(String[] packages, int distractionFlags) {
2497         try {
2498             return mPM.setDistractingPackageRestrictionsAsUser(packages, distractionFlags,
2499                     mContext.getUserId());
2500         } catch (RemoteException e) {
2501             throw e.rethrowFromSystemServer();
2502         }
2503     }
2504 
2505     @Override
setPackagesSuspended(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, String dialogMessage)2506     public String[] setPackagesSuspended(String[] packageNames, boolean suspended,
2507             PersistableBundle appExtras, PersistableBundle launcherExtras,
2508             String dialogMessage) {
2509         final SuspendDialogInfo dialogInfo = !TextUtils.isEmpty(dialogMessage)
2510                 ? new SuspendDialogInfo.Builder().setMessage(dialogMessage).build()
2511                 : null;
2512         return setPackagesSuspended(packageNames, suspended, appExtras, launcherExtras, dialogInfo);
2513     }
2514 
2515     @Override
setPackagesSuspended(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, SuspendDialogInfo dialogInfo)2516     public String[] setPackagesSuspended(String[] packageNames, boolean suspended,
2517             PersistableBundle appExtras, PersistableBundle launcherExtras,
2518             SuspendDialogInfo dialogInfo) {
2519         try {
2520             return mPM.setPackagesSuspendedAsUser(packageNames, suspended, appExtras,
2521                     launcherExtras, dialogInfo, mContext.getOpPackageName(),
2522                     getUserId());
2523         } catch (RemoteException e) {
2524             throw e.rethrowFromSystemServer();
2525         }
2526     }
2527 
2528     @Override
getUnsuspendablePackages(String[] packageNames)2529     public String[] getUnsuspendablePackages(String[] packageNames) {
2530         try {
2531             return mPM.getUnsuspendablePackagesForUser(packageNames, mContext.getUserId());
2532         } catch (RemoteException e) {
2533             throw e.rethrowFromSystemServer();
2534         }
2535     }
2536 
2537     @Override
getSuspendedPackageAppExtras()2538     public Bundle getSuspendedPackageAppExtras() {
2539         try {
2540             return mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(), getUserId());
2541         } catch (RemoteException e) {
2542             throw e.rethrowFromSystemServer();
2543         }
2544     }
2545 
2546     @Override
isPackageSuspendedForUser(String packageName, int userId)2547     public boolean isPackageSuspendedForUser(String packageName, int userId) {
2548         try {
2549             return mPM.isPackageSuspendedForUser(packageName, userId);
2550         } catch (RemoteException e) {
2551             throw e.rethrowFromSystemServer();
2552         }
2553     }
2554 
2555     /** @hide */
2556     @Override
isPackageSuspended(String packageName)2557     public boolean isPackageSuspended(String packageName) throws NameNotFoundException {
2558         try {
2559             return isPackageSuspendedForUser(packageName, getUserId());
2560         } catch (IllegalArgumentException ie) {
2561             throw new NameNotFoundException(packageName);
2562         }
2563     }
2564 
2565     @Override
isPackageSuspended()2566     public boolean isPackageSuspended() {
2567         return isPackageSuspendedForUser(mContext.getOpPackageName(), getUserId());
2568     }
2569 
2570     /** @hide */
2571     @Override
setApplicationCategoryHint(String packageName, int categoryHint)2572     public void setApplicationCategoryHint(String packageName, int categoryHint) {
2573         try {
2574             mPM.setApplicationCategoryHint(packageName, categoryHint,
2575                     mContext.getOpPackageName());
2576         } catch (RemoteException e) {
2577             throw e.rethrowFromSystemServer();
2578         }
2579     }
2580 
2581     @Override
2582     @UnsupportedAppUsage
getPackageSizeInfoAsUser(String packageName, int userHandle, IPackageStatsObserver observer)2583     public void getPackageSizeInfoAsUser(String packageName, int userHandle,
2584             IPackageStatsObserver observer) {
2585         final String msg = "Shame on you for calling the hidden API "
2586                 + "getPackageSizeInfoAsUser(). Shame!";
2587         if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {
2588             throw new UnsupportedOperationException(msg);
2589         } else if (observer != null) {
2590             Log.d(TAG, msg);
2591             try {
2592                 observer.onGetStatsCompleted(null, false);
2593             } catch (RemoteException ignored) {
2594             }
2595         }
2596     }
2597 
2598     @Override
addPackageToPreferred(String packageName)2599     public void addPackageToPreferred(String packageName) {
2600         Log.w(TAG, "addPackageToPreferred() is a no-op");
2601     }
2602 
2603     @Override
removePackageFromPreferred(String packageName)2604     public void removePackageFromPreferred(String packageName) {
2605         Log.w(TAG, "removePackageFromPreferred() is a no-op");
2606     }
2607 
2608     @Override
getPreferredPackages(int flags)2609     public List<PackageInfo> getPreferredPackages(int flags) {
2610         Log.w(TAG, "getPreferredPackages() is a no-op");
2611         return Collections.emptyList();
2612     }
2613 
2614     @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)2615     public void addPreferredActivity(IntentFilter filter,
2616                                      int match, ComponentName[] set, ComponentName activity) {
2617         try {
2618             mPM.addPreferredActivity(filter, match, set, activity, getUserId());
2619         } catch (RemoteException e) {
2620             throw e.rethrowFromSystemServer();
2621         }
2622     }
2623 
2624     @Override
addPreferredActivityAsUser(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)2625     public void addPreferredActivityAsUser(IntentFilter filter, int match,
2626             ComponentName[] set, ComponentName activity, int userId) {
2627         try {
2628             mPM.addPreferredActivity(filter, match, set, activity, userId);
2629         } catch (RemoteException e) {
2630             throw e.rethrowFromSystemServer();
2631         }
2632     }
2633 
2634     @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)2635     public void replacePreferredActivity(IntentFilter filter,
2636                                          int match, ComponentName[] set, ComponentName activity) {
2637         try {
2638             mPM.replacePreferredActivity(filter, match, set, activity, getUserId());
2639         } catch (RemoteException e) {
2640             throw e.rethrowFromSystemServer();
2641         }
2642     }
2643 
2644     @Override
replacePreferredActivityAsUser(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)2645     public void replacePreferredActivityAsUser(IntentFilter filter,
2646                                          int match, ComponentName[] set, ComponentName activity,
2647                                          int userId) {
2648         try {
2649             mPM.replacePreferredActivity(filter, match, set, activity, userId);
2650         } catch (RemoteException e) {
2651             throw e.rethrowFromSystemServer();
2652         }
2653     }
2654 
2655     @Override
clearPackagePreferredActivities(String packageName)2656     public void clearPackagePreferredActivities(String packageName) {
2657         try {
2658             mPM.clearPackagePreferredActivities(packageName);
2659         } catch (RemoteException e) {
2660             throw e.rethrowFromSystemServer();
2661         }
2662     }
2663 
2664     @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)2665     public int getPreferredActivities(List<IntentFilter> outFilters,
2666                                       List<ComponentName> outActivities, String packageName) {
2667         try {
2668             return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2669         } catch (RemoteException e) {
2670             throw e.rethrowFromSystemServer();
2671         }
2672     }
2673 
2674     @Override
getHomeActivities(List<ResolveInfo> outActivities)2675     public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
2676         try {
2677             return mPM.getHomeActivities(outActivities);
2678         } catch (RemoteException e) {
2679             throw e.rethrowFromSystemServer();
2680         }
2681     }
2682 
2683     @Override
setSyntheticAppDetailsActivityEnabled(String packageName, boolean enabled)2684     public void setSyntheticAppDetailsActivityEnabled(String packageName, boolean enabled) {
2685         try {
2686             ComponentName componentName = new ComponentName(packageName,
2687                     APP_DETAILS_ACTIVITY_CLASS_NAME);
2688             mPM.setComponentEnabledSetting(componentName, enabled
2689                     ? COMPONENT_ENABLED_STATE_DEFAULT
2690                     : COMPONENT_ENABLED_STATE_DISABLED,
2691                     DONT_KILL_APP, getUserId());
2692         } catch (RemoteException e) {
2693             throw e.rethrowFromSystemServer();
2694         }
2695     }
2696 
2697     @Override
getSyntheticAppDetailsActivityEnabled(String packageName)2698     public boolean getSyntheticAppDetailsActivityEnabled(String packageName) {
2699         try {
2700             ComponentName componentName = new ComponentName(packageName,
2701                     APP_DETAILS_ACTIVITY_CLASS_NAME);
2702             int state = mPM.getComponentEnabledSetting(componentName, getUserId());
2703             return state == COMPONENT_ENABLED_STATE_ENABLED
2704                     || state == COMPONENT_ENABLED_STATE_DEFAULT;
2705         } catch (RemoteException e) {
2706             throw e.rethrowFromSystemServer();
2707         }
2708     }
2709 
2710     @Override
setComponentEnabledSetting(ComponentName componentName, int newState, int flags)2711     public void setComponentEnabledSetting(ComponentName componentName,
2712                                            int newState, int flags) {
2713         try {
2714             mPM.setComponentEnabledSetting(componentName, newState, flags, getUserId());
2715         } catch (RemoteException e) {
2716             throw e.rethrowFromSystemServer();
2717         }
2718     }
2719 
2720     @Override
getComponentEnabledSetting(ComponentName componentName)2721     public int getComponentEnabledSetting(ComponentName componentName) {
2722         try {
2723             return mPM.getComponentEnabledSetting(componentName, getUserId());
2724         } catch (RemoteException e) {
2725             throw e.rethrowFromSystemServer();
2726         }
2727     }
2728 
2729     @Override
setApplicationEnabledSetting(String packageName, int newState, int flags)2730     public void setApplicationEnabledSetting(String packageName,
2731                                              int newState, int flags) {
2732         try {
2733             mPM.setApplicationEnabledSetting(packageName, newState, flags,
2734                     getUserId(), mContext.getOpPackageName());
2735         } catch (RemoteException e) {
2736             throw e.rethrowFromSystemServer();
2737         }
2738     }
2739 
2740     @Override
getApplicationEnabledSetting(String packageName)2741     public int getApplicationEnabledSetting(String packageName) {
2742         try {
2743             return mPM.getApplicationEnabledSetting(packageName, getUserId());
2744         } catch (RemoteException e) {
2745             throw e.rethrowFromSystemServer();
2746         }
2747     }
2748 
2749     @Override
flushPackageRestrictionsAsUser(int userId)2750     public void flushPackageRestrictionsAsUser(int userId) {
2751         try {
2752             mPM.flushPackageRestrictionsAsUser(userId);
2753         } catch (RemoteException e) {
2754             throw e.rethrowFromSystemServer();
2755         }
2756     }
2757 
2758     @Override
setApplicationHiddenSettingAsUser(String packageName, boolean hidden, UserHandle user)2759     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
2760             UserHandle user) {
2761         try {
2762             return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
2763                     user.getIdentifier());
2764         } catch (RemoteException e) {
2765             throw e.rethrowFromSystemServer();
2766         }
2767     }
2768 
2769     @Override
getApplicationHiddenSettingAsUser(String packageName, UserHandle user)2770     public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
2771         try {
2772             return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
2773         } catch (RemoteException e) {
2774             throw e.rethrowFromSystemServer();
2775         }
2776     }
2777 
2778     /** @hide */
2779     @Override
setSystemAppState(String packageName, @SystemAppState int state)2780     public void setSystemAppState(String packageName, @SystemAppState int state) {
2781         try {
2782             switch (state) {
2783                 case SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN:
2784                     mPM.setSystemAppHiddenUntilInstalled(packageName, true);
2785                     break;
2786                 case SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE:
2787                     mPM.setSystemAppHiddenUntilInstalled(packageName, false);
2788                     break;
2789                 case SYSTEM_APP_STATE_INSTALLED:
2790                     mPM.setSystemAppInstallState(packageName, true, getUserId());
2791                     break;
2792                 case SYSTEM_APP_STATE_UNINSTALLED:
2793                     mPM.setSystemAppInstallState(packageName, false, getUserId());
2794                     break;
2795                 default:
2796             }
2797         } catch (RemoteException e) {
2798             throw e.rethrowFromSystemServer();
2799         }
2800     }
2801 
2802     /** @hide */
2803     @Override
getKeySetByAlias(String packageName, String alias)2804     public KeySet getKeySetByAlias(String packageName, String alias) {
2805         Objects.requireNonNull(packageName);
2806         Objects.requireNonNull(alias);
2807         try {
2808             return mPM.getKeySetByAlias(packageName, alias);
2809         } catch (RemoteException e) {
2810             throw e.rethrowFromSystemServer();
2811         }
2812     }
2813 
2814     /** @hide */
2815     @Override
getSigningKeySet(String packageName)2816     public KeySet getSigningKeySet(String packageName) {
2817         Objects.requireNonNull(packageName);
2818         try {
2819             return mPM.getSigningKeySet(packageName);
2820         } catch (RemoteException e) {
2821             throw e.rethrowFromSystemServer();
2822         }
2823     }
2824 
2825     /** @hide */
2826     @Override
isSignedBy(String packageName, KeySet ks)2827     public boolean isSignedBy(String packageName, KeySet ks) {
2828         Objects.requireNonNull(packageName);
2829         Objects.requireNonNull(ks);
2830         try {
2831             return mPM.isPackageSignedByKeySet(packageName, ks);
2832         } catch (RemoteException e) {
2833             throw e.rethrowFromSystemServer();
2834         }
2835     }
2836 
2837     /** @hide */
2838     @Override
isSignedByExactly(String packageName, KeySet ks)2839     public boolean isSignedByExactly(String packageName, KeySet ks) {
2840         Objects.requireNonNull(packageName);
2841         Objects.requireNonNull(ks);
2842         try {
2843             return mPM.isPackageSignedByKeySetExactly(packageName, ks);
2844         } catch (RemoteException e) {
2845             throw e.rethrowFromSystemServer();
2846         }
2847     }
2848 
2849     /**
2850      * @hide
2851      */
2852     @Override
getVerifierDeviceIdentity()2853     public VerifierDeviceIdentity getVerifierDeviceIdentity() {
2854         try {
2855             return mPM.getVerifierDeviceIdentity();
2856         } catch (RemoteException e) {
2857             throw e.rethrowFromSystemServer();
2858         }
2859     }
2860 
2861     @Override
isUpgrade()2862     public boolean isUpgrade() {
2863         return isDeviceUpgrading();
2864     }
2865 
2866     @Override
isDeviceUpgrading()2867     public boolean isDeviceUpgrading() {
2868         try {
2869             return mPM.isDeviceUpgrading();
2870         } catch (RemoteException e) {
2871             throw e.rethrowFromSystemServer();
2872         }
2873     }
2874 
2875     @Override
getPackageInstaller()2876     public PackageInstaller getPackageInstaller() {
2877         synchronized (mLock) {
2878             if (mInstaller == null) {
2879                 try {
2880                     mInstaller = new PackageInstaller(mPM.getPackageInstaller(),
2881                             mContext.getPackageName(), getUserId());
2882                 } catch (RemoteException e) {
2883                     throw e.rethrowFromSystemServer();
2884                 }
2885             }
2886             return mInstaller;
2887         }
2888     }
2889 
2890     @Override
isPackageAvailable(String packageName)2891     public boolean isPackageAvailable(String packageName) {
2892         try {
2893             return mPM.isPackageAvailable(packageName, getUserId());
2894         } catch (RemoteException e) {
2895             throw e.rethrowFromSystemServer();
2896         }
2897     }
2898 
2899     /**
2900      * @hide
2901      */
2902     @Override
addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId, int flags)2903     public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
2904             int flags) {
2905         try {
2906             mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
2907                     sourceUserId, targetUserId, flags);
2908         } catch (RemoteException e) {
2909             throw e.rethrowFromSystemServer();
2910         }
2911     }
2912 
2913     /**
2914      * @hide
2915      */
2916     @Override
clearCrossProfileIntentFilters(int sourceUserId)2917     public void clearCrossProfileIntentFilters(int sourceUserId) {
2918         try {
2919             mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
2920         } catch (RemoteException e) {
2921             throw e.rethrowFromSystemServer();
2922         }
2923     }
2924 
2925     /**
2926      * @hide
2927      */
loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo)2928     public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
2929         Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
2930         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
2931             return dr;
2932         }
2933         return getUserBadgedIcon(dr, new UserHandle(getUserId()));
2934     }
2935 
2936     /**
2937      * @hide
2938      */
loadUnbadgedItemIcon(@onNull PackageItemInfo itemInfo, @Nullable ApplicationInfo appInfo)2939     public Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo,
2940             @Nullable ApplicationInfo appInfo) {
2941         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
2942             // Indicates itemInfo is for a different user (e.g. a profile's parent), so use a
2943             // generic user icon (users generally lack permission to view each other's actual icons)
2944             int targetUserId = itemInfo.showUserIcon;
2945             return UserIcons.getDefaultUserIcon(
2946                     mContext.getResources(), targetUserId, /* light= */ false);
2947         }
2948         Drawable dr = null;
2949         if (itemInfo.packageName != null) {
2950             dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
2951         }
2952         if (dr == null && itemInfo != appInfo && appInfo != null) {
2953             dr = loadUnbadgedItemIcon(appInfo, appInfo);
2954         }
2955         if (dr == null) {
2956             dr = itemInfo.loadDefaultIcon(this);
2957         }
2958         return dr;
2959     }
2960 
getBadgedDrawable(Drawable drawable, Drawable badgeDrawable, Rect badgeLocation, boolean tryBadgeInPlace)2961     private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
2962             Rect badgeLocation, boolean tryBadgeInPlace) {
2963         final int badgedWidth = drawable.getIntrinsicWidth();
2964         final int badgedHeight = drawable.getIntrinsicHeight();
2965         final boolean canBadgeInPlace = tryBadgeInPlace
2966                 && (drawable instanceof BitmapDrawable)
2967                 && ((BitmapDrawable) drawable).getBitmap().isMutable();
2968 
2969         final Bitmap bitmap;
2970         if (canBadgeInPlace) {
2971             bitmap = ((BitmapDrawable) drawable).getBitmap();
2972         } else {
2973             bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
2974         }
2975         Canvas canvas = new Canvas(bitmap);
2976 
2977         if (!canBadgeInPlace) {
2978             drawable.setBounds(0, 0, badgedWidth, badgedHeight);
2979             drawable.draw(canvas);
2980         }
2981 
2982         if (badgeLocation != null) {
2983             if (badgeLocation.left < 0 || badgeLocation.top < 0
2984                     || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
2985                 throw new IllegalArgumentException("Badge location " + badgeLocation
2986                         + " not in badged drawable bounds "
2987                         + new Rect(0, 0, badgedWidth, badgedHeight));
2988             }
2989             badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
2990 
2991             canvas.save();
2992             canvas.translate(badgeLocation.left, badgeLocation.top);
2993             badgeDrawable.draw(canvas);
2994             canvas.restore();
2995         } else {
2996             badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
2997             badgeDrawable.draw(canvas);
2998         }
2999 
3000         if (!canBadgeInPlace) {
3001             BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
3002 
3003             if (drawable instanceof BitmapDrawable) {
3004                 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
3005                 mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
3006             }
3007 
3008             return mergedDrawable;
3009         }
3010 
3011         return drawable;
3012     }
3013 
hasUserBadge(int userId)3014     private boolean hasUserBadge(int userId) {
3015         return getUserManager().hasBadge(userId);
3016     }
3017 
3018     /**
3019      * @hide
3020      */
3021     @Override
getInstallReason(String packageName, UserHandle user)3022     public int getInstallReason(String packageName, UserHandle user) {
3023         try {
3024             return mPM.getInstallReason(packageName, user.getIdentifier());
3025         } catch (RemoteException e) {
3026             throw e.rethrowFromSystemServer();
3027         }
3028     }
3029 
3030     /** {@hide} */
3031     private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
3032             Handler.Callback {
3033         private static final int MSG_CREATED = 1;
3034         private static final int MSG_STATUS_CHANGED = 2;
3035 
3036         final MoveCallback mCallback;
3037         final Handler mHandler;
3038 
MoveCallbackDelegate(MoveCallback callback, Looper looper)3039         public MoveCallbackDelegate(MoveCallback callback, Looper looper) {
3040             mCallback = callback;
3041             mHandler = new Handler(looper, this);
3042         }
3043 
3044         @Override
handleMessage(Message msg)3045         public boolean handleMessage(Message msg) {
3046             switch (msg.what) {
3047                 case MSG_CREATED: {
3048                     final SomeArgs args = (SomeArgs) msg.obj;
3049                     mCallback.onCreated(args.argi1, (Bundle) args.arg2);
3050                     args.recycle();
3051                     return true;
3052                 }
3053                 case MSG_STATUS_CHANGED: {
3054                     final SomeArgs args = (SomeArgs) msg.obj;
3055                     mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
3056                     args.recycle();
3057                     return true;
3058                 }
3059             }
3060             return false;
3061         }
3062 
3063         @Override
onCreated(int moveId, Bundle extras)3064         public void onCreated(int moveId, Bundle extras) {
3065             final SomeArgs args = SomeArgs.obtain();
3066             args.argi1 = moveId;
3067             args.arg2 = extras;
3068             mHandler.obtainMessage(MSG_CREATED, args).sendToTarget();
3069         }
3070 
3071         @Override
onStatusChanged(int moveId, int status, long estMillis)3072         public void onStatusChanged(int moveId, int status, long estMillis) {
3073             final SomeArgs args = SomeArgs.obtain();
3074             args.argi1 = moveId;
3075             args.argi2 = status;
3076             args.arg3 = estMillis;
3077             mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
3078         }
3079     }
3080 
3081     private final ContextImpl mContext;
3082     @UnsupportedAppUsage
3083     private final IPackageManager mPM;
3084     private final IPermissionManager mPermissionManager;
3085 
3086     /** Assume locked until we hear otherwise */
3087     private volatile boolean mUserUnlocked = false;
3088 
3089     private static final Object sSync = new Object();
3090     private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
3091             = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
3092     private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
3093             = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
3094 
3095     private final Map<OnPermissionsChangedListener, IOnPermissionsChangeListener>
3096             mPermissionListeners = new ArrayMap<>();
3097 
3098     public class OnPermissionsChangeListenerDelegate extends IOnPermissionsChangeListener.Stub
3099             implements Handler.Callback{
3100         private static final int MSG_PERMISSIONS_CHANGED = 1;
3101 
3102         private final OnPermissionsChangedListener mListener;
3103         private final Handler mHandler;
3104 
3105 
OnPermissionsChangeListenerDelegate(OnPermissionsChangedListener listener, Looper looper)3106         public OnPermissionsChangeListenerDelegate(OnPermissionsChangedListener listener,
3107                 Looper looper) {
3108             mListener = listener;
3109             mHandler = new Handler(looper, this);
3110         }
3111 
3112         @Override
onPermissionsChanged(int uid)3113         public void onPermissionsChanged(int uid) {
3114             mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
3115         }
3116 
3117         @Override
handleMessage(Message msg)3118         public boolean handleMessage(Message msg) {
3119             switch (msg.what) {
3120                 case MSG_PERMISSIONS_CHANGED: {
3121                     final int uid = msg.arg1;
3122                     mListener.onPermissionsChanged(uid);
3123                     return true;
3124                 }
3125             }
3126             return false;
3127         }
3128     }
3129 
3130     @Override
canRequestPackageInstalls()3131     public boolean canRequestPackageInstalls() {
3132         try {
3133             return mPM.canRequestPackageInstalls(mContext.getPackageName(), getUserId());
3134         } catch (RemoteException e) {
3135             throw e.rethrowAsRuntimeException();
3136         }
3137     }
3138 
3139     @Override
getInstantAppResolverSettingsComponent()3140     public ComponentName getInstantAppResolverSettingsComponent() {
3141         try {
3142             return mPM.getInstantAppResolverSettingsComponent();
3143         } catch (RemoteException e) {
3144             throw e.rethrowAsRuntimeException();
3145         }
3146     }
3147 
3148     @Override
getInstantAppInstallerComponent()3149     public ComponentName getInstantAppInstallerComponent() {
3150         try {
3151             return mPM.getInstantAppInstallerComponent();
3152         } catch (RemoteException e) {
3153             throw e.rethrowAsRuntimeException();
3154         }
3155     }
3156 
3157     @Override
getInstantAppAndroidId(String packageName, UserHandle user)3158     public String getInstantAppAndroidId(String packageName, UserHandle user) {
3159         try {
3160             return mPM.getInstantAppAndroidId(packageName, user.getIdentifier());
3161         } catch (RemoteException e) {
3162             throw e.rethrowAsRuntimeException();
3163         }
3164     }
3165 
3166     private static class DexModuleRegisterResult {
3167         final String dexModulePath;
3168         final boolean success;
3169         final String message;
3170 
DexModuleRegisterResult(String dexModulePath, boolean success, String message)3171         private DexModuleRegisterResult(String dexModulePath, boolean success, String message) {
3172             this.dexModulePath = dexModulePath;
3173             this.success = success;
3174             this.message = message;
3175         }
3176     }
3177 
3178     private static class DexModuleRegisterCallbackDelegate
3179             extends android.content.pm.IDexModuleRegisterCallback.Stub
3180             implements Handler.Callback {
3181         private static final int MSG_DEX_MODULE_REGISTERED = 1;
3182         private final DexModuleRegisterCallback callback;
3183         private final Handler mHandler;
3184 
DexModuleRegisterCallbackDelegate(@onNull DexModuleRegisterCallback callback)3185         DexModuleRegisterCallbackDelegate(@NonNull DexModuleRegisterCallback callback) {
3186             this.callback = callback;
3187             mHandler = new Handler(Looper.getMainLooper(), this);
3188         }
3189 
3190         @Override
onDexModuleRegistered(@onNull String dexModulePath, boolean success, @Nullable String message)3191         public void onDexModuleRegistered(@NonNull String dexModulePath, boolean success,
3192                 @Nullable String message)throws RemoteException {
3193             mHandler.obtainMessage(MSG_DEX_MODULE_REGISTERED,
3194                     new DexModuleRegisterResult(dexModulePath, success, message)).sendToTarget();
3195         }
3196 
3197         @Override
handleMessage(Message msg)3198         public boolean handleMessage(Message msg) {
3199             if (msg.what != MSG_DEX_MODULE_REGISTERED) {
3200                 return false;
3201             }
3202             DexModuleRegisterResult result = (DexModuleRegisterResult)msg.obj;
3203             callback.onDexModuleRegistered(result.dexModulePath, result.success, result.message);
3204             return true;
3205         }
3206     }
3207 
3208     @Override
registerDexModule(@onNull String dexModule, @Nullable DexModuleRegisterCallback callback)3209     public void registerDexModule(@NonNull String dexModule,
3210             @Nullable DexModuleRegisterCallback callback) {
3211         // Check if this is a shared module by looking if the others can read it.
3212         boolean isSharedModule = false;
3213         try {
3214             StructStat stat = Os.stat(dexModule);
3215             if ((OsConstants.S_IROTH & stat.st_mode) != 0) {
3216                 isSharedModule = true;
3217             }
3218         } catch (ErrnoException e) {
3219             callback.onDexModuleRegistered(dexModule, false,
3220                     "Could not get stat the module file: " + e.getMessage());
3221             return;
3222         }
3223 
3224         // Module path is ok.
3225         // Create the callback delegate to be passed to package manager service.
3226         DexModuleRegisterCallbackDelegate callbackDelegate = null;
3227         if (callback != null) {
3228             callbackDelegate = new DexModuleRegisterCallbackDelegate(callback);
3229         }
3230 
3231         // Invoke the package manager service.
3232         try {
3233             mPM.registerDexModule(mContext.getPackageName(), dexModule,
3234                     isSharedModule, callbackDelegate);
3235         } catch (RemoteException e) {
3236             throw e.rethrowAsRuntimeException();
3237         }
3238     }
3239 
3240     @Override
getHarmfulAppWarning(String packageName)3241     public CharSequence getHarmfulAppWarning(String packageName) {
3242         try {
3243             return mPM.getHarmfulAppWarning(packageName, getUserId());
3244         } catch (RemoteException e) {
3245             throw e.rethrowAsRuntimeException();
3246         }
3247     }
3248 
3249     @Override
setHarmfulAppWarning(String packageName, CharSequence warning)3250     public void setHarmfulAppWarning(String packageName, CharSequence warning) {
3251         try {
3252             mPM.setHarmfulAppWarning(packageName, warning, getUserId());
3253         } catch (RemoteException e) {
3254             throw e.rethrowAsRuntimeException();
3255         }
3256     }
3257 
3258     @Override
getArtManager()3259     public ArtManager getArtManager() {
3260         synchronized (mLock) {
3261             if (mArtManager == null) {
3262                 try {
3263                     mArtManager = new ArtManager(mContext, mPM.getArtManager());
3264                 } catch (RemoteException e) {
3265                     throw e.rethrowFromSystemServer();
3266                 }
3267             }
3268             return mArtManager;
3269         }
3270     }
3271 
3272     @Override
getDefaultTextClassifierPackageName()3273     public String getDefaultTextClassifierPackageName() {
3274         try {
3275             return mPM.getDefaultTextClassifierPackageName();
3276         } catch (RemoteException e) {
3277             throw e.rethrowAsRuntimeException();
3278         }
3279     }
3280 
3281     @Override
getSystemTextClassifierPackageName()3282     public String getSystemTextClassifierPackageName() {
3283         try {
3284             return mPM.getSystemTextClassifierPackageName();
3285         } catch (RemoteException e) {
3286             throw e.rethrowAsRuntimeException();
3287         }
3288     }
3289 
3290     @Override
getAttentionServicePackageName()3291     public String getAttentionServicePackageName() {
3292         try {
3293             return mPM.getAttentionServicePackageName();
3294         } catch (RemoteException e) {
3295             throw e.rethrowAsRuntimeException();
3296         }
3297     }
3298 
3299     @Override
getWellbeingPackageName()3300     public String getWellbeingPackageName() {
3301         try {
3302             return mPM.getWellbeingPackageName();
3303         } catch (RemoteException e) {
3304             throw e.rethrowAsRuntimeException();
3305         }
3306     }
3307 
3308     @Override
getAppPredictionServicePackageName()3309     public String getAppPredictionServicePackageName() {
3310         try {
3311             return mPM.getAppPredictionServicePackageName();
3312         } catch (RemoteException e) {
3313             throw e.rethrowAsRuntimeException();
3314         }
3315     }
3316 
3317     @Override
getSystemCaptionsServicePackageName()3318     public String getSystemCaptionsServicePackageName() {
3319         try {
3320             return mPM.getSystemCaptionsServicePackageName();
3321         } catch (RemoteException e) {
3322             throw e.rethrowAsRuntimeException();
3323         }
3324     }
3325 
3326     @Override
getSetupWizardPackageName()3327     public String getSetupWizardPackageName() {
3328         try {
3329             return mPM.getSetupWizardPackageName();
3330         } catch (RemoteException e) {
3331             throw e.rethrowAsRuntimeException();
3332         }
3333     }
3334 
3335     @Override
getIncidentReportApproverPackageName()3336     public String getIncidentReportApproverPackageName() {
3337         try {
3338             return mPM.getIncidentReportApproverPackageName();
3339         } catch (RemoteException e) {
3340             throw e.rethrowAsRuntimeException();
3341         }
3342     }
3343 
3344     @Override
getContentCaptureServicePackageName()3345     public String getContentCaptureServicePackageName() {
3346         try {
3347             return mPM.getContentCaptureServicePackageName();
3348         } catch (RemoteException e) {
3349             throw e.rethrowAsRuntimeException();
3350         }
3351     }
3352 
3353     @Override
isPackageStateProtected(String packageName, int userId)3354     public boolean isPackageStateProtected(String packageName, int userId) {
3355         try {
3356             return mPM.isPackageStateProtected(packageName, userId);
3357         } catch (RemoteException e) {
3358             throw e.rethrowAsRuntimeException();
3359         }
3360     }
3361 
sendDeviceCustomizationReadyBroadcast()3362     public void sendDeviceCustomizationReadyBroadcast() {
3363         try {
3364             mPM.sendDeviceCustomizationReadyBroadcast();
3365         } catch (RemoteException e) {
3366             throw e.rethrowAsRuntimeException();
3367         }
3368     }
3369 
3370     @Override
isAutoRevokeWhitelisted()3371     public boolean isAutoRevokeWhitelisted() {
3372         try {
3373             return mPM.isAutoRevokeWhitelisted(mContext.getPackageName());
3374         } catch (RemoteException e) {
3375             throw e.rethrowAsRuntimeException();
3376         }
3377     }
3378 
3379     @Override
setMimeGroup(String mimeGroup, Set<String> mimeTypes)3380     public void setMimeGroup(String mimeGroup, Set<String> mimeTypes) {
3381         try {
3382             mPM.setMimeGroup(mContext.getPackageName(), mimeGroup, new ArrayList<>(mimeTypes));
3383         } catch (RemoteException e) {
3384             throw e.rethrowAsRuntimeException();
3385         }
3386     }
3387 
3388     @NonNull
3389     @Override
getMimeGroup(String group)3390     public Set<String> getMimeGroup(String group) {
3391         try {
3392             List<String> mimeGroup = mPM.getMimeGroup(mContext.getPackageName(), group);
3393             return new ArraySet<>(mimeGroup);
3394         } catch (RemoteException e) {
3395             throw e.rethrowAsRuntimeException();
3396         }
3397     }
3398 }
3399