• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
4 import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
5 import static android.content.pm.PackageManager.GET_ACTIVITIES;
6 import static android.content.pm.PackageManager.GET_CONFIGURATIONS;
7 import static android.content.pm.PackageManager.GET_GIDS;
8 import static android.content.pm.PackageManager.GET_INSTRUMENTATION;
9 import static android.content.pm.PackageManager.GET_INTENT_FILTERS;
10 import static android.content.pm.PackageManager.GET_META_DATA;
11 import static android.content.pm.PackageManager.GET_PERMISSIONS;
12 import static android.content.pm.PackageManager.GET_PROVIDERS;
13 import static android.content.pm.PackageManager.GET_RECEIVERS;
14 import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
15 import static android.content.pm.PackageManager.GET_SERVICES;
16 import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES;
17 import static android.content.pm.PackageManager.GET_SIGNATURES;
18 import static android.content.pm.PackageManager.GET_URI_PERMISSION_PATTERNS;
19 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
20 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
21 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
22 import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
23 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
24 import static android.content.pm.PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
25 import static android.content.pm.PackageManager.SIGNATURE_MATCH;
26 import static android.content.pm.PackageManager.SIGNATURE_NEITHER_SIGNED;
27 import static android.content.pm.PackageManager.SIGNATURE_NO_MATCH;
28 import static android.content.pm.PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
29 import static android.content.pm.PackageManager.VERIFICATION_ALLOW;
30 import static android.os.Build.VERSION_CODES.N;
31 import static android.os.Build.VERSION_CODES.TIRAMISU;
32 import static java.util.Arrays.asList;
33 import static org.robolectric.util.reflector.Reflector.reflector;
34 
35 import android.Manifest;
36 import android.annotation.UserIdInt;
37 import android.app.Application;
38 import android.content.BroadcastReceiver;
39 import android.content.ComponentName;
40 import android.content.Context;
41 import android.content.Intent;
42 import android.content.IntentFilter;
43 import android.content.IntentSender;
44 import android.content.pm.ActivityInfo;
45 import android.content.pm.ApplicationInfo;
46 import android.content.pm.ComponentInfo;
47 import android.content.pm.FeatureInfo;
48 import android.content.pm.IPackageDataObserver;
49 import android.content.pm.IPackageDeleteObserver;
50 import android.content.pm.InstallSourceInfo;
51 import android.content.pm.ModuleInfo;
52 import android.content.pm.PackageInfo;
53 import android.content.pm.PackageManager;
54 import android.content.pm.PackageParser;
55 import android.content.pm.PackageParser.Component;
56 import android.content.pm.PackageParser.IntentInfo;
57 import android.content.pm.PackageParser.Package;
58 import android.content.pm.PackageParser.PermissionGroup;
59 import android.content.pm.PackageStats;
60 import android.content.pm.PermissionGroupInfo;
61 import android.content.pm.PermissionInfo;
62 import android.content.pm.ProviderInfo;
63 import android.content.pm.ResolveInfo;
64 import android.content.pm.ServiceInfo;
65 import android.content.pm.Signature;
66 import android.content.pm.pkg.FrameworkPackageUserState;
67 import android.content.res.Resources;
68 import android.graphics.drawable.Drawable;
69 import android.net.Uri;
70 import android.os.Binder;
71 import android.os.PersistableBundle;
72 import android.os.Process;
73 import android.os.RemoteException;
74 import android.os.UserHandle;
75 import android.util.Log;
76 import android.util.Pair;
77 import com.google.common.base.Function;
78 import com.google.common.base.Preconditions;
79 import com.google.common.collect.HashMultimap;
80 import com.google.common.collect.Multimap;
81 import com.google.errorprone.annotations.InlineMe;
82 import java.lang.reflect.Array;
83 import java.util.ArrayList;
84 import java.util.Arrays;
85 import java.util.Collections;
86 import java.util.Comparator;
87 import java.util.HashMap;
88 import java.util.HashSet;
89 import java.util.Iterator;
90 import java.util.LinkedHashMap;
91 import java.util.List;
92 import java.util.Map;
93 import java.util.Map.Entry;
94 import java.util.Set;
95 import java.util.SortedMap;
96 import java.util.TreeMap;
97 import java.util.concurrent.ConcurrentHashMap;
98 import java.util.concurrent.CopyOnWriteArraySet;
99 import java.util.function.BiConsumer;
100 import javax.annotation.Nullable;
101 import javax.annotation.concurrent.GuardedBy;
102 import org.robolectric.RuntimeEnvironment;
103 import org.robolectric.annotation.Implementation;
104 import org.robolectric.annotation.Implements;
105 import org.robolectric.annotation.RealObject;
106 import org.robolectric.annotation.Resetter;
107 import org.robolectric.shadows.ShadowPackageParser._PackageParser_;
108 import org.robolectric.util.reflector.Direct;
109 import org.robolectric.util.reflector.ForType;
110 
111 @SuppressWarnings("NewApi")
112 @Implements(PackageManager.class)
113 public class ShadowPackageManager {
114   static final String TAG = "PackageManager";
115 
116   @RealObject PackageManager realPackageManager;
117 
118   // The big-lock to control concurrency in this class.
119   // Note: not all APIs in this class have been made thread safe yet.
120   static final Object lock = new Object();
121   static Map<String, Boolean> permissionRationaleMap = new HashMap<>();
122   static List<FeatureInfo> systemAvailableFeatures = new ArrayList<>();
123   static final List<String> systemSharedLibraryNames = new ArrayList<>();
124 
125   @GuardedBy("lock")
126   static final Map<String, PackageInfo> packageInfos = new LinkedHashMap<>();
127 
128   @GuardedBy("lock")
129   static final Map<String, ModuleInfo> moduleInfos = new LinkedHashMap<>();
130 
131   static final Set<Object> permissionListeners = new CopyOnWriteArraySet<>();
132 
133   // Those maps contain filter for components. If component exists but doesn't have filters,
134   // it will have an entry in the map with an empty list.
135   static final SortedMap<ComponentName, List<IntentFilter>> activityFilters = new TreeMap<>();
136   static final SortedMap<ComponentName, List<IntentFilter>> serviceFilters = new TreeMap<>();
137   static final SortedMap<ComponentName, List<IntentFilter>> providerFilters = new TreeMap<>();
138   static final SortedMap<ComponentName, List<IntentFilter>> receiverFilters = new TreeMap<>();
139 
140   private static Map<String, PackageInfo> packageArchiveInfo = new HashMap<>();
141   static final Map<String, PackageStats> packageStatsMap = new HashMap<>();
142   static final Map<String, String> packageInstallerMap = new HashMap<>();
143   static final Map<String, Object> packageInstallSourceInfoMap = new HashMap<>();
144   static final Map<Integer, String[]> packagesForUid = new HashMap<>();
145   static final Map<String, Integer> uidForPackage = new HashMap<>();
146   static final Map<Integer, String> namesForUid = new HashMap<>();
147   static final Map<Integer, Integer> verificationResults = new HashMap<>();
148 
149   @GuardedBy("lock")
150   static final Map<Integer, Long> verificationTimeoutExtension = new HashMap<>();
151 
152   @GuardedBy("lock")
153   static final Map<Integer, Integer> verificationCodeAtTimeoutExtension = new HashMap<>();
154 
155   static final Map<String, String> currentToCanonicalNames = new HashMap<>();
156   static final Map<String, String> canonicalToCurrentNames = new HashMap<>();
157   static final Map<ComponentName, ComponentState> componentList = new LinkedHashMap<>();
158   static final Map<ComponentName, Drawable> drawableList = new LinkedHashMap<>();
159   static final Map<String, Drawable> applicationIcons = new HashMap<>();
160   static final Map<String, Drawable> unbadgedApplicationIcons = new HashMap<>();
161   static final Map<String, Boolean> systemFeatureList =
162       new LinkedHashMap<>(SystemFeatureListInitializer.getSystemFeatures());
163   static final SortedMap<ComponentName, List<IntentFilter>> preferredActivities = new TreeMap<>();
164   static final SortedMap<ComponentName, List<IntentFilter>> persistentPreferredActivities =
165       new TreeMap<>();
166   static final Map<Pair<String, Integer>, Drawable> drawables = new LinkedHashMap<>();
167   /**
168    * Map of package names to an inner map where the key is the resource id which fetches its
169    * corresponding text.
170    */
171   static final Map<String, Map<Integer, String>> stringResources = new HashMap<>();
172 
173   static final Map<String, Integer> applicationEnabledSettingMap = new HashMap<>();
174   static Map<String, PermissionInfo> extraPermissions = new HashMap<>();
175   static Map<String, PermissionGroupInfo> permissionGroups = new HashMap<>();
176   /**
177    * Map of package names to an inner map where the key is the permission and the integer represents
178    * the permission flags set for that particular permission
179    */
180   static Map<String, Map<String, Integer>> permissionFlags = new HashMap<>();
181 
182   public static Map<String, Resources> resources = new HashMap<>();
183   static final Map<Intent, List<ResolveInfo>> resolveInfoForIntent =
184       new TreeMap<>(new IntentComparator());
185 
186   @GuardedBy("lock")
187   static Set<String> deletedPackages = new HashSet<>();
188 
189   static Map<String, IPackageDeleteObserver> pendingDeleteCallbacks = new HashMap<>();
190   static Set<String> hiddenPackages = new HashSet<>();
191   static Multimap<Integer, String> sequenceNumberChangedPackagesMap = HashMultimap.create();
192   static boolean canRequestPackageInstalls = false;
193   static boolean safeMode = false;
194   static boolean whitelisted = false;
195   boolean shouldShowActivityChooser = false;
196   static final Map<String, Integer> distractingPackageRestrictions = new ConcurrentHashMap<>();
197 
198   /**
199    * Makes sure that given activity exists.
200    *
201    * If the activity doesn't exist yet, it will be created with {@code applicationInfo} set to an
202    * existing application, or if it doesn't exist, a new package will be created.
203    *
204    * @return existing or newly created activity info.
205    */
addActivityIfNotPresent(ComponentName componentName)206   public ActivityInfo addActivityIfNotPresent(ComponentName componentName) {
207     ActivityInfo activityInfo = updateName(componentName, new ActivityInfo());
208     activityInfo.flags |= ActivityInfo.FLAG_HARDWARE_ACCELERATED;
209     return addComponent(
210         activityFilters, p -> p.activities, (p, a) -> p.activities = a, activityInfo, false);
211   }
212 
213   /**
214    * Makes sure that given service exists.
215    *
216    * If the service doesn't exist yet, it will be created with {@code applicationInfo} set to an
217    * existing application, or if it doesn't exist, a new package will be created.
218    *
219    * @return existing or newly created service info.
220    */
addServiceIfNotPresent(ComponentName componentName)221   public ServiceInfo addServiceIfNotPresent(ComponentName componentName) {
222     return addComponent(
223         serviceFilters,
224         p -> p.services,
225         (p, a) -> p.services = a,
226         updateName(componentName, new ServiceInfo()),
227         false);
228   }
229 
230   /**
231    * Makes sure that given receiver exists.
232    *
233    * If the receiver doesn't exist yet, it will be created with {@code applicationInfo} set to an
234    * existing application, or if it doesn't exist, a new package will be created.
235    *
236    * @return existing or newly created receiver info.
237    */
addReceiverIfNotPresent(ComponentName componentName)238   public ActivityInfo addReceiverIfNotPresent(ComponentName componentName) {
239     return addComponent(
240         receiverFilters,
241         p -> p.receivers,
242         (p, a) -> p.receivers = a,
243         updateName(componentName, new ActivityInfo()),
244         false);
245   }
246 
247   /**
248    * Makes sure that given provider exists.
249    *
250    * If the provider doesn't exist yet, it will be created with {@code applicationInfo} set to an
251    * existing application, or if it doesn't exist, a new package will be created.
252    *
253    * @return existing or newly created provider info.
254    */
addProviderIfNotPresent(ComponentName componentName)255   public ProviderInfo addProviderIfNotPresent(ComponentName componentName) {
256     return addComponent(
257         providerFilters,
258         p -> p.providers,
259         (p, a) -> p.providers = a,
260         updateName(componentName, new ProviderInfo()),
261         false);
262   }
263 
updateName(ComponentName name, C component)264   private <C extends ComponentInfo> C updateName(ComponentName name, C component) {
265     component.name = name.getClassName();
266     component.packageName = name.getPackageName();
267     if (component.applicationInfo != null) {
268       component.applicationInfo.packageName = component.packageName;
269     }
270     return component;
271   }
272 
273   /**
274    * Adds or updates given activity in the system.
275    *
276    * If activity with the same {@link ComponentInfo#name} and {@code ComponentInfo#packageName}
277    * exists it will be updated. Its {@link ComponentInfo#applicationInfo} is always set to {@link
278    * ApplicationInfo} already existing in the system, but if no application exists a new one will
279    * be created using {@link ComponentInfo#applicationInfo} in this component.
280    */
addOrUpdateActivity(ActivityInfo activityInfo)281   public void addOrUpdateActivity(ActivityInfo activityInfo) {
282     addComponent(
283         activityFilters,
284         p -> p.activities,
285         (p, a) -> p.activities = a,
286         new ActivityInfo(activityInfo),
287         true);
288   }
289 
290   /**
291    * Adds or updates given service in the system.
292    *
293    * If service with the same {@link ComponentInfo#name} and {@code ComponentInfo#packageName}
294    * exists it will be updated. Its {@link ComponentInfo#applicationInfo} is always set to {@link
295    * ApplicationInfo} already existing in the system, but if no application exists a new one will be
296    * created using {@link ComponentInfo#applicationInfo} in this component.
297    */
addOrUpdateService(ServiceInfo serviceInfo)298   public void addOrUpdateService(ServiceInfo serviceInfo) {
299     addComponent(
300         serviceFilters,
301         p -> p.services,
302         (p, a) -> p.services = a,
303         new ServiceInfo(serviceInfo),
304         true);
305   }
306 
307   /**
308    * Adds or updates given broadcast receiver in the system.
309    *
310    * If broadcast receiver with the same {@link ComponentInfo#name} and {@code
311    * ComponentInfo#packageName} exists it will be updated. Its {@link ComponentInfo#applicationInfo}
312    * is always set to {@link ApplicationInfo} already existing in the system, but if no
313    * application exists a new one will be created using {@link ComponentInfo#applicationInfo} in
314    * this component.
315    */
addOrUpdateReceiver(ActivityInfo receiverInfo)316   public void addOrUpdateReceiver(ActivityInfo receiverInfo) {
317     addComponent(
318         receiverFilters,
319         p -> p.receivers,
320         (p, a) -> p.receivers = a,
321         new ActivityInfo(receiverInfo),
322         true);
323   }
324 
325   /**
326    * Adds or updates given content provider in the system.
327    *
328    * If content provider with the same {@link ComponentInfo#name} and {@code
329    * ComponentInfo#packageName} exists it will be updated. Its {@link ComponentInfo#applicationInfo}
330    * is always set to {@link ApplicationInfo} already existing in the system, but if no
331    * application exists a new one will be created using {@link ComponentInfo#applicationInfo} in
332    * this component.
333    */
addOrUpdateProvider(ProviderInfo providerInfo)334   public void addOrUpdateProvider(ProviderInfo providerInfo) {
335     addComponent(
336         providerFilters,
337         p -> p.providers,
338         (p, a) -> p.providers = a,
339         new ProviderInfo(providerInfo),
340         true);
341   }
342 
343   /**
344    * Removes activity from the package manager.
345    *
346    * @return the removed component or {@code null} if no such component existed.
347    */
348   @Nullable
removeActivity(ComponentName componentName)349   public ActivityInfo removeActivity(ComponentName componentName) {
350     return removeComponent(
351         componentName, activityFilters, p -> p.activities, (p, a) -> p.activities = a);
352   }
353 
354   /**
355    * Removes service from the package manager.
356    *
357    * @return the removed component or {@code null} if no such component existed.
358    */
359   @Nullable
removeService(ComponentName componentName)360   public ServiceInfo removeService(ComponentName componentName) {
361     return removeComponent(
362         componentName, serviceFilters, p -> p.services, (p, a) -> p.services = a);
363   }
364 
365   /**
366    * Removes content provider from the package manager.
367    *
368    * @return the removed component or {@code null} if no such component existed.
369    */
370   @Nullable
removeProvider(ComponentName componentName)371   public ProviderInfo removeProvider(ComponentName componentName) {
372     return removeComponent(
373         componentName, providerFilters, p -> p.providers, (p, a) -> p.providers = a);
374   }
375 
376   /**
377    * Removes broadcast receiver from the package manager.
378    *
379    * @return the removed component or {@code null} if no such component existed.
380    */
381   @Nullable
removeReceiver(ComponentName componentName)382   public ActivityInfo removeReceiver(ComponentName componentName) {
383     return removeComponent(
384         componentName, receiverFilters, p -> p.receivers, (p, a) -> p.receivers = a);
385   }
386 
addComponent( SortedMap<ComponentName, List<IntentFilter>> filtersMap, Function<PackageInfo, C[]> componentArrayInPackage, BiConsumer<PackageInfo, C[]> componentsSetter, C newComponent, boolean updateIfExists)387   private <C extends ComponentInfo> C addComponent(
388       SortedMap<ComponentName, List<IntentFilter>> filtersMap,
389       Function<PackageInfo, C[]> componentArrayInPackage,
390       BiConsumer<PackageInfo, C[]> componentsSetter,
391       C newComponent,
392       boolean updateIfExists) {
393     synchronized (lock) {
394       String packageName = newComponent.packageName;
395       if (packageName == null && newComponent.applicationInfo != null) {
396         packageName = newComponent.applicationInfo.packageName;
397       }
398       if (packageName == null) {
399         throw new IllegalArgumentException("Component needs a package name");
400       }
401       if (newComponent.name == null) {
402         throw new IllegalArgumentException("Component needs a name");
403       }
404       PackageInfo packageInfo = packageInfos.get(packageName);
405       if (packageInfo == null) {
406         packageInfo = new PackageInfo();
407         packageInfo.packageName = packageName;
408         packageInfo.applicationInfo = newComponent.applicationInfo;
409         installPackage(packageInfo);
410         packageInfo = packageInfos.get(packageName);
411       }
412       newComponent.applicationInfo = packageInfo.applicationInfo;
413       C[] components = componentArrayInPackage.apply(packageInfo);
414       if (components == null) {
415         @SuppressWarnings("unchecked")
416         C[] newComponentArray = (C[]) Array.newInstance(newComponent.getClass(), 0);
417         components = newComponentArray;
418       } else {
419         for (int i = 0; i < components.length; i++) {
420           if (newComponent.name.equals(components[i].name)) {
421             if (updateIfExists) {
422               components[i] = newComponent;
423             }
424             return components[i];
425           }
426         }
427       }
428       components = Arrays.copyOf(components, components.length + 1);
429       componentsSetter.accept(packageInfo, components);
430       components[components.length - 1] = newComponent;
431 
432       filtersMap.put(
433           new ComponentName(newComponent.packageName, newComponent.name), new ArrayList<>());
434       return newComponent;
435     }
436   }
437 
438   @Nullable
removeComponent( ComponentName componentName, SortedMap<ComponentName, List<IntentFilter>> filtersMap, Function<PackageInfo, C[]> componentArrayInPackage, BiConsumer<PackageInfo, C[]> componentsSetter)439   private <C extends ComponentInfo> C removeComponent(
440       ComponentName componentName,
441       SortedMap<ComponentName, List<IntentFilter>> filtersMap,
442       Function<PackageInfo, C[]> componentArrayInPackage,
443       BiConsumer<PackageInfo, C[]> componentsSetter) {
444     synchronized (lock) {
445       filtersMap.remove(componentName);
446       String packageName = componentName.getPackageName();
447       PackageInfo packageInfo = packageInfos.get(packageName);
448       if (packageInfo == null) {
449         return null;
450       }
451       C[] components = componentArrayInPackage.apply(packageInfo);
452       if (components == null) {
453         return null;
454       }
455       for (int i = 0; i < components.length; i++) {
456         C component = components[i];
457         if (componentName.getClassName().equals(component.name)) {
458           C[] newComponents;
459           if (components.length == 1) {
460             newComponents = null;
461           } else {
462             newComponents = Arrays.copyOf(components, components.length - 1);
463             System.arraycopy(components, i + 1, newComponents, i, components.length - i - 1);
464           }
465           componentsSetter.accept(packageInfo, newComponents);
466           return component;
467         }
468       }
469       return null;
470     }
471   }
472 
473   /**
474    * Settings for a particular package.
475    *
476    * This class mirrors {@link com.android.server.pm.PackageSetting}, which is used by {@link
477    * PackageManager}.
478    */
479   public static class PackageSetting {
480 
481     /** Whether the package is suspended in {@link PackageManager}. */
482     private boolean suspended = false;
483 
484     /** The message to be displayed to the user when they try to launch the app. */
485     private String dialogMessage = null;
486 
487     /**
488      * The info for how to display the dialog that shows to the user when they try to launch the
489      * app. On Q, one of this field or dialogMessage will be present when a package is suspended.
490      */
491     private Object dialogInfo = null;
492 
493     /** An optional {@link PersistableBundle} shared with the app. */
494     private PersistableBundle suspendedAppExtras = null;
495 
496     /** An optional {@link PersistableBundle} shared with the launcher. */
497     private PersistableBundle suspendedLauncherExtras = null;
498 
PackageSetting()499     public PackageSetting() {}
500 
PackageSetting(PackageSetting that)501     public PackageSetting(PackageSetting that) {
502       this.suspended = that.suspended;
503       this.dialogMessage = that.dialogMessage;
504       this.dialogInfo = that.dialogInfo;
505       this.suspendedAppExtras = deepCopyNullablePersistableBundle(that.suspendedAppExtras);
506       this.suspendedLauncherExtras =
507           deepCopyNullablePersistableBundle(that.suspendedLauncherExtras);
508     }
509 
510     /**
511      * Sets the suspension state of the package.
512      *
513      * <p>If {@code suspended} is false, {@code dialogInfo}, {@code appExtras}, and {@code
514      * launcherExtras} will be ignored.
515      */
setSuspended( boolean suspended, String dialogMessage, Object dialogInfo, PersistableBundle appExtras, PersistableBundle launcherExtras)516     void setSuspended(
517         boolean suspended,
518         String dialogMessage,
519         /* SuspendDialogInfo */ Object dialogInfo,
520         PersistableBundle appExtras,
521         PersistableBundle launcherExtras) {
522       Preconditions.checkArgument(dialogMessage == null || dialogInfo == null);
523       this.suspended = suspended;
524       this.dialogMessage = suspended ? dialogMessage : null;
525       this.dialogInfo = suspended ? dialogInfo : null;
526       this.suspendedAppExtras = suspended ? deepCopyNullablePersistableBundle(appExtras) : null;
527       this.suspendedLauncherExtras =
528           suspended ? deepCopyNullablePersistableBundle(launcherExtras) : null;
529     }
530 
isSuspended()531     public boolean isSuspended() {
532       return suspended;
533     }
534 
getDialogMessage()535     public String getDialogMessage() {
536       return dialogMessage;
537     }
538 
getDialogInfo()539     public Object getDialogInfo() {
540       return dialogInfo;
541     }
542 
getSuspendedAppExtras()543     public PersistableBundle getSuspendedAppExtras() {
544       return suspendedAppExtras;
545     }
546 
getSuspendedLauncherExtras()547     public PersistableBundle getSuspendedLauncherExtras() {
548       return suspendedLauncherExtras;
549     }
550 
deepCopyNullablePersistableBundle(PersistableBundle bundle)551     private static PersistableBundle deepCopyNullablePersistableBundle(PersistableBundle bundle) {
552       return bundle == null ? null : bundle.deepCopy();
553     }
554   }
555 
556   static final Map<String, PackageSetting> packageSettings = new HashMap<>();
557 
558   // From com.android.server.pm.PackageManagerService.compareSignatures().
compareSignature(Signature[] signatures1, Signature[] signatures2)559   static int compareSignature(Signature[] signatures1, Signature[] signatures2) {
560     if (signatures1 == null) {
561       return (signatures2 == null) ? SIGNATURE_NEITHER_SIGNED : SIGNATURE_FIRST_NOT_SIGNED;
562     }
563     if (signatures2 == null) {
564       return SIGNATURE_SECOND_NOT_SIGNED;
565     }
566     if (signatures1.length != signatures2.length) {
567       return SIGNATURE_NO_MATCH;
568     }
569     HashSet<Signature> signatures1set = new HashSet<>(asList(signatures1));
570     HashSet<Signature> signatures2set = new HashSet<>(asList(signatures2));
571     return signatures1set.equals(signatures2set) ? SIGNATURE_MATCH : SIGNATURE_NO_MATCH;
572   }
573 
574   // TODO(christianw): reconcile with AndroidTestEnvironment.setUpPackageStorage
setUpPackageStorage(ApplicationInfo applicationInfo)575   private static void setUpPackageStorage(ApplicationInfo applicationInfo) {
576     if (applicationInfo.sourceDir == null) {
577       applicationInfo.sourceDir = createTempDir(applicationInfo.packageName + "-sourceDir");
578     }
579 
580     if (applicationInfo.dataDir == null) {
581       applicationInfo.dataDir = createTempDir(applicationInfo.packageName + "-dataDir");
582     }
583     if (applicationInfo.publicSourceDir == null) {
584       applicationInfo.publicSourceDir = applicationInfo.sourceDir;
585     }
586     if (RuntimeEnvironment.getApiLevel() >= N) {
587       applicationInfo.credentialProtectedDataDir = createTempDir("userDataDir");
588       applicationInfo.deviceProtectedDataDir = createTempDir("deviceDataDir");
589     }
590   }
591 
createTempDir(String name)592   private static String createTempDir(String name) {
593     return RuntimeEnvironment.getTempDirectory()
594         .createIfNotExists(name)
595         .toAbsolutePath()
596         .toString();
597   }
598 
599   /**
600    * Sets extra resolve infos for an intent.
601    *
602    * Those entries are added to whatever might be in the manifest already.
603    *
604    * Note that all resolve infos will have {@link ResolveInfo#isDefault} field set to {@code
605    * true} to allow their resolution for implicit intents. If this is not what you want, then you
606    * still have the reference to those ResolveInfos, and you can set the field back to {@code
607    * false}.
608    *
609    * @deprecated see the note on {@link #addResolveInfoForIntent(Intent, ResolveInfo)}.
610    */
611   @Deprecated
setResolveInfosForIntent(Intent intent, List<ResolveInfo> info)612   public void setResolveInfosForIntent(Intent intent, List<ResolveInfo> info) {
613     resolveInfoForIntent.remove(intent);
614     for (ResolveInfo resolveInfo : info) {
615       addResolveInfoForIntent(intent, resolveInfo);
616     }
617   }
618 
619   /** @deprecated see note on {@link #addResolveInfoForIntent(Intent, ResolveInfo)}. */
620   @Deprecated
addResolveInfoForIntent(Intent intent, List<ResolveInfo> info)621   public void addResolveInfoForIntent(Intent intent, List<ResolveInfo> info) {
622     setResolveInfosForIntent(intent, info);
623   }
624 
625   /**
626    * Adds extra resolve info for an intent.
627    *
628    * Note that this resolve info will have {@link ResolveInfo#isDefault} field set to {@code
629    * true} to allow its resolution for implicit intents. If this is not what you want, then please
630    * use {@link #addResolveInfoForIntentNoDefaults} instead.
631    *
632    * @deprecated use {@link #addIntentFilterForComponent} instead and if the component doesn't exist
633    *     add it using any of {@link #installPackage}, {@link #addOrUpdateActivity}, {@link
634    *     #addActivityIfNotPresent} or their counterparts for other types of components.
635    */
636   @Deprecated
addResolveInfoForIntent(Intent intent, ResolveInfo info)637   public void addResolveInfoForIntent(Intent intent, ResolveInfo info) {
638     info.isDefault = true;
639     ComponentInfo[] componentInfos =
640         new ComponentInfo[] {info.activityInfo, info.serviceInfo, info.providerInfo};
641     for (ComponentInfo component : componentInfos) {
642       if (component != null && component.applicationInfo != null) {
643         component.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
644         if (component.applicationInfo.processName == null) {
645           component.applicationInfo.processName = component.applicationInfo.packageName;
646         }
647       }
648     }
649     if (info.match == 0) {
650       info.match = Integer.MAX_VALUE; // make sure, that this is as good match as possible.
651     }
652     addResolveInfoForIntentNoDefaults(intent, info);
653   }
654 
655   /**
656    * Adds the {@code info} as {@link ResolveInfo} for the intent but without applying any default
657    * values.
658    *
659    * In particular it will not make the {@link ResolveInfo#isDefault} field {@code true}, that
660    * means that this resolve info will not resolve for {@link Intent#resolveActivity} and {@link
661    * Context#startActivity}.
662    *
663    * @deprecated see the note on {@link #addResolveInfoForIntent(Intent, ResolveInfo)}.
664    */
665   @Deprecated
addResolveInfoForIntentNoDefaults(Intent intent, ResolveInfo info)666   public void addResolveInfoForIntentNoDefaults(Intent intent, ResolveInfo info) {
667     Preconditions.checkNotNull(info);
668     List<ResolveInfo> infoList = resolveInfoForIntent.get(intent);
669     if (infoList == null) {
670       infoList = new ArrayList<>();
671       resolveInfoForIntent.put(intent, infoList);
672     }
673     infoList.add(info);
674   }
675 
676   /**
677    * Removes {@link ResolveInfo}s registered using {@link #addResolveInfoForIntent}.
678    *
679    * @deprecated see note on {@link #addResolveInfoForIntent(Intent, ResolveInfo)}.
680    */
681   @Deprecated
removeResolveInfosForIntent(Intent intent, String packageName)682   public void removeResolveInfosForIntent(Intent intent, String packageName) {
683     List<ResolveInfo> infoList = resolveInfoForIntent.get(intent);
684     if (infoList == null) {
685       infoList = new ArrayList<>();
686       resolveInfoForIntent.put(intent, infoList);
687     }
688 
689     for (Iterator<ResolveInfo> iterator = infoList.iterator(); iterator.hasNext(); ) {
690       ResolveInfo resolveInfo = iterator.next();
691       if (getPackageName(resolveInfo).equals(packageName)) {
692         iterator.remove();
693       }
694     }
695   }
696 
getPackageName(ResolveInfo resolveInfo)697   private static String getPackageName(ResolveInfo resolveInfo) {
698     if (resolveInfo.resolvePackageName != null) {
699       return resolveInfo.resolvePackageName;
700     } else if (resolveInfo.activityInfo != null) {
701       return resolveInfo.activityInfo.packageName;
702     } else if (resolveInfo.serviceInfo != null) {
703       return resolveInfo.serviceInfo.packageName;
704     } else if (resolveInfo.providerInfo != null) {
705       return resolveInfo.providerInfo.packageName;
706     }
707     throw new IllegalStateException(
708         "Could not find package name for ResolveInfo " + resolveInfo.toString());
709   }
710 
addActivityIcon(ComponentName component, Drawable drawable)711   public void addActivityIcon(ComponentName component, Drawable drawable) {
712     drawableList.put(component, drawable);
713   }
714 
addActivityIcon(Intent intent, Drawable drawable)715   public void addActivityIcon(Intent intent, Drawable drawable) {
716     drawableList.put(intent.getComponent(), drawable);
717   }
718 
setApplicationIcon(String packageName, Drawable drawable)719   public void setApplicationIcon(String packageName, Drawable drawable) {
720     applicationIcons.put(packageName, drawable);
721   }
722 
setUnbadgedApplicationIcon(String packageName, Drawable drawable)723   public void setUnbadgedApplicationIcon(String packageName, Drawable drawable) {
724     unbadgedApplicationIcons.put(packageName, drawable);
725   }
726 
727   /**
728    * Return the flags set in call to {@link
729    * android.app.ApplicationPackageManager#setComponentEnabledSetting(ComponentName, int, int)}.
730    *
731    * @param componentName The component name.
732    * @return The flags.
733    */
getComponentEnabledSettingFlags(ComponentName componentName)734   public int getComponentEnabledSettingFlags(ComponentName componentName) {
735     ComponentState state = componentList.get(componentName);
736     return state != null ? state.flags : 0;
737   }
738 
739   /**
740    * Installs a module with the {@link PackageManager} as long as it is not {@code null}
741    *
742    * <p>In order to create ModuleInfo objects in a valid state please use {@link ModuleInfoBuilder}.
743    */
installModule(Object moduleInfoObject)744   public void installModule(Object moduleInfoObject) {
745     synchronized (lock) {
746       ModuleInfo moduleInfo = (ModuleInfo) moduleInfoObject;
747       if (moduleInfo != null) {
748         moduleInfos.put(moduleInfo.getPackageName(), moduleInfo);
749         // Checking to see if package exists in the system
750         if (packageInfos.get(moduleInfo.getPackageName()) == null) {
751           ApplicationInfo applicationInfo = new ApplicationInfo();
752           applicationInfo.packageName = moduleInfo.getPackageName();
753           applicationInfo.name = moduleInfo.getName().toString();
754 
755           PackageInfo packageInfo = new PackageInfo();
756           packageInfo.applicationInfo = applicationInfo;
757           packageInfo.packageName = moduleInfo.getPackageName();
758           installPackage(packageInfo);
759         }
760       }
761     }
762   }
763 
764   /**
765    * Deletes a module when given the module's package name {@link ModuleInfo} be sure to give the
766    * correct name as this method does not ensure existence of the module before deletion. Since
767    * module installation ensures that a package exists in the device, also delete the package for
768    * full deletion.
769    *
770    * @param packageName should be the value of {@link ModuleInfo#getPackageName}.
771    * @return deleted module of {@code null} if no module with this name exists.
772    */
deleteModule(String packageName)773   public Object deleteModule(String packageName) {
774     synchronized (lock) {
775       // Removes the accompanying package installed with the module
776       return moduleInfos.remove(packageName);
777     }
778   }
779 
780   /**
781    * Installs a package with the {@link PackageManager}.
782    *
783    * In order to create PackageInfo objects in a valid state please use {@link
784    * androidx.test.core.content.pm.PackageInfoBuilder}.
785    *
786    * This method automatically simulates instalation of a package in the system, so it adds a
787    * flag {@link ApplicationInfo#FLAG_INSTALLED} to the application info and makes sure it exits. It
788    * will update applicationInfo in package components as well.
789    *
790    * If you don't want the package to be installed, use {@link #addPackageNoDefaults} instead.
791    */
installPackage(PackageInfo packageInfo)792   public void installPackage(PackageInfo packageInfo) {
793     ApplicationInfo appInfo = packageInfo.applicationInfo;
794     if (appInfo == null) {
795       appInfo = new ApplicationInfo();
796       packageInfo.applicationInfo = appInfo;
797     }
798     if (appInfo.packageName == null) {
799       appInfo.packageName = packageInfo.packageName;
800     }
801     if (appInfo.processName == null) {
802       appInfo.processName = appInfo.packageName;
803     }
804     if (appInfo.targetSdkVersion == 0) {
805       appInfo.targetSdkVersion = RuntimeEnvironment.getApiLevel();
806     }
807     appInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
808     ComponentInfo[][] componentInfoArrays =
809         new ComponentInfo[][] {
810           packageInfo.activities,
811           packageInfo.services,
812           packageInfo.providers,
813           packageInfo.receivers,
814         };
815     int uniqueNameCounter = 0;
816     for (ComponentInfo[] componentInfos : componentInfoArrays) {
817       if (componentInfos == null) {
818         continue;
819       }
820       for (ComponentInfo componentInfo : componentInfos) {
821         if (componentInfo.name == null) {
822           componentInfo.name = appInfo.packageName + ".DefaultName" + uniqueNameCounter++;
823           componentInfo.packageName = packageInfo.packageName;
824         }
825         componentInfo.applicationInfo = appInfo;
826         componentInfo.packageName = appInfo.packageName;
827         if (componentInfo.processName == null) {
828           componentInfo.processName = appInfo.processName;
829         }
830       }
831     }
832     addPackageNoDefaults(packageInfo);
833   }
834 
835   /** Adds install source information for a package. */
setInstallSourceInfo( String packageName, String initiatingPackage, String installerPackage)836   public void setInstallSourceInfo(
837       String packageName, String initiatingPackage, String installerPackage) {
838     packageInstallSourceInfoMap.put(
839         packageName, new InstallSourceInfo(initiatingPackage, null, null, installerPackage));
840   }
841 
842   /**
843    * Adds a package to the {@link PackageManager}, but doesn't set any default values on it.
844    *
845    * <p>Right now it will not set {@link ApplicationInfo#FLAG_INSTALLED} flag on its application, so
846    * if not set explicitly, it will be treated as not installed.
847    */
addPackageNoDefaults(PackageInfo packageInfo)848   public void addPackageNoDefaults(PackageInfo packageInfo) {
849     PackageStats packageStats = new PackageStats(packageInfo.packageName);
850     addPackage(packageInfo, packageStats);
851   }
852 
853   /**
854    * Installs a package with its stats with the {@link PackageManager}.
855    *
856    * <p>This method doesn't add any defaults to the {@code packageInfo} parameters. You should make
857    * sure it is valid (see {@link #installPackage(PackageInfo)}).
858    */
addPackage(PackageInfo packageInfo, PackageStats packageStats)859   public void addPackage(PackageInfo packageInfo, PackageStats packageStats) {
860     synchronized (lock) {
861       if (packageInfo.applicationInfo != null
862           && (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
863         Log.w(TAG, "Adding not installed package: " + packageInfo.packageName);
864       }
865       Preconditions.checkArgument(packageInfo.packageName.equals(packageStats.packageName));
866 
867       packageInfos.put(packageInfo.packageName, packageInfo);
868       packageStatsMap.put(packageInfo.packageName, packageStats);
869 
870       packageSettings.put(packageInfo.packageName, new PackageSetting());
871 
872       applicationEnabledSettingMap.put(
873           packageInfo.packageName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
874       if (packageInfo.applicationInfo != null) {
875         uidForPackage.put(packageInfo.packageName, packageInfo.applicationInfo.uid);
876         namesForUid.put(packageInfo.applicationInfo.uid, packageInfo.packageName);
877       }
878     }
879   }
880 
881   /** @deprecated Use {@link #installPackage(PackageInfo)} instead. */
882   @Deprecated
addPackage(String packageName)883   public void addPackage(String packageName) {
884     PackageInfo packageInfo = new PackageInfo();
885     packageInfo.packageName = packageName;
886 
887     ApplicationInfo applicationInfo = new ApplicationInfo();
888 
889     applicationInfo.packageName = packageName;
890     // TODO: setUpPackageStorage should be in installPackage but we need to fix all tests first
891     setUpPackageStorage(applicationInfo);
892     packageInfo.applicationInfo = applicationInfo;
893     installPackage(packageInfo);
894   }
895 
896   /**
897    * @deprecated Use {@link #installPackage} instead.
898    */
899   @Deprecated
900   @InlineMe(replacement = "this.installPackage(packageInfo)")
addPackage(PackageInfo packageInfo)901   public final void addPackage(PackageInfo packageInfo) {
902     installPackage(packageInfo);
903   }
904 
905   /**
906    * Testing API allowing to retrieve internal package representation.
907    *
908    * This will allow to modify the package in a way visible to Robolectric, as this is
909    * Robolectric's internal full package representation.
910    *
911    * Note that maybe a better way is to just modify the test manifest to make those modifications
912    * in a standard way.
913    *
914    * Retrieving package info using {@link PackageManager#getPackageInfo} / {@link
915    * PackageManager#getApplicationInfo} will return defensive copies that will be stripped out of
916    * information according to provided flags. Don't use it to modify Robolectric state.
917    */
getInternalMutablePackageInfo(String packageName)918   public PackageInfo getInternalMutablePackageInfo(String packageName) {
919     synchronized (lock) {
920       return packageInfos.get(packageName);
921     }
922   }
923 
addPermissionInfo(PermissionInfo permissionInfo)924   public void addPermissionInfo(PermissionInfo permissionInfo) {
925     extraPermissions.put(permissionInfo.name, permissionInfo);
926   }
927 
928   /**
929    * Adds {@code packageName} to the list of changed packages for the particular {@code
930    * sequenceNumber}.
931    *
932    * @param sequenceNumber has to be >= 0
933    * @param packageName name of the package that was changed
934    */
addChangedPackage(int sequenceNumber, String packageName)935   public void addChangedPackage(int sequenceNumber, String packageName) {
936     if (sequenceNumber < 0) {
937       return;
938     }
939     sequenceNumberChangedPackagesMap.put(sequenceNumber, packageName);
940   }
941 
942   /**
943    * Allows overriding or adding permission-group elements. These would be otherwise specified by
944    * either (the
945    * system)[https://developer.android.com/guide/topics/permissions/requesting.html#perm-groups] or
946    * by (the app
947    * itself)[https://developer.android.com/guide/topics/manifest/permission-group-element.html], as
948    * part of its manifest
949    *
950    * {@link android.content.pm.PackageParser.PermissionGroup}s added through this method have
951    * precedence over those specified with the same name by one of the aforementioned methods.
952    *
953    * @see PackageManager#getAllPermissionGroups(int)
954    * @see PackageManager#getPermissionGroupInfo(String, int)
955    */
addPermissionGroupInfo(PermissionGroupInfo permissionGroupInfo)956   public void addPermissionGroupInfo(PermissionGroupInfo permissionGroupInfo) {
957     permissionGroups.put(permissionGroupInfo.name, permissionGroupInfo);
958   }
959 
removePackage(String packageName)960   public void removePackage(String packageName) {
961     synchronized (lock) {
962       packageInfos.remove(packageName);
963 
964       packageSettings.remove(packageName);
965     }
966   }
967 
setSystemFeature(String name, boolean supported)968   public void setSystemFeature(String name, boolean supported) {
969     systemFeatureList.put(name, supported);
970   }
971 
addDrawableResolution(String packageName, int resourceId, Drawable drawable)972   public void addDrawableResolution(String packageName, int resourceId, Drawable drawable) {
973     drawables.put(new Pair(packageName, resourceId), drawable);
974   }
975 
setNameForUid(int uid, String name)976   public void setNameForUid(int uid, String name) {
977     namesForUid.put(uid, name);
978   }
979 
setPackagesForCallingUid(String... packagesForCallingUid)980   public void setPackagesForCallingUid(String... packagesForCallingUid) {
981     packagesForUid.put(Binder.getCallingUid(), packagesForCallingUid);
982     for (String packageName : packagesForCallingUid) {
983       uidForPackage.put(packageName, Binder.getCallingUid());
984     }
985   }
986 
setPackagesForUid(int uid, String... packagesForCallingUid)987   public void setPackagesForUid(int uid, String... packagesForCallingUid) {
988     packagesForUid.put(uid, packagesForCallingUid);
989     for (String packageName : packagesForCallingUid) {
990       uidForPackage.put(packageName, uid);
991     }
992   }
993 
994   @Implementation
995   @Nullable
getPackagesForUid(int uid)996   protected String[] getPackagesForUid(int uid) {
997     return packagesForUid.get(uid);
998   }
999 
setPackageArchiveInfo(String archiveFilePath, PackageInfo packageInfo)1000   public void setPackageArchiveInfo(String archiveFilePath, PackageInfo packageInfo) {
1001     packageArchiveInfo.put(archiveFilePath, packageInfo);
1002   }
1003 
getVerificationResult(int id)1004   public int getVerificationResult(int id) {
1005     Integer result = verificationResults.get(id);
1006     if (result == null) {
1007       // 0 isn't a "valid" result, so we can check for the case when verification isn't
1008       // called, if needed
1009       return 0;
1010     }
1011     return result;
1012   }
1013 
getVerificationExtendedTimeout(int id)1014   public long getVerificationExtendedTimeout(int id) {
1015     synchronized (lock) {
1016       return verificationTimeoutExtension.getOrDefault(id, 0L);
1017     }
1018   }
1019 
getVerificationCodeAtTimeoutExtension(int id)1020   public int getVerificationCodeAtTimeoutExtension(int id) {
1021     synchronized (lock) {
1022       return verificationCodeAtTimeoutExtension.getOrDefault(id, VERIFICATION_ALLOW);
1023     }
1024   }
1025 
triggerInstallVerificationTimeout(Application appContext, int id)1026   public void triggerInstallVerificationTimeout(Application appContext, int id) {
1027     Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
1028     intent.putExtra(EXTRA_VERIFICATION_ID, id);
1029     intent.putExtra(
1030         PackageManager.EXTRA_VERIFICATION_RESULT, getVerificationCodeAtTimeoutExtension(id));
1031 
1032     // Send PACKAGE_VERIFIED broadcast to trigger the verification timeout.
1033     // Replacement api does not return the actual receiver objects.
1034     @SuppressWarnings("deprecation")
1035     List<BroadcastReceiver> receivers =
1036         ShadowApplication.getShadowInstrumentation().getReceiversForIntent(intent);
1037     for (BroadcastReceiver receiver : receivers) {
1038       receiver.onReceive(appContext, intent);
1039     }
1040   }
1041 
setShouldShowRequestPermissionRationale(String permission, boolean show)1042   public void setShouldShowRequestPermissionRationale(String permission, boolean show) {
1043     permissionRationaleMap.put(permission, show);
1044   }
1045 
addSystemAvailableFeature(FeatureInfo featureInfo)1046   public void addSystemAvailableFeature(FeatureInfo featureInfo) {
1047     systemAvailableFeatures.add(featureInfo);
1048   }
1049 
clearSystemAvailableFeatures()1050   public void clearSystemAvailableFeatures() {
1051     systemAvailableFeatures.clear();
1052   }
1053 
1054   /** Adds a value to be returned by {@link PackageManager#getSystemSharedLibraryNames()}. */
addSystemSharedLibraryName(String name)1055   public void addSystemSharedLibraryName(String name) {
1056     systemSharedLibraryNames.add(name);
1057   }
1058 
1059   /** Clears the values returned by {@link PackageManager#getSystemSharedLibraryNames()}. */
clearSystemSharedLibraryNames()1060   public void clearSystemSharedLibraryNames() {
1061     systemSharedLibraryNames.clear();
1062   }
1063 
1064   @Deprecated
1065   /** @deprecated use {@link #addCanonicalName} instead.} */
addCurrentToCannonicalName(String currentName, String canonicalName)1066   public void addCurrentToCannonicalName(String currentName, String canonicalName) {
1067     currentToCanonicalNames.put(currentName, canonicalName);
1068   }
1069 
1070   /**
1071    * Adds a canonical package name for a package.
1072    *
1073    * <p>This will be reflected when calling {@link
1074    * PackageManager#currentToCanonicalPackageNames(String[])} or {@link
1075    * PackageManager#canonicalToCurrentPackageNames(String[])} (String[])}.
1076    */
addCanonicalName(String currentName, String canonicalName)1077   public void addCanonicalName(String currentName, String canonicalName) {
1078     currentToCanonicalNames.put(currentName, canonicalName);
1079     canonicalToCurrentNames.put(canonicalName, currentName);
1080   }
1081 
1082   /**
1083    * Sets if the {@link PackageManager} is allowed to request package installs through package
1084    * installer.
1085    */
setCanRequestPackageInstalls(boolean canRequestPackageInstalls)1086   public void setCanRequestPackageInstalls(boolean canRequestPackageInstalls) {
1087     ShadowPackageManager.canRequestPackageInstalls = canRequestPackageInstalls;
1088   }
1089 
1090   @Implementation(minSdk = N)
queryBroadcastReceiversAsUser( Intent intent, int flags, UserHandle userHandle)1091   protected List<ResolveInfo> queryBroadcastReceiversAsUser(
1092       Intent intent, int flags, UserHandle userHandle) {
1093     return null;
1094   }
1095 
1096   @Implementation
queryBroadcastReceivers( Intent intent, int flags, @UserIdInt int userId)1097   protected List<ResolveInfo> queryBroadcastReceivers(
1098       Intent intent, int flags, @UserIdInt int userId) {
1099     return null;
1100   }
1101 
1102   @Implementation
getPackageArchiveInfo(String archiveFilePath, int flags)1103   protected PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) {
1104     PackageInfo shadowPackageInfo = getShadowPackageArchiveInfo(archiveFilePath, flags);
1105     if (shadowPackageInfo != null) {
1106       return shadowPackageInfo;
1107     } else {
1108       return reflector(PackageManagerReflector.class, realPackageManager)
1109           .getPackageArchiveInfo(archiveFilePath, flags);
1110     }
1111   }
1112 
getShadowPackageArchiveInfo(String archiveFilePath, int flags)1113   protected PackageInfo getShadowPackageArchiveInfo(String archiveFilePath, int flags) {
1114     synchronized (lock) {
1115       if (packageArchiveInfo.containsKey(archiveFilePath)) {
1116         return packageArchiveInfo.get(archiveFilePath);
1117       }
1118 
1119       List<PackageInfo> result = new ArrayList<>();
1120       for (PackageInfo packageInfo : packageInfos.values()) {
1121         if (applicationEnabledSettingMap.get(packageInfo.packageName)
1122                 != COMPONENT_ENABLED_STATE_DISABLED
1123             || (flags & MATCH_UNINSTALLED_PACKAGES) == MATCH_UNINSTALLED_PACKAGES) {
1124           result.add(packageInfo);
1125         }
1126       }
1127 
1128       List<PackageInfo> packages = result;
1129       for (PackageInfo aPackage : packages) {
1130         ApplicationInfo appInfo = aPackage.applicationInfo;
1131         if (appInfo != null && archiveFilePath.equals(appInfo.sourceDir)) {
1132           return aPackage;
1133         }
1134       }
1135       return null;
1136     }
1137   }
1138 
1139   @Implementation
freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer)1140   protected void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer) {}
1141 
1142   @Implementation
freeStorage(long freeStorageSize, IntentSender pi)1143   protected void freeStorage(long freeStorageSize, IntentSender pi) {}
1144 
1145   /**
1146    * Uninstalls the package from the system in a way, that will allow its discovery through {@link
1147    * PackageManager#MATCH_UNINSTALLED_PACKAGES}.
1148    */
deletePackage(String packageName)1149   public void deletePackage(String packageName) {
1150     synchronized (lock) {
1151       deletedPackages.add(packageName);
1152       packageInfos.remove(packageName);
1153       mapForPackage(activityFilters, packageName).clear();
1154       mapForPackage(serviceFilters, packageName).clear();
1155       mapForPackage(providerFilters, packageName).clear();
1156       mapForPackage(receiverFilters, packageName).clear();
1157       moduleInfos.remove(packageName);
1158     }
1159   }
1160 
1161   @Implementation
deletePackage(String packageName, IPackageDeleteObserver observer, int flags)1162   protected void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
1163     pendingDeleteCallbacks.put(packageName, observer);
1164   }
1165 
1166   /**
1167    * Runs the callbacks pending from calls to {@link PackageManager#deletePackage(String,
1168    * IPackageDeleteObserver, int)}
1169    */
doPendingUninstallCallbacks()1170   public void doPendingUninstallCallbacks() {
1171     synchronized (lock) {
1172       boolean hasDeletePackagesPermission = false;
1173       String[] requestedPermissions =
1174           packageInfos.get(RuntimeEnvironment.getApplication().getPackageName())
1175               .requestedPermissions;
1176       if (requestedPermissions != null) {
1177         for (String permission : requestedPermissions) {
1178           if (Manifest.permission.DELETE_PACKAGES.equals(permission)) {
1179             hasDeletePackagesPermission = true;
1180             break;
1181           }
1182         }
1183       }
1184 
1185       for (String packageName : pendingDeleteCallbacks.keySet()) {
1186         int resultCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
1187 
1188         PackageInfo removed = packageInfos.get(packageName);
1189         if (hasDeletePackagesPermission && removed != null) {
1190           deletePackage(packageName);
1191           resultCode = PackageManager.DELETE_SUCCEEDED;
1192         }
1193 
1194         try {
1195           pendingDeleteCallbacks.get(packageName).packageDeleted(packageName, resultCode);
1196         } catch (RemoteException e) {
1197           throw new RuntimeException(e);
1198         }
1199       }
1200       pendingDeleteCallbacks.clear();
1201     }
1202   }
1203 
1204   /**
1205    * Returns package names successfully deleted with {@link PackageManager#deletePackage(String,
1206    * IPackageDeleteObserver, int)} Note that like real {@link PackageManager} the calling context
1207    * must have {@link android.Manifest.permission#DELETE_PACKAGES} permission set.
1208    */
getDeletedPackages()1209   public Set<String> getDeletedPackages() {
1210     synchronized (lock) {
1211       return deletedPackages;
1212     }
1213   }
1214 
queryOverriddenIntents(Intent intent, int flags)1215   protected List<ResolveInfo> queryOverriddenIntents(Intent intent, int flags) {
1216     List<ResolveInfo> overrides = resolveInfoForIntent.get(intent);
1217     if (overrides == null) {
1218       return Collections.emptyList();
1219     }
1220     List<ResolveInfo> result = new ArrayList<>(overrides.size());
1221     for (ResolveInfo resolveInfo : overrides) {
1222       result.add(ShadowResolveInfo.newResolveInfo(resolveInfo));
1223     }
1224     return result;
1225   }
1226 
1227   /**
1228    * Internal use only.
1229    *
1230    * @param appPackage
1231    */
addPackageInternal(Package appPackage)1232   public void addPackageInternal(Package appPackage) {
1233     int flags =
1234         GET_ACTIVITIES
1235             | GET_RECEIVERS
1236             | GET_SERVICES
1237             | GET_PROVIDERS
1238             | GET_INSTRUMENTATION
1239             | GET_INTENT_FILTERS
1240             | GET_SIGNATURES
1241             | GET_RESOLVED_FILTER
1242             | GET_META_DATA
1243             | GET_GIDS
1244             | MATCH_DISABLED_COMPONENTS
1245             | GET_SHARED_LIBRARY_FILES
1246             | GET_URI_PERMISSION_PATTERNS
1247             | GET_PERMISSIONS
1248             | MATCH_UNINSTALLED_PACKAGES
1249             | GET_CONFIGURATIONS
1250             | MATCH_DISABLED_UNTIL_USED_COMPONENTS
1251             | MATCH_DIRECT_BOOT_UNAWARE
1252             | MATCH_DIRECT_BOOT_AWARE;
1253 
1254     for (PermissionGroup permissionGroup : appPackage.permissionGroups) {
1255       PermissionGroupInfo permissionGroupInfo =
1256           PackageParser.generatePermissionGroupInfo(permissionGroup, flags);
1257       addPermissionGroupInfo(permissionGroupInfo);
1258     }
1259     PackageInfo packageInfo = generatePackageInfo(appPackage, flags);
1260 
1261     packageInfo.applicationInfo.uid = Process.myUid();
1262     packageInfo.applicationInfo.dataDir = createTempDir(packageInfo.packageName + "-dataDir");
1263     installPackage(packageInfo);
1264     addFilters(activityFilters, appPackage.activities);
1265     addFilters(serviceFilters, appPackage.services);
1266     addFilters(providerFilters, appPackage.providers);
1267     addFilters(receiverFilters, appPackage.receivers);
1268   }
1269 
generatePackageInfo(Package appPackage, int flags)1270   protected PackageInfo generatePackageInfo(Package appPackage, int flags) {
1271 
1272     if (RuntimeEnvironment.getApiLevel() >= TIRAMISU) {
1273       return PackageParser.generatePackageInfo(
1274           appPackage,
1275           new int[] {0},
1276           flags,
1277           0,
1278           0,
1279           Collections.emptySet(),
1280           FrameworkPackageUserState.DEFAULT,
1281           0);
1282     } else {
1283       return reflector(_PackageParser_.class)
1284           .generatePackageInfo(appPackage, new int[] {0}, flags, 0, 0);
1285     }
1286   }
1287 
addFilters( Map<ComponentName, List<IntentFilter>> componentMap, List<? extends PackageParser.Component<?>> components)1288   private void addFilters(
1289       Map<ComponentName, List<IntentFilter>> componentMap,
1290       List<? extends PackageParser.Component<?>> components) {
1291     if (components == null) {
1292       return;
1293     }
1294     for (Component<?> component : components) {
1295       ComponentName componentName = component.getComponentName();
1296       List<IntentFilter> registeredFilters = componentMap.get(componentName);
1297       if (registeredFilters == null) {
1298         registeredFilters = new ArrayList<>();
1299         componentMap.put(componentName, registeredFilters);
1300       }
1301       for (IntentInfo intentInfo : component.intents) {
1302         registeredFilters.add(new IntentFilter(intentInfo));
1303       }
1304     }
1305   }
1306 
1307   public static class IntentComparator implements Comparator<Intent> {
1308 
1309     @Override
compare(Intent i1, Intent i2)1310     public int compare(Intent i1, Intent i2) {
1311       if (i1 == null && i2 == null) return 0;
1312       if (i1 == null && i2 != null) return -1;
1313       if (i1 != null && i2 == null) return 1;
1314       if (i1.equals(i2)) return 0;
1315       String action1 = i1.getAction();
1316       String action2 = i2.getAction();
1317       if (action1 == null && action2 != null) return -1;
1318       if (action1 != null && action2 == null) return 1;
1319       if (action1 != null && action2 != null) {
1320         if (!action1.equals(action2)) {
1321           return action1.compareTo(action2);
1322         }
1323       }
1324       Uri data1 = i1.getData();
1325       Uri data2 = i2.getData();
1326       if (data1 == null && data2 != null) return -1;
1327       if (data1 != null && data2 == null) return 1;
1328       if (data1 != null && data2 != null) {
1329         if (!data1.equals(data2)) {
1330           return data1.compareTo(data2);
1331         }
1332       }
1333       ComponentName component1 = i1.getComponent();
1334       ComponentName component2 = i2.getComponent();
1335       if (component1 == null && component2 != null) return -1;
1336       if (component1 != null && component2 == null) return 1;
1337       if (component1 != null && component2 != null) {
1338         if (!component1.equals(component2)) {
1339           return component1.compareTo(component2);
1340         }
1341       }
1342       String package1 = i1.getPackage();
1343       String package2 = i2.getPackage();
1344       if (package1 == null && package2 != null) return -1;
1345       if (package1 != null && package2 == null) return 1;
1346       if (package1 != null && package2 != null) {
1347         if (!package1.equals(package2)) {
1348           return package1.compareTo(package2);
1349         }
1350       }
1351       Set<String> categories1 = i1.getCategories();
1352       Set<String> categories2 = i2.getCategories();
1353       if (categories1 == null) return categories2 == null ? 0 : -1;
1354       if (categories2 == null) return 1;
1355       if (categories1.size() > categories2.size()) return 1;
1356       if (categories1.size() < categories2.size()) return -1;
1357       String[] array1 = categories1.toArray(new String[0]);
1358       String[] array2 = categories2.toArray(new String[0]);
1359       Arrays.sort(array1);
1360       Arrays.sort(array2);
1361       for (int i = 0; i < array1.length; ++i) {
1362         int val = array1[i].compareTo(array2[i]);
1363         if (val != 0) return val;
1364       }
1365       return 0;
1366     }
1367   }
1368 
1369   /**
1370    * Compares {@link ResolveInfo}s, ordering better matches before worse ones. This is the order in
1371    * which resolve infos should be returned to the user.
1372    */
1373   static class ResolveInfoComparator implements Comparator<ResolveInfo> {
1374 
1375     @Override
compare(ResolveInfo o1, ResolveInfo o2)1376     public int compare(ResolveInfo o1, ResolveInfo o2) {
1377       if (o1 == null && o2 == null) {
1378         return 0;
1379       }
1380       if (o1 == null) {
1381         return -1;
1382       }
1383       if (o2 == null) {
1384         return 1;
1385       }
1386       if (o1.preferredOrder != o2.preferredOrder) {
1387         // higher priority is before lower
1388         return -Integer.compare(o1.preferredOrder, o2.preferredOrder);
1389       }
1390       if (o1.priority != o2.priority) {
1391         // higher priority is before lower
1392         return -Integer.compare(o1.priority, o2.priority);
1393       }
1394       if (o1.match != o2.match) {
1395         // higher match is before lower
1396         return -Integer.compare(o1.match, o2.match);
1397       }
1398       return 0;
1399     }
1400   }
1401 
1402   protected static class ComponentState {
1403     public int newState;
1404     public int flags;
1405 
ComponentState(int newState, int flags)1406     public ComponentState(int newState, int flags) {
1407       this.newState = newState;
1408       this.flags = flags;
1409     }
1410   }
1411 
1412   /**
1413    * Get list of intent filters defined for given activity.
1414    *
1415    * @param componentName Name of the activity whose intent filters are to be retrieved
1416    * @return the activity's intent filters
1417    * @throws IllegalArgumentException if component with given name doesn't exist.
1418    */
getIntentFiltersForActivity(ComponentName componentName)1419   public List<IntentFilter> getIntentFiltersForActivity(ComponentName componentName) {
1420     return getIntentFiltersForComponent(componentName, activityFilters);
1421   }
1422 
1423   /**
1424    * Get list of intent filters defined for given service.
1425    *
1426    * @param componentName Name of the service whose intent filters are to be retrieved
1427    * @return the service's intent filters
1428    * @throws IllegalArgumentException if component with given name doesn't exist.
1429    */
getIntentFiltersForService(ComponentName componentName)1430   public List<IntentFilter> getIntentFiltersForService(ComponentName componentName) {
1431     return getIntentFiltersForComponent(componentName, serviceFilters);
1432   }
1433 
1434   /**
1435    * Get list of intent filters defined for given receiver.
1436    *
1437    * @param componentName Name of the receiver whose intent filters are to be retrieved
1438    * @return the receiver's intent filters
1439    * @throws IllegalArgumentException if component with given name doesn't exist.
1440    */
getIntentFiltersForReceiver(ComponentName componentName)1441   public List<IntentFilter> getIntentFiltersForReceiver(ComponentName componentName) {
1442       return getIntentFiltersForComponent(componentName, receiverFilters);
1443   }
1444 
1445   /**
1446    * Get list of intent filters defined for given provider.
1447    *
1448    * @param componentName Name of the provider whose intent filters are to be retrieved
1449    * @return the provider's intent filters
1450    * @throws IllegalArgumentException if component with given name doesn't exist.
1451    */
getIntentFiltersForProvider(ComponentName componentName)1452   public List<IntentFilter> getIntentFiltersForProvider(ComponentName componentName) {
1453     return getIntentFiltersForComponent(componentName, providerFilters);
1454   }
1455 
1456   /**
1457    * Add intent filter for given activity.
1458    *
1459    * @throws IllegalArgumentException if component with given name doesn't exist.
1460    */
addIntentFilterForActivity(ComponentName componentName, IntentFilter filter)1461   public void addIntentFilterForActivity(ComponentName componentName, IntentFilter filter) {
1462     addIntentFilterForComponent(componentName, filter, activityFilters);
1463   }
1464 
1465   /**
1466    * Add intent filter for given service.
1467    *
1468    * @throws IllegalArgumentException if component with given name doesn't exist.
1469    */
addIntentFilterForService(ComponentName componentName, IntentFilter filter)1470   public void addIntentFilterForService(ComponentName componentName, IntentFilter filter) {
1471     addIntentFilterForComponent(componentName, filter, serviceFilters);
1472   }
1473 
1474   /**
1475    * Add intent filter for given receiver.
1476    *
1477    * @throws IllegalArgumentException if component with given name doesn't exist.
1478    */
addIntentFilterForReceiver(ComponentName componentName, IntentFilter filter)1479   public void addIntentFilterForReceiver(ComponentName componentName, IntentFilter filter) {
1480     addIntentFilterForComponent(componentName, filter, receiverFilters);
1481   }
1482 
1483   /**
1484    * Add intent filter for given provider.
1485    *
1486    * @throws IllegalArgumentException if component with given name doesn't exist.
1487    */
addIntentFilterForProvider(ComponentName componentName, IntentFilter filter)1488   public void addIntentFilterForProvider(ComponentName componentName, IntentFilter filter) {
1489     addIntentFilterForComponent(componentName, filter, providerFilters);
1490   }
1491 
1492   /**
1493    * Clears intent filters for given activity.
1494    *
1495    * @throws IllegalArgumentException if component with given name doesn't exist.
1496    */
clearIntentFilterForActivity(ComponentName componentName)1497   public void clearIntentFilterForActivity(ComponentName componentName) {
1498     clearIntentFilterForComponent(componentName, activityFilters);
1499   }
1500 
1501   /**
1502    * Clears intent filters for given service.
1503    *
1504    * @throws IllegalArgumentException if component with given name doesn't exist.
1505    */
clearIntentFilterForService(ComponentName componentName)1506   public void clearIntentFilterForService(ComponentName componentName) {
1507     clearIntentFilterForComponent(componentName, serviceFilters);
1508   }
1509 
1510   /**
1511    * Clears intent filters for given receiver.
1512    *
1513    * @throws IllegalArgumentException if component with given name doesn't exist.
1514    */
clearIntentFilterForReceiver(ComponentName componentName)1515   public void clearIntentFilterForReceiver(ComponentName componentName) {
1516     clearIntentFilterForComponent(componentName, receiverFilters);
1517   }
1518 
1519   /**
1520    * Clears intent filters for given provider.
1521    *
1522    * @throws IllegalArgumentException if component with given name doesn't exist.
1523    */
clearIntentFilterForProvider(ComponentName componentName)1524   public void clearIntentFilterForProvider(ComponentName componentName) {
1525     clearIntentFilterForComponent(componentName, providerFilters);
1526   }
1527 
addIntentFilterForComponent( ComponentName componentName, IntentFilter filter, Map<ComponentName, List<IntentFilter>> filterMap)1528   private void addIntentFilterForComponent(
1529       ComponentName componentName,
1530       IntentFilter filter,
1531       Map<ComponentName, List<IntentFilter>> filterMap) {
1532     // Existing components should have an entry in respective filterMap.
1533     // It is OK to search over all filter maps, as it is impossible to have the same component name
1534     // being of two comopnent types (like activity and service at the same time).
1535     List<IntentFilter> filters = filterMap.get(componentName);
1536     if (filters != null) {
1537       filters.add(filter);
1538       return;
1539     }
1540     throw new IllegalArgumentException(componentName + " doesn't exist");
1541   }
1542 
clearIntentFilterForComponent( ComponentName componentName, Map<ComponentName, List<IntentFilter>> filterMap)1543   private void clearIntentFilterForComponent(
1544       ComponentName componentName, Map<ComponentName, List<IntentFilter>> filterMap) {
1545     List<IntentFilter> filters = filterMap.get(componentName);
1546     if (filters != null) {
1547       filters.clear();
1548       return;
1549     }
1550     throw new IllegalArgumentException(componentName + " doesn't exist");
1551   }
1552 
getIntentFiltersForComponent( ComponentName componentName, Map<ComponentName, List<IntentFilter>> filterMap)1553   private List<IntentFilter> getIntentFiltersForComponent(
1554       ComponentName componentName, Map<ComponentName, List<IntentFilter>> filterMap) {
1555     List<IntentFilter> filters = filterMap.get(componentName);
1556     if (filters != null) {
1557       return new ArrayList<>(filters);
1558     }
1559     throw new IllegalArgumentException(componentName + " doesn't exist");
1560   }
1561 
1562   /**
1563    * Method to retrieve persistent preferred activities as set by {@link
1564    * android.app.admin.DevicePolicyManager#addPersistentPreferredActivity}.
1565    *
1566    * <p>Works the same way as analogous {@link PackageManager#getPreferredActivities} for regular
1567    * preferred activities.
1568    */
getPersistentPreferredActivities( List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)1569   public int getPersistentPreferredActivities(
1570       List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName) {
1571     return getPreferredActivitiesInternal(
1572         outFilters, outActivities, packageName, persistentPreferredActivities);
1573   }
1574 
getPreferredActivitiesInternal( List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName, SortedMap<ComponentName, List<IntentFilter>> preferredActivitiesMap)1575   protected static int getPreferredActivitiesInternal(
1576       List<IntentFilter> outFilters,
1577       List<ComponentName> outActivities,
1578       String packageName,
1579       SortedMap<ComponentName, List<IntentFilter>> preferredActivitiesMap) {
1580     SortedMap<ComponentName, List<IntentFilter>> preferredMap = preferredActivitiesMap;
1581     if (packageName != null) {
1582       preferredMap = mapForPackage(preferredActivitiesMap, packageName);
1583     }
1584     int result = 0;
1585     for (Entry<ComponentName, List<IntentFilter>> entry : preferredMap.entrySet()) {
1586       int filterCount = entry.getValue().size();
1587       result += filterCount;
1588       ComponentName[] componentNames = new ComponentName[filterCount];
1589       Arrays.fill(componentNames, entry.getKey());
1590       outActivities.addAll(asList(componentNames));
1591       outFilters.addAll(entry.getValue());
1592     }
1593 
1594     return result;
1595   }
1596 
clearPackagePersistentPreferredActivities(String packageName)1597   void clearPackagePersistentPreferredActivities(String packageName) {
1598     clearPackagePreferredActivitiesInternal(packageName, persistentPreferredActivities);
1599   }
1600 
clearPackagePreferredActivitiesInternal( String packageName, SortedMap<ComponentName, List<IntentFilter>> preferredActivitiesMap)1601   protected static void clearPackagePreferredActivitiesInternal(
1602       String packageName, SortedMap<ComponentName, List<IntentFilter>> preferredActivitiesMap) {
1603     mapForPackage(preferredActivitiesMap, packageName).clear();
1604   }
1605 
addPersistentPreferredActivity(IntentFilter filter, ComponentName activity)1606   void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity) {
1607     addPreferredActivityInternal(filter, activity, persistentPreferredActivities);
1608   }
1609 
addPreferredActivityInternal( IntentFilter filter, ComponentName activity, SortedMap<ComponentName, List<IntentFilter>> preferredActivitiesMap)1610   protected static void addPreferredActivityInternal(
1611       IntentFilter filter,
1612       ComponentName activity,
1613       SortedMap<ComponentName, List<IntentFilter>> preferredActivitiesMap) {
1614     List<IntentFilter> filters = preferredActivitiesMap.get(activity);
1615     if (filters == null) {
1616       filters = new ArrayList<>();
1617       preferredActivitiesMap.put(activity, filters);
1618     }
1619     filters.add(filter);
1620   }
1621 
mapForPackage( SortedMap<ComponentName, V> input, @Nullable String packageName)1622   protected static <V> SortedMap<ComponentName, V> mapForPackage(
1623       SortedMap<ComponentName, V> input, @Nullable String packageName) {
1624     if (packageName == null) {
1625       return input;
1626     }
1627     return input.subMap(
1628         new ComponentName(packageName, ""), new ComponentName(packageName + " ", ""));
1629   }
1630 
isComponentEnabled(@ullable ComponentInfo componentInfo)1631   static boolean isComponentEnabled(@Nullable ComponentInfo componentInfo) {
1632     if (componentInfo == null) {
1633       return true;
1634     }
1635     if (componentInfo.applicationInfo == null
1636         || componentInfo.applicationInfo.packageName == null
1637         || componentInfo.name == null) {
1638       return componentInfo.enabled;
1639     }
1640     ComponentName name =
1641         new ComponentName(componentInfo.applicationInfo.packageName, componentInfo.name);
1642     ComponentState componentState = componentList.get(name);
1643     if (componentState == null
1644         || componentState.newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
1645       return componentInfo.enabled;
1646     }
1647     return componentState.newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
1648   }
1649 
1650   /**
1651    * Returns the current {@link PackageSetting} of {@code packageName}.
1652    *
1653    * If {@code packageName} is not present in this {@link ShadowPackageManager}, this method will
1654    * return null.
1655    */
getPackageSetting(String packageName)1656   public PackageSetting getPackageSetting(String packageName) {
1657     PackageSetting setting = packageSettings.get(packageName);
1658     return setting == null ? null : new PackageSetting(setting);
1659   }
1660 
1661   /**
1662    * If this method has been called with true, then in cases where many activities match a filter,
1663    * an activity chooser will be resolved instead of just the first pick.
1664    */
setShouldShowActivityChooser(boolean shouldShowActivityChooser)1665   public void setShouldShowActivityChooser(boolean shouldShowActivityChooser) {
1666     this.shouldShowActivityChooser = shouldShowActivityChooser;
1667   }
1668 
1669   /** Set value to be returned by {@link PackageManager#isSafeMode}. */
setSafeMode(boolean safeMode)1670   public void setSafeMode(boolean safeMode) {
1671     ShadowPackageManager.safeMode = safeMode;
1672   }
1673 
1674   /**
1675    * Returns the last value provided to {@code setDistractingPackageRestrictions} for {@code pkg}.
1676    *
1677    * Defaults to {@code PackageManager.RESTRICTION_NONE} if {@code
1678    * setDistractingPackageRestrictions} has not been called for {@code pkg}.
1679    */
getDistractingPackageRestrictions(String pkg)1680   public int getDistractingPackageRestrictions(String pkg) {
1681     return distractingPackageRestrictions.getOrDefault(pkg, PackageManager.RESTRICTION_NONE);
1682   }
1683 
1684   /**
1685    * Adds a String resource with {@code resId} corresponding to {@code packageName}. This is
1686    * retrieved in shadow implementation of {@link PackageManager#getText(String, int,
1687    * ApplicationInfo)}.
1688    */
addStringResource(String packageName, int resId, String text)1689   public void addStringResource(String packageName, int resId, String text) {
1690     if (!stringResources.containsKey(packageName)) {
1691       stringResources.put(packageName, new HashMap<>());
1692     }
1693 
1694     stringResources.get(packageName).put(resId, text);
1695   }
1696 
1697   /** Set value to be returned by {@link PackageManager#isAutoRevokeWhitelisted}. */
setAutoRevokeWhitelisted(boolean whitelisted)1698   public void setAutoRevokeWhitelisted(boolean whitelisted) {
1699     ShadowPackageManager.whitelisted = whitelisted;
1700   }
1701 
1702   @Resetter
reset()1703   public static void reset() {
1704     synchronized (lock) {
1705       permissionRationaleMap.clear();
1706       systemAvailableFeatures.clear();
1707       systemSharedLibraryNames.clear();
1708       packageInfos.clear();
1709       packageArchiveInfo.clear();
1710       packageStatsMap.clear();
1711       packageInstallerMap.clear();
1712       packageInstallSourceInfoMap.clear();
1713       packagesForUid.clear();
1714       uidForPackage.clear();
1715       namesForUid.clear();
1716       verificationResults.clear();
1717       verificationTimeoutExtension.clear();
1718       verificationCodeAtTimeoutExtension.clear();
1719       currentToCanonicalNames.clear();
1720       canonicalToCurrentNames.clear();
1721       componentList.clear();
1722       drawableList.clear();
1723       applicationIcons.clear();
1724       unbadgedApplicationIcons.clear();
1725       systemFeatureList.clear();
1726       systemFeatureList.putAll(SystemFeatureListInitializer.getSystemFeatures());
1727       preferredActivities.clear();
1728       persistentPreferredActivities.clear();
1729       drawables.clear();
1730       stringResources.clear();
1731       applicationEnabledSettingMap.clear();
1732       extraPermissions.clear();
1733       permissionGroups.clear();
1734       permissionFlags.clear();
1735       resources.clear();
1736       resolveInfoForIntent.clear();
1737       deletedPackages.clear();
1738       pendingDeleteCallbacks.clear();
1739       hiddenPackages.clear();
1740       sequenceNumberChangedPackagesMap.clear();
1741       activityFilters.clear();
1742       serviceFilters.clear();
1743       providerFilters.clear();
1744       receiverFilters.clear();
1745       packageSettings.clear();
1746       safeMode = false;
1747       whitelisted = false;
1748     }
1749   }
1750 
1751   @ForType(PackageManager.class)
1752   interface PackageManagerReflector {
1753 
1754     @Direct
getPackageArchiveInfo(String archiveFilePath, int flags)1755     PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags);
1756   }
1757 }
1758