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