1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.bedstead.nene.devicepolicy; 18 19 import static android.Manifest.permission.CREATE_USERS; 20 import static android.Manifest.permission.INTERACT_ACROSS_USERS; 21 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 22 import static android.app.role.RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT; 23 import static android.os.Build.VERSION.SDK_INT; 24 import static android.os.Build.VERSION_CODES.TIRAMISU; 25 import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; 26 27 import static com.android.bedstead.nene.permissions.CommonPermissions.FORCE_DEVICE_POLICY_MANAGER_LOGS; 28 import static com.android.bedstead.nene.permissions.CommonPermissions.MANAGE_DEVICE_ADMINS; 29 import static com.android.bedstead.nene.permissions.CommonPermissions.MANAGE_PROFILE_AND_DEVICE_OWNERS; 30 import static com.android.bedstead.nene.permissions.CommonPermissions.MANAGE_ROLE_HOLDERS; 31 import static com.android.bedstead.nene.permissions.CommonPermissions.QUERY_ADMIN_POLICY; 32 33 import android.annotation.TargetApi; 34 import android.app.admin.DevicePolicyManager; 35 import android.content.ComponentName; 36 import android.content.Intent; 37 import android.content.pm.PackageManager; 38 import android.content.pm.ResolveInfo; 39 import android.os.Build; 40 import android.os.PersistableBundle; 41 import android.os.UserHandle; 42 import android.util.Log; 43 44 import androidx.annotation.Nullable; 45 46 import com.android.bedstead.nene.TestApis; 47 import com.android.bedstead.nene.annotations.Experimental; 48 import com.android.bedstead.nene.exceptions.AdbException; 49 import com.android.bedstead.nene.exceptions.AdbParseException; 50 import com.android.bedstead.nene.exceptions.NeneException; 51 import com.android.bedstead.nene.logcat.BlockingLogcatListener; 52 import com.android.bedstead.nene.packages.ComponentReference; 53 import com.android.bedstead.nene.packages.Package; 54 import com.android.bedstead.nene.permissions.CommonPermissions; 55 import com.android.bedstead.nene.permissions.PermissionContext; 56 import com.android.bedstead.nene.roles.RoleContext; 57 import com.android.bedstead.nene.users.UserReference; 58 import com.android.bedstead.nene.utils.Poll; 59 import com.android.bedstead.nene.utils.Retry; 60 import com.android.bedstead.nene.utils.ShellCommand; 61 import com.android.bedstead.nene.utils.ShellCommandUtils; 62 import com.android.bedstead.nene.utils.Versions; 63 64 import java.lang.reflect.InvocationTargetException; 65 import java.time.Duration; 66 import java.util.HashSet; 67 import java.util.List; 68 import java.util.Map; 69 import java.util.Set; 70 import java.util.stream.Collectors; 71 72 /** 73 * Test APIs related to device policy. 74 */ 75 public final class DevicePolicy { 76 77 public static final DevicePolicy sInstance = new DevicePolicy(); 78 79 private static final String LOG_TAG = "DevicePolicy"; 80 81 private final AdbDevicePolicyParser mParser; 82 83 private DeviceOwner mCachedDeviceOwner; 84 private Map<UserReference, ProfileOwner> mCachedProfileOwners; 85 86 private static final DevicePolicyManager sDevicePolicyManager = 87 TestApis.context().instrumentedContext() 88 .getSystemService(DevicePolicyManager.class); 89 DevicePolicy()90 private DevicePolicy() { 91 mParser = AdbDevicePolicyParser.get(SDK_INT); 92 } 93 94 /** 95 * Set the profile owner for a given {@link UserReference}. 96 */ setProfileOwner(UserReference user, ComponentName profileOwnerComponent)97 public ProfileOwner setProfileOwner(UserReference user, ComponentName profileOwnerComponent) { 98 if (user == null || profileOwnerComponent == null) { 99 throw new NullPointerException(); 100 } 101 102 ShellCommand.Builder command = 103 ShellCommand.builderForUser(user, "dpm set-profile-owner") 104 .addOperand(profileOwnerComponent.flattenToShortString()) 105 .validate(ShellCommandUtils::startsWithSuccess); 106 107 // TODO(b/187925230): If it fails, we check for terminal failure states - and if not 108 // we retry because if the profile owner was recently removed, it can take some time 109 // to be allowed to set it again 110 try { 111 Retry.logic(command::execute) 112 .terminalException((ex) -> { 113 114 if (!Versions.meetsMinimumSdkVersionRequirement(Build.VERSION_CODES.S)) { 115 return false; // Just retry on old versions as we don't have stderr 116 } 117 if (ex instanceof AdbException) { 118 String error = ((AdbException) ex).error(); 119 if (error != null && error.contains("is already set")) { 120 // This can happen for a while when it is being tidied up 121 return false; 122 } 123 124 if (error != null && error.contains("is being removed")) { 125 return false; 126 } 127 } 128 129 // Assume all other errors are terminal 130 return true; 131 }) 132 .timeout(Duration.ofMinutes(5)) 133 .run(); 134 } catch (Throwable e) { 135 throw new NeneException("Could not set profile owner for user " 136 + user + " component " + profileOwnerComponent, e); 137 } 138 139 Poll.forValue("Profile Owner", () -> TestApis.devicePolicy().getProfileOwner(user)) 140 .toNotBeNull() 141 .errorOnFail() 142 .await(); 143 144 return new ProfileOwner(user, 145 TestApis.packages().find( 146 profileOwnerComponent.getPackageName()), profileOwnerComponent); 147 } 148 149 /** 150 * Get the organization owned profile owner for the device, if any, otherwise null. 151 */ getOrganizationOwnedProfileOwner()152 public ProfileOwner getOrganizationOwnedProfileOwner() { 153 for (UserReference user : TestApis.users().all()) { 154 ProfileOwner profileOwner = getProfileOwner(user); 155 if (profileOwner != null && profileOwner.isOrganizationOwned()) { 156 return profileOwner; 157 } 158 } 159 160 return null; 161 } 162 163 164 /** 165 * Get the profile owner for the instrumented user. 166 */ getProfileOwner()167 public ProfileOwner getProfileOwner() { 168 return getProfileOwner(TestApis.users().instrumented()); 169 } 170 171 /** 172 * Get the profile owner for a given {@link UserHandle}. 173 */ getProfileOwner(UserHandle user)174 public ProfileOwner getProfileOwner(UserHandle user) { 175 return getProfileOwner(UserReference.of(user)); 176 } 177 178 /** 179 * Get the profile owner for a given {@link UserReference}. 180 */ getProfileOwner(UserReference user)181 public ProfileOwner getProfileOwner(UserReference user) { 182 if (user == null) { 183 throw new NullPointerException(); 184 } 185 fillCache(); 186 return mCachedProfileOwners.get(user); 187 } 188 189 /** 190 * Set the device owner. 191 */ setDeviceOwner(ComponentName deviceOwnerComponent)192 public DeviceOwner setDeviceOwner(ComponentName deviceOwnerComponent) { 193 if (deviceOwnerComponent == null) { 194 throw new NullPointerException(); 195 } 196 197 if (!Versions.meetsMinimumSdkVersionRequirement(Build.VERSION_CODES.S)) { 198 return setDeviceOwnerPreS(deviceOwnerComponent); 199 } else if (!Versions.meetsMinimumSdkVersionRequirement(Versions.U)) { 200 return setDeviceOwnerPreU(deviceOwnerComponent); 201 } 202 203 UserReference user = TestApis.users().system(); 204 205 try (PermissionContext p = 206 TestApis.permissions().withPermission( 207 MANAGE_PROFILE_AND_DEVICE_OWNERS, MANAGE_DEVICE_ADMINS, 208 INTERACT_ACROSS_USERS_FULL, INTERACT_ACROSS_USERS, CREATE_USERS)) { 209 210 ShellCommand.Builder command = ShellCommand.builderForUser( 211 user, "dpm set-device-owner --device-owner-only") 212 .addOperand(deviceOwnerComponent.flattenToShortString()) 213 .validate(ShellCommandUtils::startsWithSuccess); 214 // TODO(b/187925230): If it fails, we check for terminal failure states - and if not 215 // we retry because if the DO/PO was recently removed, it can take some time 216 // to be allowed to set it again 217 Retry.logic(command::execute) 218 .terminalException( 219 (e) -> checkForTerminalDeviceOwnerFailures( 220 user, 221 deviceOwnerComponent, 222 /* allowAdditionalUsers= */ false, 223 e)) 224 .timeout(Duration.ofMinutes(5)) 225 .run(); 226 } catch (Throwable e) { 227 throw new NeneException("Error setting device owner.", e); 228 } 229 230 Package deviceOwnerPackage = TestApis.packages().find( 231 deviceOwnerComponent.getPackageName()); 232 233 Poll.forValue("Device Owner", () -> TestApis.devicePolicy().getDeviceOwner()) 234 .toNotBeNull() 235 .errorOnFail() 236 .await(); 237 238 return new DeviceOwner(user, deviceOwnerPackage, deviceOwnerComponent); 239 } 240 241 /** 242 * Set Device Owner without changing any other device state. 243 * 244 * <p>This is used instead of {@link DevicePolicyManager#setDeviceOwner(ComponentName)} directly 245 * because on S_V2 and above, that method can also set profile owners and install packages in 246 * some circumstances. 247 */ setDeviceOwnerOnly(DevicePolicyManager devicePolicyManager, ComponentName component, int deviceOwnerUserId)248 private void setDeviceOwnerOnly(DevicePolicyManager devicePolicyManager, 249 ComponentName component, int deviceOwnerUserId) { 250 if (Versions.meetsMinimumSdkVersionRequirement(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)) { 251 devicePolicyManager.setDeviceOwnerOnly(component, deviceOwnerUserId); 252 } else if (Versions.meetsMinimumSdkVersionRequirement(Build.VERSION_CODES.S_V2)) { 253 try { 254 DevicePolicyManager.class.getMethod( 255 "setDeviceOwnerOnly", ComponentName.class, String.class, int.class) 256 .invoke(devicePolicyManager, component, null, deviceOwnerUserId); 257 } catch (IllegalAccessException | InvocationTargetException 258 | NoSuchMethodException e) { 259 throw new NeneException("Error executing setDeviceOwnerOnly", e); 260 } 261 } else { 262 try { 263 DevicePolicyManager.class.getMethod( 264 "setDeviceOwner", ComponentName.class, String.class, int.class) 265 .invoke(devicePolicyManager, component, null, deviceOwnerUserId); 266 } catch (IllegalAccessException | InvocationTargetException 267 | NoSuchMethodException e) { 268 throw new NeneException("Error executing setDeviceOwner", e); 269 } 270 } 271 } 272 273 /** 274 * Resets organization ID via @TestApi. 275 * @param user whose organization ID to clear 276 */ clearOrganizationId(UserReference user)277 public void clearOrganizationId(UserReference user) { 278 try (PermissionContext p = 279 TestApis.permissions().withPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)) { 280 devicePolicyManager(user).clearOrganizationId(); 281 } 282 } 283 devicePolicyManager(UserReference user)284 private DevicePolicyManager devicePolicyManager(UserReference user) { 285 return TestApis.context().instrumentedContextAsUser(user) 286 .getSystemService(DevicePolicyManager.class); 287 } 288 setDeviceOwnerPreU(ComponentName deviceOwnerComponent)289 private DeviceOwner setDeviceOwnerPreU(ComponentName deviceOwnerComponent) { 290 UserReference user = TestApis.users().system(); 291 292 boolean dpmUserSetupComplete = user.getSetupComplete(); 293 Boolean currentUserSetupComplete = null; 294 295 try { 296 user.setSetupComplete(false); 297 298 try (PermissionContext p = 299 TestApis.permissions().withPermission( 300 MANAGE_PROFILE_AND_DEVICE_OWNERS, MANAGE_DEVICE_ADMINS, 301 INTERACT_ACROSS_USERS_FULL, INTERACT_ACROSS_USERS, CREATE_USERS)) { 302 303 // TODO(b/187925230): If it fails, we check for terminal failure states - and if not 304 // we retry because if the DO/PO was recently removed, it can take some time 305 // to be allowed to set it again 306 Retry.logic( 307 () -> { 308 sDevicePolicyManager.setActiveAdmin( 309 deviceOwnerComponent, 310 /* refreshing= */ true, 311 user.id()); 312 setDeviceOwnerOnly( 313 sDevicePolicyManager, deviceOwnerComponent, user.id()); 314 }) 315 .terminalException( 316 (e) -> checkForTerminalDeviceOwnerFailures( 317 user, 318 deviceOwnerComponent, 319 /* allowAdditionalUsers= */ true, 320 e)) 321 .timeout(Duration.ofMinutes(5)) 322 .run(); 323 } catch (Throwable e) { 324 throw new NeneException("Error setting device owner", e); 325 } 326 } finally { 327 user.setSetupComplete(dpmUserSetupComplete); 328 if (currentUserSetupComplete != null) { 329 TestApis.users().current().setSetupComplete(currentUserSetupComplete); 330 } 331 } 332 333 Poll.forValue("Device Owner", () -> TestApis.devicePolicy().getDeviceOwner()) 334 .toNotBeNull() 335 .errorOnFail() 336 .await(); 337 338 return new DeviceOwner(user, 339 TestApis.packages().find(deviceOwnerComponent.getPackageName()), 340 deviceOwnerComponent); 341 } 342 setDeviceOwnerPreS(ComponentName deviceOwnerComponent)343 private DeviceOwner setDeviceOwnerPreS(ComponentName deviceOwnerComponent) { 344 UserReference user = TestApis.users().system(); 345 346 ShellCommand.Builder command = ShellCommand.builderForUser( 347 user, "dpm set-device-owner") 348 .addOperand(deviceOwnerComponent.flattenToShortString()) 349 .validate(ShellCommandUtils::startsWithSuccess); 350 // TODO(b/187925230): If it fails, we check for terminal failure states - and if not 351 // we retry because if the device owner was recently removed, it can take some time 352 // to be allowed to set it again 353 354 try { 355 Retry.logic(command::execute) 356 .terminalException( 357 (e) -> 358 checkForTerminalDeviceOwnerFailures( 359 user, 360 deviceOwnerComponent, 361 /* allowAdditionalUsers= */ false, 362 e)) 363 .timeout(Duration.ofMinutes(5)) 364 .run(); 365 } catch (Throwable e) { 366 throw new NeneException("Error setting device owner", e); 367 } 368 369 return new DeviceOwner(user, 370 TestApis.packages().find( 371 deviceOwnerComponent.getPackageName()), deviceOwnerComponent); 372 } 373 checkForTerminalDeviceOwnerFailures( UserReference user, ComponentName deviceOwnerComponent, boolean allowAdditionalUsers, Throwable e)374 private boolean checkForTerminalDeviceOwnerFailures( 375 UserReference user, 376 ComponentName deviceOwnerComponent, 377 boolean allowAdditionalUsers, 378 Throwable e) { 379 DeviceOwner deviceOwner = getDeviceOwner(); 380 if (deviceOwner != null) { 381 // TODO(scottjonathan): Should we actually fail here if the component name is the 382 // same? 383 384 throw new NeneException( 385 "Could not set device owner for user " 386 + user 387 + " as a device owner is already set: " 388 + deviceOwner, 389 e); 390 } 391 392 Package pkg = TestApis.packages().find( 393 deviceOwnerComponent.getPackageName()); 394 if (!TestApis.packages().installedForUser(user).contains(pkg)) { 395 throw new NeneException( 396 "Could not set device owner for user " 397 + user 398 + " as the package " 399 + pkg 400 + " is not installed", 401 e); 402 } 403 404 if (!componentCanBeSetAsDeviceAdmin(deviceOwnerComponent, user)) { 405 throw new NeneException( 406 "Could not set device owner for user " 407 + user 408 + " as component " 409 + deviceOwnerComponent 410 + " is not valid", 411 e); 412 } 413 414 if (!allowAdditionalUsers && nonTestNonPrecreatedUsersExist()) { 415 throw new NeneException( 416 "Could not set device owner for user " 417 + user 418 + " as there are already additional non-test on the device", 419 e); 420 } 421 // TODO(scottjonathan): Check accounts 422 423 return false; 424 } 425 componentCanBeSetAsDeviceAdmin(ComponentName component, UserReference user)426 private boolean componentCanBeSetAsDeviceAdmin(ComponentName component, UserReference user) { 427 PackageManager packageManager = 428 TestApis.context().instrumentedContext().getPackageManager(); 429 Intent intent = new Intent("android.app.action.DEVICE_ADMIN_ENABLED"); 430 intent.setComponent(component); 431 432 try (PermissionContext p = 433 TestApis.permissions().withPermission(INTERACT_ACROSS_USERS_FULL)) { 434 List<ResolveInfo> r = 435 packageManager.queryBroadcastReceiversAsUser( 436 intent, /* flags= */ 0, user.userHandle()); 437 return (!r.isEmpty()); 438 } 439 } 440 441 /** 442 * Get the device owner. 443 */ 444 @Nullable getDeviceOwner()445 public DeviceOwner getDeviceOwner() { 446 fillCache(); 447 return mCachedDeviceOwner; 448 } 449 fillCache()450 private void fillCache() { 451 int retries = 5; 452 while (true) { 453 try { 454 // TODO: Replace use of adb on supported versions of Android 455 String devicePolicyDumpsysOutput = 456 ShellCommand.builder("dumpsys device_policy").execute(); 457 AdbDevicePolicyParser.ParseResult result = mParser.parse(devicePolicyDumpsysOutput); 458 459 mCachedDeviceOwner = result.mDeviceOwner; 460 mCachedProfileOwners = result.mProfileOwners; 461 462 return; 463 } catch (AdbParseException e) { 464 if (e.adbOutput().contains("DUMP TIMEOUT") && retries-- > 0) { 465 // Sometimes this call times out - just retry 466 Log.e(LOG_TAG, "Dump timeout when filling cache, retrying", e); 467 } else { 468 throw new NeneException("Error filling cache", e); 469 } 470 } catch (AdbException e) { 471 throw new NeneException("Error filling cache", e); 472 } 473 } 474 } 475 476 /** See {@link android.app.admin.DevicePolicyManager#getPolicyExemptApps()}. */ 477 @Experimental getPolicyExemptApps()478 public Set<String> getPolicyExemptApps() { 479 try (PermissionContext p = TestApis.permissions().withPermission(MANAGE_DEVICE_ADMINS)) { 480 return TestApis.context() 481 .instrumentedContext() 482 .getSystemService(DevicePolicyManager.class) 483 .getPolicyExemptApps(); 484 } 485 } 486 487 @Experimental forceNetworkLogs()488 public void forceNetworkLogs() { 489 try (PermissionContext p = TestApis.permissions().withPermission(FORCE_DEVICE_POLICY_MANAGER_LOGS)) { 490 long throttle = TestApis.context() 491 .instrumentedContext() 492 .getSystemService(DevicePolicyManager.class) 493 .forceNetworkLogs(); 494 495 if (throttle == -1) { 496 throw new NeneException("Error forcing network logs: returned -1"); 497 } 498 if (throttle == 0) { 499 return; 500 } 501 try { 502 Thread.sleep(throttle); 503 } catch (InterruptedException e) { 504 throw new NeneException("Error waiting for network log throttle", e); 505 } 506 507 forceNetworkLogs(); 508 } 509 } 510 511 /** 512 * Sets the provided {@code packageName} as a device policy management role holder. 513 */ 514 @TargetApi(Build.VERSION_CODES.TIRAMISU) 515 @Experimental setDevicePolicyManagementRoleHolder(Package pkg, UserReference user)516 public RoleContext setDevicePolicyManagementRoleHolder(Package pkg, UserReference user) { 517 Versions.requireMinimumVersion(TIRAMISU); 518 519 if (!Versions.meetsMinimumSdkVersionRequirement(Versions.U)) { 520 if (TestApis.users().all().size() > 1) { 521 throw new NeneException("Could not set device policy management role holder as" 522 + " more than one user is on the device"); 523 } 524 } 525 526 if (nonTestNonPrecreatedUsersExist()) { 527 throw new NeneException("Could not set device policy management role holder as" 528 + " non-test users already exist"); 529 } 530 531 TestApis.roles().setBypassingRoleQualification(true); 532 533 return pkg.setAsRoleHolder(ROLE_DEVICE_POLICY_MANAGEMENT, user); 534 } 535 nonTestNonPrecreatedUsersExist()536 private boolean nonTestNonPrecreatedUsersExist() { 537 int expectedPrecreatedUsers = TestApis.users().isHeadlessSystemUserMode() ? 2 : 1; 538 539 return TestApis.users().all().stream() 540 .filter(u -> !u.isForTesting()) 541 .count() > expectedPrecreatedUsers; 542 } 543 544 /** 545 * Unsets the provided {@code packageName} as a device policy management role holder. 546 */ 547 @TargetApi(Build.VERSION_CODES.TIRAMISU) 548 @Experimental unsetDevicePolicyManagementRoleHolder(Package pkg, UserReference user)549 public void unsetDevicePolicyManagementRoleHolder(Package pkg, UserReference user) { 550 Versions.requireMinimumVersion(TIRAMISU); 551 552 pkg.removeAsRoleHolder(ROLE_DEVICE_POLICY_MANAGEMENT, user); 553 } 554 555 /** 556 * Returns true if the AutoTimeRequired policy is set to true for the given user. 557 */ 558 @Experimental autoTimeRequired(UserReference user)559 public boolean autoTimeRequired(UserReference user) { 560 return TestApis.context().androidContextAsUser(user) 561 .getSystemService(DevicePolicyManager.class) 562 .getAutoTimeRequired(); 563 } 564 565 /** 566 * Returns true if the AutoTimeRequired policy is set to true for the instrumented user. 567 */ 568 @Experimental autoTimeRequired()569 public boolean autoTimeRequired() { 570 return autoTimeRequired(TestApis.users().instrumented()); 571 } 572 573 /** 574 * See {@code DevicePolicyManager#isNewUserDisclaimerAcknowledged}. 575 */ 576 @Experimental isNewUserDisclaimerAcknowledged(UserReference user)577 public boolean isNewUserDisclaimerAcknowledged(UserReference user) { 578 try (PermissionContext p = TestApis.permissions().withPermission( 579 CommonPermissions.INTERACT_ACROSS_USERS)) { 580 return TestApis.context().androidContextAsUser(user).getSystemService( 581 DevicePolicyManager.class).isNewUserDisclaimerAcknowledged(); 582 } 583 } 584 585 /** 586 * See {@code DevicePolicyManager#isNewUserDisclaimerAcknowledged}. 587 */ 588 @Experimental isNewUserDisclaimerAcknowledged()589 public boolean isNewUserDisclaimerAcknowledged() { 590 return isNewUserDisclaimerAcknowledged(TestApis.users().instrumented()); 591 } 592 593 /** 594 * Access APIs related to Device Policy resource overriding. 595 */ 596 @TargetApi(TIRAMISU) resources()597 public DevicePolicyResources resources() { 598 Versions.requireMinimumVersion(TIRAMISU); 599 return DevicePolicyResources.sInstance; 600 } 601 602 /** 603 * Get active admins on the instrumented user. 604 */ getActiveAdmins()605 public Set<ComponentReference> getActiveAdmins() { 606 return getActiveAdmins(TestApis.users().instrumented()); 607 } 608 609 /** 610 * Get active admins on the given user. 611 */ getActiveAdmins(UserReference user)612 public Set<ComponentReference> getActiveAdmins(UserReference user) { 613 try (PermissionContext p = 614 TestApis.permissions().withPermission(INTERACT_ACROSS_USERS_FULL)) { 615 List<ComponentName> activeAdmins = devicePolicyManager(user).getActiveAdmins(); 616 if (activeAdmins == null) { 617 return Set.of(); 618 } 619 return activeAdmins.stream().map(ComponentReference::new).collect( 620 Collectors.toSet()); 621 } 622 } 623 624 /** 625 * See {@link DevicePolicyManager#resetShouldAllowBypassingDevicePolicyManagementRoleQualificationState}. 626 */ 627 @TargetApi(UPSIDE_DOWN_CAKE) resetShouldAllowBypassingDevicePolicyManagementRoleQualificationState()628 public void resetShouldAllowBypassingDevicePolicyManagementRoleQualificationState() { 629 Versions.requireMinimumVersion(UPSIDE_DOWN_CAKE); 630 631 try (PermissionContext p = TestApis.permissions().withPermission(MANAGE_ROLE_HOLDERS)) { 632 devicePolicyManager(TestApis.users().instrumented()) 633 .resetShouldAllowBypassingDevicePolicyManagementRoleQualificationState(); 634 } 635 } 636 637 /** 638 * Set or check user restrictions. 639 */ userRestrictions(UserHandle user)640 public UserRestrictions userRestrictions(UserHandle user) { 641 return userRestrictions(UserReference.of(user)); 642 } 643 644 /** 645 * Set or check user restrictions on the instrumented user 646 */ userRestrictions()647 public UserRestrictions userRestrictions() { 648 return new UserRestrictions(TestApis.users().instrumented()); 649 } 650 651 /** 652 * Set or check user restrictions. 653 */ userRestrictions(UserReference user)654 public UserRestrictions userRestrictions(UserReference user) { 655 return new UserRestrictions(user); 656 } 657 658 /** 659 * OEM-Set default cross profile packages. 660 */ 661 @Experimental defaultCrossProfilePackages()662 public Set<Package> defaultCrossProfilePackages() { 663 return sDevicePolicyManager.getDefaultCrossProfilePackages() 664 .stream().map(i -> TestApis.packages().find(i)) 665 .collect(Collectors.toSet()); 666 } 667 668 /** 669 * True if there is a Device Owner who can grant sensor permissions. 670 */ 671 @Experimental 672 @SuppressWarnings("NewApi") canAdminGrantSensorsPermissions()673 public boolean canAdminGrantSensorsPermissions() { 674 if (!Versions.meetsMinimumSdkVersionRequirement(31)) { 675 return true; 676 } 677 return sDevicePolicyManager.canAdminGrantSensorsPermissions(); 678 } 679 680 /** 681 * See DevicePolicyManager#getUserProvisioningState(). 682 */ 683 @Experimental getUserProvisioningState()684 public int getUserProvisioningState() { 685 return getUserProvisioningState(TestApis.users().instrumented()); 686 } 687 688 /** 689 * @see DevicePolicyManager#getUserProvisioningState(). 690 */ 691 @Experimental getUserProvisioningState(UserReference user)692 public int getUserProvisioningState(UserReference user) { 693 try (PermissionContext p = 694 TestApis.permissions().withPermission(INTERACT_ACROSS_USERS)) { 695 return devicePolicyManager(user).getUserProvisioningState(); 696 } 697 } 698 699 /** 700 * Get password expiration timeout for the instrumented user. 701 */ 702 @Experimental getPasswordExpirationTimeout()703 public long getPasswordExpirationTimeout() { 704 return getPasswordExpirationTimeout(TestApis.users().instrumented()); 705 } 706 707 /** 708 * See {@link DevicePolicyManager#getPasswordExpirationTimeout}. 709 */ 710 @Experimental getPasswordExpirationTimeout(UserReference user)711 public long getPasswordExpirationTimeout(UserReference user) { 712 try (PermissionContext p = 713 TestApis.permissions().withPermission(INTERACT_ACROSS_USERS)) { 714 return devicePolicyManager(user) 715 .getPasswordExpirationTimeout(/* componentName= */ null); 716 } 717 } 718 719 /** 720 * Get maximum time to lock for the instrumented user. 721 */ 722 @Experimental getMaximumTimeToLock()723 public long getMaximumTimeToLock() { 724 return getMaximumTimeToLock(TestApis.users().instrumented()); 725 } 726 727 /** 728 * See {@link DevicePolicyManager#getMaximumTimeToLock}. 729 */ 730 @Experimental getMaximumTimeToLock(UserReference user)731 public long getMaximumTimeToLock(UserReference user) { 732 try (PermissionContext p = 733 TestApis.permissions().withPermission(INTERACT_ACROSS_USERS)) { 734 return devicePolicyManager(user) 735 .getMaximumTimeToLock(/* componentName= */ null); 736 } 737 } 738 739 /** 740 * Get strong auth timeout for the instrumented user. 741 */ 742 @Experimental getRequiredStrongAuthTimeout()743 public long getRequiredStrongAuthTimeout() { 744 return getRequiredStrongAuthTimeout(TestApis.users().instrumented()); 745 } 746 747 /** 748 * See {@link DevicePolicyManager#getRequiredStrongAuthTimeout}. 749 */ 750 @Experimental getRequiredStrongAuthTimeout(UserReference user)751 public long getRequiredStrongAuthTimeout(UserReference user) { 752 try (PermissionContext p = 753 TestApis.permissions().withPermission(INTERACT_ACROSS_USERS)) { 754 return devicePolicyManager(user) 755 .getRequiredStrongAuthTimeout(/* componentName= */ null); 756 } 757 } 758 759 // TODO: Consider wrapping keyguard disabled features with a bedstead concept instead of flags 760 761 /** 762 * Get keyguard disabled features for the instrumented user. 763 */ 764 @Experimental getKeyguardDisabledFeatures()765 public int getKeyguardDisabledFeatures() { 766 return getKeyguardDisabledFeatures(TestApis.users().instrumented()); 767 } 768 769 /** 770 * See {@link DevicePolicyManager#getKeyguardDisabledFeatures}. 771 */ 772 @Experimental getKeyguardDisabledFeatures(UserReference user)773 public int getKeyguardDisabledFeatures(UserReference user) { 774 try (PermissionContext p = 775 TestApis.permissions().withPermission(INTERACT_ACROSS_USERS)) { 776 return devicePolicyManager(user) 777 .getKeyguardDisabledFeatures(/* componentName= */ null); 778 } 779 } 780 781 /** 782 * Get keyguard disabled features for the instrumented user. 783 */ 784 @Experimental getTrustAgentConfiguration(ComponentName trustAgent)785 public Set<PersistableBundle> getTrustAgentConfiguration(ComponentName trustAgent) { 786 return getTrustAgentConfiguration(trustAgent, TestApis.users().instrumented()); 787 } 788 789 /** 790 * See {@link DevicePolicyManager#getTrustAgentConfiguration}. 791 */ 792 @Experimental getTrustAgentConfiguration( ComponentName trustAgent, UserReference user)793 public Set<PersistableBundle> getTrustAgentConfiguration( 794 ComponentName trustAgent, UserReference user) { 795 try (PermissionContext p = 796 TestApis.permissions().withPermission(INTERACT_ACROSS_USERS)) { 797 List<PersistableBundle> configurations = devicePolicyManager(user) 798 .getTrustAgentConfiguration(/* componentName= */ null, trustAgent); 799 return configurations == null ? Set.of() : Set.copyOf(configurations); 800 } 801 } 802 803 /** 804 * True if either this is the system user or the user is affiliated with a device owner on 805 * the device. 806 */ 807 @Experimental isAffiliated()808 public boolean isAffiliated() { 809 return isAffiliated(TestApis.users().instrumented()); 810 } 811 812 // TODO(276248451): Make user handle aware so it'll work cross-user 813 @Experimental isAffiliated(UserReference user)814 private boolean isAffiliated(UserReference user) { 815 return devicePolicyManager(user).isAffiliatedUser(); 816 } 817 818 @Experimental getPermittedInputMethods()819 public List<String> getPermittedInputMethods() { 820 // TODO: Enable cross-user 821 try (PermissionContext p = TestApis.permissions().withPermission(QUERY_ADMIN_POLICY)) { 822 return sDevicePolicyManager.getPermittedInputMethodsForCurrentUser(); 823 } 824 } 825 826 /** 827 * Recalculate the "hasIncompatibleAccounts" cache inside DevicePolicyManager. 828 */ 829 @Experimental calculateHasIncompatibleAccounts()830 public void calculateHasIncompatibleAccounts() { 831 if (!Versions.meetsMinimumSdkVersionRequirement(Versions.U)) { 832 // Nothing to calculate pre-U 833 return; 834 } 835 try (BlockingLogcatListener b = 836 TestApis.logcat().listen( 837 l -> l.contains("Finished calculating hasIncompatibleAccountsTask"))) { 838 sDevicePolicyManager.calculateHasIncompatibleAccounts(); 839 } 840 } 841 842 /** See {@link DevicePolicyManager#getPermittedAccessibilityServices} */ 843 @Experimental getPermittedAccessibilityServices()844 public Set<Package> getPermittedAccessibilityServices() { 845 return getPermittedAccessibilityServices(TestApis.users().instrumented()); 846 } 847 848 /** See {@link DevicePolicyManager#getPermittedAccessibilityServices} */ 849 @Experimental getPermittedAccessibilityServices(UserReference user)850 public Set<Package> getPermittedAccessibilityServices(UserReference user) { 851 try (PermissionContext p = TestApis.permissions().withPermission(INTERACT_ACROSS_USERS, QUERY_ADMIN_POLICY)) { 852 List<String> services = sDevicePolicyManager.getPermittedAccessibilityServices(user.id()); 853 if (services == null) { 854 return null; 855 } 856 return services.stream() 857 .map(packageName -> TestApis.packages().find(packageName)) 858 .collect(Collectors.toSet()); 859 } 860 } 861 } 862