1 package org.robolectric.shadows; 2 3 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME; 4 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS; 5 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW; 6 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; 7 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; 8 import static android.os.Build.VERSION_CODES.LOLLIPOP; 9 import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1; 10 import static android.os.Build.VERSION_CODES.M; 11 import static android.os.Build.VERSION_CODES.N; 12 import static android.os.Build.VERSION_CODES.N_MR1; 13 import static android.os.Build.VERSION_CODES.O; 14 import static android.os.Build.VERSION_CODES.P; 15 import static android.os.Build.VERSION_CODES.Q; 16 import static android.os.Build.VERSION_CODES.R; 17 import static android.os.Build.VERSION_CODES.S; 18 import static android.os.Build.VERSION_CODES.S_V2; 19 import static android.os.Build.VERSION_CODES.TIRAMISU; 20 import static org.robolectric.Shadows.shadowOf; 21 import static org.robolectric.shadow.api.Shadow.invokeConstructor; 22 import static org.robolectric.util.ReflectionHelpers.ClassParameter.from; 23 24 import android.accounts.Account; 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.annotation.RequiresPermission; 28 import android.annotation.SuppressLint; 29 import android.annotation.SystemApi; 30 import android.app.ApplicationPackageManager; 31 import android.app.KeyguardManager; 32 import android.app.admin.DeviceAdminReceiver; 33 import android.app.admin.DevicePolicyManager; 34 import android.app.admin.DevicePolicyManager.NearbyStreamingPolicy; 35 import android.app.admin.DevicePolicyManager.PasswordComplexity; 36 import android.app.admin.DevicePolicyManager.UserProvisioningState; 37 import android.app.admin.IDevicePolicyManager; 38 import android.app.admin.SystemUpdatePolicy; 39 import android.content.ComponentName; 40 import android.content.Context; 41 import android.content.Intent; 42 import android.content.IntentFilter; 43 import android.content.ServiceConnection; 44 import android.content.pm.PackageInfo; 45 import android.content.pm.PackageManager; 46 import android.content.pm.PackageManager.NameNotFoundException; 47 import android.os.Build; 48 import android.os.Build.VERSION_CODES; 49 import android.os.Bundle; 50 import android.os.Handler; 51 import android.os.PersistableBundle; 52 import android.os.Process; 53 import android.os.UserHandle; 54 import android.text.TextUtils; 55 import com.android.internal.util.Preconditions; 56 import com.google.common.collect.ImmutableList; 57 import java.util.ArrayList; 58 import java.util.Arrays; 59 import java.util.Collection; 60 import java.util.Collections; 61 import java.util.HashMap; 62 import java.util.HashSet; 63 import java.util.List; 64 import java.util.Map; 65 import java.util.Objects; 66 import java.util.Set; 67 import org.robolectric.RuntimeEnvironment; 68 import org.robolectric.annotation.Implementation; 69 import org.robolectric.annotation.Implements; 70 import org.robolectric.annotation.RealObject; 71 import org.robolectric.shadow.api.Shadow; 72 73 @Implements(DevicePolicyManager.class) 74 @SuppressLint("NewApi") 75 public class ShadowDevicePolicyManager { 76 /** 77 * @see 78 * https://developer.android.com/reference/android/app/admin/DevicePolicyManager.html#setOrganizationColor(android.content.ComponentName, 79 * int) 80 */ 81 private static final int DEFAULT_ORGANIZATION_COLOR = 0xFF008080; // teal 82 83 private ComponentName deviceOwner; 84 private ComponentName profileOwner; 85 private List<ComponentName> deviceAdmins = new ArrayList<>(); 86 private Map<Integer, String> profileOwnerNamesMap = new HashMap<>(); 87 private List<String> permittedAccessibilityServices = new ArrayList<>(); 88 private List<String> permittedInputMethods = new ArrayList<>(); 89 private Map<String, Bundle> applicationRestrictionsMap = new HashMap<>(); 90 private CharSequence organizationName; 91 private int organizationColor; 92 private boolean isAutoTimeEnabled; 93 private boolean isAutoTimeRequired; 94 private boolean isAutoTimeZoneEnabled; 95 private String timeZone; 96 private int keyguardDisabledFeatures; 97 private String lastSetPassword; 98 private int requiredPasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 99 100 private int passwordMinimumLength; 101 private int passwordMinimumLetters = 1; 102 private int passwordMinimumLowerCase; 103 private int passwordMinimumUpperCase; 104 private int passwordMinimumNonLetter; 105 private int passwordMinimumNumeric = 1; 106 private int passwordMinimumSymbols = 1; 107 private int passwordHistoryLength = 0; 108 private long passwordExpiration = 0; 109 private long passwordExpirationTimeout = 0; 110 private int maximumFailedPasswordsForWipe = 0; 111 private long maximumTimeToLock = 0; 112 private boolean cameraDisabled; 113 private boolean isActivePasswordSufficient; 114 private boolean isUniqueDeviceAttestationSupported; 115 @PasswordComplexity private int passwordComplexity; 116 117 private int wipeCalled; 118 private int storageEncryptionStatus; 119 private int permissionPolicy; 120 private boolean storageEncryptionRequested; 121 private final Set<String> wasHiddenPackages = new HashSet<>(); 122 private final Set<String> accountTypesWithManagementDisabled = new HashSet<>(); 123 private final Set<String> systemAppsEnabled = new HashSet<>(); 124 private final Set<String> uninstallBlockedPackages = new HashSet<>(); 125 private final Set<String> suspendedPackages = new HashSet<>(); 126 private final Set<String> affiliationIds = new HashSet<>(); 127 private final Map<PackageAndPermission, Boolean> appPermissionGrantedMap = new HashMap<>(); 128 private final Map<PackageAndPermission, Integer> appPermissionGrantStateMap = new HashMap<>(); 129 private final Map<ComponentName, byte[]> passwordResetTokens = new HashMap<>(); 130 private final Map<ComponentName, Set<Integer>> adminPolicyGrantedMap = new HashMap<>(); 131 private final Map<ComponentName, CharSequence> shortSupportMessageMap = new HashMap<>(); 132 private final Map<ComponentName, CharSequence> longSupportMessageMap = new HashMap<>(); 133 private final Set<ComponentName> componentsWithActivatedTokens = new HashSet<>(); 134 private Collection<String> packagesToFailForSetApplicationHidden = Collections.emptySet(); 135 private int lockTaskFeatures; 136 private final List<String> lockTaskPackages = new ArrayList<>(); 137 private Context context; 138 private ApplicationPackageManager applicationPackageManager; 139 private SystemUpdatePolicy policy; 140 private List<UserHandle> bindDeviceAdminTargetUsers = ImmutableList.of(); 141 private boolean isDeviceProvisioned; 142 private boolean isDeviceProvisioningConfigApplied; 143 private volatile boolean organizationOwnedDeviceWithManagedProfile = false; 144 private int nearbyNotificationStreamingPolicy = 145 DevicePolicyManager.NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY; 146 private int nearbyAppStreamingPolicy = 147 DevicePolicyManager.NEARBY_STREAMING_NOT_CONTROLLED_BY_POLICY; 148 private boolean isUsbDataSignalingEnabled = true; 149 @Nullable private String devicePolicyManagementRoleHolderPackage; 150 private final Map<UserHandle, Account> finalizedWorkProfileProvisioningMap = new HashMap<>(); 151 private List<UserHandle> policyManagedProfiles = new ArrayList<>(); 152 private final Map<Integer, Integer> userProvisioningStatesMap = new HashMap<>(); 153 @Nullable private PersistableBundle lastTransferOwnershipBundle; 154 155 private @RealObject DevicePolicyManager realObject; 156 157 private static class PackageAndPermission { 158 PackageAndPermission(String packageName, String permission)159 public PackageAndPermission(String packageName, String permission) { 160 this.packageName = packageName; 161 this.permission = permission; 162 } 163 164 private String packageName; 165 private String permission; 166 167 @Override equals(Object o)168 public boolean equals(Object o) { 169 if (!(o instanceof PackageAndPermission)) { 170 return false; 171 } 172 PackageAndPermission other = (PackageAndPermission) o; 173 return packageName.equals(other.packageName) && permission.equals(other.permission); 174 } 175 176 @Override hashCode()177 public int hashCode() { 178 int result = packageName.hashCode(); 179 result = 31 * result + permission.hashCode(); 180 return result; 181 } 182 } 183 184 @Implementation(maxSdk = M) __constructor__(Context context, Handler handler)185 protected void __constructor__(Context context, Handler handler) { 186 init(context); 187 invokeConstructor( 188 DevicePolicyManager.class, 189 realObject, 190 from(Context.class, context), 191 from(Handler.class, handler)); 192 } 193 194 @Implementation(minSdk = N, maxSdk = N_MR1) __constructor__(Context context, boolean parentInstance)195 protected void __constructor__(Context context, boolean parentInstance) { 196 init(context); 197 } 198 199 @Implementation(minSdk = O) __constructor__(Context context, IDevicePolicyManager service)200 protected void __constructor__(Context context, IDevicePolicyManager service) { 201 init(context); 202 } 203 init(Context context)204 private void init(Context context) { 205 this.context = context; 206 this.applicationPackageManager = 207 (ApplicationPackageManager) context.getApplicationContext().getPackageManager(); 208 organizationColor = DEFAULT_ORGANIZATION_COLOR; 209 storageEncryptionStatus = DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; 210 } 211 212 @Implementation(minSdk = JELLY_BEAN_MR2) isDeviceOwnerApp(String packageName)213 protected boolean isDeviceOwnerApp(String packageName) { 214 return deviceOwner != null && deviceOwner.getPackageName().equals(packageName); 215 } 216 217 @Implementation(minSdk = LOLLIPOP) isProfileOwnerApp(String packageName)218 protected boolean isProfileOwnerApp(String packageName) { 219 return profileOwner != null && profileOwner.getPackageName().equals(packageName); 220 } 221 222 @Implementation isAdminActive(ComponentName who)223 protected boolean isAdminActive(ComponentName who) { 224 return who != null && deviceAdmins.contains(who); 225 } 226 227 @Implementation getActiveAdmins()228 protected List<ComponentName> getActiveAdmins() { 229 return deviceAdmins; 230 } 231 232 @Implementation(minSdk = LOLLIPOP) addUserRestriction(ComponentName admin, String key)233 protected void addUserRestriction(ComponentName admin, String key) { 234 enforceActiveAdmin(admin); 235 getShadowUserManager().setUserRestriction(Process.myUserHandle(), key, true); 236 } 237 238 @Implementation(minSdk = LOLLIPOP) clearUserRestriction(ComponentName admin, String key)239 protected void clearUserRestriction(ComponentName admin, String key) { 240 enforceActiveAdmin(admin); 241 getShadowUserManager().setUserRestriction(Process.myUserHandle(), key, false); 242 } 243 244 @Implementation(minSdk = LOLLIPOP) setApplicationHidden(ComponentName admin, String packageName, boolean hidden)245 protected boolean setApplicationHidden(ComponentName admin, String packageName, boolean hidden) { 246 enforceActiveAdmin(admin); 247 if (packagesToFailForSetApplicationHidden.contains(packageName)) { 248 return false; 249 } 250 if (hidden) { 251 wasHiddenPackages.add(packageName); 252 } 253 return applicationPackageManager.setApplicationHiddenSettingAsUser( 254 packageName, hidden, Process.myUserHandle()); 255 } 256 257 /** 258 * Set package names for witch {@link DevicePolicyManager#setApplicationHidden} should fail. 259 * 260 * @param packagesToFail collection of package names or {@code null} to clear the packages. 261 */ failSetApplicationHiddenFor(Collection<String> packagesToFail)262 public void failSetApplicationHiddenFor(Collection<String> packagesToFail) { 263 if (packagesToFail == null) { 264 packagesToFail = Collections.emptySet(); 265 } 266 packagesToFailForSetApplicationHidden = packagesToFail; 267 } 268 269 @Implementation(minSdk = LOLLIPOP) isApplicationHidden(ComponentName admin, String packageName)270 protected boolean isApplicationHidden(ComponentName admin, String packageName) { 271 enforceActiveAdmin(admin); 272 return applicationPackageManager.getApplicationHiddenSettingAsUser( 273 packageName, Process.myUserHandle()); 274 } 275 276 /** Returns {@code true} if the given {@code packageName} was ever hidden. */ wasPackageEverHidden(String packageName)277 public boolean wasPackageEverHidden(String packageName) { 278 return wasHiddenPackages.contains(packageName); 279 } 280 281 @Implementation(minSdk = LOLLIPOP) enableSystemApp(ComponentName admin, String packageName)282 protected void enableSystemApp(ComponentName admin, String packageName) { 283 enforceActiveAdmin(admin); 284 systemAppsEnabled.add(packageName); 285 } 286 287 /** Returns {@code true} if the given {@code packageName} was a system app and was enabled. */ wasSystemAppEnabled(String packageName)288 public boolean wasSystemAppEnabled(String packageName) { 289 return systemAppsEnabled.contains(packageName); 290 } 291 292 @Implementation(minSdk = LOLLIPOP) setUninstallBlocked( ComponentName admin, String packageName, boolean uninstallBlocked)293 protected void setUninstallBlocked( 294 ComponentName admin, String packageName, boolean uninstallBlocked) { 295 enforceActiveAdmin(admin); 296 if (uninstallBlocked) { 297 uninstallBlockedPackages.add(packageName); 298 } else { 299 uninstallBlockedPackages.remove(packageName); 300 } 301 } 302 303 @Implementation(minSdk = LOLLIPOP) isUninstallBlocked(@ullable ComponentName admin, String packageName)304 protected boolean isUninstallBlocked(@Nullable ComponentName admin, String packageName) { 305 if (admin == null) { 306 // Starting from LOLLIPOP_MR1, the behavior of this API is changed such that passing null as 307 // the admin parameter will return if any admin has blocked the uninstallation. Before L MR1, 308 // passing null will cause a NullPointerException to be raised. 309 if (Build.VERSION.SDK_INT < LOLLIPOP_MR1) { 310 throw new NullPointerException("ComponentName is null"); 311 } 312 } else { 313 enforceActiveAdmin(admin); 314 } 315 return uninstallBlockedPackages.contains(packageName); 316 } 317 setIsUniqueDeviceAttestationSupported(boolean supported)318 public void setIsUniqueDeviceAttestationSupported(boolean supported) { 319 isUniqueDeviceAttestationSupported = supported; 320 } 321 322 @Implementation(minSdk = R) isUniqueDeviceAttestationSupported()323 protected boolean isUniqueDeviceAttestationSupported() { 324 return isUniqueDeviceAttestationSupported; 325 } 326 327 /** Sets USB signaling device restriction. */ setIsUsbDataSignalingEnabled(boolean isEnabled)328 public void setIsUsbDataSignalingEnabled(boolean isEnabled) { 329 isUsbDataSignalingEnabled = isEnabled; 330 } 331 332 @Implementation(minSdk = S) isUsbDataSignalingEnabled()333 protected boolean isUsbDataSignalingEnabled() { 334 return isUsbDataSignalingEnabled; 335 } 336 337 /** 338 * @see #setDeviceOwner(ComponentName) 339 */ 340 @Implementation(minSdk = JELLY_BEAN_MR2) getDeviceOwner()341 protected String getDeviceOwner() { 342 return deviceOwner != null ? deviceOwner.getPackageName() : null; 343 } 344 345 /** 346 * @see #setDeviceOwner(ComponentName) 347 */ 348 @Implementation(minSdk = N) isDeviceManaged()349 public boolean isDeviceManaged() { 350 return getDeviceOwner() != null; 351 } 352 353 /** 354 * @see #setProfileOwner(ComponentName) 355 */ 356 @Implementation(minSdk = LOLLIPOP) getProfileOwner()357 protected ComponentName getProfileOwner() { 358 return profileOwner; 359 } 360 361 /** 362 * Returns the human-readable name of the profile owner for a user if set using {@link 363 * #setProfileOwnerName}, otherwise null. 364 */ 365 @Implementation(minSdk = LOLLIPOP) getProfileOwnerNameAsUser(int userId)366 protected String getProfileOwnerNameAsUser(int userId) { 367 return profileOwnerNamesMap.get(userId); 368 } 369 370 @Implementation(minSdk = P) transferOwnership( ComponentName admin, ComponentName target, @Nullable PersistableBundle bundle)371 protected void transferOwnership( 372 ComponentName admin, ComponentName target, @Nullable PersistableBundle bundle) { 373 Objects.requireNonNull(admin, "ComponentName is null"); 374 Objects.requireNonNull(target, "Target cannot be null."); 375 Preconditions.checkArgument( 376 !admin.equals(target), "Provided administrator and target are the same object."); 377 Preconditions.checkArgument( 378 !admin.getPackageName().equals(target.getPackageName()), 379 "Provided administrator and target have the same package name."); 380 try { 381 context.getPackageManager().getReceiverInfo(target, 0); 382 } catch (PackageManager.NameNotFoundException e) { 383 throw new IllegalArgumentException("Unknown admin: " + target); 384 } 385 if (admin.equals(deviceOwner)) { 386 deviceOwner = target; 387 } else if (admin.equals(profileOwner)) { 388 profileOwner = target; 389 } else { 390 throw new SecurityException("Calling identity is not authorized"); 391 } 392 lastTransferOwnershipBundle = bundle; 393 } 394 395 @Implementation(minSdk = P) 396 @Nullable getTransferOwnershipBundle()397 protected PersistableBundle getTransferOwnershipBundle() { 398 return lastTransferOwnershipBundle; 399 } 400 getShadowUserManager()401 private ShadowUserManager getShadowUserManager() { 402 return Shadow.extract(context.getSystemService(Context.USER_SERVICE)); 403 } 404 405 /** 406 * Sets the admin as active admin and device owner. 407 * 408 * @see DevicePolicyManager#getDeviceOwner() 409 */ 410 @Implementation(minSdk = N, maxSdk = S_V2) setDeviceOwner(ComponentName admin)411 public boolean setDeviceOwner(ComponentName admin) { 412 setActiveAdmin(admin); 413 deviceOwner = admin; 414 return true; 415 } 416 417 /** 418 * Sets the admin as active admin and profile owner. 419 * 420 * @see DevicePolicyManager#getProfileOwner() 421 */ setProfileOwner(ComponentName admin)422 public void setProfileOwner(ComponentName admin) { 423 setActiveAdmin(admin); 424 profileOwner = admin; 425 } 426 setProfileOwnerName(int userId, String name)427 public void setProfileOwnerName(int userId, String name) { 428 profileOwnerNamesMap.put(userId, name); 429 } 430 431 /** Sets the given {@code componentName} as one of the active admins. */ setActiveAdmin(ComponentName componentName)432 public void setActiveAdmin(ComponentName componentName) { 433 deviceAdmins.add(componentName); 434 } 435 436 @Implementation removeActiveAdmin(ComponentName admin)437 protected void removeActiveAdmin(ComponentName admin) { 438 deviceAdmins.remove(admin); 439 } 440 441 @Implementation(minSdk = LOLLIPOP) clearProfileOwner(ComponentName admin)442 protected void clearProfileOwner(ComponentName admin) { 443 profileOwner = null; 444 lastTransferOwnershipBundle = null; 445 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 446 removeActiveAdmin(admin); 447 } 448 } 449 450 @Implementation(minSdk = LOLLIPOP) getApplicationRestrictions(ComponentName admin, String packageName)451 protected Bundle getApplicationRestrictions(ComponentName admin, String packageName) { 452 enforceDeviceOwnerOrProfileOwner(admin); 453 return getApplicationRestrictions(packageName); 454 } 455 456 /** Returns all application restrictions of the {@code packageName} in a {@link Bundle}. */ getApplicationRestrictions(String packageName)457 public Bundle getApplicationRestrictions(String packageName) { 458 Bundle bundle = applicationRestrictionsMap.get(packageName); 459 // If no restrictions were saved, DPM method should return an empty Bundle as per JavaDoc. 460 return bundle != null ? new Bundle(bundle) : new Bundle(); 461 } 462 463 @Implementation(minSdk = LOLLIPOP) setApplicationRestrictions( ComponentName admin, String packageName, Bundle applicationRestrictions)464 protected void setApplicationRestrictions( 465 ComponentName admin, String packageName, Bundle applicationRestrictions) { 466 enforceDeviceOwnerOrProfileOwner(admin); 467 setApplicationRestrictions(packageName, applicationRestrictions); 468 } 469 470 /** 471 * Sets the application restrictions of the {@code packageName}. 472 * 473 * <p>The new {@code applicationRestrictions} always completely overwrites any existing ones. 474 */ setApplicationRestrictions(String packageName, Bundle applicationRestrictions)475 public void setApplicationRestrictions(String packageName, Bundle applicationRestrictions) { 476 applicationRestrictionsMap.put(packageName, new Bundle(applicationRestrictions)); 477 } 478 enforceProfileOwner(ComponentName admin)479 private void enforceProfileOwner(ComponentName admin) { 480 if (!admin.equals(profileOwner)) { 481 throw new SecurityException("[" + admin + "] is not a profile owner"); 482 } 483 } 484 enforceDeviceOwnerOrProfileOwner(ComponentName admin)485 private void enforceDeviceOwnerOrProfileOwner(ComponentName admin) { 486 if (!admin.equals(deviceOwner) && !admin.equals(profileOwner)) { 487 throw new SecurityException("[" + admin + "] is neither a device owner nor a profile owner."); 488 } 489 } 490 enforceActiveAdmin(ComponentName admin)491 private void enforceActiveAdmin(ComponentName admin) { 492 if (!deviceAdmins.contains(admin)) { 493 throw new SecurityException("[" + admin + "] is not an active device admin"); 494 } 495 } 496 497 @Implementation(minSdk = LOLLIPOP) setAccountManagementDisabled( ComponentName admin, String accountType, boolean disabled)498 protected void setAccountManagementDisabled( 499 ComponentName admin, String accountType, boolean disabled) { 500 enforceDeviceOwnerOrProfileOwner(admin); 501 if (disabled) { 502 accountTypesWithManagementDisabled.add(accountType); 503 } else { 504 accountTypesWithManagementDisabled.remove(accountType); 505 } 506 } 507 508 @Implementation(minSdk = LOLLIPOP) getAccountTypesWithManagementDisabled()509 protected String[] getAccountTypesWithManagementDisabled() { 510 return accountTypesWithManagementDisabled.toArray(new String[0]); 511 } 512 513 /** 514 * Sets organization name. 515 * 516 * <p>The API can only be called by profile owner since Android N and can be called by both of 517 * profile owner and device owner since Android O. 518 */ 519 @Implementation(minSdk = N) setOrganizationName(ComponentName admin, @Nullable CharSequence name)520 protected void setOrganizationName(ComponentName admin, @Nullable CharSequence name) { 521 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 522 enforceDeviceOwnerOrProfileOwner(admin); 523 } else { 524 enforceProfileOwner(admin); 525 } 526 527 if (TextUtils.isEmpty(name)) { 528 organizationName = null; 529 } else { 530 organizationName = name; 531 } 532 } 533 534 @Implementation(minSdk = N) setPackagesSuspended( ComponentName admin, String[] packageNames, boolean suspended)535 protected String[] setPackagesSuspended( 536 ComponentName admin, String[] packageNames, boolean suspended) { 537 if (admin != null) { 538 enforceDeviceOwnerOrProfileOwner(admin); 539 } 540 if (packageNames == null) { 541 throw new NullPointerException("package names cannot be null"); 542 } 543 PackageManager pm = context.getPackageManager(); 544 ArrayList<String> packagesFailedToSuspend = new ArrayList<>(); 545 for (String packageName : packageNames) { 546 try { 547 // check if it is installed 548 pm.getPackageInfo(packageName, 0); 549 if (suspended) { 550 suspendedPackages.add(packageName); 551 } else { 552 suspendedPackages.remove(packageName); 553 } 554 } catch (NameNotFoundException e) { 555 packagesFailedToSuspend.add(packageName); 556 } 557 } 558 return packagesFailedToSuspend.toArray(new String[0]); 559 } 560 561 @Implementation(minSdk = N) isPackageSuspended(ComponentName admin, String packageName)562 protected boolean isPackageSuspended(ComponentName admin, String packageName) 563 throws NameNotFoundException { 564 if (admin != null) { 565 enforceDeviceOwnerOrProfileOwner(admin); 566 } 567 // Throws NameNotFoundException 568 context.getPackageManager().getPackageInfo(packageName, 0); 569 return suspendedPackages.contains(packageName); 570 } 571 572 @Implementation(minSdk = N) setOrganizationColor(ComponentName admin, int color)573 protected void setOrganizationColor(ComponentName admin, int color) { 574 enforceProfileOwner(admin); 575 organizationColor = color; 576 } 577 578 /** 579 * Returns organization name. 580 * 581 * <p>The API can only be called by profile owner since Android N. 582 * 583 * <p>Android framework has a hidden API for getting the organization name for device owner since 584 * Android O. This method, however, is extended to return the organization name for device owners 585 * too to make testing of {@link #setOrganizationName(ComponentName, CharSequence)} easier for 586 * device owner cases. 587 */ 588 @Implementation(minSdk = N) 589 @Nullable getOrganizationName(ComponentName admin)590 protected CharSequence getOrganizationName(ComponentName admin) { 591 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 592 enforceDeviceOwnerOrProfileOwner(admin); 593 } else { 594 enforceProfileOwner(admin); 595 } 596 597 return organizationName; 598 } 599 600 @Implementation(minSdk = N) getOrganizationColor(ComponentName admin)601 protected int getOrganizationColor(ComponentName admin) { 602 enforceProfileOwner(admin); 603 return organizationColor; 604 } 605 606 @Implementation(minSdk = R) setAutoTimeEnabled(ComponentName admin, boolean enabled)607 protected void setAutoTimeEnabled(ComponentName admin, boolean enabled) { 608 enforceDeviceOwnerOrProfileOwner(admin); 609 isAutoTimeEnabled = enabled; 610 } 611 612 @Implementation(minSdk = R) getAutoTimeEnabled(ComponentName admin)613 protected boolean getAutoTimeEnabled(ComponentName admin) { 614 enforceDeviceOwnerOrProfileOwner(admin); 615 return isAutoTimeEnabled; 616 } 617 618 @Implementation(minSdk = LOLLIPOP) setAutoTimeRequired(ComponentName admin, boolean required)619 protected void setAutoTimeRequired(ComponentName admin, boolean required) { 620 enforceDeviceOwnerOrProfileOwner(admin); 621 isAutoTimeRequired = required; 622 } 623 624 @Implementation(minSdk = LOLLIPOP) getAutoTimeRequired()625 protected boolean getAutoTimeRequired() { 626 return isAutoTimeRequired; 627 } 628 629 @Implementation(minSdk = R) setAutoTimeZoneEnabled(ComponentName admin, boolean enabled)630 protected void setAutoTimeZoneEnabled(ComponentName admin, boolean enabled) { 631 enforceDeviceOwnerOrProfileOwner(admin); 632 isAutoTimeZoneEnabled = enabled; 633 } 634 635 @Implementation(minSdk = R) getAutoTimeZoneEnabled(ComponentName admin)636 protected boolean getAutoTimeZoneEnabled(ComponentName admin) { 637 enforceDeviceOwnerOrProfileOwner(admin); 638 return isAutoTimeZoneEnabled; 639 } 640 641 @Implementation(minSdk = P) setTimeZone(ComponentName admin, String timeZone)642 protected boolean setTimeZone(ComponentName admin, String timeZone) { 643 enforceDeviceOwnerOrProfileOwner(admin); 644 if (isAutoTimeZoneEnabled) { 645 return false; 646 } 647 this.timeZone = timeZone; 648 return true; 649 } 650 651 /** Returns the time zone set by setTimeZone. */ getTimeZone()652 public String getTimeZone() { 653 return timeZone; 654 } 655 656 /** 657 * Sets permitted accessibility services. 658 * 659 * <p>The API can be called by either a profile or device owner. 660 * 661 * <p>This method does not check already enabled non-system accessibility services, so will always 662 * set the restriction and return true. 663 */ 664 @Implementation(minSdk = LOLLIPOP) setPermittedAccessibilityServices( ComponentName admin, List<String> packageNames)665 protected boolean setPermittedAccessibilityServices( 666 ComponentName admin, List<String> packageNames) { 667 enforceDeviceOwnerOrProfileOwner(admin); 668 permittedAccessibilityServices = packageNames; 669 return true; 670 } 671 672 @Implementation(minSdk = LOLLIPOP) 673 @Nullable getPermittedAccessibilityServices(ComponentName admin)674 protected List<String> getPermittedAccessibilityServices(ComponentName admin) { 675 enforceDeviceOwnerOrProfileOwner(admin); 676 return permittedAccessibilityServices; 677 } 678 679 /** 680 * Sets permitted input methods. 681 * 682 * <p>The API can be called by either a profile or device owner. 683 * 684 * <p>This method does not check already enabled non-system input methods, so will always set the 685 * restriction and return true. 686 */ 687 @Implementation(minSdk = LOLLIPOP) setPermittedInputMethods(ComponentName admin, List<String> packageNames)688 protected boolean setPermittedInputMethods(ComponentName admin, List<String> packageNames) { 689 enforceDeviceOwnerOrProfileOwner(admin); 690 permittedInputMethods = packageNames; 691 return true; 692 } 693 694 @Implementation(minSdk = LOLLIPOP) 695 @Nullable getPermittedInputMethods(ComponentName admin)696 protected List<String> getPermittedInputMethods(ComponentName admin) { 697 enforceDeviceOwnerOrProfileOwner(admin); 698 return permittedInputMethods; 699 } 700 701 /** 702 * @return the previously set status; default is {@link 703 * DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED} 704 * @see #setStorageEncryptionStatus(int) 705 */ 706 @Implementation getStorageEncryptionStatus()707 protected int getStorageEncryptionStatus() { 708 return storageEncryptionStatus; 709 } 710 711 /** Setter for {@link DevicePolicyManager#getStorageEncryptionStatus()}. */ setStorageEncryptionStatus(int status)712 public void setStorageEncryptionStatus(int status) { 713 switch (status) { 714 case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: 715 case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE: 716 case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING: 717 case DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED: 718 break; 719 case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY: 720 if (RuntimeEnvironment.getApiLevel() < M) { 721 throw new IllegalArgumentException("status " + status + " requires API " + M); 722 } 723 break; 724 case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER: 725 if (RuntimeEnvironment.getApiLevel() < N) { 726 throw new IllegalArgumentException("status " + status + " requires API " + N); 727 } 728 break; 729 default: 730 throw new IllegalArgumentException("Unknown status: " + status); 731 } 732 733 storageEncryptionStatus = status; 734 } 735 736 @Implementation setStorageEncryption(ComponentName admin, boolean encrypt)737 protected int setStorageEncryption(ComponentName admin, boolean encrypt) { 738 enforceActiveAdmin(admin); 739 this.storageEncryptionRequested = encrypt; 740 return storageEncryptionStatus; 741 } 742 743 @Implementation getStorageEncryption(ComponentName admin)744 protected boolean getStorageEncryption(ComponentName admin) { 745 return storageEncryptionRequested; 746 } 747 748 @Implementation(minSdk = VERSION_CODES.M) getPermissionGrantState( ComponentName admin, String packageName, String permission)749 protected int getPermissionGrantState( 750 ComponentName admin, String packageName, String permission) { 751 enforceDeviceOwnerOrProfileOwner(admin); 752 Integer state = 753 appPermissionGrantStateMap.get(new PackageAndPermission(packageName, permission)); 754 return state == null ? DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT : state; 755 } 756 isPermissionGranted(String packageName, String permission)757 public boolean isPermissionGranted(String packageName, String permission) { 758 Boolean isGranted = 759 appPermissionGrantedMap.get(new PackageAndPermission(packageName, permission)); 760 return isGranted == null ? false : isGranted; 761 } 762 763 @Implementation(minSdk = VERSION_CODES.M) setPermissionGrantState( ComponentName admin, String packageName, String permission, int grantState)764 protected boolean setPermissionGrantState( 765 ComponentName admin, String packageName, String permission, int grantState) { 766 enforceDeviceOwnerOrProfileOwner(admin); 767 768 String selfPackageName = context.getPackageName(); 769 770 if (packageName.equals(selfPackageName)) { 771 PackageInfo packageInfo; 772 try { 773 packageInfo = 774 context 775 .getPackageManager() 776 .getPackageInfo(selfPackageName, PackageManager.GET_PERMISSIONS); 777 } catch (NameNotFoundException e) { 778 throw new RuntimeException(e); 779 } 780 if (Arrays.asList(packageInfo.requestedPermissions).contains(permission)) { 781 if (grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED) { 782 ShadowApplication.getInstance().grantPermissions(permission); 783 } 784 if (grantState == DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED) { 785 ShadowApplication.getInstance().denyPermissions(permission); 786 } 787 } else { 788 // the app does not require this permission 789 return false; 790 } 791 } 792 PackageAndPermission key = new PackageAndPermission(packageName, permission); 793 switch (grantState) { 794 case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: 795 appPermissionGrantedMap.put(key, true); 796 break; 797 case DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED: 798 appPermissionGrantedMap.put(key, false); 799 break; 800 default: 801 // no-op 802 } 803 appPermissionGrantStateMap.put(key, grantState); 804 return true; 805 } 806 807 @Implementation lockNow()808 protected void lockNow() { 809 KeyguardManager keyguardManager = 810 (KeyguardManager) this.context.getSystemService(Context.KEYGUARD_SERVICE); 811 ShadowKeyguardManager shadowKeyguardManager = Shadow.extract(keyguardManager); 812 shadowKeyguardManager.setKeyguardLocked(true); 813 shadowKeyguardManager.setIsDeviceLocked(true); 814 } 815 816 @Implementation wipeData(int flags)817 protected void wipeData(int flags) { 818 wipeCalled++; 819 } 820 getWipeCalledTimes()821 public long getWipeCalledTimes() { 822 return wipeCalled; 823 } 824 825 @Implementation setPasswordQuality(ComponentName admin, int quality)826 protected void setPasswordQuality(ComponentName admin, int quality) { 827 enforceActiveAdmin(admin); 828 requiredPasswordQuality = quality; 829 } 830 831 @Implementation getPasswordQuality(ComponentName admin)832 protected int getPasswordQuality(ComponentName admin) { 833 if (admin != null) { 834 enforceActiveAdmin(admin); 835 } 836 return requiredPasswordQuality; 837 } 838 839 @Implementation resetPassword(String password, int flags)840 protected boolean resetPassword(String password, int flags) { 841 if (!passwordMeetsRequirements(password)) { 842 return false; 843 } 844 lastSetPassword = password; 845 boolean secure = !password.isEmpty(); 846 KeyguardManager keyguardManager = 847 (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); 848 shadowOf(keyguardManager).setIsDeviceSecure(secure); 849 shadowOf(keyguardManager).setIsKeyguardSecure(secure); 850 return true; 851 } 852 853 @Implementation(minSdk = O) resetPasswordWithToken( ComponentName admin, String password, byte[] token, int flags)854 protected boolean resetPasswordWithToken( 855 ComponentName admin, String password, byte[] token, int flags) { 856 enforceDeviceOwnerOrProfileOwner(admin); 857 if (!Arrays.equals(passwordResetTokens.get(admin), token) 858 || !componentsWithActivatedTokens.contains(admin)) { 859 throw new IllegalStateException("wrong or not activated token"); 860 } 861 resetPassword(password, flags); 862 return true; 863 } 864 865 @Implementation(minSdk = O) isResetPasswordTokenActive(ComponentName admin)866 protected boolean isResetPasswordTokenActive(ComponentName admin) { 867 enforceDeviceOwnerOrProfileOwner(admin); 868 return componentsWithActivatedTokens.contains(admin); 869 } 870 871 @Implementation(minSdk = O) setResetPasswordToken(ComponentName admin, byte[] token)872 protected boolean setResetPasswordToken(ComponentName admin, byte[] token) { 873 if (token.length < 32) { 874 throw new IllegalArgumentException("token too short: " + token.length); 875 } 876 enforceDeviceOwnerOrProfileOwner(admin); 877 passwordResetTokens.put(admin, token); 878 componentsWithActivatedTokens.remove(admin); 879 KeyguardManager keyguardManager = 880 (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); 881 if (!keyguardManager.isDeviceSecure()) { 882 activateResetToken(admin); 883 } 884 return true; 885 } 886 887 @Implementation setPasswordMinimumLength(ComponentName admin, int length)888 protected void setPasswordMinimumLength(ComponentName admin, int length) { 889 enforceActiveAdmin(admin); 890 passwordMinimumLength = length; 891 } 892 893 @Implementation getPasswordMinimumLength(ComponentName admin)894 protected int getPasswordMinimumLength(ComponentName admin) { 895 if (admin != null) { 896 enforceActiveAdmin(admin); 897 } 898 return passwordMinimumLength; 899 } 900 901 @Implementation setPasswordMinimumLetters(ComponentName admin, int length)902 protected void setPasswordMinimumLetters(ComponentName admin, int length) { 903 enforceActiveAdmin(admin); 904 passwordMinimumLetters = length; 905 } 906 907 @Implementation getPasswordMinimumLetters(ComponentName admin)908 protected int getPasswordMinimumLetters(ComponentName admin) { 909 if (admin != null) { 910 enforceActiveAdmin(admin); 911 } 912 return passwordMinimumLetters; 913 } 914 915 @Implementation setPasswordMinimumLowerCase(ComponentName admin, int length)916 protected void setPasswordMinimumLowerCase(ComponentName admin, int length) { 917 enforceActiveAdmin(admin); 918 passwordMinimumLowerCase = length; 919 } 920 921 @Implementation getPasswordMinimumLowerCase(ComponentName admin)922 protected int getPasswordMinimumLowerCase(ComponentName admin) { 923 if (admin != null) { 924 enforceActiveAdmin(admin); 925 } 926 return passwordMinimumLowerCase; 927 } 928 929 @Implementation setPasswordMinimumUpperCase(ComponentName admin, int length)930 protected void setPasswordMinimumUpperCase(ComponentName admin, int length) { 931 enforceActiveAdmin(admin); 932 passwordMinimumUpperCase = length; 933 } 934 935 @Implementation getPasswordMinimumUpperCase(ComponentName admin)936 protected int getPasswordMinimumUpperCase(ComponentName admin) { 937 if (admin != null) { 938 enforceActiveAdmin(admin); 939 } 940 return passwordMinimumUpperCase; 941 } 942 943 @Implementation setPasswordMinimumNonLetter(ComponentName admin, int length)944 protected void setPasswordMinimumNonLetter(ComponentName admin, int length) { 945 enforceActiveAdmin(admin); 946 passwordMinimumNonLetter = length; 947 } 948 949 @Implementation getPasswordMinimumNonLetter(ComponentName admin)950 protected int getPasswordMinimumNonLetter(ComponentName admin) { 951 if (admin != null) { 952 enforceActiveAdmin(admin); 953 } 954 return passwordMinimumNonLetter; 955 } 956 957 @Implementation setPasswordMinimumNumeric(ComponentName admin, int length)958 protected void setPasswordMinimumNumeric(ComponentName admin, int length) { 959 enforceActiveAdmin(admin); 960 passwordMinimumNumeric = length; 961 } 962 963 @Implementation getPasswordMinimumNumeric(ComponentName admin)964 protected int getPasswordMinimumNumeric(ComponentName admin) { 965 if (admin != null) { 966 enforceActiveAdmin(admin); 967 } 968 return passwordMinimumNumeric; 969 } 970 971 @Implementation setPasswordMinimumSymbols(ComponentName admin, int length)972 protected void setPasswordMinimumSymbols(ComponentName admin, int length) { 973 enforceActiveAdmin(admin); 974 passwordMinimumSymbols = length; 975 } 976 977 @Implementation getPasswordMinimumSymbols(ComponentName admin)978 protected int getPasswordMinimumSymbols(ComponentName admin) { 979 if (admin != null) { 980 enforceActiveAdmin(admin); 981 } 982 return passwordMinimumSymbols; 983 } 984 985 @Implementation setMaximumFailedPasswordsForWipe(ComponentName admin, int num)986 protected void setMaximumFailedPasswordsForWipe(ComponentName admin, int num) { 987 enforceActiveAdmin(admin); 988 maximumFailedPasswordsForWipe = num; 989 } 990 991 @Implementation getMaximumFailedPasswordsForWipe(ComponentName admin)992 protected int getMaximumFailedPasswordsForWipe(ComponentName admin) { 993 if (admin != null) { 994 enforceActiveAdmin(admin); 995 } 996 return maximumFailedPasswordsForWipe; 997 } 998 999 @Implementation setCameraDisabled(ComponentName admin, boolean disabled)1000 protected void setCameraDisabled(ComponentName admin, boolean disabled) { 1001 enforceActiveAdmin(admin); 1002 cameraDisabled = disabled; 1003 } 1004 1005 @Implementation getCameraDisabled(ComponentName admin)1006 protected boolean getCameraDisabled(ComponentName admin) { 1007 if (admin != null) { 1008 enforceActiveAdmin(admin); 1009 } 1010 return cameraDisabled; 1011 } 1012 1013 @Implementation setPasswordExpirationTimeout(ComponentName admin, long timeout)1014 protected void setPasswordExpirationTimeout(ComponentName admin, long timeout) { 1015 enforceActiveAdmin(admin); 1016 passwordExpirationTimeout = timeout; 1017 } 1018 1019 @Implementation getPasswordExpirationTimeout(ComponentName admin)1020 protected long getPasswordExpirationTimeout(ComponentName admin) { 1021 if (admin != null) { 1022 enforceActiveAdmin(admin); 1023 } 1024 return passwordExpirationTimeout; 1025 } 1026 1027 /** 1028 * Sets the password expiration time for a particular admin. 1029 * 1030 * @param admin which DeviceAdminReceiver this request is associated with. 1031 * @param timeout the password expiration time, in milliseconds since epoch. 1032 */ setPasswordExpiration(ComponentName admin, long timeout)1033 public void setPasswordExpiration(ComponentName admin, long timeout) { 1034 enforceActiveAdmin(admin); 1035 passwordExpiration = timeout; 1036 } 1037 1038 @Implementation getPasswordExpiration(ComponentName admin)1039 protected long getPasswordExpiration(ComponentName admin) { 1040 if (admin != null) { 1041 enforceActiveAdmin(admin); 1042 } 1043 return passwordExpiration; 1044 } 1045 1046 @Implementation setMaximumTimeToLock(ComponentName admin, long timeMs)1047 protected void setMaximumTimeToLock(ComponentName admin, long timeMs) { 1048 enforceActiveAdmin(admin); 1049 maximumTimeToLock = timeMs; 1050 } 1051 1052 @Implementation getMaximumTimeToLock(ComponentName admin)1053 protected long getMaximumTimeToLock(ComponentName admin) { 1054 if (admin != null) { 1055 enforceActiveAdmin(admin); 1056 } 1057 return maximumTimeToLock; 1058 } 1059 1060 @Implementation setPasswordHistoryLength(ComponentName admin, int length)1061 protected void setPasswordHistoryLength(ComponentName admin, int length) { 1062 enforceActiveAdmin(admin); 1063 passwordHistoryLength = length; 1064 } 1065 1066 @Implementation getPasswordHistoryLength(ComponentName admin)1067 protected int getPasswordHistoryLength(ComponentName admin) { 1068 if (admin != null) { 1069 enforceActiveAdmin(admin); 1070 } 1071 return passwordHistoryLength; 1072 } 1073 1074 /** 1075 * Sets if the password meets the current requirements. 1076 * 1077 * @param sufficient indicates the password meets the current requirements 1078 */ setActivePasswordSufficient(boolean sufficient)1079 public void setActivePasswordSufficient(boolean sufficient) { 1080 isActivePasswordSufficient = sufficient; 1081 } 1082 1083 @Implementation isActivePasswordSufficient()1084 protected boolean isActivePasswordSufficient() { 1085 return isActivePasswordSufficient; 1086 } 1087 1088 /** Sets whether the device is provisioned. */ setDeviceProvisioned(boolean isProvisioned)1089 public void setDeviceProvisioned(boolean isProvisioned) { 1090 isDeviceProvisioned = isProvisioned; 1091 } 1092 1093 @Implementation(minSdk = O) 1094 @SystemApi 1095 @RequiresPermission(android.Manifest.permission.MANAGE_USERS) isDeviceProvisioned()1096 protected boolean isDeviceProvisioned() { 1097 return isDeviceProvisioned; 1098 } 1099 1100 @Implementation(minSdk = O) 1101 @SystemApi 1102 @RequiresPermission(android.Manifest.permission.MANAGE_USERS) setDeviceProvisioningConfigApplied()1103 protected void setDeviceProvisioningConfigApplied() { 1104 isDeviceProvisioningConfigApplied = true; 1105 } 1106 1107 @Implementation(minSdk = O) 1108 @SystemApi 1109 @RequiresPermission(android.Manifest.permission.MANAGE_USERS) isDeviceProvisioningConfigApplied()1110 protected boolean isDeviceProvisioningConfigApplied() { 1111 return isDeviceProvisioningConfigApplied; 1112 } 1113 1114 /** Sets the password complexity. */ setPasswordComplexity(@asswordComplexity int passwordComplexity)1115 public void setPasswordComplexity(@PasswordComplexity int passwordComplexity) { 1116 this.passwordComplexity = passwordComplexity; 1117 } 1118 1119 @PasswordComplexity 1120 @Implementation(minSdk = Q) getPasswordComplexity()1121 protected int getPasswordComplexity() { 1122 return passwordComplexity; 1123 } 1124 passwordMeetsRequirements(String password)1125 private boolean passwordMeetsRequirements(String password) { 1126 int digit = 0; 1127 int alpha = 0; 1128 int upper = 0; 1129 int lower = 0; 1130 int symbol = 0; 1131 for (int i = 0; i < password.length(); i++) { 1132 char c = password.charAt(i); 1133 if (Character.isDigit(c)) { 1134 digit++; 1135 } 1136 if (Character.isLetter(c)) { 1137 alpha++; 1138 } 1139 if (Character.isUpperCase(c)) { 1140 upper++; 1141 } 1142 if (Character.isLowerCase(c)) { 1143 lower++; 1144 } 1145 if (!Character.isLetterOrDigit(c)) { 1146 symbol++; 1147 } 1148 } 1149 switch (requiredPasswordQuality) { 1150 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: 1151 case DevicePolicyManager.PASSWORD_QUALITY_MANAGED: 1152 case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK: 1153 return true; 1154 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 1155 return password.length() > 0; 1156 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 1157 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: // complexity not enforced 1158 return digit > 0 && password.length() >= passwordMinimumLength; 1159 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 1160 return digit > 0 && alpha > 0 && password.length() >= passwordMinimumLength; 1161 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 1162 return password.length() >= passwordMinimumLength 1163 && alpha >= passwordMinimumLetters 1164 && lower >= passwordMinimumLowerCase 1165 && upper >= passwordMinimumUpperCase 1166 && digit + symbol >= passwordMinimumNonLetter 1167 && digit >= passwordMinimumNumeric 1168 && symbol >= passwordMinimumSymbols; 1169 default: 1170 return true; 1171 } 1172 } 1173 1174 /** 1175 * Retrieves last password set through {@link DevicePolicyManager#resetPassword} or {@link 1176 * DevicePolicyManager#resetPasswordWithToken}. 1177 */ getLastSetPassword()1178 public String getLastSetPassword() { 1179 return lastSetPassword; 1180 } 1181 1182 /** 1183 * Activates reset token for given admin. 1184 * 1185 * @param admin Which {@link DeviceAdminReceiver} this request is associated with. 1186 * @return if the activation state changed. 1187 * @throws IllegalArgumentException if there is no token set for this admin. 1188 */ activateResetToken(ComponentName admin)1189 public boolean activateResetToken(ComponentName admin) { 1190 if (!passwordResetTokens.containsKey(admin)) { 1191 throw new IllegalArgumentException("No token set for comopnent: " + admin); 1192 } 1193 return componentsWithActivatedTokens.add(admin); 1194 } 1195 1196 @Implementation(minSdk = LOLLIPOP) addPersistentPreferredActivity( ComponentName admin, IntentFilter filter, ComponentName activity)1197 protected void addPersistentPreferredActivity( 1198 ComponentName admin, IntentFilter filter, ComponentName activity) { 1199 enforceDeviceOwnerOrProfileOwner(admin); 1200 1201 PackageManager packageManager = context.getPackageManager(); 1202 Shadow.<ShadowPackageManager>extract(packageManager) 1203 .addPersistentPreferredActivity(filter, activity); 1204 } 1205 1206 @Implementation(minSdk = LOLLIPOP) clearPackagePersistentPreferredActivities( ComponentName admin, String packageName)1207 protected void clearPackagePersistentPreferredActivities( 1208 ComponentName admin, String packageName) { 1209 enforceDeviceOwnerOrProfileOwner(admin); 1210 PackageManager packageManager = context.getPackageManager(); 1211 Shadow.<ShadowPackageManager>extract(packageManager) 1212 .clearPackagePersistentPreferredActivities(packageName); 1213 } 1214 1215 @Implementation(minSdk = JELLY_BEAN_MR1) setKeyguardDisabledFeatures(ComponentName admin, int which)1216 protected void setKeyguardDisabledFeatures(ComponentName admin, int which) { 1217 enforceActiveAdmin(admin); 1218 keyguardDisabledFeatures = which; 1219 } 1220 1221 @Implementation(minSdk = JELLY_BEAN_MR1) getKeyguardDisabledFeatures(ComponentName admin)1222 protected int getKeyguardDisabledFeatures(ComponentName admin) { 1223 return keyguardDisabledFeatures; 1224 } 1225 1226 /** 1227 * Sets the user provisioning state. 1228 * 1229 * @param state to store provisioning state 1230 */ setUserProvisioningState(int state)1231 public void setUserProvisioningState(int state) { 1232 setUserProvisioningState(state, Process.myUserHandle()); 1233 } 1234 1235 @Implementation(minSdk = TIRAMISU) setUserProvisioningState(@serProvisioningState int state, UserHandle userHandle)1236 protected void setUserProvisioningState(@UserProvisioningState int state, UserHandle userHandle) { 1237 userProvisioningStatesMap.put(userHandle.getIdentifier(), state); 1238 } 1239 1240 /** 1241 * Returns the provisioning state set in {@link #setUserProvisioningState(int)}, or {@link 1242 * DevicePolicyManager#STATE_USER_UNMANAGED} if none is set. 1243 */ 1244 @Implementation(minSdk = N) getUserProvisioningState()1245 protected int getUserProvisioningState() { 1246 return getUserProvisioningStateForUser(Process.myUserHandle().getIdentifier()); 1247 } 1248 1249 @Implementation hasGrantedPolicy(@onNull ComponentName admin, int usesPolicy)1250 protected boolean hasGrantedPolicy(@NonNull ComponentName admin, int usesPolicy) { 1251 enforceActiveAdmin(admin); 1252 Set<Integer> policyGrantedSet = adminPolicyGrantedMap.get(admin); 1253 return policyGrantedSet != null && policyGrantedSet.contains(usesPolicy); 1254 } 1255 1256 @Implementation(minSdk = P) getLockTaskFeatures(ComponentName admin)1257 protected int getLockTaskFeatures(ComponentName admin) { 1258 Objects.requireNonNull(admin, "ComponentName is null"); 1259 enforceDeviceOwnerOrProfileOwner(admin); 1260 return lockTaskFeatures; 1261 } 1262 1263 @Implementation(minSdk = P) setLockTaskFeatures(ComponentName admin, int flags)1264 protected void setLockTaskFeatures(ComponentName admin, int flags) { 1265 Objects.requireNonNull(admin, "ComponentName is null"); 1266 enforceDeviceOwnerOrProfileOwner(admin); 1267 // Throw if Overview is used without Home. 1268 boolean hasHome = (flags & LOCK_TASK_FEATURE_HOME) != 0; 1269 boolean hasOverview = (flags & LOCK_TASK_FEATURE_OVERVIEW) != 0; 1270 Preconditions.checkArgument( 1271 hasHome || !hasOverview, 1272 "Cannot use LOCK_TASK_FEATURE_OVERVIEW without LOCK_TASK_FEATURE_HOME"); 1273 boolean hasNotification = (flags & LOCK_TASK_FEATURE_NOTIFICATIONS) != 0; 1274 Preconditions.checkArgument( 1275 hasHome || !hasNotification, 1276 "Cannot use LOCK_TASK_FEATURE_NOTIFICATIONS without LOCK_TASK_FEATURE_HOME"); 1277 1278 lockTaskFeatures = flags; 1279 } 1280 1281 @Implementation(minSdk = LOLLIPOP) setLockTaskPackages(@onNull ComponentName admin, String[] packages)1282 protected void setLockTaskPackages(@NonNull ComponentName admin, String[] packages) { 1283 enforceDeviceOwnerOrProfileOwner(admin); 1284 lockTaskPackages.clear(); 1285 Collections.addAll(lockTaskPackages, packages); 1286 } 1287 1288 @Implementation(minSdk = LOLLIPOP) getLockTaskPackages(@onNull ComponentName admin)1289 protected String[] getLockTaskPackages(@NonNull ComponentName admin) { 1290 enforceDeviceOwnerOrProfileOwner(admin); 1291 return lockTaskPackages.toArray(new String[0]); 1292 } 1293 1294 @Implementation(minSdk = LOLLIPOP) isLockTaskPermitted(@onNull String pkg)1295 protected boolean isLockTaskPermitted(@NonNull String pkg) { 1296 return lockTaskPackages.contains(pkg); 1297 } 1298 1299 @Implementation(minSdk = O) setAffiliationIds(@onNull ComponentName admin, @NonNull Set<String> ids)1300 protected void setAffiliationIds(@NonNull ComponentName admin, @NonNull Set<String> ids) { 1301 enforceDeviceOwnerOrProfileOwner(admin); 1302 affiliationIds.clear(); 1303 affiliationIds.addAll(ids); 1304 } 1305 1306 @Implementation(minSdk = O) getAffiliationIds(@onNull ComponentName admin)1307 protected Set<String> getAffiliationIds(@NonNull ComponentName admin) { 1308 enforceDeviceOwnerOrProfileOwner(admin); 1309 return affiliationIds; 1310 } 1311 1312 @Implementation(minSdk = M) setPermissionPolicy(@onNull ComponentName admin, int policy)1313 protected void setPermissionPolicy(@NonNull ComponentName admin, int policy) { 1314 enforceDeviceOwnerOrProfileOwner(admin); 1315 permissionPolicy = policy; 1316 } 1317 1318 @Implementation(minSdk = M) getPermissionPolicy(ComponentName admin)1319 protected int getPermissionPolicy(ComponentName admin) { 1320 enforceDeviceOwnerOrProfileOwner(admin); 1321 return permissionPolicy; 1322 } 1323 1324 /** 1325 * Grants a particular device policy for an active ComponentName. 1326 * 1327 * @param admin the ComponentName which DeviceAdminReceiver this request is associated with. Must 1328 * be an active administrator, or an exception will be thrown. This value must never be null. 1329 * @param usesPolicy the uses-policy to check 1330 */ grantPolicy(@onNull ComponentName admin, int usesPolicy)1331 public void grantPolicy(@NonNull ComponentName admin, int usesPolicy) { 1332 enforceActiveAdmin(admin); 1333 Set<Integer> policyGrantedSet = adminPolicyGrantedMap.get(admin); 1334 if (policyGrantedSet == null) { 1335 policyGrantedSet = new HashSet<>(); 1336 policyGrantedSet.add(usesPolicy); 1337 adminPolicyGrantedMap.put(admin, policyGrantedSet); 1338 } else { 1339 policyGrantedSet.add(usesPolicy); 1340 } 1341 } 1342 1343 @Implementation(minSdk = M) getSystemUpdatePolicy()1344 protected SystemUpdatePolicy getSystemUpdatePolicy() { 1345 return policy; 1346 } 1347 1348 @Implementation(minSdk = M) setSystemUpdatePolicy(ComponentName admin, SystemUpdatePolicy policy)1349 protected void setSystemUpdatePolicy(ComponentName admin, SystemUpdatePolicy policy) { 1350 this.policy = policy; 1351 } 1352 1353 /** 1354 * Sets the system update policy. 1355 * 1356 * @see #setSystemUpdatePolicy(ComponentName, SystemUpdatePolicy) 1357 */ setSystemUpdatePolicy(SystemUpdatePolicy policy)1358 public void setSystemUpdatePolicy(SystemUpdatePolicy policy) { 1359 setSystemUpdatePolicy(null, policy); 1360 } 1361 1362 /** 1363 * Set the list of target users that the calling device or profile owner can use when calling 1364 * {@link #bindDeviceAdminServiceAsUser}. 1365 * 1366 * @see #getBindDeviceAdminTargetUsers(ComponentName) 1367 */ setBindDeviceAdminTargetUsers(List<UserHandle> bindDeviceAdminTargetUsers)1368 public void setBindDeviceAdminTargetUsers(List<UserHandle> bindDeviceAdminTargetUsers) { 1369 this.bindDeviceAdminTargetUsers = bindDeviceAdminTargetUsers; 1370 } 1371 1372 /** 1373 * Returns the list of target users that the calling device or profile owner can use when calling 1374 * {@link #bindDeviceAdminServiceAsUser}. 1375 * 1376 * @see #setBindDeviceAdminTargetUsers(List) 1377 */ 1378 @Implementation(minSdk = O) getBindDeviceAdminTargetUsers(ComponentName admin)1379 protected List<UserHandle> getBindDeviceAdminTargetUsers(ComponentName admin) { 1380 return bindDeviceAdminTargetUsers; 1381 } 1382 1383 /** 1384 * Bind to the same package in another user. 1385 * 1386 * <p>This validates that the targetUser is one from {@link 1387 * #getBindDeviceAdminTargetUsers(ComponentName)} but does not actually bind to a different user, 1388 * instead binding to the same user. 1389 * 1390 * <p>It also does not validate the service being bound to. 1391 */ 1392 @Implementation(minSdk = O) bindDeviceAdminServiceAsUser( ComponentName admin, Intent serviceIntent, ServiceConnection conn, int flags, UserHandle targetUser)1393 protected boolean bindDeviceAdminServiceAsUser( 1394 ComponentName admin, 1395 Intent serviceIntent, 1396 ServiceConnection conn, 1397 int flags, 1398 UserHandle targetUser) { 1399 if (!getBindDeviceAdminTargetUsers(admin).contains(targetUser)) { 1400 throw new SecurityException("Not allowed to bind to target user id"); 1401 } 1402 1403 return context.bindServiceAsUser(serviceIntent, conn, flags, targetUser); 1404 } 1405 1406 @Implementation(minSdk = N) setShortSupportMessage(ComponentName admin, @Nullable CharSequence message)1407 protected void setShortSupportMessage(ComponentName admin, @Nullable CharSequence message) { 1408 enforceActiveAdmin(admin); 1409 shortSupportMessageMap.put(admin, message); 1410 } 1411 1412 @Implementation(minSdk = N) 1413 @Nullable getShortSupportMessage(ComponentName admin)1414 protected CharSequence getShortSupportMessage(ComponentName admin) { 1415 enforceActiveAdmin(admin); 1416 return shortSupportMessageMap.get(admin); 1417 } 1418 1419 @Implementation(minSdk = N) setLongSupportMessage(ComponentName admin, @Nullable CharSequence message)1420 protected void setLongSupportMessage(ComponentName admin, @Nullable CharSequence message) { 1421 enforceActiveAdmin(admin); 1422 longSupportMessageMap.put(admin, message); 1423 } 1424 1425 @Implementation(minSdk = N) 1426 @Nullable getLongSupportMessage(ComponentName admin)1427 protected CharSequence getLongSupportMessage(ComponentName admin) { 1428 enforceActiveAdmin(admin); 1429 return longSupportMessageMap.get(admin); 1430 } 1431 1432 /** 1433 * Sets the return value of the {@link 1434 * DevicePolicyManager#isOrganizationOwnedDeviceWithManagedProfile} method (only for Android R+). 1435 */ setOrganizationOwnedDeviceWithManagedProfile(boolean value)1436 public void setOrganizationOwnedDeviceWithManagedProfile(boolean value) { 1437 organizationOwnedDeviceWithManagedProfile = value; 1438 } 1439 1440 /** 1441 * Returns the value stored using in the shadow, while the real method returns the value store on 1442 * the device. 1443 * 1444 * <p>The value can be set by {@link #setOrganizationOwnedDeviceWithManagedProfile} and is {@code 1445 * false} by default. 1446 */ 1447 @Implementation(minSdk = R) isOrganizationOwnedDeviceWithManagedProfile()1448 protected boolean isOrganizationOwnedDeviceWithManagedProfile() { 1449 return organizationOwnedDeviceWithManagedProfile; 1450 } 1451 1452 @Implementation(minSdk = S) 1453 @NearbyStreamingPolicy getNearbyNotificationStreamingPolicy()1454 protected int getNearbyNotificationStreamingPolicy() { 1455 return nearbyNotificationStreamingPolicy; 1456 } 1457 1458 @Implementation(minSdk = S) setNearbyNotificationStreamingPolicy(@earbyStreamingPolicy int policy)1459 protected void setNearbyNotificationStreamingPolicy(@NearbyStreamingPolicy int policy) { 1460 nearbyNotificationStreamingPolicy = policy; 1461 } 1462 1463 @Implementation(minSdk = S) 1464 @NearbyStreamingPolicy getNearbyAppStreamingPolicy()1465 protected int getNearbyAppStreamingPolicy() { 1466 return nearbyAppStreamingPolicy; 1467 } 1468 1469 @Implementation(minSdk = S) setNearbyAppStreamingPolicy(@earbyStreamingPolicy int policy)1470 protected void setNearbyAppStreamingPolicy(@NearbyStreamingPolicy int policy) { 1471 nearbyAppStreamingPolicy = policy; 1472 } 1473 1474 @Nullable 1475 @Implementation(minSdk = TIRAMISU) getDevicePolicyManagementRoleHolderPackage()1476 protected String getDevicePolicyManagementRoleHolderPackage() { 1477 return devicePolicyManagementRoleHolderPackage; 1478 } 1479 1480 /** 1481 * Sets the package name of the device policy management role holder. 1482 * 1483 * @see #getDevicePolicyManagementRoleHolderPackage() 1484 */ setDevicePolicyManagementRoleHolderPackage(@ullable String packageName)1485 public void setDevicePolicyManagementRoleHolderPackage(@Nullable String packageName) { 1486 devicePolicyManagementRoleHolderPackage = packageName; 1487 } 1488 1489 @Implementation(minSdk = TIRAMISU) finalizeWorkProfileProvisioning( UserHandle managedProfileUser, @Nullable Account migratedAccount)1490 protected void finalizeWorkProfileProvisioning( 1491 UserHandle managedProfileUser, @Nullable Account migratedAccount) { 1492 finalizedWorkProfileProvisioningMap.put(managedProfileUser, migratedAccount); 1493 } 1494 1495 /** 1496 * Returns if {@link #finalizeWorkProfileProvisioning(UserHandle, Account)} was called with the 1497 * provided parameters. 1498 */ isWorkProfileProvisioningFinalized( UserHandle userHandle, @Nullable Account migratedAccount)1499 public boolean isWorkProfileProvisioningFinalized( 1500 UserHandle userHandle, @Nullable Account migratedAccount) { 1501 return finalizedWorkProfileProvisioningMap.containsKey(userHandle) 1502 && Objects.equals(finalizedWorkProfileProvisioningMap.get(userHandle), migratedAccount); 1503 } 1504 1505 /** 1506 * Returns the managed profiles set in {@link #setPolicyManagedProfiles(List)}. This value does 1507 * not take the user handle parameter into account. 1508 */ 1509 @Implementation(minSdk = TIRAMISU) getPolicyManagedProfiles(UserHandle userHandle)1510 protected List<UserHandle> getPolicyManagedProfiles(UserHandle userHandle) { 1511 return policyManagedProfiles; 1512 } 1513 1514 /** Sets the value returned by {@link #getPolicyManagedProfiles(UserHandle)}. */ setPolicyManagedProfiles(List<UserHandle> policyManagedProfiles)1515 public void setPolicyManagedProfiles(List<UserHandle> policyManagedProfiles) { 1516 this.policyManagedProfiles = policyManagedProfiles; 1517 } 1518 1519 /** 1520 * Returns the user provisioning state set by {@link #setUserProvisioningState(int, UserHandle)}, 1521 * or {@link DevicePolicyManager#STATE_USER_UNMANAGED} if none is set. 1522 */ 1523 @UserProvisioningState getUserProvisioningStateForUser(int userId)1524 public int getUserProvisioningStateForUser(int userId) { 1525 return userProvisioningStatesMap.getOrDefault(userId, DevicePolicyManager.STATE_USER_UNMANAGED); 1526 } 1527 } 1528