• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app;
18 
19 import static android.app.PropertyInvalidatedCache.MODULE_SYSTEM;
20 import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_COLORED;
21 import static android.app.admin.DevicePolicyResources.Drawables.Style.SOLID_NOT_COLORED;
22 import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON;
23 import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON_BADGE;
24 import static android.app.admin.DevicePolicyResources.UNDEFINED;
25 import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256;
26 import static android.content.pm.Checksum.TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512;
27 import static android.content.pm.Checksum.TYPE_WHOLE_MD5;
28 import static android.content.pm.Checksum.TYPE_WHOLE_MERKLE_ROOT_4K_SHA256;
29 import static android.content.pm.Checksum.TYPE_WHOLE_SHA1;
30 import static android.content.pm.Checksum.TYPE_WHOLE_SHA256;
31 import static android.content.pm.Checksum.TYPE_WHOLE_SHA512;
32 
33 import android.annotation.CallbackExecutor;
34 import android.annotation.DrawableRes;
35 import android.annotation.NonNull;
36 import android.annotation.Nullable;
37 import android.annotation.StringRes;
38 import android.annotation.UserIdInt;
39 import android.annotation.XmlRes;
40 import android.app.admin.DevicePolicyManager;
41 import android.app.role.RoleManager;
42 import android.compat.annotation.UnsupportedAppUsage;
43 import android.content.ComponentName;
44 import android.content.ContentResolver;
45 import android.content.Context;
46 import android.content.Intent;
47 import android.content.IntentFilter;
48 import android.content.IntentSender;
49 import android.content.pm.ActivityInfo;
50 import android.content.pm.ApkChecksum;
51 import android.content.pm.ApplicationInfo;
52 import android.content.pm.ArchivedPackageInfo;
53 import android.content.pm.ChangedPackages;
54 import android.content.pm.Checksum;
55 import android.content.pm.ComponentInfo;
56 import android.content.pm.FeatureInfo;
57 import android.content.pm.IOnChecksumsReadyListener;
58 import android.content.pm.IPackageDataObserver;
59 import android.content.pm.IPackageDeleteObserver;
60 import android.content.pm.IPackageManager;
61 import android.content.pm.IPackageMoveObserver;
62 import android.content.pm.IPackageStatsObserver;
63 import android.content.pm.InstallSourceInfo;
64 import android.content.pm.InstantAppInfo;
65 import android.content.pm.InstrumentationInfo;
66 import android.content.pm.IntentFilterVerificationInfo;
67 import android.content.pm.KeySet;
68 import android.content.pm.ModuleInfo;
69 import android.content.pm.PackageInfo;
70 import android.content.pm.PackageInstaller;
71 import android.content.pm.PackageItemInfo;
72 import android.content.pm.PackageManager;
73 import android.content.pm.ParceledListSlice;
74 import android.content.pm.PermissionGroupInfo;
75 import android.content.pm.PermissionInfo;
76 import android.content.pm.ProviderInfo;
77 import android.content.pm.ResolveInfo;
78 import android.content.pm.ServiceInfo;
79 import android.content.pm.SharedLibraryInfo;
80 import android.content.pm.SuspendDialogInfo;
81 import android.content.pm.SystemFeaturesCache;
82 import android.content.pm.VerifierDeviceIdentity;
83 import android.content.pm.VersionedPackage;
84 import android.content.pm.dex.ArtManager;
85 import android.content.pm.parsing.ApkLiteParseUtils;
86 import android.content.res.ApkAssets;
87 import android.content.res.Configuration;
88 import android.content.res.Resources;
89 import android.content.res.TypedArray;
90 import android.content.res.XmlResourceParser;
91 import android.graphics.Bitmap;
92 import android.graphics.Canvas;
93 import android.graphics.Rect;
94 import android.graphics.drawable.BitmapDrawable;
95 import android.graphics.drawable.Drawable;
96 import android.graphics.drawable.LayerDrawable;
97 import android.os.Build;
98 import android.os.Bundle;
99 import android.os.Handler;
100 import android.os.IRemoteCallback;
101 import android.os.Looper;
102 import android.os.Message;
103 import android.os.ParcelFileDescriptor;
104 import android.os.ParcelableException;
105 import android.os.PersistableBundle;
106 import android.os.Process;
107 import android.os.RemoteException;
108 import android.os.StrictMode;
109 import android.os.SystemProperties;
110 import android.os.UserHandle;
111 import android.os.UserManager;
112 import android.os.storage.StorageManager;
113 import android.os.storage.VolumeInfo;
114 import android.permission.PermissionControllerManager;
115 import android.permission.PermissionManager;
116 import android.provider.Settings;
117 import android.ravenwood.annotation.RavenwoodKeepPartialClass;
118 import android.ravenwood.annotation.RavenwoodReplace;
119 import android.system.ErrnoException;
120 import android.system.Os;
121 import android.system.OsConstants;
122 import android.system.StructStat;
123 import android.text.TextUtils;
124 import android.util.ArrayMap;
125 import android.util.ArraySet;
126 import android.util.AttributeSet;
127 import android.util.LauncherIcons;
128 import android.util.Log;
129 import android.util.Slog;
130 import android.util.Xml;
131 
132 import com.android.internal.annotations.GuardedBy;
133 import com.android.internal.annotations.VisibleForTesting;
134 import com.android.internal.os.SomeArgs;
135 import com.android.internal.pm.RoSystemFeatures;
136 import com.android.internal.util.UserIcons;
137 
138 import dalvik.system.VMRuntime;
139 
140 import libcore.util.EmptyArray;
141 
142 import org.xmlpull.v1.XmlPullParser;
143 import org.xmlpull.v1.XmlPullParserException;
144 
145 import java.io.File;
146 import java.io.IOException;
147 import java.io.InputStream;
148 import java.lang.ref.WeakReference;
149 import java.security.cert.Certificate;
150 import java.security.cert.CertificateEncodingException;
151 import java.security.cert.X509Certificate;
152 import java.util.ArrayList;
153 import java.util.Arrays;
154 import java.util.Collections;
155 import java.util.Iterator;
156 import java.util.List;
157 import java.util.Objects;
158 import java.util.Set;
159 import java.util.concurrent.Executor;
160 import java.util.function.Consumer;
161 import java.util.function.Function;
162 
163 /** @hide */
164 @RavenwoodKeepPartialClass
165 public class ApplicationPackageManager extends PackageManager {
166     private static final String TAG = "ApplicationPackageManager";
167     private static final boolean DEBUG_ICONS = false;
168 
169     private static final int DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES = 16384; // 16KB
170 
171     // Default flags to use with PackageManager when no flags are given.
172     private static final int sDefaultFlags = GET_SHARED_LIBRARY_FILES;
173 
174     /** Default set of checksums - includes all available checksums.
175      * @see PackageManager#requestChecksums  */
176     private static final int DEFAULT_CHECKSUMS =
177             TYPE_WHOLE_MERKLE_ROOT_4K_SHA256 | TYPE_WHOLE_MD5 | TYPE_WHOLE_SHA1 | TYPE_WHOLE_SHA256
178                     | TYPE_WHOLE_SHA512 | TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256
179                     | TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512;
180 
181     // Name of the resource which provides background permission button string
182     public static final String APP_PERMISSION_BUTTON_ALLOW_ALWAYS =
183             "app_permission_button_allow_always";
184 
185     // Name of the package which the permission controller's resources are in.
186     public static final String PERMISSION_CONTROLLER_RESOURCE_PACKAGE =
187             "com.android.permissioncontroller";
188 
189     private volatile UserManager mUserManager;
190     private volatile PermissionManager mPermissionManager;
191     private volatile PackageInstaller mInstaller;
192     private volatile ArtManager mArtManager;
193     private volatile DevicePolicyManager mDevicePolicyManager;
194     private volatile String mPermissionsControllerPackageName;
195 
196     @GuardedBy("mDelegates")
197     private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();
198 
199     @NonNull
200     @GuardedBy("mPackageMonitorCallbacks")
201     private final ArraySet<IRemoteCallback> mPackageMonitorCallbacks = new ArraySet<>();
202 
203     private final boolean mUseSystemFeaturesCache;
204 
getUserManager()205     UserManager getUserManager() {
206         if (mUserManager == null) {
207             mUserManager = UserManager.get(mContext);
208         }
209         return mUserManager;
210     }
211 
getDevicePolicyManager()212     DevicePolicyManager getDevicePolicyManager() {
213         if (mDevicePolicyManager == null) {
214             mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
215         }
216         return mDevicePolicyManager;
217     }
218 
getPermissionManager()219     private PermissionManager getPermissionManager() {
220         if (mPermissionManager == null) {
221             mPermissionManager = mContext.getSystemService(PermissionManager.class);
222         }
223         return mPermissionManager;
224     }
225 
226     @Override
getUserId()227     public int getUserId() {
228         return mContext.getUserId();
229     }
230 
231     @Override
getPackageInfo(String packageName, int flags)232     public PackageInfo getPackageInfo(String packageName, int flags)
233             throws NameNotFoundException {
234         return getPackageInfo(packageName, PackageInfoFlags.of(flags));
235     }
236 
237     @Override
getPackageInfo(String packageName, PackageInfoFlags flags)238     public PackageInfo getPackageInfo(String packageName, PackageInfoFlags flags)
239             throws NameNotFoundException {
240         return getPackageInfoAsUser(packageName, flags, getUserId());
241     }
242 
243     @Override
getPackageInfo(VersionedPackage versionedPackage, int flags)244     public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags)
245             throws NameNotFoundException {
246         return getPackageInfo(versionedPackage, PackageInfoFlags.of(flags));
247     }
248 
249     @Override
getPackageInfo(VersionedPackage versionedPackage, PackageInfoFlags flags)250     public PackageInfo getPackageInfo(VersionedPackage versionedPackage, PackageInfoFlags flags)
251             throws NameNotFoundException {
252         final int userId = getUserId();
253         try {
254             PackageInfo pi = mPM.getPackageInfoVersioned(versionedPackage,
255                     updateFlagsForPackage(flags.getValue(), userId), userId);
256             if (pi != null) {
257                 return pi;
258             }
259         } catch (RemoteException e) {
260             throw e.rethrowFromSystemServer();
261         }
262         throw new NameNotFoundException(versionedPackage.toString());
263     }
264 
265     @Override
getPackageInfoAsUser(String packageName, int flags, int userId)266     public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
267             throws NameNotFoundException {
268         return getPackageInfoAsUser(packageName, PackageInfoFlags.of(flags), userId);
269     }
270 
271     @Override
getPackageInfoAsUser(String packageName, PackageInfoFlags flags, int userId)272     public PackageInfo getPackageInfoAsUser(String packageName, PackageInfoFlags flags, int userId)
273             throws NameNotFoundException {
274         PackageInfo pi =
275                 getPackageInfoAsUserCached(
276                         packageName,
277                         updateFlagsForPackage(flags.getValue(), userId),
278                         userId);
279         if (pi == null) {
280             throw new NameNotFoundException(packageName);
281         }
282         return pi;
283     }
284 
285     @Override
currentToCanonicalPackageNames(String[] names)286     public String[] currentToCanonicalPackageNames(String[] names) {
287         try {
288             return mPM.currentToCanonicalPackageNames(names);
289         } catch (RemoteException e) {
290             throw e.rethrowFromSystemServer();
291         }
292     }
293 
294     @Override
canonicalToCurrentPackageNames(String[] names)295     public String[] canonicalToCurrentPackageNames(String[] names) {
296         try {
297             return mPM.canonicalToCurrentPackageNames(names);
298         } catch (RemoteException e) {
299             throw e.rethrowFromSystemServer();
300         }
301     }
302 
303     @Override
getLaunchIntentForPackage(String packageName)304     public Intent getLaunchIntentForPackage(String packageName) {
305         return getLaunchIntentForPackage(packageName, false);
306     }
307 
308     @Override
309     @Nullable
getLaunchIntentForPackage(@onNull String packageName, boolean includeDirectBootUnaware)310     public Intent getLaunchIntentForPackage(@NonNull String packageName,
311             boolean includeDirectBootUnaware) {
312         ResolveInfoFlags queryFlags = ResolveInfoFlags.of(
313                 includeDirectBootUnaware ? MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE : 0);
314 
315         // First see if the package has an INFO activity; the existence of
316         // such an activity is implied to be the desired front-door for the
317         // overall package (such as if it has multiple launcher entries).
318         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
319         intentToResolve.addCategory(Intent.CATEGORY_INFO);
320         intentToResolve.setPackage(packageName);
321         List<ResolveInfo> ris = queryIntentActivities(intentToResolve, queryFlags);
322 
323         // Otherwise, try to find a main launcher activity.
324         if (ris == null || ris.size() <= 0) {
325             // reuse the intent instance
326             intentToResolve.removeCategory(Intent.CATEGORY_INFO);
327             intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
328             intentToResolve.setPackage(packageName);
329             ris = queryIntentActivities(intentToResolve, queryFlags);
330         }
331         if (ris == null || ris.size() <= 0) {
332             return null;
333         }
334         Intent intent = new Intent(intentToResolve);
335         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
336         intent.setClassName(ris.get(0).activityInfo.packageName,
337                 ris.get(0).activityInfo.name);
338         return intent;
339     }
340 
341     @Override
getLeanbackLaunchIntentForPackage(String packageName)342     public Intent getLeanbackLaunchIntentForPackage(String packageName) {
343         return getLaunchIntentForPackageAndCategory(packageName, Intent.CATEGORY_LEANBACK_LAUNCHER);
344     }
345 
346     @Override
getCarLaunchIntentForPackage(String packageName)347     public Intent getCarLaunchIntentForPackage(String packageName) {
348         return getLaunchIntentForPackageAndCategory(packageName, Intent.CATEGORY_CAR_LAUNCHER);
349     }
350 
getLaunchIntentForPackageAndCategory(String packageName, String category)351     private Intent getLaunchIntentForPackageAndCategory(String packageName, String category) {
352         // Try to find a main launcher activity for the given categories.
353         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
354         intentToResolve.addCategory(category);
355         intentToResolve.setPackage(packageName);
356         List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
357 
358         if (ris == null || ris.size() <= 0) {
359             return null;
360         }
361         Intent intent = new Intent(intentToResolve);
362         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
363         intent.setClassName(ris.get(0).activityInfo.packageName,
364                 ris.get(0).activityInfo.name);
365         return intent;
366     }
367 
368     @Override
getLaunchIntentSenderForPackage(@onNull String packageName)369     public @NonNull IntentSender getLaunchIntentSenderForPackage(@NonNull String packageName) {
370         try {
371             return mPM.getLaunchIntentSenderForPackage(packageName, mContext.getPackageName(),
372                     mContext.getAttributionTag(), getUserId());
373         } catch (RemoteException e) {
374             throw e.rethrowFromSystemServer();
375         }
376     }
377 
378     @Override
getPackageGids(String packageName)379     public int[] getPackageGids(String packageName) throws NameNotFoundException {
380         return getPackageGids(packageName, 0);
381     }
382 
383     @Override
getPackageGids(String packageName, int flags)384     public int[] getPackageGids(String packageName, int flags)
385             throws NameNotFoundException {
386         return getPackageGids(packageName, PackageInfoFlags.of(flags));
387     }
388 
389     @Override
getPackageGids(String packageName, PackageInfoFlags flags)390     public int[] getPackageGids(String packageName, PackageInfoFlags flags)
391             throws NameNotFoundException {
392         final int userId = getUserId();
393         try {
394             int[] gids = mPM.getPackageGids(packageName,
395                     updateFlagsForPackage(flags.getValue(), userId), userId);
396             if (gids != null) {
397                 return gids;
398             }
399         } catch (RemoteException e) {
400             throw e.rethrowFromSystemServer();
401         }
402 
403         throw new NameNotFoundException(packageName);
404     }
405 
406     @Override
getPackageUid(String packageName, int flags)407     public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
408         return getPackageUid(packageName, PackageInfoFlags.of(flags));
409     }
410 
411     @Override
getPackageUid(String packageName, PackageInfoFlags flags)412     public int getPackageUid(String packageName, PackageInfoFlags flags)
413             throws NameNotFoundException {
414         return getPackageUidAsUser(packageName, flags, getUserId());
415     }
416 
417     @Override
getPackageUidAsUser(String packageName, int userId)418     public int getPackageUidAsUser(String packageName, int userId) throws NameNotFoundException {
419         return getPackageUidAsUser(packageName, 0, userId);
420     }
421 
422     @Override
getPackageUidAsUser(String packageName, int flags, int userId)423     public int getPackageUidAsUser(String packageName, int flags, int userId)
424             throws NameNotFoundException {
425         return getPackageUidAsUser(packageName, PackageInfoFlags.of(flags), userId);
426     }
427 
428     @Override
getPackageUidAsUser(String packageName, PackageInfoFlags flags, int userId)429     public int getPackageUidAsUser(String packageName, PackageInfoFlags flags, int userId)
430             throws NameNotFoundException {
431         try {
432             int uid = mPM.getPackageUid(packageName,
433                     updateFlagsForPackage(flags.getValue(), userId), userId);
434             if (uid >= 0) {
435                 return uid;
436             }
437         } catch (RemoteException e) {
438             throw e.rethrowFromSystemServer();
439         }
440 
441         throw new NameNotFoundException(packageName);
442     }
443 
444     @Override
445     @SuppressWarnings("unchecked")
getAllPermissionGroups(int flags)446     public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
447         return getPermissionManager().getAllPermissionGroups(flags);
448     }
449 
450     @Override
getPermissionGroupInfo(String groupName, int flags)451     public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags)
452             throws NameNotFoundException {
453         final PermissionGroupInfo permissionGroupInfo = getPermissionManager()
454                 .getPermissionGroupInfo(groupName, flags);
455         if (permissionGroupInfo == null) {
456             throw new NameNotFoundException(groupName);
457         }
458         return permissionGroupInfo;
459     }
460 
461     @Override
getPermissionInfo(String permName, int flags)462     public PermissionInfo getPermissionInfo(String permName, int flags)
463             throws NameNotFoundException {
464         final PermissionInfo permissionInfo = getPermissionManager().getPermissionInfo(permName,
465                 flags);
466         if (permissionInfo == null) {
467             throw new NameNotFoundException(permName);
468         }
469         return permissionInfo;
470     }
471 
472     @Override
473     @SuppressWarnings("unchecked")
queryPermissionsByGroup(String groupName, int flags)474     public List<PermissionInfo> queryPermissionsByGroup(String groupName, int flags)
475             throws NameNotFoundException {
476         final List<PermissionInfo> permissionInfos = getPermissionManager().queryPermissionsByGroup(
477                 groupName, flags);
478         if (permissionInfos == null) {
479             throw new NameNotFoundException(groupName);
480         }
481         return permissionInfos;
482     }
483 
484     @Override
getPlatformPermissionsForGroup(@onNull String permissionGroupName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<List<String>> callback)485     public void getPlatformPermissionsForGroup(@NonNull String permissionGroupName,
486             @NonNull @CallbackExecutor Executor executor,
487             @NonNull Consumer<List<String>> callback) {
488         final PermissionControllerManager permissionControllerManager = mContext.getSystemService(
489                 PermissionControllerManager.class);
490         permissionControllerManager.getPlatformPermissionsForGroup(permissionGroupName, executor,
491                 callback);
492     }
493 
494     @Override
getGroupOfPlatformPermission(@onNull String permissionName, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<String> callback)495     public void getGroupOfPlatformPermission(@NonNull String permissionName,
496             @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<String> callback) {
497         final PermissionControllerManager permissionControllerManager = mContext.getSystemService(
498                 PermissionControllerManager.class);
499         permissionControllerManager.getGroupOfPlatformPermission(permissionName, executor,
500                 callback);
501     }
502 
503     @Override
arePermissionsIndividuallyControlled()504     public boolean arePermissionsIndividuallyControlled() {
505         return mContext.getResources().getBoolean(
506                 com.android.internal.R.bool.config_permissionsIndividuallyControlled);
507     }
508 
509     @Override
isWirelessConsentModeEnabled()510     public boolean isWirelessConsentModeEnabled() {
511         return mContext.getResources().getBoolean(
512                 com.android.internal.R.bool.config_wirelessConsentRequired);
513     }
514 
515     @Override
getApplicationInfo(String packageName, int flags)516     public ApplicationInfo getApplicationInfo(String packageName, int flags)
517             throws NameNotFoundException {
518         return getApplicationInfo(packageName, ApplicationInfoFlags.of(flags));
519     }
520 
521     @Override
getApplicationInfo(String packageName, ApplicationInfoFlags flags)522     public ApplicationInfo getApplicationInfo(String packageName, ApplicationInfoFlags flags)
523             throws NameNotFoundException {
524         return getApplicationInfoAsUser(packageName, flags, getUserId());
525     }
526 
527     @Override
getApplicationInfoAsUser(String packageName, int flags, int userId)528     public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
529             throws NameNotFoundException {
530         return getApplicationInfoAsUser(packageName, ApplicationInfoFlags.of(flags), userId);
531     }
532 
533     @Override
getApplicationInfoAsUser(String packageName, ApplicationInfoFlags flags, int userId)534     public ApplicationInfo getApplicationInfoAsUser(String packageName, ApplicationInfoFlags flags,
535             int userId) throws NameNotFoundException {
536         ApplicationInfo ai = getApplicationInfoAsUserCached(
537                         packageName,
538                         updateFlagsForApplication(flags.getValue(), userId),
539                         userId);
540         if (ai == null) {
541             throw new NameNotFoundException(packageName);
542         }
543         return maybeAdjustApplicationInfo(ai);
544     }
545 
maybeAdjustApplicationInfo(ApplicationInfo info)546     private static ApplicationInfo maybeAdjustApplicationInfo(ApplicationInfo info) {
547         // If we're dealing with a multi-arch application that has both
548         // 32 and 64 bit shared libraries, we might need to choose the secondary
549         // depending on what the current runtime's instruction set is.
550         if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
551             final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
552 
553             // Get the instruction set that the libraries of secondary Abi is supported.
554             // In presence of a native bridge this might be different than the one secondary Abi used.
555             String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
556             final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
557             secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
558 
559             // If the runtimeIsa is the same as the primary isa, then we do nothing.
560             // Everything will be set up correctly because info.nativeLibraryDir will
561             // correspond to the right ISA.
562             if (runtimeIsa.equals(secondaryIsa)) {
563                 ApplicationInfo modified = new ApplicationInfo(info);
564                 modified.nativeLibraryDir = info.secondaryNativeLibraryDir;
565                 return modified;
566             }
567         }
568         return info;
569     }
570 
571     @Override
getTargetSdkVersion(@onNull String packageName)572     public int getTargetSdkVersion(@NonNull String packageName) throws NameNotFoundException {
573         try {
574             int version = mPM.getTargetSdkVersion(packageName);
575             if (version != -1) {
576                 return version;
577             }
578         } catch (RemoteException e) {
579             throw e.rethrowFromSystemServer();
580         }
581         throw new PackageManager.NameNotFoundException(packageName);
582     }
583 
584     @Override
getActivityInfo(ComponentName className, int flags)585     public ActivityInfo getActivityInfo(ComponentName className, int flags)
586             throws NameNotFoundException {
587         return getActivityInfo(className, ComponentInfoFlags.of(flags));
588     }
589 
590     @Override
getActivityInfo(ComponentName className, ComponentInfoFlags flags)591     public ActivityInfo getActivityInfo(ComponentName className, ComponentInfoFlags flags)
592             throws NameNotFoundException {
593         final int userId = getUserId();
594         try {
595             ActivityInfo ai = mPM.getActivityInfo(className,
596                     updateFlagsForComponent(flags.getValue(), userId, null), userId);
597             if (ai != null) {
598                 return ai;
599             }
600         } catch (RemoteException e) {
601             throw e.rethrowFromSystemServer();
602         }
603 
604         throw new NameNotFoundException(className.toString());
605     }
606 
607     @Override
getReceiverInfo(ComponentName className, int flags)608     public ActivityInfo getReceiverInfo(ComponentName className, int flags)
609             throws NameNotFoundException {
610         return getReceiverInfo(className, ComponentInfoFlags.of(flags));
611     }
612 
613     @Override
getReceiverInfo(ComponentName className, ComponentInfoFlags flags)614     public ActivityInfo getReceiverInfo(ComponentName className, ComponentInfoFlags flags)
615             throws NameNotFoundException {
616         final int userId = getUserId();
617         try {
618             ActivityInfo ai = mPM.getReceiverInfo(className,
619                     updateFlagsForComponent(flags.getValue(), userId, null), userId);
620             if (ai != null) {
621                 return ai;
622             }
623         } catch (RemoteException e) {
624             throw e.rethrowFromSystemServer();
625         }
626 
627         throw new NameNotFoundException(className.toString());
628     }
629 
630     @Override
getServiceInfo(ComponentName className, int flags)631     public ServiceInfo getServiceInfo(ComponentName className, int flags)
632             throws NameNotFoundException {
633         return getServiceInfo(className, ComponentInfoFlags.of(flags));
634     }
635 
636     @Override
getServiceInfo(ComponentName className, ComponentInfoFlags flags)637     public ServiceInfo getServiceInfo(ComponentName className, ComponentInfoFlags flags)
638             throws NameNotFoundException {
639         final int userId = getUserId();
640         try {
641             ServiceInfo si = mPM.getServiceInfo(className,
642                     updateFlagsForComponent(flags.getValue(), userId, null), userId);
643             if (si != null) {
644                 return si;
645             }
646         } catch (RemoteException e) {
647             throw e.rethrowFromSystemServer();
648         }
649 
650         throw new NameNotFoundException(className.toString());
651     }
652 
653     @Override
getProviderInfo(ComponentName className, int flags)654     public ProviderInfo getProviderInfo(ComponentName className, int flags)
655             throws NameNotFoundException {
656         return getProviderInfo(className, ComponentInfoFlags.of(flags));
657     }
658 
659     @Override
getProviderInfo(ComponentName className, ComponentInfoFlags flags)660     public ProviderInfo getProviderInfo(ComponentName className, ComponentInfoFlags flags)
661             throws NameNotFoundException {
662         final int userId = getUserId();
663         try {
664             ProviderInfo pi = mPM.getProviderInfo(className,
665                     updateFlagsForComponent(flags.getValue(), userId, null), userId);
666             if (pi != null) {
667                 return pi;
668             }
669         } catch (RemoteException e) {
670             throw e.rethrowFromSystemServer();
671         }
672 
673         throw new NameNotFoundException(className.toString());
674     }
675 
676     @Override
getSystemSharedLibraryNames()677     public String[] getSystemSharedLibraryNames() {
678         try {
679             return mPM.getSystemSharedLibraryNames();
680         } catch (RemoteException e) {
681             throw e.rethrowFromSystemServer();
682         }
683     }
684 
685     /** @hide */
686     @Override
getSharedLibraries(int flags)687     public @NonNull List<SharedLibraryInfo> getSharedLibraries(int flags) {
688         return this.getSharedLibraries(PackageInfoFlags.of(flags));
689     }
690 
691     /** @hide
692      * @param flags */
693     @Override
getSharedLibraries(PackageInfoFlags flags)694     public @NonNull List<SharedLibraryInfo> getSharedLibraries(PackageInfoFlags flags) {
695         return getSharedLibrariesAsUser(flags, getUserId());
696     }
697 
698     /** @hide */
699     @Override
getSharedLibrariesAsUser(int flags, int userId)700     public @NonNull List<SharedLibraryInfo> getSharedLibrariesAsUser(int flags, int userId) {
701         return getSharedLibrariesAsUser(PackageInfoFlags.of(flags), userId);
702     }
703 
704     /** @hide */
705     @Override
706     @SuppressWarnings("unchecked")
getSharedLibrariesAsUser(PackageInfoFlags flags, int userId)707     public @NonNull List<SharedLibraryInfo> getSharedLibrariesAsUser(PackageInfoFlags flags,
708             int userId) {
709         try {
710             ParceledListSlice<SharedLibraryInfo> sharedLibs = mPM.getSharedLibraries(
711                     mContext.getOpPackageName(), flags.getValue(), userId);
712             if (sharedLibs == null) {
713                 return Collections.emptyList();
714             }
715             return sharedLibs.getList();
716         } catch (RemoteException e) {
717             throw e.rethrowFromSystemServer();
718         }
719     }
720 
721     @NonNull
722     @Override
getDeclaredSharedLibraries(@onNull String packageName, int flags)723     public List<SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String packageName,
724             int flags) {
725         return getDeclaredSharedLibraries(packageName, PackageInfoFlags.of(flags));
726     }
727 
728     @NonNull
729     @Override
730     @SuppressWarnings("unchecked")
getDeclaredSharedLibraries(@onNull String packageName, PackageInfoFlags flags)731     public List<SharedLibraryInfo> getDeclaredSharedLibraries(@NonNull String packageName,
732             PackageInfoFlags flags) {
733         try {
734             ParceledListSlice<SharedLibraryInfo> sharedLibraries = mPM.getDeclaredSharedLibraries(
735                     packageName, flags.getValue(), mContext.getUserId());
736             return sharedLibraries != null ? sharedLibraries.getList() : Collections.emptyList();
737         } catch (RemoteException e) {
738             throw e.rethrowFromSystemServer();
739         }
740     }
741 
742     /** @hide */
743     @Override
getServicesSystemSharedLibraryPackageName()744     public @NonNull String getServicesSystemSharedLibraryPackageName() {
745         try {
746             return mPM.getServicesSystemSharedLibraryPackageName();
747         } catch (RemoteException e) {
748             throw e.rethrowFromSystemServer();
749         }
750     }
751 
752     /**
753      * @hide
754      */
getSharedSystemSharedLibraryPackageName()755     public @NonNull String getSharedSystemSharedLibraryPackageName() {
756         try {
757             return mPM.getSharedSystemSharedLibraryPackageName();
758         } catch (RemoteException e) {
759             throw e.rethrowFromSystemServer();
760         }
761     }
762 
763     @Override
getChangedPackages(int sequenceNumber)764     public ChangedPackages getChangedPackages(int sequenceNumber) {
765         try {
766             return mPM.getChangedPackages(sequenceNumber, getUserId());
767         } catch (RemoteException e) {
768             throw e.rethrowFromSystemServer();
769         }
770     }
771 
772     @Override
773     @SuppressWarnings("unchecked")
getSystemAvailableFeatures()774     public FeatureInfo[] getSystemAvailableFeatures() {
775         try {
776             ParceledListSlice<FeatureInfo> parceledList =
777                     mPM.getSystemAvailableFeatures();
778             if (parceledList == null) {
779                 return new FeatureInfo[0];
780             }
781             final List<FeatureInfo> list = parceledList.getList();
782             final FeatureInfo[] res = new FeatureInfo[list.size()];
783             for (int i = 0; i < res.length; i++) {
784                 res[i] = list.get(i);
785             }
786             return res;
787         } catch (RemoteException e) {
788             throw e.rethrowFromSystemServer();
789         }
790     }
791 
792     @Override
hasSystemFeature(String name)793     public boolean hasSystemFeature(String name) {
794         return hasSystemFeature(name, 0);
795     }
796 
797     /**
798      * The API and cache name for hasSystemFeature.
799      */
800     private static final String HAS_SYSTEM_FEATURE_API = "has_system_feature";
801 
802     /**
803      * Identifies a single hasSystemFeature query.
804      */
HasSystemFeatureQuery(String name, int version)805     private record HasSystemFeatureQuery(String name, int version) {}
806 
807     // Make this cache relatively large.  There are many system features and
808     // none are ever invalidated.  MPTS tests suggests that the cache should
809     // hold at least 150 entries.
810     private final static PropertyInvalidatedCache<HasSystemFeatureQuery, Boolean>
811             mHasSystemFeatureCache = new PropertyInvalidatedCache<>(
812                 new PropertyInvalidatedCache.Args(MODULE_SYSTEM)
813                 .api(HAS_SYSTEM_FEATURE_API).maxEntries(SDK_FEATURE_COUNT).isolateUids(false),
814                 HAS_SYSTEM_FEATURE_API, null) {
815 
816                 @Override
817                 public Boolean recompute(HasSystemFeatureQuery query) {
818                     try {
819                         return ActivityThread.currentActivityThread().getPackageManager().
820                             hasSystemFeature(query.name, query.version);
821                     } catch (RemoteException e) {
822                         throw e.rethrowFromSystemServer();
823                     }
824                 }
825             };
826 
827     @Override
hasSystemFeature(String name, int version)828     public boolean hasSystemFeature(String name, int version) {
829         // We check for system features in the following order:
830         //    * Build time-defined system features (constant, very efficient)
831         //    * SDK-defined system features (cached at process start, very efficient)
832         //    * IPC-retrieved system features (lazily cached, requires per-feature IPC)
833         // TODO(b/375000483): Refactor all of this logic, including flag queries, into
834         // the SystemFeaturesCache class after initial rollout and validation.
835         Boolean maybeHasSystemFeature = RoSystemFeatures.maybeHasFeature(name, version);
836         if (maybeHasSystemFeature != null) {
837             return maybeHasSystemFeature;
838         }
839         if (mUseSystemFeaturesCache) {
840             maybeHasSystemFeature =
841                     SystemFeaturesCache.getInstance().maybeHasFeature(name, version);
842             if (maybeHasSystemFeature != null) {
843                 return maybeHasSystemFeature;
844             }
845         }
846         return mHasSystemFeatureCache.query(new HasSystemFeatureQuery(name, version));
847     }
848 
849     /** @hide */
invalidateHasSystemFeatureCache()850     public static void invalidateHasSystemFeatureCache() {
851         mHasSystemFeatureCache.invalidateCache();
852     }
853 
854     @Override
checkPermission(String permName, String pkgName)855     public int checkPermission(String permName, String pkgName) {
856         return getPermissionManager().checkPackageNamePermission(permName, pkgName,
857                 mContext.getDeviceId(), getUserId());
858     }
859 
860     @Override
isPermissionRevokedByPolicy(String permName, String pkgName)861     public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
862         return getPermissionManager().isPermissionRevokedByPolicy(pkgName, permName);
863     }
864 
865     /**
866      * @hide
867      */
868     @Override
getPermissionControllerPackageName()869     public String getPermissionControllerPackageName() {
870         if (mPermissionsControllerPackageName == null) {
871             try {
872                 mPermissionsControllerPackageName = mPM.getPermissionControllerPackageName();
873             } catch (RemoteException e) {
874                 throw e.rethrowFromSystemServer();
875             }
876         }
877         return mPermissionsControllerPackageName;
878     }
879 
880     /**
881      * @hide
882      */
883     @Override
getSdkSandboxPackageName()884     public String getSdkSandboxPackageName() {
885         try {
886             return mPM.getSdkSandboxPackageName();
887         } catch (RemoteException e) {
888             throw e.rethrowFromSystemServer();
889         }
890     }
891 
892     @Override
addPermission(PermissionInfo info)893     public boolean addPermission(PermissionInfo info) {
894         return getPermissionManager().addPermission(info, false);
895     }
896 
897     @Override
addPermissionAsync(PermissionInfo info)898     public boolean addPermissionAsync(PermissionInfo info) {
899         return getPermissionManager().addPermission(info, true);
900     }
901 
902     @Override
removePermission(String name)903     public void removePermission(String name) {
904         getPermissionManager().removePermission(name);
905     }
906 
907     @Override
grantRuntimePermission(String packageName, String permissionName, UserHandle user)908     public void grantRuntimePermission(String packageName, String permissionName,
909             UserHandle user) {
910         getPermissionManager().grantRuntimePermission(packageName, permissionName, user);
911     }
912 
913     @Override
revokeRuntimePermission(String packageName, String permName, UserHandle user)914     public void revokeRuntimePermission(String packageName, String permName, UserHandle user) {
915         revokeRuntimePermission(packageName, permName, user, null);
916     }
917 
918     @Override
revokeRuntimePermission(String packageName, String permName, UserHandle user, String reason)919     public void revokeRuntimePermission(String packageName, String permName, UserHandle user,
920             String reason) {
921         getPermissionManager().revokeRuntimePermission(packageName, permName, user, reason);
922     }
923 
924     @Override
getPermissionFlags(String permName, String packageName, UserHandle user)925     public int getPermissionFlags(String permName, String packageName, UserHandle user) {
926         return getPermissionManager().getPermissionFlags(packageName, permName, user);
927     }
928 
929     @Override
updatePermissionFlags(String permName, String packageName, int flagMask, int flagValues, UserHandle user)930     public void updatePermissionFlags(String permName, String packageName,
931             int flagMask, int flagValues, UserHandle user) {
932         getPermissionManager().updatePermissionFlags(packageName, permName, flagMask, flagValues,
933                 user);
934     }
935 
936     @Override
getWhitelistedRestrictedPermissions( @onNull String packageName, @PermissionWhitelistFlags int flags)937     public @NonNull Set<String> getWhitelistedRestrictedPermissions(
938             @NonNull String packageName, @PermissionWhitelistFlags int flags) {
939         return getPermissionManager().getAllowlistedRestrictedPermissions(packageName, flags);
940     }
941 
942     @Override
addWhitelistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PermissionWhitelistFlags int flags)943     public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
944             @NonNull String permName, @PermissionWhitelistFlags int flags) {
945         return getPermissionManager().addAllowlistedRestrictedPermission(packageName, permName,
946                 flags);
947     }
948 
949     @Override
setAutoRevokeWhitelisted(@onNull String packageName, boolean whitelisted)950     public boolean setAutoRevokeWhitelisted(@NonNull String packageName, boolean whitelisted) {
951         return getPermissionManager().setAutoRevokeExempted(packageName, whitelisted);
952     }
953 
954     @Override
isAutoRevokeWhitelisted(@onNull String packageName)955     public boolean isAutoRevokeWhitelisted(@NonNull String packageName) {
956         return getPermissionManager().isAutoRevokeExempted(packageName);
957     }
958 
959     @Override
removeWhitelistedRestrictedPermission(@onNull String packageName, @NonNull String permName, @PermissionWhitelistFlags int flags)960     public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
961             @NonNull String permName, @PermissionWhitelistFlags int flags) {
962         return getPermissionManager().removeAllowlistedRestrictedPermission(packageName, permName,
963                 flags);
964     }
965 
966     @Override
967     @UnsupportedAppUsage
shouldShowRequestPermissionRationale(String permName)968     public boolean shouldShowRequestPermissionRationale(String permName) {
969         return getPermissionManager().shouldShowRequestPermissionRationale(permName);
970     }
971 
972     @Override
buildRequestPermissionsIntent(@onNull String[] permissions)973     public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) {
974         Intent intent = super.buildRequestPermissionsIntent(permissions);
975         intent.putExtra(EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, mContext.getDeviceId());
976         return intent;
977     }
978 
979     @Override
getBackgroundPermissionOptionLabel()980     public CharSequence getBackgroundPermissionOptionLabel() {
981         try {
982 
983             String permissionController = getPermissionControllerPackageName();
984             Context context =
985                     mContext.createPackageContext(permissionController, 0);
986 
987             int textId = context.getResources().getIdentifier(APP_PERMISSION_BUTTON_ALLOW_ALWAYS,
988                     "string", PERMISSION_CONTROLLER_RESOURCE_PACKAGE);
989             if (textId != 0) {
990                 return context.getText(textId);
991             }
992         } catch (NameNotFoundException e) {
993             Log.e(TAG, "Permission controller not found.", e);
994         }
995         return "";
996     }
997 
998     @Override
checkSignatures(String pkg1, String pkg2)999     public int checkSignatures(String pkg1, String pkg2) {
1000         try {
1001             return mPM.checkSignatures(pkg1, pkg2, getUserId());
1002         } catch (RemoteException e) {
1003             throw e.rethrowFromSystemServer();
1004         }
1005     }
1006 
1007     @Override
checkSignatures(int uid1, int uid2)1008     public int checkSignatures(int uid1, int uid2) {
1009         try {
1010             return mPM.checkUidSignatures(uid1, uid2);
1011         } catch (RemoteException e) {
1012             throw e.rethrowFromSystemServer();
1013         }
1014     }
1015 
1016     @Override
hasSigningCertificate( String packageName, byte[] certificate, @CertificateInputType int type)1017     public boolean hasSigningCertificate(
1018             String packageName, byte[] certificate, @CertificateInputType int type) {
1019         try {
1020             return mPM.hasSigningCertificate(packageName, certificate, type);
1021         } catch (RemoteException e) {
1022             throw e.rethrowFromSystemServer();
1023         }
1024     }
1025 
1026     @Override
hasSigningCertificate( int uid, byte[] certificate, @CertificateInputType int type)1027     public boolean hasSigningCertificate(
1028             int uid, byte[] certificate, @CertificateInputType int type) {
1029         try {
1030             return mPM.hasUidSigningCertificate(uid, certificate, type);
1031         } catch (RemoteException e) {
1032             throw e.rethrowFromSystemServer();
1033         }
1034     }
1035 
1036     @Override
setPageSizeAppCompatFlagsSettingsOverride(String packageName, boolean enabled)1037     public void setPageSizeAppCompatFlagsSettingsOverride(String packageName, boolean enabled) {
1038         try {
1039             mPM.setPageSizeAppCompatFlagsSettingsOverride(packageName, enabled);
1040         } catch (RemoteException e) {
1041             throw e.rethrowFromSystemServer();
1042         }
1043     }
1044 
1045     @Override
isPageSizeCompatEnabled(String packageName)1046     public boolean isPageSizeCompatEnabled(String packageName) {
1047         try {
1048             return mPM.isPageSizeCompatEnabled(packageName);
1049         } catch (RemoteException e) {
1050             throw e.rethrowFromSystemServer();
1051         }
1052     }
1053 
1054     @Override
getPageSizeCompatWarningMessage(String packageName)1055     public String getPageSizeCompatWarningMessage(String packageName) {
1056         try {
1057             return mPM.getPageSizeCompatWarningMessage(packageName);
1058         } catch (RemoteException e) {
1059             throw e.rethrowFromSystemServer();
1060         }
1061     }
1062 
encodeCertificates(List<Certificate> certs)1063     private static List<byte[]> encodeCertificates(List<Certificate> certs) throws
1064             CertificateEncodingException {
1065         if (certs == null) {
1066             return null;
1067         }
1068         List<byte[]> result = new ArrayList<>(certs.size());
1069         for (Certificate cert : certs) {
1070             if (!(cert instanceof X509Certificate)) {
1071                 throw new CertificateEncodingException("Only X509 certificates supported.");
1072             }
1073             result.add(cert.getEncoded());
1074         }
1075         return result;
1076     }
1077 
1078     @Override
requestChecksums(@onNull String packageName, boolean includeSplits, @Checksum.TypeMask int required, @NonNull List<Certificate> trustedInstallers, @NonNull OnChecksumsReadyListener onChecksumsReadyListener)1079     public void requestChecksums(@NonNull String packageName, boolean includeSplits,
1080             @Checksum.TypeMask int required, @NonNull List<Certificate> trustedInstallers,
1081             @NonNull OnChecksumsReadyListener onChecksumsReadyListener)
1082             throws CertificateEncodingException, NameNotFoundException {
1083         Objects.requireNonNull(packageName);
1084         Objects.requireNonNull(onChecksumsReadyListener);
1085         Objects.requireNonNull(trustedInstallers);
1086         if (trustedInstallers == TRUST_ALL) {
1087             trustedInstallers = null;
1088         } else if (trustedInstallers == TRUST_NONE) {
1089             trustedInstallers = Collections.emptyList();
1090         } else if (trustedInstallers.isEmpty()) {
1091             throw new IllegalArgumentException(
1092                     "trustedInstallers has to be one of TRUST_ALL/TRUST_NONE or a non-empty "
1093                             + "list of certificates.");
1094         }
1095         try {
1096             IOnChecksumsReadyListener onChecksumsReadyListenerDelegate =
1097                     new IOnChecksumsReadyListener.Stub() {
1098                         @Override
1099                         public void onChecksumsReady(List<ApkChecksum> checksums)
1100                                 throws RemoteException {
1101                             onChecksumsReadyListener.onChecksumsReady(checksums);
1102                         }
1103                     };
1104             mPM.requestPackageChecksums(packageName, includeSplits, DEFAULT_CHECKSUMS, required,
1105                     encodeCertificates(trustedInstallers), onChecksumsReadyListenerDelegate,
1106                     getUserId());
1107         } catch (ParcelableException e) {
1108             e.maybeRethrow(PackageManager.NameNotFoundException.class);
1109             throw new RuntimeException(e);
1110         } catch (RemoteException e) {
1111             throw e.rethrowFromSystemServer();
1112         }
1113     }
1114 
1115     /**
1116      * Wrap the cached value in a class that does deep compares on string
1117      * arrays.  The comparison is needed only for the verification mode of
1118      * PropertyInvalidatedCache; this mode is only enabled for debugging.
1119      * The return result is an array of strings but the order in the array
1120      * is not important.  To properly compare two arrays, the arrays are
1121      * sorted before the comparison.
1122      */
1123     private static class GetPackagesForUidResult {
1124         private final String [] mValue;
GetPackagesForUidResult(String []s)1125         GetPackagesForUidResult(String []s) {
1126             mValue = s;
1127         }
value()1128         public String[] value() {
1129             return mValue;
1130         }
1131         @Override
toString()1132         public String toString() {
1133             return Arrays.toString(mValue);
1134         }
1135         @Override
hashCode()1136         public int hashCode() {
1137             return Arrays.hashCode(mValue);
1138         }
1139         /**
1140          * Arrays.sort() throws an NPE if passed a null pointer, so nulls
1141          * are handled first.
1142          */
1143         @Override
equals(@ullable Object o)1144         public boolean equals(@Nullable Object o) {
1145             if (o instanceof GetPackagesForUidResult) {
1146                 String [] r = ((GetPackagesForUidResult) o).mValue;
1147                 String [] l = mValue;
1148                 if ((r == null) != (l == null)) {
1149                     return false;
1150                 } else if (r == null) {
1151                     return true;
1152                 }
1153                 // Both arrays are non-null.  Sort before comparing.
1154                 Arrays.sort(r);
1155                 Arrays.sort(l);
1156                 return Arrays.equals(l, r);
1157             } else {
1158                 return false;
1159             }
1160         }
1161     }
1162 
1163     private static final String CACHE_KEY_PACKAGES_FOR_UID_API = "get_packages_for_uid";
1164 
1165     /** @hide */
1166     @VisibleForTesting
1167     public static final PropertyInvalidatedCache<Integer, GetPackagesForUidResult>
1168             sGetPackagesForUidCache = new PropertyInvalidatedCache<>(
1169                 new PropertyInvalidatedCache.Args(MODULE_SYSTEM)
1170                 .maxEntries(1024).api(CACHE_KEY_PACKAGES_FOR_UID_API).cacheNulls(true),
1171                 CACHE_KEY_PACKAGES_FOR_UID_API, null) {
1172 
1173                 @Override
1174                 public GetPackagesForUidResult recompute(Integer uid) {
1175                     try {
1176                         return new GetPackagesForUidResult(
1177                             ActivityThread.currentActivityThread().
1178                             getPackageManager().getPackagesForUid(uid));
1179                     } catch (RemoteException e) {
1180                         throw e.rethrowFromSystemServer();
1181                     }
1182                 }
1183                 @Override
1184                 public String queryToString(Integer uid) {
1185                     return String.format("uid=%d", uid.intValue());
1186                 }
1187             };
1188 
1189     @Override
getPackagesForUid(int uid)1190     public String[] getPackagesForUid(int uid) {
1191         return sGetPackagesForUidCache.query(uid).value();
1192     }
1193 
1194     /** @hide */
disableGetPackagesForUidCache()1195     public static void disableGetPackagesForUidCache() {
1196         sGetPackagesForUidCache.disableLocal();
1197     }
1198 
1199     /** @hide */
invalidateGetPackagesForUidCache()1200     public static void invalidateGetPackagesForUidCache() {
1201         sGetPackagesForUidCache.invalidateCache();
1202     }
1203 
1204     @Override
getNameForUid(int uid)1205     public String getNameForUid(int uid) {
1206         try {
1207             return mPM.getNameForUid(uid);
1208         } catch (RemoteException e) {
1209             throw e.rethrowFromSystemServer();
1210         }
1211     }
1212 
1213     @Override
getNamesForUids(int[] uids)1214     public String[] getNamesForUids(int[] uids) {
1215         try {
1216             return mPM.getNamesForUids(uids);
1217         } catch (RemoteException e) {
1218             throw e.rethrowFromSystemServer();
1219         }
1220     }
1221 
1222     @Override
getUidForSharedUser(String sharedUserName)1223     public int getUidForSharedUser(String sharedUserName)
1224             throws NameNotFoundException {
1225         try {
1226             int uid = mPM.getUidForSharedUser(sharedUserName);
1227             if (uid != Process.INVALID_UID) {
1228                 return uid;
1229             }
1230         } catch (RemoteException e) {
1231             throw e.rethrowFromSystemServer();
1232         }
1233         throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1234     }
1235 
1236     @Override
getInstalledModules(int flags)1237     public List<ModuleInfo> getInstalledModules(int flags) {
1238         try {
1239             return mPM.getInstalledModules(flags);
1240         } catch (RemoteException e) {
1241             throw e.rethrowFromSystemServer();
1242         }
1243     }
1244 
1245     @Override
getModuleInfo(String packageName, int flags)1246     public ModuleInfo getModuleInfo(String packageName, int flags) throws NameNotFoundException {
1247         try {
1248             ModuleInfo mi = mPM.getModuleInfo(packageName, flags);
1249             if (mi != null) {
1250                 return mi;
1251             }
1252         } catch (RemoteException e) {
1253             throw e.rethrowFromSystemServer();
1254         }
1255 
1256         throw new NameNotFoundException("No module info for package: " + packageName);
1257     }
1258 
1259     @SuppressWarnings("unchecked")
1260     @Override
getInstalledPackages(int flags)1261     public List<PackageInfo> getInstalledPackages(int flags) {
1262         return getInstalledPackages(PackageInfoFlags.of(flags));
1263     }
1264 
1265     @SuppressWarnings("unchecked")
1266     @Override
getInstalledPackages(PackageInfoFlags flags)1267     public List<PackageInfo> getInstalledPackages(PackageInfoFlags flags) {
1268         return getInstalledPackagesAsUser(flags, getUserId());
1269     }
1270 
1271     /** @hide */
1272     @Override
1273     @SuppressWarnings("unchecked")
getInstalledPackagesAsUser(int flags, int userId)1274     public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
1275         return getInstalledPackagesAsUser(PackageInfoFlags.of(flags), userId);
1276     }
1277 
1278     /** @hide */
1279     @Override
1280     @SuppressWarnings("unchecked")
getInstalledPackagesAsUser(PackageInfoFlags flags, int userId)1281     public List<PackageInfo> getInstalledPackagesAsUser(PackageInfoFlags flags, int userId) {
1282         try {
1283             ParceledListSlice<PackageInfo> parceledList =
1284                     mPM.getInstalledPackages(updateFlagsForPackage(flags.getValue(), userId),
1285                             userId);
1286             if (parceledList == null) {
1287                 return Collections.emptyList();
1288             }
1289             return parceledList.getList();
1290         } catch (RemoteException e) {
1291             throw e.rethrowFromSystemServer();
1292         }
1293     }
1294 
1295     @Override
1296     @NonNull
getAppMetadata(@onNull String packageName)1297     public PersistableBundle getAppMetadata(@NonNull String packageName)
1298             throws NameNotFoundException {
1299         PersistableBundle appMetadata = null;
1300         ParcelFileDescriptor pfd = null;
1301         try {
1302             pfd = mPM.getAppMetadataFd(packageName, getUserId());
1303         } catch (ParcelableException e) {
1304             e.maybeRethrow(NameNotFoundException.class);
1305             throw new RuntimeException(e);
1306         } catch (RemoteException e) {
1307             throw e.rethrowFromSystemServer();
1308         }
1309         if (pfd != null) {
1310             try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
1311                 appMetadata = PersistableBundle.readFromStream(inputStream);
1312             } catch (IOException e) {
1313                 throw new RuntimeException(e);
1314             }
1315         }
1316 
1317         return appMetadata != null ? appMetadata : new PersistableBundle();
1318     }
1319 
1320     @Override
getAppMetadataSource(@onNull String packageName)1321     public @AppMetadataSource int getAppMetadataSource(@NonNull String packageName)
1322             throws NameNotFoundException {
1323         Objects.requireNonNull(packageName, "packageName cannot be null");
1324         int source = PackageManager.APP_METADATA_SOURCE_UNKNOWN;
1325         try {
1326             source = mPM.getAppMetadataSource(packageName, getUserId());
1327         } catch (ParcelableException e) {
1328             e.maybeRethrow(NameNotFoundException.class);
1329             throw new RuntimeException(e);
1330         } catch (RemoteException e) {
1331             throw e.rethrowFromSystemServer();
1332         }
1333         return source;
1334     }
1335 
1336     @SuppressWarnings("unchecked")
1337     @Override
getPackagesHoldingPermissions(String[] permissions, int flags)1338     public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) {
1339         return this.getPackagesHoldingPermissions(permissions, PackageInfoFlags.of(flags));
1340     }
1341 
1342     @SuppressWarnings("unchecked")
1343     @Override
getPackagesHoldingPermissions(String[] permissions, PackageInfoFlags flags)1344     public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions,
1345             PackageInfoFlags flags) {
1346         final int userId = getUserId();
1347         try {
1348             ParceledListSlice<PackageInfo> parceledList =
1349                     mPM.getPackagesHoldingPermissions(permissions,
1350                             updateFlagsForPackage(flags.getValue(), userId), userId);
1351             if (parceledList == null) {
1352                 return Collections.emptyList();
1353             }
1354             return parceledList.getList();
1355         } catch (RemoteException e) {
1356             throw e.rethrowFromSystemServer();
1357         }
1358     }
1359 
1360     @SuppressWarnings("unchecked")
1361     @Override
getInstalledApplications(int flags)1362     public List<ApplicationInfo> getInstalledApplications(int flags) {
1363         return getInstalledApplicationsAsUser(flags, getUserId());
1364     }
1365 
1366     @Override
getInstalledApplications(ApplicationInfoFlags flags)1367     public List<ApplicationInfo> getInstalledApplications(ApplicationInfoFlags flags) {
1368         return getInstalledApplicationsAsUser(flags, getUserId());
1369     }
1370 
1371     /** @hide */
1372     @SuppressWarnings("unchecked")
1373     @Override
getInstalledApplicationsAsUser(int flags, int userId)1374     public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
1375         return getInstalledApplicationsAsUser(ApplicationInfoFlags.of(flags), userId);
1376     }
1377 
1378     /** @hide */
1379     @SuppressWarnings("unchecked")
1380     @Override
getInstalledApplicationsAsUser(ApplicationInfoFlags flags, int userId)1381     public List<ApplicationInfo> getInstalledApplicationsAsUser(ApplicationInfoFlags flags,
1382             int userId) {
1383         try {
1384             ParceledListSlice<ApplicationInfo> parceledList =
1385                     mPM.getInstalledApplications(updateFlagsForApplication(
1386                             flags.getValue(), userId), userId);
1387             if (parceledList == null) {
1388                 return Collections.emptyList();
1389             }
1390             return parceledList.getList();
1391         } catch (RemoteException e) {
1392             throw e.rethrowFromSystemServer();
1393         }
1394     }
1395 
1396     /** @hide */
1397     @SuppressWarnings("unchecked")
1398     @Override
getInstantApps()1399     public List<InstantAppInfo> getInstantApps() {
1400         try {
1401             ParceledListSlice<InstantAppInfo> slice = mPM.getInstantApps(getUserId());
1402             if (slice != null) {
1403                 return slice.getList();
1404             }
1405             return Collections.emptyList();
1406         } catch (RemoteException e) {
1407             throw e.rethrowFromSystemServer();
1408         }
1409     }
1410 
1411     /** @hide */
1412     @Override
getInstantAppIcon(String packageName)1413     public Drawable getInstantAppIcon(String packageName) {
1414         try {
1415             Bitmap bitmap = mPM.getInstantAppIcon(packageName, getUserId());
1416             if (bitmap != null) {
1417                 return new BitmapDrawable(null, bitmap);
1418             }
1419             return null;
1420         } catch (RemoteException e) {
1421             throw e.rethrowFromSystemServer();
1422         }
1423     }
1424 
1425     @Override
isInstantApp()1426     public boolean isInstantApp() {
1427         return isInstantApp(mContext.getPackageName());
1428     }
1429 
1430     @Override
isInstantApp(String packageName)1431     public boolean isInstantApp(String packageName) {
1432         try {
1433             return mPM.isInstantApp(packageName, getUserId());
1434         } catch (RemoteException e) {
1435             throw e.rethrowFromSystemServer();
1436         }
1437     }
1438 
getInstantAppCookieMaxBytes()1439     public int getInstantAppCookieMaxBytes() {
1440         return Settings.Global.getInt(mContext.getContentResolver(),
1441                 Settings.Global.EPHEMERAL_COOKIE_MAX_SIZE_BYTES,
1442                 DEFAULT_EPHEMERAL_COOKIE_MAX_SIZE_BYTES);
1443     }
1444 
1445     @Override
getInstantAppCookieMaxSize()1446     public int getInstantAppCookieMaxSize() {
1447         return getInstantAppCookieMaxBytes();
1448     }
1449 
1450     @Override
getInstantAppCookie()1451     public @NonNull byte[] getInstantAppCookie() {
1452         try {
1453             final byte[] cookie = mPM.getInstantAppCookie(mContext.getPackageName(), getUserId());
1454             if (cookie != null) {
1455                 return cookie;
1456             } else {
1457                 return EmptyArray.BYTE;
1458             }
1459         } catch (RemoteException e) {
1460             throw e.rethrowFromSystemServer();
1461         }
1462     }
1463 
1464     @Override
clearInstantAppCookie()1465     public void clearInstantAppCookie() {
1466         updateInstantAppCookie(null);
1467     }
1468 
1469     @Override
updateInstantAppCookie(@onNull byte[] cookie)1470     public void updateInstantAppCookie(@NonNull byte[] cookie) {
1471         if (cookie != null && cookie.length > getInstantAppCookieMaxBytes()) {
1472             throw new IllegalArgumentException("instant cookie longer than "
1473                     + getInstantAppCookieMaxBytes());
1474         }
1475         try {
1476             mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId());
1477         } catch (RemoteException e) {
1478             throw e.rethrowFromSystemServer();
1479         }
1480     }
1481 
1482     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
1483     @Override
setInstantAppCookie(@onNull byte[] cookie)1484     public boolean setInstantAppCookie(@NonNull byte[] cookie) {
1485         try {
1486             return mPM.setInstantAppCookie(mContext.getPackageName(), cookie, getUserId());
1487         } catch (RemoteException e) {
1488             throw e.rethrowFromSystemServer();
1489         }
1490     }
1491 
1492     @Override
resolveActivity(Intent intent, int flags)1493     public ResolveInfo resolveActivity(Intent intent, int flags) {
1494         return resolveActivity(intent, ResolveInfoFlags.of(flags));
1495     }
1496 
1497     @Override
resolveActivity(Intent intent, ResolveInfoFlags flags)1498     public ResolveInfo resolveActivity(Intent intent, ResolveInfoFlags flags) {
1499         return resolveActivityAsUser(intent, flags, getUserId());
1500     }
1501 
1502     @Override
resolveActivityAsUser(Intent intent, int flags, int userId)1503     public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
1504         return resolveActivityAsUser(intent, ResolveInfoFlags.of(flags), userId);
1505     }
1506 
1507     @Override
resolveActivityAsUser(Intent intent, ResolveInfoFlags flags, int userId)1508     public ResolveInfo resolveActivityAsUser(Intent intent, ResolveInfoFlags flags, int userId) {
1509         try {
1510             return mPM.resolveIntent(
1511                 intent,
1512                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1513                 updateFlagsForComponent(flags.getValue(), userId, intent),
1514                 userId);
1515         } catch (RemoteException e) {
1516             throw e.rethrowFromSystemServer();
1517         }
1518     }
1519 
1520     @Override
queryIntentActivities(Intent intent, int flags)1521     public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
1522         return queryIntentActivities(intent, ResolveInfoFlags.of(flags));
1523     }
1524 
1525     @Override
queryIntentActivities(Intent intent, ResolveInfoFlags flags)1526     public List<ResolveInfo> queryIntentActivities(Intent intent, ResolveInfoFlags flags) {
1527         return queryIntentActivitiesAsUser(intent, flags, getUserId());
1528     }
1529 
1530     /** @hide Same as above but for a specific user */
1531     @Override
queryIntentActivitiesAsUser(Intent intent, int flags, int userId)1532     public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
1533         return queryIntentActivitiesAsUser(intent, ResolveInfoFlags.of(flags), userId);
1534     }
1535 
1536     /** @hide Same as above but for a specific user */
1537     @Override
1538     @SuppressWarnings("unchecked")
queryIntentActivitiesAsUser(Intent intent, ResolveInfoFlags flags, int userId)1539     public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, ResolveInfoFlags flags,
1540             int userId) {
1541         try {
1542             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivities(
1543                     intent,
1544                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1545                     updateFlagsForComponent(flags.getValue(), userId, intent),
1546                     userId);
1547             if (parceledList == null) {
1548                 return Collections.emptyList();
1549             }
1550             return parceledList.getList();
1551         } catch (RemoteException e) {
1552             throw e.rethrowFromSystemServer();
1553         }
1554     }
1555 
1556     @Override
queryIntentActivityOptions(ComponentName caller, Intent[] specifics, Intent intent, int flags)1557     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics,
1558             Intent intent, int flags) {
1559         return queryIntentActivityOptions(caller,
1560                 specifics == null ? null : new ArrayList<>(Arrays.asList(specifics)),
1561                 intent, ResolveInfoFlags.of(flags));
1562     }
1563 
1564     @Override
1565     @SuppressWarnings("unchecked")
queryIntentActivityOptions(ComponentName caller, List<Intent> specifics, Intent intent, ResolveInfoFlags flags)1566     public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
1567             List<Intent> specifics, Intent intent, ResolveInfoFlags flags) {
1568         final int userId = getUserId();
1569         final ContentResolver resolver = mContext.getContentResolver();
1570 
1571         String[] specificTypes = null;
1572         if (specifics != null) {
1573             final int numSpecifics = specifics.size();
1574             for (int i = 0; i < numSpecifics; i++) {
1575                 Intent sp = specifics.get(i);
1576                 if (sp != null) {
1577                     String t = sp.resolveTypeIfNeeded(resolver);
1578                     if (t != null) {
1579                         if (specificTypes == null) {
1580                             specificTypes = new String[numSpecifics];
1581                         }
1582                         specificTypes[i] = t;
1583                     }
1584                 }
1585             }
1586         }
1587 
1588         try {
1589             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentActivityOptions(
1590                     caller,
1591                     specifics == null ? null : specifics.toArray(new Intent[0]),
1592                     specificTypes,
1593                     intent,
1594                     intent.resolveTypeIfNeeded(resolver),
1595                     updateFlagsForComponent(flags.getValue(), userId, intent),
1596                     userId);
1597             if (parceledList == null) {
1598                 return Collections.emptyList();
1599             }
1600             return parceledList.getList();
1601         } catch (RemoteException e) {
1602             throw e.rethrowFromSystemServer();
1603         }
1604     }
1605 
1606     /**
1607      * @hide
1608      */
1609     @Override
queryBroadcastReceiversAsUser(Intent intent, int flags, int userId)1610     public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
1611         return queryBroadcastReceiversAsUser(intent, ResolveInfoFlags.of(flags), userId);
1612     }
1613 
1614     /**
1615      * @hide
1616      */
1617     @Override
1618     @SuppressWarnings("unchecked")
queryBroadcastReceiversAsUser(Intent intent, ResolveInfoFlags flags, int userId)1619     public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, ResolveInfoFlags flags,
1620             int userId) {
1621         try {
1622             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentReceivers(
1623                     intent,
1624                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1625                     updateFlagsForComponent(flags.getValue(), userId, intent),
1626                     userId);
1627             if (parceledList == null) {
1628                 return Collections.emptyList();
1629             }
1630             return parceledList.getList();
1631         } catch (RemoteException e) {
1632             throw e.rethrowFromSystemServer();
1633         }
1634     }
1635 
1636     @Override
queryBroadcastReceivers(Intent intent, int flags)1637     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
1638         return queryBroadcastReceivers(intent, ResolveInfoFlags.of(flags));
1639     }
1640 
1641     @Override
queryBroadcastReceivers(Intent intent, ResolveInfoFlags flags)1642     public List<ResolveInfo> queryBroadcastReceivers(Intent intent, ResolveInfoFlags flags) {
1643         return queryBroadcastReceiversAsUser(intent, flags, getUserId());
1644     }
1645 
1646     @Override
resolveServiceAsUser(Intent intent, int flags, @UserIdInt int userId)1647     public ResolveInfo resolveServiceAsUser(Intent intent, int flags, @UserIdInt int userId) {
1648         return resolveServiceAsUser(intent, ResolveInfoFlags.of(flags), userId);
1649     }
1650 
1651     @Override
resolveServiceAsUser(Intent intent, ResolveInfoFlags flags, @UserIdInt int userId)1652     public ResolveInfo resolveServiceAsUser(Intent intent, ResolveInfoFlags flags,
1653             @UserIdInt int userId) {
1654         try {
1655             return mPM.resolveService(
1656                 intent,
1657                 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1658                 updateFlagsForComponent(flags.getValue(), userId, intent),
1659                 userId);
1660         } catch (RemoteException e) {
1661             throw e.rethrowFromSystemServer();
1662         }
1663     }
1664 
1665     @Override
resolveService(Intent intent, int flags)1666     public ResolveInfo resolveService(Intent intent, int flags) {
1667         return resolveService(intent, ResolveInfoFlags.of(flags));
1668     }
1669 
1670     @Override
resolveService(Intent intent, ResolveInfoFlags flags)1671     public ResolveInfo resolveService(Intent intent, ResolveInfoFlags flags) {
1672         return resolveServiceAsUser(intent, flags, getUserId());
1673     }
1674 
1675     @Override
queryIntentServicesAsUser(Intent intent, int flags, int userId)1676     public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
1677         return queryIntentServicesAsUser(intent, ResolveInfoFlags.of(flags), userId);
1678     }
1679 
1680     @Override
1681     @SuppressWarnings("unchecked")
queryIntentServicesAsUser(Intent intent, ResolveInfoFlags flags, int userId)1682     public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, ResolveInfoFlags flags,
1683             int userId) {
1684         try {
1685             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentServices(
1686                     intent,
1687                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1688                     updateFlagsForComponent(flags.getValue(), userId, intent),
1689                     userId);
1690             if (parceledList == null) {
1691                 return Collections.emptyList();
1692             }
1693             return parceledList.getList();
1694         } catch (RemoteException e) {
1695             throw e.rethrowFromSystemServer();
1696         }
1697     }
1698 
1699     @Override
queryIntentServices(Intent intent, int flags)1700     public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
1701         return queryIntentServices(intent, ResolveInfoFlags.of(flags));
1702     }
1703 
1704     @Override
queryIntentServices(Intent intent, ResolveInfoFlags flags)1705     public List<ResolveInfo> queryIntentServices(Intent intent, ResolveInfoFlags flags) {
1706         return queryIntentServicesAsUser(intent, flags, getUserId());
1707     }
1708 
1709     @Override
queryIntentContentProvidersAsUser( Intent intent, int flags, int userId)1710     public List<ResolveInfo> queryIntentContentProvidersAsUser(
1711             Intent intent, int flags, int userId) {
1712         return queryIntentContentProvidersAsUser(intent, ResolveInfoFlags.of(flags), userId);
1713     }
1714 
1715     @Override
1716     @SuppressWarnings("unchecked")
queryIntentContentProvidersAsUser( Intent intent, ResolveInfoFlags flags, int userId)1717     public List<ResolveInfo> queryIntentContentProvidersAsUser(
1718             Intent intent, ResolveInfoFlags flags, int userId) {
1719         try {
1720             ParceledListSlice<ResolveInfo> parceledList = mPM.queryIntentContentProviders(
1721                     intent,
1722                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1723                     updateFlagsForComponent(flags.getValue(), userId, intent),
1724                     userId);
1725             if (parceledList == null) {
1726                 return Collections.emptyList();
1727             }
1728             return parceledList.getList();
1729         } catch (RemoteException e) {
1730             throw e.rethrowFromSystemServer();
1731         }
1732     }
1733 
1734     @Override
queryIntentContentProviders(Intent intent, int flags)1735     public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
1736         return queryIntentContentProviders(intent, ResolveInfoFlags.of(flags));
1737     }
1738 
1739     @Override
queryIntentContentProviders(Intent intent, ResolveInfoFlags flags)1740     public List<ResolveInfo> queryIntentContentProviders(Intent intent, ResolveInfoFlags flags) {
1741         return queryIntentContentProvidersAsUser(intent, flags, getUserId());
1742     }
1743 
1744     @Override
resolveContentProvider(String name, int flags)1745     public ProviderInfo resolveContentProvider(String name, int flags) {
1746         return resolveContentProvider(name, ComponentInfoFlags.of(flags));
1747     }
1748 
1749     @Override
resolveContentProvider(String name, ComponentInfoFlags flags)1750     public ProviderInfo resolveContentProvider(String name, ComponentInfoFlags flags) {
1751         return resolveContentProviderAsUser(name, flags, getUserId());
1752     }
1753 
1754     /** @hide **/
1755     @Override
resolveContentProviderAsUser(String name, int flags, int userId)1756     public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
1757         return resolveContentProviderAsUser(name, ComponentInfoFlags.of(flags), userId);
1758     }
1759 
1760     /** @hide **/
1761     @Override
resolveContentProviderAsUser(String name, ComponentInfoFlags flags, int userId)1762     public ProviderInfo resolveContentProviderAsUser(String name, ComponentInfoFlags flags,
1763             int userId) {
1764         try {
1765             return mPM.resolveContentProvider(name,
1766                     updateFlagsForComponent(flags.getValue(), userId, null), userId);
1767         } catch (RemoteException e) {
1768             throw e.rethrowFromSystemServer();
1769         }
1770     }
1771 
1772     /** @hide **/
1773     @Override
resolveContentProviderForUid(@onNull String authority, ComponentInfoFlags flags, int callingUid)1774     public ProviderInfo resolveContentProviderForUid(@NonNull String authority,
1775             ComponentInfoFlags flags, int callingUid) {
1776         try {
1777             return mPM.resolveContentProviderForUid(authority,
1778                 updateFlagsForComponent(flags.getValue(), getUserId(), null), getUserId(),
1779                 callingUid);
1780         } catch (RemoteException e) {
1781             throw e.rethrowFromSystemServer();
1782         }
1783     }
1784 
1785     @Override
queryContentProviders(String processName, int uid, int flags)1786     public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
1787         return queryContentProviders(processName, uid, ComponentInfoFlags.of(flags));
1788     }
1789 
1790     @Override
queryContentProviders(String processName, int uid, ComponentInfoFlags flags)1791     public List<ProviderInfo> queryContentProviders(String processName, int uid,
1792             ComponentInfoFlags flags) {
1793         return queryContentProviders(processName, uid, flags, null);
1794     }
1795 
1796     @Override
queryContentProviders(String processName, int uid, int flags, String metaDataKey)1797     public List<ProviderInfo> queryContentProviders(String processName,
1798             int uid, int flags, String metaDataKey) {
1799         return queryContentProviders(processName, uid, ComponentInfoFlags.of(flags), metaDataKey);
1800     }
1801 
1802     @Override
1803     @SuppressWarnings("unchecked")
queryContentProviders(String processName, int uid, ComponentInfoFlags flags, String metaDataKey)1804     public List<ProviderInfo> queryContentProviders(String processName,
1805             int uid, ComponentInfoFlags flags, String metaDataKey) {
1806         try {
1807             ParceledListSlice<ProviderInfo> slice = mPM.queryContentProviders(processName, uid,
1808                     updateFlagsForComponent(flags.getValue(), UserHandle.getUserId(uid),
1809                             null), metaDataKey);
1810             return slice != null ? slice.getList() : Collections.emptyList();
1811         } catch (RemoteException e) {
1812             throw e.rethrowFromSystemServer();
1813         }
1814     }
1815 
1816     @Override
getInstrumentationInfo( ComponentName className, int flags)1817     public InstrumentationInfo getInstrumentationInfo(
1818         ComponentName className, int flags)
1819             throws NameNotFoundException {
1820         try {
1821             InstrumentationInfo ii = mPM.getInstrumentationInfoAsUser(
1822                     className, flags, getUserId());
1823             if (ii != null) {
1824                 return ii;
1825             }
1826         } catch (RemoteException e) {
1827             throw e.rethrowFromSystemServer();
1828         }
1829 
1830         throw new NameNotFoundException(className.toString());
1831     }
1832 
1833     @Override
1834     @SuppressWarnings("unchecked")
queryInstrumentation( String targetPackage, int flags)1835     public List<InstrumentationInfo> queryInstrumentation(
1836         String targetPackage, int flags) {
1837         try {
1838             ParceledListSlice<InstrumentationInfo> parceledList =
1839                     mPM.queryInstrumentationAsUser(targetPackage, flags, getUserId());
1840             if (parceledList == null) {
1841                 return Collections.emptyList();
1842             }
1843             return parceledList.getList();
1844         } catch (RemoteException e) {
1845             throw e.rethrowFromSystemServer();
1846         }
1847     }
1848 
1849     @Nullable
1850     @Override
getDrawable(String packageName, @DrawableRes int resId, @Nullable ApplicationInfo appInfo)1851     public Drawable getDrawable(String packageName, @DrawableRes int resId,
1852             @Nullable ApplicationInfo appInfo) {
1853         final ResourceName name = new ResourceName(packageName, resId);
1854         final Drawable cachedIcon = getCachedIcon(name);
1855         if (cachedIcon != null) {
1856             return cachedIcon;
1857         }
1858 
1859         if (appInfo == null) {
1860             try {
1861                 appInfo = getApplicationInfo(packageName, sDefaultFlags);
1862             } catch (NameNotFoundException e) {
1863                 return null;
1864             }
1865         }
1866 
1867         if (resId != 0) {
1868             try {
1869                 final Resources r = getResourcesForApplication(appInfo);
1870                 final Drawable dr = r.getDrawable(resId, null);
1871                 if (dr != null) {
1872                     putCachedIcon(name, dr);
1873                 }
1874 
1875                 if (false) {
1876                     RuntimeException e = new RuntimeException("here");
1877                     Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resId)
1878                                     + " from package " + packageName
1879                                     + ": app scale=" + r.getCompatibilityInfo().applicationScale
1880                                     + ", caller scale=" + mContext.getResources()
1881                                     .getCompatibilityInfo().applicationScale,
1882                             e);
1883                 }
1884                 if (DEBUG_ICONS) {
1885                     Log.v(TAG, "Getting drawable 0x"
1886                             + Integer.toHexString(resId) + " from " + r
1887                             + ": " + dr);
1888                 }
1889                 return dr;
1890             } catch (NameNotFoundException e) {
1891                 Log.w("PackageManager", "Failure retrieving resources for "
1892                         + appInfo.packageName);
1893             } catch (Resources.NotFoundException e) {
1894                 Log.w("PackageManager", "Failure retrieving resources for "
1895                         + appInfo.packageName + ": " + e.getMessage());
1896             } catch (Exception e) {
1897                 // If an exception was thrown, fall through to return
1898                 // default icon.
1899                 Log.w("PackageManager", "Failure retrieving icon 0x"
1900                         + Integer.toHexString(resId) + " in package "
1901                         + packageName, e);
1902             }
1903         }
1904 
1905         return null;
1906     }
1907 
getActivityIcon(ComponentName activityName)1908     @Override public Drawable getActivityIcon(ComponentName activityName)
1909             throws NameNotFoundException {
1910         return getActivityInfo(activityName, sDefaultFlags).loadIcon(this);
1911     }
1912 
getActivityIcon(Intent intent)1913     @Override public Drawable getActivityIcon(Intent intent)
1914             throws NameNotFoundException {
1915         if (intent.getComponent() != null) {
1916             return getActivityIcon(intent.getComponent());
1917         }
1918 
1919         ResolveInfo info = resolveActivity(intent, MATCH_DEFAULT_ONLY);
1920         if (info != null) {
1921             return info.activityInfo.loadIcon(this);
1922         }
1923 
1924         throw new NameNotFoundException(intent.toUri(0));
1925     }
1926 
getDefaultActivityIcon()1927     @Override public Drawable getDefaultActivityIcon() {
1928         return mContext.getDrawable(com.android.internal.R.drawable.sym_def_app_icon);
1929     }
1930 
getApplicationIcon(ApplicationInfo info)1931     @Override public Drawable getApplicationIcon(ApplicationInfo info) {
1932         return info.loadIcon(this);
1933     }
1934 
getApplicationIcon(String packageName)1935     @Override public Drawable getApplicationIcon(String packageName)
1936             throws NameNotFoundException {
1937         return getApplicationIcon(getApplicationInfo(packageName, sDefaultFlags));
1938     }
1939 
1940     @Override
getActivityBanner(ComponentName activityName)1941     public Drawable getActivityBanner(ComponentName activityName)
1942             throws NameNotFoundException {
1943         return getActivityInfo(activityName, sDefaultFlags).loadBanner(this);
1944     }
1945 
1946     @Override
getActivityBanner(Intent intent)1947     public Drawable getActivityBanner(Intent intent)
1948             throws NameNotFoundException {
1949         if (intent.getComponent() != null) {
1950             return getActivityBanner(intent.getComponent());
1951         }
1952 
1953         ResolveInfo info = resolveActivity(
1954                 intent, MATCH_DEFAULT_ONLY);
1955         if (info != null) {
1956             return info.activityInfo.loadBanner(this);
1957         }
1958 
1959         throw new NameNotFoundException(intent.toUri(0));
1960     }
1961 
1962     @Override
getApplicationBanner(ApplicationInfo info)1963     public Drawable getApplicationBanner(ApplicationInfo info) {
1964         return info.loadBanner(this);
1965     }
1966 
1967     @Override
getApplicationBanner(String packageName)1968     public Drawable getApplicationBanner(String packageName)
1969             throws NameNotFoundException {
1970         return getApplicationBanner(getApplicationInfo(packageName, sDefaultFlags));
1971     }
1972 
1973     @Override
getActivityLogo(ComponentName activityName)1974     public Drawable getActivityLogo(ComponentName activityName)
1975             throws NameNotFoundException {
1976         return getActivityInfo(activityName, sDefaultFlags).loadLogo(this);
1977     }
1978 
1979     @Override
getActivityLogo(Intent intent)1980     public Drawable getActivityLogo(Intent intent)
1981             throws NameNotFoundException {
1982         if (intent.getComponent() != null) {
1983             return getActivityLogo(intent.getComponent());
1984         }
1985 
1986         ResolveInfo info = resolveActivity(intent, MATCH_DEFAULT_ONLY);
1987         if (info != null) {
1988             return info.activityInfo.loadLogo(this);
1989         }
1990 
1991         throw new NameNotFoundException(intent.toUri(0));
1992     }
1993 
1994     @Override
getApplicationLogo(ApplicationInfo info)1995     public Drawable getApplicationLogo(ApplicationInfo info) {
1996         return info.loadLogo(this);
1997     }
1998 
1999     @Override
getApplicationLogo(String packageName)2000     public Drawable getApplicationLogo(String packageName)
2001             throws NameNotFoundException {
2002         return getApplicationLogo(getApplicationInfo(packageName, sDefaultFlags));
2003     }
2004 
2005     @Override
getUserBadgedIcon(Drawable icon, UserHandle user)2006     public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
2007         if (!hasUserBadge(user.getIdentifier())) {
2008             return icon;
2009         }
2010 
2011         final Drawable badgeForeground = getDevicePolicyManager().getResources().getDrawable(
2012                 getUpdatableUserIconBadgeId(user),
2013                 SOLID_COLORED,
2014                 () -> getDefaultUserIconBadge(user));
2015 
2016         Drawable badge = new LauncherIcons(mContext).getBadgeDrawable(
2017                 badgeForeground,
2018                 getUserBadgeColor(user, false));
2019         return getBadgedDrawable(icon, badge, null, true);
2020     }
2021 
getUpdatableUserIconBadgeId(UserHandle user)2022     private String getUpdatableUserIconBadgeId(UserHandle user) {
2023         return getUserManager().isManagedProfile(user.getIdentifier())
2024                 ? WORK_PROFILE_ICON_BADGE : UNDEFINED;
2025     }
2026 
getDefaultUserIconBadge(UserHandle user)2027     private Drawable getDefaultUserIconBadge(UserHandle user) {
2028         return mContext.getDrawable(getUserManager().getUserIconBadgeResId(user.getIdentifier()));
2029     }
2030 
2031     @Override
getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user, Rect badgeLocation, int badgeDensity)2032     public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
2033             Rect badgeLocation, int badgeDensity) {
2034         Drawable badgeDrawable = getUserBadgeForDensity(user, badgeDensity);
2035         if (badgeDrawable == null) {
2036             return drawable;
2037         }
2038         return getBadgedDrawable(drawable, badgeDrawable, badgeLocation, true);
2039     }
2040 
2041     /**
2042      * Returns the color of the user's actual badge (not the badge's shadow).
2043      * @param checkTheme whether to check the theme to determine the badge color. This should be
2044      *                   true if the background is determined by the theme. Otherwise, if
2045      *                   checkTheme is false, returns the color assuming a light background.
2046      */
getUserBadgeColor(UserHandle user, boolean checkTheme)2047     private int getUserBadgeColor(UserHandle user, boolean checkTheme) {
2048         if (checkTheme && mContext.getResources().getConfiguration().isNightModeActive()) {
2049             return getUserManager().getUserBadgeDarkColor(user.getIdentifier());
2050         }
2051         return getUserManager().getUserBadgeColor(user.getIdentifier());
2052     }
2053 
2054     @Override
getUserBadgeForDensity(UserHandle user, int density)2055     public Drawable getUserBadgeForDensity(UserHandle user, int density) {
2056         // This is part of the shadow, not the main color, and is not actually corp-specific.
2057         Drawable badgeColor = getProfileIconForDensity(user,
2058                 com.android.internal.R.drawable.ic_corp_badge_color, density);
2059         if (badgeColor == null) {
2060             return null;
2061         }
2062 
2063         final Drawable badgeForeground = getDevicePolicyManager().getResources()
2064                 .getDrawableForDensity(
2065                         getUpdatableUserBadgeId(user),
2066                         SOLID_COLORED,
2067                         density,
2068                         () -> getDefaultUserBadgeForDensity(user, density));
2069 
2070         badgeForeground.setTint(getUserBadgeColor(user, false));
2071         Drawable badge = new LayerDrawable(new Drawable[] {badgeColor, badgeForeground });
2072         return badge;
2073     }
2074 
getUpdatableUserBadgeId(UserHandle user)2075     private String getUpdatableUserBadgeId(UserHandle user) {
2076         return getUserManager().isManagedProfile(user.getIdentifier())
2077                 ? WORK_PROFILE_ICON : UNDEFINED;
2078     }
2079 
getDefaultUserBadgeForDensity(UserHandle user, int density)2080     private Drawable getDefaultUserBadgeForDensity(UserHandle user, int density) {
2081         return getDrawableForDensity(
2082                 getUserManager().getUserBadgeResId(user.getIdentifier()), density);
2083     }
2084 
2085     /**
2086      * Returns the badge color based on whether device has dark theme enabled or not.
2087      */
2088     @Override
getUserBadgeForDensityNoBackground(UserHandle user, int density)2089     public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
2090         if (!hasUserBadge(user.getIdentifier())) {
2091             return null;
2092         }
2093 
2094         final Drawable badge = getDevicePolicyManager().getResources().getDrawableForDensity(
2095                 getUpdatableUserBadgeId(user),
2096                 SOLID_NOT_COLORED,
2097                 density,
2098                 () -> getDefaultUserBadgeNoBackgroundForDensity(user, density));
2099 
2100         if (badge != null) {
2101             badge.setTint(getUserBadgeColor(user, true));
2102         }
2103         return badge;
2104     }
2105 
getDefaultUserBadgeNoBackgroundForDensity(UserHandle user, int density)2106     private Drawable getDefaultUserBadgeNoBackgroundForDensity(UserHandle user, int density) {
2107         return getDrawableForDensity(
2108                 getUserManager().getUserBadgeNoBackgroundResId(user.getIdentifier()), density);
2109     }
2110 
getDrawableForDensity(int drawableId, int density)2111     private Drawable getDrawableForDensity(int drawableId, int density) {
2112         if (density <= 0) {
2113             density = mContext.getResources().getDisplayMetrics().densityDpi;
2114         }
2115         return mContext.getResources().getDrawableForDensity(drawableId, density);
2116     }
2117 
getProfileIconForDensity(UserHandle user, int drawableId, int density)2118     private Drawable getProfileIconForDensity(UserHandle user, int drawableId, int density) {
2119         if (hasUserBadge(user.getIdentifier())) {
2120             return getDrawableForDensity(drawableId, density);
2121         }
2122         return null;
2123     }
2124 
2125     @Override
getUserBadgedLabel(CharSequence label, UserHandle user)2126     public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
2127         return getUserManager().getBadgedLabelForUser(label, user);
2128     }
2129 
2130     @Override
getResourcesForActivity(ComponentName activityName)2131     public Resources getResourcesForActivity(ComponentName activityName)
2132             throws NameNotFoundException {
2133         return getResourcesForApplication(
2134             getActivityInfo(activityName, sDefaultFlags).applicationInfo);
2135     }
2136 
2137     @Override
getResourcesForApplication(@onNull ApplicationInfo app)2138     public Resources getResourcesForApplication(@NonNull ApplicationInfo app)
2139             throws NameNotFoundException {
2140         return getResourcesForApplication(app, null);
2141     }
2142 
2143     @Override
getResourcesForApplication(@onNull ApplicationInfo app, @Nullable Configuration configuration)2144     public Resources getResourcesForApplication(@NonNull ApplicationInfo app,
2145             @Nullable Configuration configuration) throws NameNotFoundException {
2146         if (app.packageName.equals("system")) {
2147             Context sysuiContext = mContext.mMainThread.getSystemUiContext();
2148             if (configuration != null) {
2149                 sysuiContext = sysuiContext.createConfigurationContext(configuration);
2150             }
2151             return sysuiContext.getResources();
2152         }
2153         final boolean sameUid = (app.uid == Process.myUid());
2154         final Resources r = mContext.mMainThread.getTopLevelResources(
2155                 sameUid ? app.sourceDir : app.publicSourceDir,
2156                 sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
2157                 app.resourceDirs, app.overlayPaths, app.sharedLibraryFiles,
2158                 mContext.mPackageInfo, configuration);
2159         if (r != null) {
2160             return r;
2161         }
2162         throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2163     }
2164 
2165     @Override
getResourcesForApplication(String appPackageName)2166     public Resources getResourcesForApplication(String appPackageName)
2167             throws NameNotFoundException {
2168         return getResourcesForApplication(
2169             getApplicationInfo(appPackageName, sDefaultFlags));
2170     }
2171 
2172     /** @hide */
2173     @Override
getResourcesForApplicationAsUser(String appPackageName, int userId)2174     public Resources getResourcesForApplicationAsUser(String appPackageName, int userId)
2175             throws NameNotFoundException {
2176         if (userId < 0) {
2177             throw new IllegalArgumentException(
2178                     "Call does not support special user #" + userId);
2179         }
2180         if ("system".equals(appPackageName)) {
2181             return mContext.mMainThread.getSystemUiContext().getResources();
2182         }
2183         try {
2184             ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, sDefaultFlags, userId);
2185             if (ai != null) {
2186                 return getResourcesForApplication(ai);
2187             }
2188         } catch (RemoteException e) {
2189             throw e.rethrowFromSystemServer();
2190         }
2191         throw new NameNotFoundException("Package " + appPackageName + " doesn't exist");
2192     }
2193 
2194     volatile int mCachedSafeMode = -1;
2195 
2196     @Override
isSafeMode()2197     public boolean isSafeMode() {
2198         try {
2199             if (mCachedSafeMode < 0) {
2200                 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2201             }
2202             return mCachedSafeMode != 0;
2203         } catch (RemoteException e) {
2204             throw e.rethrowFromSystemServer();
2205         }
2206     }
2207 
2208     @Override
addOnPermissionsChangeListener(OnPermissionsChangedListener listener)2209     public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
2210         getPermissionManager().addOnPermissionsChangeListener(listener);
2211     }
2212 
2213     @Override
removeOnPermissionsChangeListener(OnPermissionsChangedListener listener)2214     public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
2215         getPermissionManager().removeOnPermissionsChangeListener(listener);
2216     }
2217 
2218     @UnsupportedAppUsage
2219     @RavenwoodReplace(reason = "<cinit> crashes due to unsupported class PropertyInvalidatedCache")
configurationChanged()2220     static void configurationChanged() {
2221         synchronized (sSync) {
2222             sIconCache.clear();
2223             sStringCache.clear();
2224         }
2225     }
2226 
configurationChanged$ravenwood()2227     private static void configurationChanged$ravenwood() {
2228         /* no-op */
2229     }
2230 
2231     @UnsupportedAppUsage
ApplicationPackageManager(ContextImpl context, IPackageManager pm)2232     protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
2233         mContext = context;
2234         mPM = pm;
2235         mUseSystemFeaturesCache = isSystemFeaturesCacheEnabledAndAvailable();
2236     }
2237 
isSystemFeaturesCacheEnabledAndAvailable()2238     private static boolean isSystemFeaturesCacheEnabledAndAvailable() {
2239         if (!android.content.pm.Flags.cacheSdkSystemFeatures()) {
2240             return false;
2241         }
2242         if (!com.android.internal.os.Flags.applicationSharedMemoryEnabled()) {
2243             return false;
2244         }
2245         if (ActivityThread.isSystem() && !SystemFeaturesCache.hasInstance()) {
2246             // There are a handful of utility "system" processes that are neither system_server nor
2247             // bound as applications. For these processes, we don't have access to application
2248             // shared memory or the dependent system features cache.
2249             // TODO(b/400713460): Revisit this exception after deprecating these command-like
2250             // system processes.
2251             return false;
2252         }
2253         return true;
2254     }
2255 
2256     /**
2257      * Update given flags when being used to request {@link PackageInfo}.
2258      */
updateFlagsForPackage(long flags, int userId)2259     private long updateFlagsForPackage(long flags, int userId) {
2260         if ((flags & (GET_ACTIVITIES | GET_RECEIVERS | GET_SERVICES | GET_PROVIDERS)) != 0) {
2261             // Caller is asking for component details, so they'd better be
2262             // asking for specific Direct Boot matching behavior
2263             if ((flags & (MATCH_DIRECT_BOOT_UNAWARE
2264                     | MATCH_DIRECT_BOOT_AWARE
2265                     | MATCH_DIRECT_BOOT_AUTO)) == 0) {
2266                 onImplicitDirectBoot(userId);
2267             }
2268         }
2269         return flags;
2270     }
2271 
2272     /**
2273      * Update given flags when being used to request {@link ApplicationInfo}.
2274      */
updateFlagsForApplication(long flags, int userId)2275     private long updateFlagsForApplication(long flags, int userId) {
2276         return updateFlagsForPackage(flags, userId);
2277     }
2278 
2279     /**
2280      * Update given flags when being used to request {@link ComponentInfo}.
2281      */
updateFlagsForComponent(@omponentInfoFlagsBits long flags, int userId, Intent intent)2282     private long updateFlagsForComponent(@ComponentInfoFlagsBits long flags, int userId,
2283             Intent intent) {
2284         if (intent != null) {
2285             if ((intent.getFlags() & Intent.FLAG_DIRECT_BOOT_AUTO) != 0) {
2286                 flags |= MATCH_DIRECT_BOOT_AUTO;
2287             }
2288         }
2289 
2290         // Caller is asking for component details, so they'd better be
2291         // asking for specific Direct Boot matching behavior
2292         if ((flags & (MATCH_DIRECT_BOOT_UNAWARE
2293                 | MATCH_DIRECT_BOOT_AWARE
2294                 | MATCH_DIRECT_BOOT_AUTO)) == 0) {
2295             onImplicitDirectBoot(userId);
2296         }
2297         return flags;
2298     }
2299 
onImplicitDirectBoot(int userId)2300     private void onImplicitDirectBoot(int userId) {
2301         // Only report if someone is relying on implicit behavior while the user
2302         // is locked; code running when unlocked is going to see both aware and
2303         // unaware components.
2304         if (StrictMode.vmImplicitDirectBootEnabled()) {
2305             // We can cache the unlocked state for the userId we're running as,
2306             // since any relocking of that user will always result in our
2307             // process being killed to release any CE FDs we're holding onto.
2308             if (userId == UserHandle.myUserId()) {
2309                 if (mUserUnlocked) {
2310                     return;
2311                 } else if (mContext.getSystemService(UserManager.class)
2312                         .isUserUnlockingOrUnlocked(userId)) {
2313                     mUserUnlocked = true;
2314                 } else {
2315                     StrictMode.onImplicitDirectBoot();
2316                 }
2317             } else if (!mContext.getSystemService(UserManager.class)
2318                     .isUserUnlockingOrUnlocked(userId)) {
2319                 StrictMode.onImplicitDirectBoot();
2320             }
2321         }
2322     }
2323 
2324     @Nullable
getCachedIcon(@onNull ResourceName name)2325     private Drawable getCachedIcon(@NonNull ResourceName name) {
2326         synchronized (sSync) {
2327             final WeakReference<Drawable.ConstantState> wr = sIconCache.get(name);
2328             if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2329                                    + name + ": " + wr);
2330             if (wr != null) {   // we have the activity
2331                 final Drawable.ConstantState state = wr.get();
2332                 if (state != null) {
2333                     if (DEBUG_ICONS) {
2334                         Log.v(TAG, "Get cached drawable state for " + name + ": " + state);
2335                     }
2336                     // Note: It's okay here to not use the newDrawable(Resources) variant
2337                     //       of the API. The ConstantState comes from a drawable that was
2338                     //       originally created by passing the proper app Resources instance
2339                     //       which means the state should already contain the proper
2340                     //       resources specific information (like density.) See
2341                     //       BitmapDrawable.BitmapState for instance.
2342                     return state.newDrawable();
2343                 }
2344                 // our entry has been purged
2345                 sIconCache.remove(name);
2346             }
2347         }
2348         return null;
2349     }
2350 
putCachedIcon(@onNull ResourceName name, @NonNull Drawable dr)2351     private void putCachedIcon(@NonNull ResourceName name, @NonNull Drawable dr) {
2352         synchronized (sSync) {
2353             sIconCache.put(name, new WeakReference<>(dr.getConstantState()));
2354             if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable state for " + name + ": " + dr);
2355         }
2356     }
2357 
handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo)2358     static void handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo) {
2359         boolean immediateGc = false;
2360         if (cmd == ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE) {
2361             immediateGc = true;
2362         }
2363         if (pkgList != null && (pkgList.length > 0)) {
2364             boolean needCleanup = false;
2365             for (String ssp : pkgList) {
2366                 synchronized (sSync) {
2367                     for (int i=sIconCache.size()-1; i>=0; i--) {
2368                         ResourceName nm = sIconCache.keyAt(i);
2369                         if (nm.packageName.equals(ssp)) {
2370                             //Log.i(TAG, "Removing cached drawable for " + nm);
2371                             sIconCache.removeAt(i);
2372                             needCleanup = true;
2373                         }
2374                     }
2375                     for (int i=sStringCache.size()-1; i>=0; i--) {
2376                         ResourceName nm = sStringCache.keyAt(i);
2377                         if (nm.packageName.equals(ssp)) {
2378                             //Log.i(TAG, "Removing cached string for " + nm);
2379                             sStringCache.removeAt(i);
2380                             needCleanup = true;
2381                         }
2382                     }
2383                 }
2384             }
2385             if (needCleanup || hasPkgInfo) {
2386                 if (immediateGc) {
2387                     // Schedule an immediate gc.
2388                     Runtime.getRuntime().gc();
2389                 } else {
2390                     ActivityThread.currentActivityThread().scheduleGcIdler();
2391                 }
2392             }
2393         }
2394     }
2395 
2396     private static final class ResourceName {
2397         final String packageName;
2398         final int iconId;
2399 
ResourceName(String _packageName, int _iconId)2400         ResourceName(String _packageName, int _iconId) {
2401             packageName = _packageName;
2402             iconId = _iconId;
2403         }
2404 
ResourceName(ApplicationInfo aInfo, int _iconId)2405         ResourceName(ApplicationInfo aInfo, int _iconId) {
2406             this(aInfo.packageName, _iconId);
2407         }
2408 
ResourceName(ComponentInfo cInfo, int _iconId)2409         ResourceName(ComponentInfo cInfo, int _iconId) {
2410             this(cInfo.applicationInfo.packageName, _iconId);
2411         }
2412 
ResourceName(ResolveInfo rInfo, int _iconId)2413         ResourceName(ResolveInfo rInfo, int _iconId) {
2414             this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2415         }
2416 
2417         @Override
equals(@ullable Object o)2418         public boolean equals(@Nullable Object o) {
2419             if (this == o) return true;
2420             if (o == null || getClass() != o.getClass()) return false;
2421 
2422             ResourceName that = (ResourceName) o;
2423 
2424             if (iconId != that.iconId) return false;
2425             return !(packageName != null ?
2426                      !packageName.equals(that.packageName) : that.packageName != null);
2427 
2428         }
2429 
2430         @Override
hashCode()2431         public int hashCode() {
2432             int result;
2433             result = packageName.hashCode();
2434             result = 31 * result + iconId;
2435             return result;
2436         }
2437 
2438         @Override
toString()2439         public String toString() {
2440             return "{ResourceName " + packageName + " / " + iconId + "}";
2441         }
2442     }
2443 
getCachedString(ResourceName name)2444     private CharSequence getCachedString(ResourceName name) {
2445         synchronized (sSync) {
2446             WeakReference<CharSequence> wr = sStringCache.get(name);
2447             if (wr != null) {   // we have the activity
2448                 CharSequence cs = wr.get();
2449                 if (cs != null) {
2450                     return cs;
2451                 }
2452                 // our entry has been purged
2453                 sStringCache.remove(name);
2454             }
2455         }
2456         return null;
2457     }
2458 
putCachedString(ResourceName name, CharSequence cs)2459     private void putCachedString(ResourceName name, CharSequence cs) {
2460         synchronized (sSync) {
2461             sStringCache.put(name, new WeakReference<CharSequence>(cs));
2462         }
2463     }
2464 
2465     @Override
getText(String packageName, @StringRes int resid, ApplicationInfo appInfo)2466     public CharSequence getText(String packageName, @StringRes int resid,
2467                                 ApplicationInfo appInfo) {
2468         ResourceName name = new ResourceName(packageName, resid);
2469         CharSequence text = getCachedString(name);
2470         if (text != null) {
2471             return text;
2472         }
2473         if (appInfo == null) {
2474             try {
2475                 appInfo = getApplicationInfo(packageName, sDefaultFlags);
2476             } catch (NameNotFoundException e) {
2477                 return null;
2478             }
2479         }
2480         try {
2481             Resources r = getResourcesForApplication(appInfo);
2482             text = r.getText(resid);
2483             putCachedString(name, text);
2484             return text;
2485         } catch (NameNotFoundException e) {
2486             Log.w("PackageManager", "Failure retrieving resources for "
2487                   + appInfo.packageName);
2488         } catch (RuntimeException e) {
2489             // If an exception was thrown, fall through to return
2490             // default icon.
2491             Log.w("PackageManager", "Failure retrieving text 0x"
2492                   + Integer.toHexString(resid) + " in package "
2493                   + packageName, e);
2494         }
2495         return null;
2496     }
2497 
2498     @Override
getXml(String packageName, @XmlRes int resid, ApplicationInfo appInfo)2499     public XmlResourceParser getXml(String packageName, @XmlRes int resid,
2500                                     ApplicationInfo appInfo) {
2501         if (appInfo == null) {
2502             try {
2503                 appInfo = getApplicationInfo(packageName, sDefaultFlags);
2504             } catch (NameNotFoundException e) {
2505                 return null;
2506             }
2507         }
2508         try {
2509             Resources r = getResourcesForApplication(appInfo);
2510             return r.getXml(resid);
2511         } catch (RuntimeException e) {
2512             // If an exception was thrown, fall through to return
2513             // default icon.
2514             Log.w("PackageManager", "Failure retrieving xml 0x"
2515                   + Integer.toHexString(resid) + " in package "
2516                   + packageName, e);
2517         } catch (NameNotFoundException e) {
2518             Log.w("PackageManager", "Failure retrieving resources for "
2519                   + appInfo.packageName);
2520         }
2521         return null;
2522     }
2523 
2524     @Override
getApplicationLabel(ApplicationInfo info)2525     public CharSequence getApplicationLabel(ApplicationInfo info) {
2526         return info.loadLabel(this);
2527     }
2528 
2529     @Override
installExistingPackage(String packageName)2530     public int installExistingPackage(String packageName) throws NameNotFoundException {
2531         return installExistingPackage(packageName, INSTALL_REASON_UNKNOWN);
2532     }
2533 
2534     @Override
installExistingPackage(String packageName, int installReason)2535     public int installExistingPackage(String packageName, int installReason)
2536             throws NameNotFoundException {
2537         return installExistingPackageAsUser(packageName, installReason, getUserId());
2538     }
2539 
2540     @Override
installExistingPackageAsUser(String packageName, int userId)2541     public int installExistingPackageAsUser(String packageName, int userId)
2542             throws NameNotFoundException {
2543         return installExistingPackageAsUser(packageName, INSTALL_REASON_UNKNOWN,
2544                 userId);
2545     }
2546 
installExistingPackageAsUser(String packageName, int installReason, int userId)2547     private int installExistingPackageAsUser(String packageName, int installReason, int userId)
2548             throws NameNotFoundException {
2549         try {
2550             int res = mPM.installExistingPackageAsUser(packageName, userId,
2551                     INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS, installReason, null);
2552             if (res == INSTALL_FAILED_INVALID_URI) {
2553                 throw new NameNotFoundException("Package " + packageName + " doesn't exist");
2554             }
2555             return res;
2556         } catch (RemoteException e) {
2557             throw e.rethrowFromSystemServer();
2558         }
2559     }
2560 
2561     @Override
verifyPendingInstall(int id, int response)2562     public void verifyPendingInstall(int id, int response) {
2563         try {
2564             mPM.verifyPendingInstall(id, response);
2565         } catch (RemoteException e) {
2566             throw e.rethrowFromSystemServer();
2567         }
2568     }
2569 
2570     @Override
extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay)2571     public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
2572             long millisecondsToDelay) {
2573         try {
2574             mPM.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay);
2575         } catch (RemoteException e) {
2576             throw e.rethrowFromSystemServer();
2577         }
2578     }
2579 
2580     @Override
verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)2581     public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
2582         try {
2583             mPM.verifyIntentFilter(id, verificationCode, failedDomains);
2584         } catch (RemoteException e) {
2585             throw e.rethrowFromSystemServer();
2586         }
2587     }
2588 
2589     @Override
getIntentVerificationStatusAsUser(String packageName, int userId)2590     public int getIntentVerificationStatusAsUser(String packageName, int userId) {
2591         try {
2592             return mPM.getIntentVerificationStatus(packageName, userId);
2593         } catch (RemoteException e) {
2594             throw e.rethrowFromSystemServer();
2595         }
2596     }
2597 
2598     @Override
updateIntentVerificationStatusAsUser(String packageName, int status, int userId)2599     public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
2600         try {
2601             return mPM.updateIntentVerificationStatus(packageName, status, userId);
2602         } catch (RemoteException e) {
2603             throw e.rethrowFromSystemServer();
2604         }
2605     }
2606 
2607     @Override
2608     @SuppressWarnings("unchecked")
getIntentFilterVerifications(String packageName)2609     public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
2610         try {
2611             ParceledListSlice<IntentFilterVerificationInfo> parceledList =
2612                     mPM.getIntentFilterVerifications(packageName);
2613             if (parceledList == null) {
2614                 return Collections.emptyList();
2615             }
2616             return parceledList.getList();
2617         } catch (RemoteException e) {
2618             throw e.rethrowFromSystemServer();
2619         }
2620     }
2621 
2622     @Override
2623     @SuppressWarnings("unchecked")
getAllIntentFilters(String packageName)2624     public List<IntentFilter> getAllIntentFilters(String packageName) {
2625         try {
2626             ParceledListSlice<IntentFilter> parceledList =
2627                     mPM.getAllIntentFilters(packageName);
2628             if (parceledList == null) {
2629                 return Collections.emptyList();
2630             }
2631             return parceledList.getList();
2632         } catch (RemoteException e) {
2633             throw e.rethrowFromSystemServer();
2634         }
2635     }
2636 
2637     @Override
getDefaultBrowserPackageNameAsUser(int userId)2638     public String getDefaultBrowserPackageNameAsUser(int userId) {
2639         RoleManager roleManager = mContext.getSystemService(RoleManager.class);
2640         return roleManager.getBrowserRoleHolder(userId);
2641     }
2642 
2643     @Override
setDefaultBrowserPackageNameAsUser(String packageName, int userId)2644     public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
2645         RoleManager roleManager = mContext.getSystemService(RoleManager.class);
2646         return roleManager.setBrowserRoleHolder(packageName, userId);
2647     }
2648 
2649     @Override
setInstallerPackageName(String targetPackage, String installerPackageName)2650     public void setInstallerPackageName(String targetPackage,
2651             String installerPackageName) {
2652         try {
2653             mPM.setInstallerPackageName(targetPackage, installerPackageName);
2654         } catch (RemoteException e) {
2655             throw e.rethrowFromSystemServer();
2656         }
2657     }
2658 
2659     @Override
setUpdateAvailable(String packageName, boolean updateAvailable)2660     public void setUpdateAvailable(String packageName, boolean updateAvailable) {
2661         try {
2662             mPM.setUpdateAvailable(packageName, updateAvailable);
2663         } catch (RemoteException e) {
2664             throw e.rethrowFromSystemServer();
2665         }
2666     }
2667 
2668     @Override
getInstallerPackageName(String packageName)2669     public String getInstallerPackageName(String packageName) {
2670         try {
2671             return mPM.getInstallerPackageName(packageName);
2672         } catch (RemoteException e) {
2673             throw e.rethrowFromSystemServer();
2674         }
2675     }
2676 
2677     @Override
2678     @NonNull
getInstallSourceInfo(String packageName)2679     public InstallSourceInfo getInstallSourceInfo(String packageName) throws NameNotFoundException {
2680         final InstallSourceInfo installSourceInfo;
2681         try {
2682             installSourceInfo = mPM.getInstallSourceInfo(packageName, getUserId());
2683         } catch (RemoteException e) {
2684             throw e.rethrowFromSystemServer();
2685         }
2686         if (installSourceInfo == null) {
2687             throw new NameNotFoundException(packageName);
2688         }
2689         return installSourceInfo;
2690     }
2691 
2692     @Override
isAppArchivable(String packageName)2693     public boolean isAppArchivable(String packageName) throws NameNotFoundException {
2694         try {
2695             Objects.requireNonNull(packageName);
2696             return mPM.isAppArchivable(packageName, new UserHandle(getUserId()));
2697         } catch (ParcelableException e) {
2698             e.maybeRethrow(NameNotFoundException.class);
2699             throw new RuntimeException(e);
2700         } catch (RemoteException e) {
2701             throw e.rethrowFromSystemServer();
2702         }
2703     }
2704 
2705     @Override
getMoveStatus(int moveId)2706     public int getMoveStatus(int moveId) {
2707         try {
2708             return mPM.getMoveStatus(moveId);
2709         } catch (RemoteException e) {
2710             throw e.rethrowFromSystemServer();
2711         }
2712     }
2713 
2714     @Override
registerMoveCallback(MoveCallback callback, Handler handler)2715     public void registerMoveCallback(MoveCallback callback, Handler handler) {
2716         synchronized (mDelegates) {
2717             final MoveCallbackDelegate delegate = new MoveCallbackDelegate(callback,
2718                     handler.getLooper());
2719             try {
2720                 mPM.registerMoveCallback(delegate);
2721             } catch (RemoteException e) {
2722                 throw e.rethrowFromSystemServer();
2723             }
2724             mDelegates.add(delegate);
2725         }
2726     }
2727 
2728     @Override
unregisterMoveCallback(MoveCallback callback)2729     public void unregisterMoveCallback(MoveCallback callback) {
2730         synchronized (mDelegates) {
2731             for (Iterator<MoveCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
2732                 final MoveCallbackDelegate delegate = i.next();
2733                 if (delegate.mCallback == callback) {
2734                     try {
2735                         mPM.unregisterMoveCallback(delegate);
2736                     } catch (RemoteException e) {
2737                         throw e.rethrowFromSystemServer();
2738                     }
2739                     i.remove();
2740                 }
2741             }
2742         }
2743     }
2744 
2745     @Override
movePackage(String packageName, VolumeInfo vol)2746     public int movePackage(String packageName, VolumeInfo vol) {
2747         try {
2748             final String volumeUuid;
2749             if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
2750                 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
2751             } else if (vol.isPrimaryPhysical()) {
2752                 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
2753             } else {
2754                 volumeUuid = Objects.requireNonNull(vol.fsUuid);
2755             }
2756 
2757             return mPM.movePackage(packageName, volumeUuid);
2758         } catch (RemoteException e) {
2759             throw e.rethrowFromSystemServer();
2760         }
2761     }
2762 
2763     @Override
2764     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
getPackageCurrentVolume(ApplicationInfo app)2765     public @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
2766         final StorageManager storage = mContext.getSystemService(StorageManager.class);
2767         return getPackageCurrentVolume(app, storage);
2768     }
2769 
2770     @VisibleForTesting
getPackageCurrentVolume(ApplicationInfo app, StorageManager storage)2771     protected @Nullable VolumeInfo getPackageCurrentVolume(ApplicationInfo app,
2772             StorageManager storage) {
2773         if (app.isInternal()) {
2774             return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
2775         } else {
2776             return storage.findVolumeByUuid(app.volumeUuid);
2777         }
2778     }
2779 
2780     @Override
getPackageCandidateVolumes(ApplicationInfo app)2781     public @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
2782         final StorageManager storageManager = mContext.getSystemService(StorageManager.class);
2783         return getPackageCandidateVolumes(app, storageManager, mPM);
2784     }
2785 
2786     @VisibleForTesting
getPackageCandidateVolumes(ApplicationInfo app, StorageManager storageManager, IPackageManager pm)2787     protected @NonNull List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app,
2788             StorageManager storageManager, IPackageManager pm) {
2789         final VolumeInfo currentVol = getPackageCurrentVolume(app, storageManager);
2790         final List<VolumeInfo> vols = storageManager.getVolumes();
2791         final List<VolumeInfo> candidates = new ArrayList<>();
2792         for (VolumeInfo vol : vols) {
2793             if (Objects.equals(vol, currentVol)
2794                     || isPackageCandidateVolume(mContext, app, vol, pm)) {
2795                 candidates.add(vol);
2796             }
2797         }
2798         return candidates;
2799     }
2800 
2801     @VisibleForTesting
isForceAllowOnExternal(Context context)2802     protected boolean isForceAllowOnExternal(Context context) {
2803         return Settings.Global.getInt(
2804                 context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0;
2805     }
2806 
2807     @VisibleForTesting
isAllow3rdPartyOnInternal(Context context)2808     protected boolean isAllow3rdPartyOnInternal(Context context) {
2809         return context.getResources().getBoolean(
2810                 com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
2811     }
2812 
isPackageCandidateVolume( ContextImpl context, ApplicationInfo app, VolumeInfo vol, IPackageManager pm)2813     private boolean isPackageCandidateVolume(
2814             ContextImpl context, ApplicationInfo app, VolumeInfo vol, IPackageManager pm) {
2815         final boolean forceAllowOnExternal = isForceAllowOnExternal(context);
2816 
2817         if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
2818             return app.isSystemApp() || isAllow3rdPartyOnInternal(context);
2819         }
2820 
2821         // System apps and apps demanding internal storage can't be moved
2822         // anywhere else
2823         if (app.isSystemApp()) {
2824             return false;
2825         }
2826         if (!forceAllowOnExternal
2827                 && (app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY
2828                         || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED)) {
2829             return false;
2830         }
2831 
2832         // Gotta be able to write there
2833         if (!vol.isMountedWritable()) {
2834             return false;
2835         }
2836 
2837         // Moving into an ASEC on public primary is only option internal
2838         if (vol.isPrimaryPhysical()) {
2839             return app.isInternal();
2840         }
2841 
2842         // Some apps can't be moved. (e.g. device admins)
2843         try {
2844             if (pm.isPackageDeviceAdminOnAnyUser(app.packageName)) {
2845                 return false;
2846             }
2847         } catch (RemoteException e) {
2848             throw e.rethrowFromSystemServer();
2849         }
2850 
2851         // Otherwise we can move to any private volume
2852         return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
2853     }
2854 
2855     @Override
movePrimaryStorage(VolumeInfo vol)2856     public int movePrimaryStorage(VolumeInfo vol) {
2857         try {
2858             final String volumeUuid;
2859             if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.id)) {
2860                 volumeUuid = StorageManager.UUID_PRIVATE_INTERNAL;
2861             } else if (vol.isPrimaryPhysical()) {
2862                 volumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
2863             } else {
2864                 volumeUuid = Objects.requireNonNull(vol.fsUuid);
2865             }
2866 
2867             return mPM.movePrimaryStorage(volumeUuid);
2868         } catch (RemoteException e) {
2869             throw e.rethrowFromSystemServer();
2870         }
2871     }
2872 
2873     @Override
getPrimaryStorageCurrentVolume()2874     public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
2875         final StorageManager storage = mContext.getSystemService(StorageManager.class);
2876         final String volumeUuid = storage.getPrimaryStorageUuid();
2877         return storage.findVolumeByQualifiedUuid(volumeUuid);
2878     }
2879 
2880     @Override
getPrimaryStorageCandidateVolumes()2881     public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
2882         final StorageManager storage = mContext.getSystemService(StorageManager.class);
2883         final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
2884         final List<VolumeInfo> vols = storage.getVolumes();
2885         final List<VolumeInfo> candidates = new ArrayList<>();
2886         if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL,
2887                 storage.getPrimaryStorageUuid()) && currentVol != null) {
2888             // TODO: support moving primary physical to emulated volume
2889             candidates.add(currentVol);
2890         } else {
2891             for (VolumeInfo vol : vols) {
2892                 if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
2893                     candidates.add(vol);
2894                 }
2895             }
2896         }
2897         return candidates;
2898     }
2899 
isPrimaryStorageCandidateVolume(VolumeInfo vol)2900     private static boolean isPrimaryStorageCandidateVolume(VolumeInfo vol) {
2901         // Private internal is always an option
2902         if (VolumeInfo.ID_PRIVATE_INTERNAL.equals(vol.getId())) {
2903             return true;
2904         }
2905 
2906         // Gotta be able to write there
2907         if (!vol.isMountedWritable()) {
2908             return false;
2909         }
2910 
2911         // We can move to any private volume
2912         return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
2913     }
2914 
2915     @Override
2916     @UnsupportedAppUsage
deletePackage(String packageName, IPackageDeleteObserver observer, int flags)2917     public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2918         deletePackageAsUser(packageName, observer, flags, getUserId());
2919     }
2920 
2921     @Override
deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags, int userId)2922     public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer,
2923             int flags, int userId) {
2924         try {
2925             mPM.deletePackageAsUser(packageName, VERSION_CODE_HIGHEST,
2926                     observer, userId, flags);
2927         } catch (RemoteException e) {
2928             throw e.rethrowFromSystemServer();
2929         }
2930     }
2931 
2932     @Override
clearApplicationUserData(String packageName, IPackageDataObserver observer)2933     public void clearApplicationUserData(String packageName,
2934                                          IPackageDataObserver observer) {
2935         try {
2936             mPM.clearApplicationUserData(packageName, observer, getUserId());
2937         } catch (RemoteException e) {
2938             throw e.rethrowFromSystemServer();
2939         }
2940     }
2941     @Override
deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer)2942     public void deleteApplicationCacheFiles(String packageName,
2943                                             IPackageDataObserver observer) {
2944         try {
2945             mPM.deleteApplicationCacheFiles(packageName, observer);
2946         } catch (RemoteException e) {
2947             throw e.rethrowFromSystemServer();
2948         }
2949     }
2950 
2951     @Override
deleteApplicationCacheFilesAsUser(String packageName, int userId, IPackageDataObserver observer)2952     public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
2953             IPackageDataObserver observer) {
2954         try {
2955             mPM.deleteApplicationCacheFilesAsUser(packageName, userId, observer);
2956         } catch (RemoteException e) {
2957             throw e.rethrowFromSystemServer();
2958         }
2959     }
2960 
2961     @Override
freeStorageAndNotify(String volumeUuid, long idealStorageSize, IPackageDataObserver observer)2962     public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
2963             IPackageDataObserver observer) {
2964         try {
2965             mPM.freeStorageAndNotify(volumeUuid, idealStorageSize, 0, observer);
2966         } catch (RemoteException e) {
2967             throw e.rethrowFromSystemServer();
2968         }
2969     }
2970 
2971     @Override
freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi)2972     public void freeStorage(String volumeUuid, long freeStorageSize, IntentSender pi) {
2973         try {
2974             mPM.freeStorage(volumeUuid, freeStorageSize, 0, pi);
2975         } catch (RemoteException e) {
2976             throw e.rethrowFromSystemServer();
2977         }
2978     }
2979 
2980     @Override
setDistractingPackageRestrictions(String[] packages, int distractionFlags)2981     public String[] setDistractingPackageRestrictions(String[] packages, int distractionFlags) {
2982         try {
2983             return mPM.setDistractingPackageRestrictionsAsUser(packages, distractionFlags,
2984                     mContext.getUserId());
2985         } catch (RemoteException e) {
2986             throw e.rethrowFromSystemServer();
2987         }
2988     }
2989 
2990     @Override
setPackagesSuspended(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, String dialogMessage)2991     public String[] setPackagesSuspended(String[] packageNames, boolean suspended,
2992             PersistableBundle appExtras, PersistableBundle launcherExtras,
2993             String dialogMessage) {
2994         final SuspendDialogInfo dialogInfo = !TextUtils.isEmpty(dialogMessage)
2995                 ? new SuspendDialogInfo.Builder().setMessage(dialogMessage).build()
2996                 : null;
2997         return setPackagesSuspended(packageNames, suspended, appExtras, launcherExtras,
2998                 dialogInfo, 0);
2999     }
3000 
3001     @Override
setPackagesSuspended(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, SuspendDialogInfo dialogInfo)3002     public String[] setPackagesSuspended(String[] packageNames, boolean suspended,
3003             PersistableBundle appExtras, PersistableBundle launcherExtras,
3004             SuspendDialogInfo dialogInfo) {
3005         return setPackagesSuspended(packageNames, suspended, appExtras, launcherExtras,
3006                 dialogInfo, 0);
3007     }
3008 
3009     @Override
setPackagesSuspended(String[] packageNames, boolean suspended, PersistableBundle appExtras, PersistableBundle launcherExtras, SuspendDialogInfo dialogInfo, int flags)3010     public String[] setPackagesSuspended(String[] packageNames, boolean suspended,
3011             PersistableBundle appExtras, PersistableBundle launcherExtras,
3012             SuspendDialogInfo dialogInfo, int flags) {
3013         try {
3014             return mPM.setPackagesSuspendedAsUser(packageNames, suspended, appExtras,
3015                     launcherExtras, dialogInfo, flags, mContext.getOpPackageName(),
3016                     UserHandle.myUserId() /* suspendingUserId */, getUserId() /* targetUserId */);
3017         } catch (RemoteException e) {
3018             throw e.rethrowFromSystemServer();
3019         }
3020     }
3021 
3022     @Override
getUnsuspendablePackages(String[] packageNames)3023     public String[] getUnsuspendablePackages(String[] packageNames) {
3024         try {
3025             return mPM.getUnsuspendablePackagesForUser(packageNames, mContext.getUserId());
3026         } catch (RemoteException e) {
3027             throw e.rethrowFromSystemServer();
3028         }
3029     }
3030 
3031     @Override
getSuspendedPackageAppExtras()3032     public Bundle getSuspendedPackageAppExtras() {
3033         try {
3034             return mPM.getSuspendedPackageAppExtras(mContext.getOpPackageName(), getUserId());
3035         } catch (RemoteException e) {
3036             throw e.rethrowFromSystemServer();
3037         }
3038     }
3039 
3040     @Override
getSuspendingPackage(String suspendedPackage)3041     public String getSuspendingPackage(String suspendedPackage) {
3042         try {
3043             return mPM.getSuspendingPackage(suspendedPackage, getUserId());
3044         } catch (RemoteException e) {
3045             throw e.rethrowFromSystemServer();
3046         }
3047     }
3048 
3049     @Override
isPackageSuspendedForUser(String packageName, int userId)3050     public boolean isPackageSuspendedForUser(String packageName, int userId) {
3051         try {
3052             return mPM.isPackageSuspendedForUser(packageName, userId);
3053         } catch (RemoteException e) {
3054             throw e.rethrowFromSystemServer();
3055         }
3056     }
3057 
3058     /** @hide */
3059     @Override
isPackageSuspended(String packageName)3060     public boolean isPackageSuspended(String packageName) throws NameNotFoundException {
3061         try {
3062             return isPackageSuspendedForUser(packageName, getUserId());
3063         } catch (IllegalArgumentException ie) {
3064             throw new NameNotFoundException(packageName);
3065         }
3066     }
3067 
3068     @Override
isPackageSuspended()3069     public boolean isPackageSuspended() {
3070         return isPackageSuspendedForUser(mContext.getOpPackageName(), getUserId());
3071     }
3072 
3073     @Override
isPackageQuarantined(@onNull String packageName)3074     public boolean isPackageQuarantined(@NonNull String packageName) throws NameNotFoundException {
3075         try {
3076             return mPM.isPackageQuarantinedForUser(packageName, getUserId());
3077         } catch (IllegalArgumentException ie) {
3078             throw new NameNotFoundException(packageName);
3079         } catch (RemoteException e) {
3080             throw e.rethrowFromSystemServer();
3081         }
3082     }
3083 
3084     @Override
isPackageStopped(@onNull String packageName)3085     public boolean isPackageStopped(@NonNull String packageName) throws NameNotFoundException {
3086         try {
3087             return mPM.isPackageStoppedForUser(packageName, getUserId());
3088         } catch (IllegalArgumentException ie) {
3089             throw new NameNotFoundException(packageName);
3090         } catch (RemoteException e) {
3091             throw e.rethrowFromSystemServer();
3092         }
3093     }
3094 
3095     /** @hide */
3096     @Override
setApplicationCategoryHint(String packageName, int categoryHint)3097     public void setApplicationCategoryHint(String packageName, int categoryHint) {
3098         try {
3099             mPM.setApplicationCategoryHint(packageName, categoryHint,
3100                     mContext.getOpPackageName());
3101         } catch (RemoteException e) {
3102             throw e.rethrowFromSystemServer();
3103         }
3104     }
3105 
3106     @Override
3107     @UnsupportedAppUsage
getPackageSizeInfoAsUser(String packageName, int userHandle, IPackageStatsObserver observer)3108     public void getPackageSizeInfoAsUser(String packageName, int userHandle,
3109             IPackageStatsObserver observer) {
3110         final String msg = "Shame on you for calling the hidden API "
3111                 + "getPackageSizeInfoAsUser(). Shame!";
3112         if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {
3113             throw new UnsupportedOperationException(msg);
3114         } else if (observer != null) {
3115             Log.d(TAG, msg);
3116             try {
3117                 observer.onGetStatsCompleted(null, false);
3118             } catch (RemoteException ignored) {
3119             }
3120         }
3121     }
3122 
3123     @Override
addPackageToPreferred(String packageName)3124     public void addPackageToPreferred(String packageName) {
3125         Log.w(TAG, "addPackageToPreferred() is a no-op");
3126     }
3127 
3128     @Override
removePackageFromPreferred(String packageName)3129     public void removePackageFromPreferred(String packageName) {
3130         Log.w(TAG, "removePackageFromPreferred() is a no-op");
3131     }
3132 
3133     @Override
getPreferredPackages(int flags)3134     public List<PackageInfo> getPreferredPackages(int flags) {
3135         Log.w(TAG, "getPreferredPackages() is a no-op");
3136         return Collections.emptyList();
3137     }
3138 
3139     @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)3140     public void addPreferredActivity(IntentFilter filter,
3141                                      int match, ComponentName[] set, ComponentName activity) {
3142         try {
3143             mPM.addPreferredActivity(filter, match, set, activity, getUserId(), false);
3144         } catch (RemoteException e) {
3145             throw e.rethrowFromSystemServer();
3146         }
3147     }
3148 
3149     @Override
addPreferredActivityAsUser(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)3150     public void addPreferredActivityAsUser(IntentFilter filter, int match,
3151             ComponentName[] set, ComponentName activity, int userId) {
3152         try {
3153             mPM.addPreferredActivity(filter, match, set, activity, userId, false);
3154         } catch (RemoteException e) {
3155             throw e.rethrowFromSystemServer();
3156         }
3157     }
3158 
3159     @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)3160     public void replacePreferredActivity(IntentFilter filter,
3161                                          int match, ComponentName[] set, ComponentName activity) {
3162         try {
3163             mPM.replacePreferredActivity(filter, match, set, activity, getUserId());
3164         } catch (RemoteException e) {
3165             throw e.rethrowFromSystemServer();
3166         }
3167     }
3168 
3169     @Override
replacePreferredActivityAsUser(IntentFilter filter, int match, ComponentName[] set, ComponentName activity, int userId)3170     public void replacePreferredActivityAsUser(IntentFilter filter,
3171                                          int match, ComponentName[] set, ComponentName activity,
3172                                          int userId) {
3173         try {
3174             mPM.replacePreferredActivity(filter, match, set, activity, userId);
3175         } catch (RemoteException e) {
3176             throw e.rethrowFromSystemServer();
3177         }
3178     }
3179 
3180     @Override
clearPackagePreferredActivities(String packageName)3181     public void clearPackagePreferredActivities(String packageName) {
3182         try {
3183             mPM.clearPackagePreferredActivities(packageName);
3184         } catch (RemoteException e) {
3185             throw e.rethrowFromSystemServer();
3186         }
3187     }
3188 
3189     @Override
addUniquePreferredActivity(@onNull IntentFilter filter, int match, @Nullable ComponentName[] set, @NonNull ComponentName activity)3190     public void addUniquePreferredActivity(@NonNull IntentFilter filter, int match,
3191             @Nullable ComponentName[] set, @NonNull ComponentName activity) {
3192         try {
3193             mPM.addPreferredActivity(filter, match, set, activity, getUserId(), true);
3194         } catch (RemoteException e) {
3195             throw e.rethrowFromSystemServer();
3196         }
3197     }
3198 
3199     @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)3200     public int getPreferredActivities(List<IntentFilter> outFilters,
3201                                       List<ComponentName> outActivities, String packageName) {
3202         try {
3203             return mPM.getPreferredActivities(outFilters, outActivities, packageName);
3204         } catch (RemoteException e) {
3205             throw e.rethrowFromSystemServer();
3206         }
3207     }
3208 
3209     @Override
getHomeActivities(List<ResolveInfo> outActivities)3210     public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
3211         try {
3212             return mPM.getHomeActivities(outActivities);
3213         } catch (RemoteException e) {
3214             throw e.rethrowFromSystemServer();
3215         }
3216     }
3217 
3218     @Override
setSyntheticAppDetailsActivityEnabled(String packageName, boolean enabled)3219     public void setSyntheticAppDetailsActivityEnabled(String packageName, boolean enabled) {
3220         try {
3221             ComponentName componentName = new ComponentName(packageName,
3222                     APP_DETAILS_ACTIVITY_CLASS_NAME);
3223             mPM.setComponentEnabledSetting(componentName, enabled
3224                     ? COMPONENT_ENABLED_STATE_DEFAULT
3225                     : COMPONENT_ENABLED_STATE_DISABLED,
3226                     DONT_KILL_APP, getUserId(), mContext.getOpPackageName());
3227         } catch (RemoteException e) {
3228             throw e.rethrowFromSystemServer();
3229         }
3230     }
3231 
3232     @Override
getSyntheticAppDetailsActivityEnabled(String packageName)3233     public boolean getSyntheticAppDetailsActivityEnabled(String packageName) {
3234         try {
3235             ComponentName componentName = new ComponentName(packageName,
3236                     APP_DETAILS_ACTIVITY_CLASS_NAME);
3237             int state = mPM.getComponentEnabledSetting(componentName, getUserId());
3238             return state == COMPONENT_ENABLED_STATE_ENABLED
3239                     || state == COMPONENT_ENABLED_STATE_DEFAULT;
3240         } catch (RemoteException e) {
3241             throw e.rethrowFromSystemServer();
3242         }
3243     }
3244 
3245     @Override
setComponentEnabledSetting(ComponentName componentName, int newState, int flags)3246     public void setComponentEnabledSetting(ComponentName componentName,
3247                                            int newState, int flags) {
3248         try {
3249             mPM.setComponentEnabledSetting(componentName, newState, flags, getUserId(),
3250                     mContext.getOpPackageName());
3251         } catch (RemoteException e) {
3252             throw e.rethrowFromSystemServer();
3253         }
3254     }
3255 
3256     @Override
setComponentEnabledSettings(List<ComponentEnabledSetting> settings)3257     public void setComponentEnabledSettings(List<ComponentEnabledSetting> settings) {
3258         try {
3259             mPM.setComponentEnabledSettings(settings, getUserId(), mContext.getOpPackageName());
3260         } catch (RemoteException e) {
3261             throw e.rethrowFromSystemServer();
3262         }
3263     }
3264 
3265     @Override
getComponentEnabledSetting(ComponentName componentName)3266     public int getComponentEnabledSetting(ComponentName componentName) {
3267         try {
3268             return mPM.getComponentEnabledSetting(componentName, getUserId());
3269         } catch (RemoteException e) {
3270             throw e.rethrowFromSystemServer();
3271         }
3272     }
3273 
3274     @Override
setApplicationEnabledSetting(String packageName, int newState, int flags)3275     public void setApplicationEnabledSetting(String packageName,
3276                                              int newState, int flags) {
3277         try {
3278             mPM.setApplicationEnabledSetting(packageName, newState, flags,
3279                     getUserId(), mContext.getOpPackageName());
3280         } catch (RemoteException e) {
3281             throw e.rethrowFromSystemServer();
3282         }
3283     }
3284 
3285     @Override
getApplicationEnabledSetting(String packageName)3286     public int getApplicationEnabledSetting(String packageName) {
3287         try {
3288             return mPM.getApplicationEnabledSetting(packageName, getUserId());
3289         } catch (RemoteException e) {
3290             throw e.rethrowFromSystemServer();
3291         }
3292     }
3293 
3294     @Override
flushPackageRestrictionsAsUser(int userId)3295     public void flushPackageRestrictionsAsUser(int userId) {
3296         try {
3297             mPM.flushPackageRestrictionsAsUser(userId);
3298         } catch (RemoteException e) {
3299             throw e.rethrowFromSystemServer();
3300         }
3301     }
3302 
3303     @Override
setApplicationHiddenSettingAsUser(String packageName, boolean hidden, UserHandle user)3304     public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
3305             UserHandle user) {
3306         try {
3307             return mPM.setApplicationHiddenSettingAsUser(packageName, hidden,
3308                     user.getIdentifier());
3309         } catch (RemoteException e) {
3310             throw e.rethrowFromSystemServer();
3311         }
3312     }
3313 
3314     @Override
getApplicationHiddenSettingAsUser(String packageName, UserHandle user)3315     public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
3316         try {
3317             return mPM.getApplicationHiddenSettingAsUser(packageName, user.getIdentifier());
3318         } catch (RemoteException e) {
3319             throw e.rethrowFromSystemServer();
3320         }
3321     }
3322 
3323     /** @hide */
3324     @Override
setSystemAppState(String packageName, @SystemAppState int state)3325     public void setSystemAppState(String packageName, @SystemAppState int state) {
3326         try {
3327             switch (state) {
3328                 case SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN:
3329                     mPM.setSystemAppHiddenUntilInstalled(packageName, true);
3330                     break;
3331                 case SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE:
3332                     mPM.setSystemAppHiddenUntilInstalled(packageName, false);
3333                     break;
3334                 case SYSTEM_APP_STATE_INSTALLED:
3335                     mPM.setSystemAppInstallState(packageName, true, getUserId());
3336                     break;
3337                 case SYSTEM_APP_STATE_UNINSTALLED:
3338                     mPM.setSystemAppInstallState(packageName, false, getUserId());
3339                     break;
3340                 default:
3341             }
3342         } catch (RemoteException e) {
3343             throw e.rethrowFromSystemServer();
3344         }
3345     }
3346 
3347     /** @hide */
3348     @Override
getKeySetByAlias(String packageName, String alias)3349     public KeySet getKeySetByAlias(String packageName, String alias) {
3350         Objects.requireNonNull(packageName);
3351         Objects.requireNonNull(alias);
3352         try {
3353             return mPM.getKeySetByAlias(packageName, alias);
3354         } catch (RemoteException e) {
3355             throw e.rethrowFromSystemServer();
3356         }
3357     }
3358 
3359     /** @hide */
3360     @Override
getSigningKeySet(String packageName)3361     public KeySet getSigningKeySet(String packageName) {
3362         Objects.requireNonNull(packageName);
3363         try {
3364             return mPM.getSigningKeySet(packageName);
3365         } catch (RemoteException e) {
3366             throw e.rethrowFromSystemServer();
3367         }
3368     }
3369 
3370     /** @hide */
3371     @Override
isSignedBy(String packageName, KeySet ks)3372     public boolean isSignedBy(String packageName, KeySet ks) {
3373         Objects.requireNonNull(packageName);
3374         Objects.requireNonNull(ks);
3375         try {
3376             return mPM.isPackageSignedByKeySet(packageName, ks);
3377         } catch (RemoteException e) {
3378             throw e.rethrowFromSystemServer();
3379         }
3380     }
3381 
3382     /** @hide */
3383     @Override
isSignedByExactly(String packageName, KeySet ks)3384     public boolean isSignedByExactly(String packageName, KeySet ks) {
3385         Objects.requireNonNull(packageName);
3386         Objects.requireNonNull(ks);
3387         try {
3388             return mPM.isPackageSignedByKeySetExactly(packageName, ks);
3389         } catch (RemoteException e) {
3390             throw e.rethrowFromSystemServer();
3391         }
3392     }
3393 
3394     /**
3395      * @hide
3396      */
3397     @Override
getVerifierDeviceIdentity()3398     public VerifierDeviceIdentity getVerifierDeviceIdentity() {
3399         try {
3400             return mPM.getVerifierDeviceIdentity();
3401         } catch (RemoteException e) {
3402             throw e.rethrowFromSystemServer();
3403         }
3404     }
3405 
3406     @Override
isUpgrade()3407     public boolean isUpgrade() {
3408         return isDeviceUpgrading();
3409     }
3410 
3411     @Override
isDeviceUpgrading()3412     public boolean isDeviceUpgrading() {
3413         try {
3414             return mPM.isDeviceUpgrading();
3415         } catch (RemoteException e) {
3416             throw e.rethrowFromSystemServer();
3417         }
3418     }
3419 
3420     @Override
getPackageInstaller()3421     public PackageInstaller getPackageInstaller() {
3422         if (mInstaller == null) {
3423             try {
3424                 mInstaller = new PackageInstaller(mPM.getPackageInstaller(),
3425                         mContext.getPackageName(), mContext.getAttributionTag(), getUserId());
3426             } catch (RemoteException e) {
3427                 throw e.rethrowFromSystemServer();
3428             }
3429         }
3430         return mInstaller;
3431     }
3432 
3433     @Override
isPackageAvailable(String packageName)3434     public boolean isPackageAvailable(String packageName) {
3435         try {
3436             return mPM.isPackageAvailable(packageName, getUserId());
3437         } catch (RemoteException e) {
3438             throw e.rethrowFromSystemServer();
3439         }
3440     }
3441 
3442     /**
3443      * @hide
3444      */
3445     @Override
addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId, int flags)3446     public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
3447             int flags) {
3448         try {
3449             mPM.addCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
3450                     sourceUserId, targetUserId, flags);
3451         } catch (RemoteException e) {
3452             throw e.rethrowFromSystemServer();
3453         }
3454     }
3455 
3456     /**
3457      * @hide
3458      */
3459     @Override
removeCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId, int flags)3460     public boolean removeCrossProfileIntentFilter(IntentFilter filter, int sourceUserId,
3461             int targetUserId, int flags) {
3462         try {
3463             return mPM.removeCrossProfileIntentFilter(filter, mContext.getOpPackageName(),
3464                     sourceUserId, targetUserId, flags);
3465         } catch (RemoteException e) {
3466             throw e.rethrowFromSystemServer();
3467         }
3468     }
3469 
3470     /**
3471      * @hide
3472      */
3473     @Override
clearCrossProfileIntentFilters(int sourceUserId)3474     public void clearCrossProfileIntentFilters(int sourceUserId) {
3475         try {
3476             mPM.clearCrossProfileIntentFilters(sourceUserId, mContext.getOpPackageName());
3477         } catch (RemoteException e) {
3478             throw e.rethrowFromSystemServer();
3479         }
3480     }
3481 
3482     /**
3483      * @hide
3484      */
loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo)3485     public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
3486         Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
3487         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
3488             return dr;
3489         }
3490         return getUserBadgedIcon(dr, new UserHandle(getUserId()));
3491     }
3492 
3493     /**
3494      * @hide
3495      */
loadUnbadgedItemIcon(@onNull PackageItemInfo itemInfo, @Nullable ApplicationInfo appInfo)3496     public Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo,
3497             @Nullable ApplicationInfo appInfo) {
3498         if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
3499             // Indicates itemInfo is for a different user (e.g. a profile's parent), so use a
3500             // generic user icon (users generally lack permission to view each other's actual icons)
3501             int targetUserId = itemInfo.showUserIcon;
3502             return UserIcons.getDefaultUserIcon(
3503                     mContext.getResources(), targetUserId, /* light= */ false);
3504         }
3505         Drawable dr = null;
3506         if (itemInfo.packageName != null) {
3507             if (itemInfo.isArchived) {
3508                 dr = getArchivedAppIcon(itemInfo.packageName);
3509             } else {
3510                 dr = getDrawable(itemInfo.packageName, itemInfo.icon, appInfo);
3511             }
3512         }
3513         if (dr == null && itemInfo != appInfo && appInfo != null) {
3514             dr = loadUnbadgedItemIcon(appInfo, appInfo);
3515         }
3516         if (dr == null) {
3517             dr = itemInfo.loadDefaultIcon(this);
3518         }
3519         return dr;
3520     }
3521 
getBadgedDrawable(Drawable drawable, Drawable badgeDrawable, Rect badgeLocation, boolean tryBadgeInPlace)3522     private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
3523             Rect badgeLocation, boolean tryBadgeInPlace) {
3524         final int badgedWidth = drawable.getIntrinsicWidth();
3525         final int badgedHeight = drawable.getIntrinsicHeight();
3526         final boolean canBadgeInPlace = tryBadgeInPlace
3527                 && (drawable instanceof BitmapDrawable)
3528                 && ((BitmapDrawable) drawable).getBitmap().isMutable();
3529 
3530         final Bitmap bitmap;
3531         if (canBadgeInPlace) {
3532             bitmap = ((BitmapDrawable) drawable).getBitmap();
3533         } else {
3534             bitmap = Bitmap.createBitmap(badgedWidth, badgedHeight, Bitmap.Config.ARGB_8888);
3535         }
3536         Canvas canvas = new Canvas(bitmap);
3537 
3538         if (!canBadgeInPlace) {
3539             drawable.setBounds(0, 0, badgedWidth, badgedHeight);
3540             drawable.draw(canvas);
3541         }
3542 
3543         if (badgeLocation != null) {
3544             if (badgeLocation.left < 0 || badgeLocation.top < 0
3545                     || badgeLocation.width() > badgedWidth || badgeLocation.height() > badgedHeight) {
3546                 throw new IllegalArgumentException("Badge location " + badgeLocation
3547                         + " not in badged drawable bounds "
3548                         + new Rect(0, 0, badgedWidth, badgedHeight));
3549             }
3550             badgeDrawable.setBounds(0, 0, badgeLocation.width(), badgeLocation.height());
3551 
3552             canvas.save();
3553             canvas.translate(badgeLocation.left, badgeLocation.top);
3554             badgeDrawable.draw(canvas);
3555             canvas.restore();
3556         } else {
3557             badgeDrawable.setBounds(0, 0, badgedWidth, badgedHeight);
3558             badgeDrawable.draw(canvas);
3559         }
3560 
3561         if (!canBadgeInPlace) {
3562             BitmapDrawable mergedDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
3563 
3564             if (drawable instanceof BitmapDrawable) {
3565                 BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
3566                 mergedDrawable.setTargetDensity(bitmapDrawable.getBitmap().getDensity());
3567             }
3568 
3569             return mergedDrawable;
3570         }
3571 
3572         return drawable;
3573     }
3574 
hasUserBadge(int userId)3575     private boolean hasUserBadge(int userId) {
3576         return getUserManager().hasBadge(userId);
3577     }
3578 
3579     /**
3580      * @hide
3581      */
3582     @Override
getInstallReason(String packageName, UserHandle user)3583     public int getInstallReason(String packageName, UserHandle user) {
3584         try {
3585             return mPM.getInstallReason(packageName, user.getIdentifier());
3586         } catch (RemoteException e) {
3587             throw e.rethrowFromSystemServer();
3588         }
3589     }
3590 
3591     /** {@hide} */
3592     private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
3593             Handler.Callback {
3594         private static final int MSG_CREATED = 1;
3595         private static final int MSG_STATUS_CHANGED = 2;
3596 
3597         final MoveCallback mCallback;
3598         final Handler mHandler;
3599 
MoveCallbackDelegate(MoveCallback callback, Looper looper)3600         public MoveCallbackDelegate(MoveCallback callback, Looper looper) {
3601             mCallback = callback;
3602             mHandler = new Handler(looper, this);
3603         }
3604 
3605         @Override
handleMessage(Message msg)3606         public boolean handleMessage(Message msg) {
3607             switch (msg.what) {
3608                 case MSG_CREATED: {
3609                     final SomeArgs args = (SomeArgs) msg.obj;
3610                     mCallback.onCreated(args.argi1, (Bundle) args.arg2);
3611                     args.recycle();
3612                     return true;
3613                 }
3614                 case MSG_STATUS_CHANGED: {
3615                     final SomeArgs args = (SomeArgs) msg.obj;
3616                     mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
3617                     args.recycle();
3618                     return true;
3619                 }
3620             }
3621             return false;
3622         }
3623 
3624         @Override
onCreated(int moveId, Bundle extras)3625         public void onCreated(int moveId, Bundle extras) {
3626             final SomeArgs args = SomeArgs.obtain();
3627             args.argi1 = moveId;
3628             args.arg2 = extras;
3629             mHandler.obtainMessage(MSG_CREATED, args).sendToTarget();
3630         }
3631 
3632         @Override
onStatusChanged(int moveId, int status, long estMillis)3633         public void onStatusChanged(int moveId, int status, long estMillis) {
3634             final SomeArgs args = SomeArgs.obtain();
3635             args.argi1 = moveId;
3636             args.argi2 = status;
3637             args.arg3 = estMillis;
3638             mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
3639         }
3640     }
3641 
3642     private final ContextImpl mContext;
3643     @UnsupportedAppUsage
3644     private final IPackageManager mPM;
3645 
3646     /** Assume locked until we hear otherwise */
3647     private volatile boolean mUserUnlocked = false;
3648 
3649     private static final Object sSync = new Object();
3650     private static ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>> sIconCache
3651             = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>();
3652     private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache
3653             = new ArrayMap<ResourceName, WeakReference<CharSequence>>();
3654 
3655     @Override
canRequestPackageInstalls()3656     public boolean canRequestPackageInstalls() {
3657         try {
3658             return mPM.canRequestPackageInstalls(mContext.getPackageName(), getUserId());
3659         } catch (RemoteException e) {
3660             throw e.rethrowAsRuntimeException();
3661         }
3662     }
3663 
3664     @Override
getInstantAppResolverSettingsComponent()3665     public ComponentName getInstantAppResolverSettingsComponent() {
3666         try {
3667             return mPM.getInstantAppResolverSettingsComponent();
3668         } catch (RemoteException e) {
3669             throw e.rethrowAsRuntimeException();
3670         }
3671     }
3672 
3673     @Override
getInstantAppInstallerComponent()3674     public ComponentName getInstantAppInstallerComponent() {
3675         try {
3676             return mPM.getInstantAppInstallerComponent();
3677         } catch (RemoteException e) {
3678             throw e.rethrowAsRuntimeException();
3679         }
3680     }
3681 
3682     @Override
getInstantAppAndroidId(String packageName, UserHandle user)3683     public String getInstantAppAndroidId(String packageName, UserHandle user) {
3684         try {
3685             return mPM.getInstantAppAndroidId(packageName, user.getIdentifier());
3686         } catch (RemoteException e) {
3687             throw e.rethrowAsRuntimeException();
3688         }
3689     }
3690 
3691     private static class DexModuleRegisterResult {
3692         final String dexModulePath;
3693         final boolean success;
3694         final String message;
3695 
DexModuleRegisterResult(String dexModulePath, boolean success, String message)3696         private DexModuleRegisterResult(String dexModulePath, boolean success, String message) {
3697             this.dexModulePath = dexModulePath;
3698             this.success = success;
3699             this.message = message;
3700         }
3701     }
3702 
3703     private static class DexModuleRegisterCallbackDelegate
3704             extends android.content.pm.IDexModuleRegisterCallback.Stub
3705             implements Handler.Callback {
3706         private static final int MSG_DEX_MODULE_REGISTERED = 1;
3707         private final DexModuleRegisterCallback callback;
3708         private final Handler mHandler;
3709 
DexModuleRegisterCallbackDelegate(@onNull DexModuleRegisterCallback callback)3710         DexModuleRegisterCallbackDelegate(@NonNull DexModuleRegisterCallback callback) {
3711             this.callback = callback;
3712             mHandler = new Handler(Looper.getMainLooper(), this);
3713         }
3714 
3715         @Override
onDexModuleRegistered(@onNull String dexModulePath, boolean success, @Nullable String message)3716         public void onDexModuleRegistered(@NonNull String dexModulePath, boolean success,
3717                 @Nullable String message)throws RemoteException {
3718             mHandler.obtainMessage(MSG_DEX_MODULE_REGISTERED,
3719                     new DexModuleRegisterResult(dexModulePath, success, message)).sendToTarget();
3720         }
3721 
3722         @Override
handleMessage(Message msg)3723         public boolean handleMessage(Message msg) {
3724             if (msg.what != MSG_DEX_MODULE_REGISTERED) {
3725                 return false;
3726             }
3727             DexModuleRegisterResult result = (DexModuleRegisterResult)msg.obj;
3728             callback.onDexModuleRegistered(result.dexModulePath, result.success, result.message);
3729             return true;
3730         }
3731     }
3732 
3733     @Override
registerDexModule(@onNull String dexModule, @Nullable DexModuleRegisterCallback callback)3734     public void registerDexModule(@NonNull String dexModule,
3735             @Nullable DexModuleRegisterCallback callback) {
3736         // Create the callback delegate to be passed to package manager service.
3737         DexModuleRegisterCallbackDelegate callbackDelegate = null;
3738         if (callback != null) {
3739             callbackDelegate = new DexModuleRegisterCallbackDelegate(callback);
3740         }
3741 
3742         // Check if this is a shared module by looking if the others can read it.
3743         boolean isSharedModule = false;
3744         try {
3745             StructStat stat = Os.stat(dexModule);
3746             if ((OsConstants.S_IROTH & stat.st_mode) != 0) {
3747                 isSharedModule = true;
3748             }
3749         } catch (ErrnoException e) {
3750             if (callbackDelegate != null) {
3751                 callback.onDexModuleRegistered(dexModule, false,
3752                         "Could not get stat the module file: " + e.getMessage());
3753             }
3754             return;
3755         }
3756 
3757         // Invoke the package manager service.
3758         try {
3759             mPM.registerDexModule(mContext.getPackageName(), dexModule,
3760                     isSharedModule, callbackDelegate);
3761         } catch (RemoteException e) {
3762             throw e.rethrowAsRuntimeException();
3763         }
3764     }
3765 
3766     @Override
getHarmfulAppWarning(String packageName)3767     public CharSequence getHarmfulAppWarning(String packageName) {
3768         try {
3769             return mPM.getHarmfulAppWarning(packageName, getUserId());
3770         } catch (RemoteException e) {
3771             throw e.rethrowAsRuntimeException();
3772         }
3773     }
3774 
3775     @Override
setHarmfulAppWarning(String packageName, CharSequence warning)3776     public void setHarmfulAppWarning(String packageName, CharSequence warning) {
3777         try {
3778             mPM.setHarmfulAppWarning(packageName, warning, getUserId());
3779         } catch (RemoteException e) {
3780             throw e.rethrowAsRuntimeException();
3781         }
3782     }
3783 
3784     @Override
getArtManager()3785     public ArtManager getArtManager() {
3786         if (mArtManager == null) {
3787             try {
3788                 mArtManager = new ArtManager(mContext, mPM.getArtManager());
3789             } catch (RemoteException e) {
3790                 throw e.rethrowFromSystemServer();
3791             }
3792         }
3793         return mArtManager;
3794     }
3795 
3796     @Override
getDefaultTextClassifierPackageName()3797     public String getDefaultTextClassifierPackageName() {
3798         try {
3799             return mPM.getDefaultTextClassifierPackageName();
3800         } catch (RemoteException e) {
3801             throw e.rethrowAsRuntimeException();
3802         }
3803     }
3804 
3805     @Override
getSystemTextClassifierPackageName()3806     public String getSystemTextClassifierPackageName() {
3807         try {
3808             return mPM.getSystemTextClassifierPackageName();
3809         } catch (RemoteException e) {
3810             throw e.rethrowAsRuntimeException();
3811         }
3812     }
3813 
3814     @Override
getAttentionServicePackageName()3815     public String getAttentionServicePackageName() {
3816         try {
3817             return mPM.getAttentionServicePackageName();
3818         } catch (RemoteException e) {
3819             throw e.rethrowAsRuntimeException();
3820         }
3821     }
3822 
3823     @Override
getRotationResolverPackageName()3824     public String getRotationResolverPackageName() {
3825         try {
3826             return mPM.getRotationResolverPackageName();
3827         } catch (RemoteException e) {
3828             throw e.rethrowAsRuntimeException();
3829         }
3830     }
3831 
3832     @Override
getWellbeingPackageName()3833     public String getWellbeingPackageName() {
3834         try {
3835             return mPM.getWellbeingPackageName();
3836         } catch (RemoteException e) {
3837             throw e.rethrowAsRuntimeException();
3838         }
3839     }
3840 
3841     @Override
getAppPredictionServicePackageName()3842     public String getAppPredictionServicePackageName() {
3843         try {
3844             return mPM.getAppPredictionServicePackageName();
3845         } catch (RemoteException e) {
3846             throw e.rethrowAsRuntimeException();
3847         }
3848     }
3849 
3850     @Override
getSystemCaptionsServicePackageName()3851     public String getSystemCaptionsServicePackageName() {
3852         try {
3853             return mPM.getSystemCaptionsServicePackageName();
3854         } catch (RemoteException e) {
3855             throw e.rethrowAsRuntimeException();
3856         }
3857     }
3858 
3859     @Override
getSetupWizardPackageName()3860     public String getSetupWizardPackageName() {
3861         try {
3862             return mPM.getSetupWizardPackageName();
3863         } catch (RemoteException e) {
3864             throw e.rethrowAsRuntimeException();
3865         }
3866     }
3867 
3868     @Override
getIncidentReportApproverPackageName()3869     public String getIncidentReportApproverPackageName() {
3870         try {
3871             return mPM.getIncidentReportApproverPackageName();
3872         } catch (RemoteException e) {
3873             throw e.rethrowAsRuntimeException();
3874         }
3875     }
3876 
3877     @Override
isPackageStateProtected(String packageName, int userId)3878     public boolean isPackageStateProtected(String packageName, int userId) {
3879         try {
3880             return mPM.isPackageStateProtected(packageName, userId);
3881         } catch (RemoteException e) {
3882             throw e.rethrowAsRuntimeException();
3883         }
3884     }
3885 
sendDeviceCustomizationReadyBroadcast()3886     public void sendDeviceCustomizationReadyBroadcast() {
3887         try {
3888             mPM.sendDeviceCustomizationReadyBroadcast();
3889         } catch (RemoteException e) {
3890             throw e.rethrowAsRuntimeException();
3891         }
3892     }
3893 
3894     @Override
isAutoRevokeWhitelisted()3895     public boolean isAutoRevokeWhitelisted() {
3896         try {
3897             return mPM.isAutoRevokeWhitelisted(mContext.getPackageName());
3898         } catch (RemoteException e) {
3899             throw e.rethrowAsRuntimeException();
3900         }
3901     }
3902 
3903     @Override
setMimeGroup(String mimeGroup, Set<String> mimeTypes)3904     public void setMimeGroup(String mimeGroup, Set<String> mimeTypes) {
3905         try {
3906             mPM.setMimeGroup(mContext.getPackageName(), mimeGroup, new ArrayList<>(mimeTypes));
3907         } catch (RemoteException e) {
3908             throw e.rethrowAsRuntimeException();
3909         }
3910     }
3911 
3912     @NonNull
3913     @Override
getMimeGroup(String group)3914     public Set<String> getMimeGroup(String group) {
3915         try {
3916             List<String> mimeGroup = mPM.getMimeGroup(mContext.getPackageName(), group);
3917             return new ArraySet<>(mimeGroup);
3918         } catch (RemoteException e) {
3919             throw e.rethrowAsRuntimeException();
3920         }
3921     }
3922 
3923     @Override
getProperty(String propertyName, String packageName)3924     public Property getProperty(String propertyName, String packageName)
3925             throws NameNotFoundException {
3926         Objects.requireNonNull(packageName);
3927         Objects.requireNonNull(propertyName);
3928         return getPropertyAsUser(propertyName, packageName, null /* className */, getUserId());
3929     }
3930 
3931     @Override
getProperty(String propertyName, ComponentName component)3932     public Property getProperty(String propertyName, ComponentName component)
3933             throws NameNotFoundException {
3934         Objects.requireNonNull(component);
3935         Objects.requireNonNull(propertyName);
3936         return getPropertyAsUser(propertyName,
3937                 component.getPackageName(), component.getClassName(), getUserId());
3938     }
3939 
3940     @Override
getPropertyAsUser(@onNull String propertyName, @NonNull String packageName, @Nullable String className, int userId)3941     public Property getPropertyAsUser(@NonNull String propertyName, @NonNull String packageName,
3942             @Nullable String className, int userId) throws NameNotFoundException {
3943         Objects.requireNonNull(packageName);
3944         Objects.requireNonNull(propertyName);
3945         try {
3946             final Property property = mPM.getPropertyAsUser(propertyName,
3947                     packageName, className, userId);
3948             if (property == null) {
3949                 throw new NameNotFoundException();
3950             }
3951             return property;
3952         } catch (RemoteException e) {
3953             throw e.rethrowAsRuntimeException();
3954         }
3955     }
3956 
3957     @Override
queryApplicationProperty(String propertyName)3958     public List<Property> queryApplicationProperty(String propertyName) {
3959         Objects.requireNonNull(propertyName);
3960         try {
3961             final ParceledListSlice<Property> parceledList =
3962                     mPM.queryProperty(propertyName, TYPE_APPLICATION);
3963             if (parceledList == null) {
3964                 return Collections.emptyList();
3965             }
3966             return parceledList.getList();
3967         } catch (RemoteException e) {
3968             throw e.rethrowAsRuntimeException();
3969         }
3970     }
3971 
3972     @Override
queryActivityProperty(String propertyName)3973     public List<Property> queryActivityProperty(String propertyName) {
3974         Objects.requireNonNull(propertyName);
3975         try {
3976             final ParceledListSlice<Property> parceledList =
3977                     mPM.queryProperty(propertyName, TYPE_ACTIVITY);
3978             if (parceledList == null) {
3979                 return Collections.emptyList();
3980             }
3981             return parceledList.getList();
3982         } catch (RemoteException e) {
3983             throw e.rethrowAsRuntimeException();
3984         }
3985     }
3986 
3987     @Override
queryProviderProperty(String propertyName)3988     public List<Property> queryProviderProperty(String propertyName) {
3989         Objects.requireNonNull(propertyName);
3990         try {
3991             final ParceledListSlice<Property> parceledList =
3992                     mPM.queryProperty(propertyName, TYPE_PROVIDER);
3993             if (parceledList == null) {
3994                 return Collections.emptyList();
3995             }
3996             return parceledList.getList();
3997         } catch (RemoteException e) {
3998             throw e.rethrowAsRuntimeException();
3999         }
4000     }
4001 
4002     @Override
queryReceiverProperty(String propertyName)4003     public List<Property> queryReceiverProperty(String propertyName) {
4004         Objects.requireNonNull(propertyName);
4005         try {
4006             final ParceledListSlice<Property> parceledList =
4007                     mPM.queryProperty(propertyName, TYPE_RECEIVER);
4008             if (parceledList == null) {
4009                 return Collections.emptyList();
4010             }
4011             return parceledList.getList();
4012         } catch (RemoteException e) {
4013             throw e.rethrowAsRuntimeException();
4014         }
4015     }
4016 
4017     @Override
queryServiceProperty(String propertyName)4018     public List<Property> queryServiceProperty(String propertyName) {
4019         Objects.requireNonNull(propertyName);
4020         try {
4021             final ParceledListSlice<Property> parceledList =
4022                     mPM.queryProperty(propertyName, TYPE_SERVICE);
4023             if (parceledList == null) {
4024                 return Collections.emptyList();
4025             }
4026             return parceledList.getList();
4027         } catch (RemoteException e) {
4028             throw e.rethrowAsRuntimeException();
4029         }
4030     }
4031 
4032     @Override
canPackageQuery(@onNull String sourcePackageName, @NonNull String targetPackageName)4033     public boolean canPackageQuery(@NonNull String sourcePackageName,
4034             @NonNull String targetPackageName) throws NameNotFoundException {
4035         Objects.requireNonNull(sourcePackageName);
4036         Objects.requireNonNull(targetPackageName);
4037         return canPackageQuery(sourcePackageName, new String[]{targetPackageName})[0];
4038     }
4039 
4040     @Override
4041     @NonNull
canPackageQuery(@onNull String sourcePackageName, @NonNull String[] targetPackageNames)4042     public boolean[] canPackageQuery(@NonNull String sourcePackageName,
4043             @NonNull String[] targetPackageNames) throws NameNotFoundException {
4044         Objects.requireNonNull(sourcePackageName);
4045         Objects.requireNonNull(targetPackageNames);
4046         try {
4047             return mPM.canPackageQuery(sourcePackageName, targetPackageNames, getUserId());
4048         } catch (ParcelableException e) {
4049             e.maybeRethrow(PackageManager.NameNotFoundException.class);
4050             throw new RuntimeException(e);
4051         } catch (RemoteException re) {
4052             throw re.rethrowAsRuntimeException();
4053         }
4054     }
4055 
4056     @Override
makeUidVisible(int recipientUid, int visibleUid)4057     public void makeUidVisible(int recipientUid, int visibleUid) {
4058         try {
4059             mPM.makeUidVisible(recipientUid, visibleUid);
4060         } catch (RemoteException e) {
4061             throw e.rethrowAsRuntimeException();
4062         }
4063     }
4064 
4065     @Override
getArchivedPackage(@onNull String packageName)4066     public @Nullable ArchivedPackageInfo getArchivedPackage(@NonNull String packageName) {
4067         try {
4068             var parcel = mPM.getArchivedPackage(packageName, mContext.getUserId());
4069             if (parcel == null) {
4070                 return null;
4071             }
4072             return new ArchivedPackageInfo(parcel);
4073         } catch (RemoteException e) {
4074             throw e.rethrowAsRuntimeException();
4075         }
4076     }
4077 
4078     @Override
canUserUninstall(String packageName, UserHandle user)4079     public boolean canUserUninstall(String packageName, UserHandle user) {
4080         try {
4081             return mPM.getBlockUninstallForUser(packageName, user.getIdentifier());
4082         } catch (RemoteException e) {
4083             throw e.rethrowAsRuntimeException();
4084         }
4085     }
4086 
4087     @Override
shouldShowNewAppInstalledNotification()4088     public boolean shouldShowNewAppInstalledNotification() {
4089         return Settings.Global.getInt(mContext.getContentResolver(),
4090                 Settings.Global.SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED, 0) == 1;
4091     }
4092 
4093     @Override
relinquishUpdateOwnership(String targetPackage)4094     public void relinquishUpdateOwnership(String targetPackage) {
4095         Objects.requireNonNull(targetPackage);
4096         try {
4097             mPM.relinquishUpdateOwnership(targetPackage);
4098         } catch (RemoteException e) {
4099             throw e.rethrowFromSystemServer();
4100         }
4101     }
4102 
4103     @Override
registerPackageMonitorCallback(@onNull IRemoteCallback callback, int userId)4104     public void registerPackageMonitorCallback(@NonNull IRemoteCallback callback, int userId) {
4105         Objects.requireNonNull(callback);
4106         try {
4107             mPM.registerPackageMonitorCallback(callback, userId);
4108             synchronized (mPackageMonitorCallbacks) {
4109                 if (mPackageMonitorCallbacks.contains(callback)) {
4110                     throw new IllegalStateException(
4111                             "registerPackageMonitorCallback: callback already registered: "
4112                                     + callback);
4113                 }
4114                 mPackageMonitorCallbacks.add(callback);
4115             }
4116         } catch (RemoteException e) {
4117             throw e.rethrowFromSystemServer();
4118         }
4119     }
4120 
4121     @Override
unregisterPackageMonitorCallback(@onNull IRemoteCallback callback)4122     public void unregisterPackageMonitorCallback(@NonNull IRemoteCallback callback) {
4123         Objects.requireNonNull(callback);
4124         try {
4125             mPM.unregisterPackageMonitorCallback(callback);
4126             synchronized (mPackageMonitorCallbacks) {
4127                 mPackageMonitorCallbacks.remove(callback);
4128             }
4129         } catch (RemoteException e) {
4130             throw e.rethrowFromSystemServer();
4131         }
4132     }
4133 
4134     @Nullable
getArchivedAppIcon(String packageName)4135     private Drawable getArchivedAppIcon(String packageName) {
4136         try {
4137             Bitmap archivedAppIcon = mPM.getArchivedAppIcon(packageName,
4138                     new UserHandle(getUserId()),
4139                     mContext.getPackageName());
4140             if (archivedAppIcon == null) {
4141                 return null;
4142             }
4143             return new BitmapDrawable(null, archivedAppIcon);
4144         } catch (RemoteException e) {
4145             Slog.e(TAG, "Failed to retrieve archived app icon: " + e.getMessage());
4146             return null;
4147         }
4148     }
4149 
4150     @Override
parseAndroidManifest(@onNull File apkFile, @NonNull Function<XmlResourceParser, T> parserFunction)4151     public <T> T parseAndroidManifest(@NonNull File apkFile,
4152             @NonNull Function<XmlResourceParser, T> parserFunction) throws IOException {
4153         Objects.requireNonNull(apkFile, "apkFile cannot be null");
4154         Objects.requireNonNull(parserFunction, "parserFunction cannot be null");
4155         try (XmlResourceParser xmlResourceParser = getAndroidManifestParser(apkFile)) {
4156             return parserFunction.apply(xmlResourceParser);
4157         } catch (IOException e) {
4158             Log.w(TAG, "Failed to get the android manifest parser", e);
4159             throw e;
4160         }
4161     }
4162 
getAndroidManifestParser(@onNull File apkFile)4163     private static XmlResourceParser getAndroidManifestParser(@NonNull File apkFile)
4164             throws IOException {
4165         ApkAssets apkAssets = null;
4166         try {
4167             apkAssets = ApkAssets.loadFromPath(apkFile.getAbsolutePath());
4168             return apkAssets.openXml(ApkLiteParseUtils.ANDROID_MANIFEST_FILENAME);
4169         } finally {
4170             if (apkAssets != null) {
4171                 try {
4172                     apkAssets.close();
4173                 } catch (Throwable ignored) {
4174                     Log.w(TAG, "Failed to close apkAssets", ignored);
4175                 }
4176             }
4177         }
4178     }
4179 
4180 
4181     @Override
parseAndroidManifest(@onNull ParcelFileDescriptor apkFileDescriptor, @NonNull Function<XmlResourceParser, T> parserFunction)4182     public <T> T parseAndroidManifest(@NonNull ParcelFileDescriptor apkFileDescriptor,
4183             @NonNull Function<XmlResourceParser, T> parserFunction) throws IOException {
4184         Objects.requireNonNull(apkFileDescriptor, "apkFileDescriptor cannot be null");
4185         Objects.requireNonNull(parserFunction, "parserFunction cannot be null");
4186         try (XmlResourceParser xmlResourceParser = getAndroidManifestParser(apkFileDescriptor)) {
4187             return parserFunction.apply(xmlResourceParser);
4188         } catch (IOException e) {
4189             Log.w(TAG, "Failed to get the android manifest parser", e);
4190             throw e;
4191         }
4192     }
4193 
getAndroidManifestParser(@onNull ParcelFileDescriptor fd)4194     private static XmlResourceParser getAndroidManifestParser(@NonNull ParcelFileDescriptor fd)
4195             throws IOException {
4196         ApkAssets apkAssets = null;
4197         try {
4198             apkAssets = ApkAssets.loadFromFd(
4199                     fd.getFileDescriptor(), fd.toString(), /* flags= */ 0 , /* assets= */null);
4200             return apkAssets.openXml(ApkLiteParseUtils.ANDROID_MANIFEST_FILENAME);
4201         } finally {
4202             if (apkAssets != null) {
4203                 try {
4204                     apkAssets.close();
4205                 } catch (Throwable ignored) {
4206                     Log.w(TAG, "Failed to close apkAssets", ignored);
4207                 }
4208             }
4209         }
4210     }
4211 
4212     @Override
extractPackageItemInfoAttributes(PackageItemInfo info, String name, String rootTag, int[] attributes)4213     public TypedArray extractPackageItemInfoAttributes(PackageItemInfo info, String name,
4214             String rootTag, int[] attributes) {
4215         if (info == null || info.metaData == null) {
4216             return null;
4217         }
4218 
4219         try (XmlResourceParser parser = info.loadXmlMetaData(this, name)) {
4220             if (parser == null) {
4221                 Log.w(TAG, "No " + name + " metadata");
4222                 return null;
4223             }
4224 
4225             final AttributeSet attrs = Xml.asAttributeSet(parser);
4226             while (true) {
4227                 final int type = parser.next();
4228                 if (type == XmlPullParser.END_DOCUMENT || type == XmlPullParser.START_TAG) {
4229                     break;
4230                 }
4231             }
4232 
4233             if (!TextUtils.equals(parser.getName(), rootTag)) {
4234                 Log.w(TAG, "Metadata does not start with " + name + " tag");
4235                 return null;
4236             }
4237 
4238             return getResourcesForApplication(info.getApplicationInfo())
4239                     .obtainAttributes(attrs, attributes);
4240         } catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
4241             Log.e(TAG, "Error parsing: " + info.packageName, e);
4242             return null;
4243         }
4244     }
4245 }
4246