1 /* 2 * Copyright (C) 2015 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 package com.android.server.devicepolicy; 17 18 import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS; 19 import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL; 20 import static android.app.admin.DevicePolicyManager.WIPE_EUICC; 21 import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY; 22 import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY; 23 import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED; 24 25 import static com.android.server.testutis.TestUtils.assertExpectException; 26 27 import static org.mockito.Matchers.any; 28 import static org.mockito.Matchers.anyInt; 29 import static org.mockito.Matchers.anyLong; 30 import static org.mockito.Matchers.anyObject; 31 import static org.mockito.Matchers.anyString; 32 import static org.mockito.Matchers.eq; 33 import static org.mockito.Matchers.isNull; 34 import static org.mockito.Mockito.atLeast; 35 import static org.mockito.Mockito.doAnswer; 36 import static org.mockito.Mockito.doReturn; 37 import static org.mockito.Mockito.mock; 38 import static org.mockito.Mockito.never; 39 import static org.mockito.Mockito.nullable; 40 import static org.mockito.Mockito.reset; 41 import static org.mockito.Mockito.timeout; 42 import static org.mockito.Mockito.times; 43 import static org.mockito.Mockito.verify; 44 import static org.mockito.Mockito.verifyZeroInteractions; 45 import static org.mockito.Mockito.when; 46 import static org.mockito.hamcrest.MockitoHamcrest.argThat; 47 48 import android.Manifest.permission; 49 import android.app.Activity; 50 import android.app.Notification; 51 import android.app.admin.DeviceAdminReceiver; 52 import android.app.admin.DevicePolicyManager; 53 import android.app.admin.DevicePolicyManagerInternal; 54 import android.app.admin.PasswordMetrics; 55 import android.content.BroadcastReceiver; 56 import android.content.ComponentName; 57 import android.content.Context; 58 import android.content.Intent; 59 import android.content.pm.ApplicationInfo; 60 import android.content.pm.PackageInfo; 61 import android.content.pm.PackageManager; 62 import android.content.pm.StringParceledListSlice; 63 import android.content.pm.UserInfo; 64 import android.graphics.Color; 65 import android.net.Uri; 66 import android.net.wifi.WifiInfo; 67 import android.os.Build.VERSION_CODES; 68 import android.os.Bundle; 69 import android.os.Process; 70 import android.os.UserHandle; 71 import android.os.UserManager; 72 import android.platform.test.annotations.Presubmit; 73 import android.provider.Settings; 74 import android.security.KeyChain; 75 import android.telephony.TelephonyManager; 76 import android.test.MoreAsserts; 77 import android.test.suitebuilder.annotation.SmallTest; 78 import android.util.ArraySet; 79 import android.util.Pair; 80 81 import com.android.internal.R; 82 import com.android.internal.widget.LockPatternUtils; 83 import com.android.server.LocalServices; 84 import com.android.server.SystemService; 85 import com.android.server.pm.UserRestrictionsUtils; 86 87 import org.hamcrest.BaseMatcher; 88 import org.hamcrest.Description; 89 import org.mockito.invocation.InvocationOnMock; 90 import org.mockito.stubbing.Answer; 91 92 import java.util.ArrayList; 93 import java.util.Arrays; 94 import java.util.Collections; 95 import java.util.HashMap; 96 import java.util.List; 97 import java.util.Map; 98 import java.util.Set; 99 import java.util.concurrent.TimeUnit; 100 101 /** 102 * Tests for DevicePolicyManager( and DevicePolicyManagerService). 103 * You can run them via: 104 m FrameworksServicesTests && 105 adb install \ 106 -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && 107 adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest \ 108 -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner 109 110 (mmma frameworks/base/services/tests/servicestests/ for non-ninja build) 111 * 112 * , or: 113 * runtest -c com.android.server.devicepolicy.DevicePolicyManagerTest frameworks-services 114 */ 115 @SmallTest 116 @Presubmit 117 public class DevicePolicyManagerTest extends DpmTestBase { 118 private static final List<String> OWNER_SETUP_PERMISSIONS = Arrays.asList( 119 permission.MANAGE_DEVICE_ADMINS, permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, 120 permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL); 121 public static final String NOT_DEVICE_OWNER_MSG = "does not own the device"; 122 public static final String ONGOING_CALL_MSG = "ongoing call on the device"; 123 124 // TODO replace all instances of this with explicit {@link #mServiceContext}. 125 @Deprecated 126 private DpmMockContext mContext; 127 128 private DpmMockContext mServiceContext; 129 private DpmMockContext mAdmin1Context; 130 public DevicePolicyManager dpm; 131 public DevicePolicyManagerServiceTestable dpms; 132 133 /* 134 * The CA cert below is the content of cacert.pem as generated by: 135 * 136 * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem 137 */ 138 private static final String TEST_CA = 139 "-----BEGIN CERTIFICATE-----\n" + 140 "MIIDXTCCAkWgAwIBAgIJAK9Tl/F9V8kSMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n" + 141 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n" + 142 "aWRnaXRzIFB0eSBMdGQwHhcNMTUwMzA2MTczMjExWhcNMjUwMzAzMTczMjExWjBF\n" + 143 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n" + 144 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" + 145 "CgKCAQEAvItOutsE75WBTgTyNAHt4JXQ3JoseaGqcC3WQij6vhrleWi5KJ0jh1/M\n" + 146 "Rpry7Fajtwwb4t8VZa0NuM2h2YALv52w1xivql88zce/HU1y7XzbXhxis9o6SCI+\n" + 147 "oVQSbPeXRgBPppFzBEh3ZqYTVhAqw451XhwdA4Aqs3wts7ddjwlUzyMdU44osCUg\n" + 148 "kVg7lfPf9sTm5IoHVcfLSCWH5n6Nr9sH3o2ksyTwxuOAvsN11F/a0mmUoPciYPp+\n" + 149 "q7DzQzdi7akRG601DZ4YVOwo6UITGvDyuAAdxl5isovUXqe6Jmz2/myTSpAKxGFs\n" + 150 "jk9oRoG6WXWB1kni490GIPjJ1OceyQIDAQABo1AwTjAdBgNVHQ4EFgQUH1QIlPKL\n" + 151 "p2OQ/AoLOjKvBW4zK3AwHwYDVR0jBBgwFoAUH1QIlPKLp2OQ/AoLOjKvBW4zK3Aw\n" + 152 "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcMi4voMMJHeQLjtq8Oky\n" + 153 "Azpyk8moDwgCd4llcGj7izOkIIFqq/lyqKdtykVKUWz2bSHO5cLrtaOCiBWVlaCV\n" + 154 "DYAnnVLM8aqaA6hJDIfaGs4zmwz0dY8hVMFCuCBiLWuPfiYtbEmjHGSmpQTG6Qxn\n" + 155 "ZJlaK5CZyt5pgh5EdNdvQmDEbKGmu0wpCq9qjZImwdyAul1t/B0DrsWApZMgZpeI\n" + 156 "d2od0VBrCICB1K4p+C51D93xyQiva7xQcCne+TAnGNy9+gjQ/MyR8MRpwRLv5ikD\n" + 157 "u0anJCN8pXo6IMglfMAsoton1J6o5/ae5uhC6caQU8bNUsCK570gpNfjkzo6rbP0\n" + 158 "wQ==\n" + 159 "-----END CERTIFICATE-----\n"; 160 161 @Override 162 protected void setUp() throws Exception { 163 super.setUp(); 164 165 mContext = getContext(); 166 mServiceContext = mContext; 167 mServiceContext.binder.callingUid = DpmMockContext.CALLER_UID; 168 when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN))) 169 .thenReturn(true); 170 171 // By default, pretend all users are running and unlocked. 172 when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true); 173 174 initializeDpms(); 175 176 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 177 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 178 setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID); 179 setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID); 180 181 mAdmin1Context = new DpmMockContext(getServices(), mRealTestContext); 182 mAdmin1Context.packageName = admin1.getPackageName(); 183 mAdmin1Context.applicationInfo = new ApplicationInfo(); 184 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID; 185 186 setUpUserManager(); 187 } 188 189 @Override 190 protected void tearDown() throws Exception { 191 flushTasks(); 192 super.tearDown(); 193 } 194 195 private void initializeDpms() { 196 // Need clearCallingIdentity() to pass permission checks. 197 final long ident = mContext.binder.clearCallingIdentity(); 198 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); 199 200 dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext); 201 dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY); 202 dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED); 203 204 dpm = new DevicePolicyManagerTestable(mContext, dpms); 205 206 mContext.binder.restoreCallingIdentity(ident); 207 } 208 209 private void setUpUserManager() { 210 // Emulate UserManager.set/getApplicationRestriction(). 211 final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>(); 212 213 // UM.setApplicationRestrictions() will save to appRestrictions. 214 doAnswer(new Answer<Void>() { 215 @Override 216 public Void answer(InvocationOnMock invocation) throws Throwable { 217 String pkg = (String) invocation.getArguments()[0]; 218 Bundle bundle = (Bundle) invocation.getArguments()[1]; 219 UserHandle user = (UserHandle) invocation.getArguments()[2]; 220 221 appRestrictions.put(Pair.create(pkg, user), bundle); 222 223 return null; 224 } 225 }).when(getServices().userManager).setApplicationRestrictions( 226 anyString(), nullable(Bundle.class), any(UserHandle.class)); 227 228 // UM.getApplicationRestrictions() will read from appRestrictions. 229 doAnswer(new Answer<Bundle>() { 230 @Override 231 public Bundle answer(InvocationOnMock invocation) throws Throwable { 232 String pkg = (String) invocation.getArguments()[0]; 233 UserHandle user = (UserHandle) invocation.getArguments()[1]; 234 235 return appRestrictions.get(Pair.create(pkg, user)); 236 } 237 }).when(getServices().userManager).getApplicationRestrictions( 238 anyString(), any(UserHandle.class)); 239 240 // Add the first secondary user. 241 getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0); 242 } 243 244 private void setAsProfileOwner(ComponentName admin) { 245 final long ident = mServiceContext.binder.clearCallingIdentity(); 246 247 mServiceContext.binder.callingUid = 248 UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); 249 runAsCaller(mServiceContext, dpms, dpm -> { 250 // PO needs to be a DA. 251 dpm.setActiveAdmin(admin, /*replace=*/ false); 252 // Fire! 253 assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE)); 254 // Check 255 assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE)); 256 }); 257 258 mServiceContext.binder.restoreCallingIdentity(ident); 259 } 260 261 public void testHasNoFeature() throws Exception { 262 when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN))) 263 .thenReturn(false); 264 265 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); 266 new DevicePolicyManagerServiceTestable(getServices(), mContext); 267 268 // If the device has no DPMS feature, it shouldn't register the local service. 269 assertNull(LocalServices.getService(DevicePolicyManagerInternal.class)); 270 } 271 272 /** 273 * Caller doesn't have proper permissions. 274 */ 275 public void testSetActiveAdmin_SecurityException() { 276 // 1. Failure cases. 277 278 // Caller doesn't have MANAGE_DEVICE_ADMINS. 279 assertExpectException(SecurityException.class, /* messageRegex= */ null, 280 () -> dpm.setActiveAdmin(admin1, false)); 281 282 // Caller has MANAGE_DEVICE_ADMINS, but for different user. 283 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 284 285 assertExpectException(SecurityException.class, /* messageRegex= */ null, 286 () -> dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1)); 287 } 288 289 /** 290 * Test for: 291 * {@link DevicePolicyManager#setActiveAdmin} 292 * with replace=false and replace=true 293 * {@link DevicePolicyManager#isAdminActive} 294 * {@link DevicePolicyManager#isAdminActiveAsUser} 295 * {@link DevicePolicyManager#getActiveAdmins} 296 * {@link DevicePolicyManager#getActiveAdminsAsUser} 297 */ 298 public void testSetActiveAdmin() throws Exception { 299 // 1. Make sure the caller has proper permissions. 300 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 301 302 // 2. Call the API. 303 dpm.setActiveAdmin(admin1, /* replace =*/ false); 304 305 // 3. Verify internal calls. 306 307 // Check if the boradcast is sent. 308 verify(mContext.spiedContext).sendBroadcastAsUser( 309 MockUtils.checkIntentAction( 310 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 311 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE)); 312 verify(mContext.spiedContext).sendBroadcastAsUser( 313 MockUtils.checkIntentAction( 314 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED), 315 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE)); 316 317 verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting( 318 eq(admin1.getPackageName()), 319 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT), 320 eq(PackageManager.DONT_KILL_APP), 321 eq(DpmMockContext.CALLER_USER_HANDLE), 322 anyString()); 323 324 // TODO Verify other calls too. 325 326 // Make sure it's active admin1. 327 assertTrue(dpm.isAdminActive(admin1)); 328 assertFalse(dpm.isAdminActive(admin2)); 329 assertFalse(dpm.isAdminActive(admin3)); 330 331 // But not admin1 for a different user. 332 333 // For this to work, caller needs android.permission.INTERACT_ACROSS_USERS_FULL. 334 // (Because we're checking a different user's status from CALLER_USER_HANDLE.) 335 mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL"); 336 337 assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE + 1)); 338 assertFalse(dpm.isAdminActiveAsUser(admin2, DpmMockContext.CALLER_USER_HANDLE + 1)); 339 340 mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL"); 341 342 // Next, add one more admin. 343 // Before doing so, update the application info, now it's enabled. 344 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID, 345 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); 346 347 dpm.setActiveAdmin(admin2, /* replace =*/ false); 348 349 // Now we have two admins. 350 assertTrue(dpm.isAdminActive(admin1)); 351 assertTrue(dpm.isAdminActive(admin2)); 352 assertFalse(dpm.isAdminActive(admin3)); 353 354 // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called 355 // again. (times(1) because it was previously called for admin1) 356 verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting( 357 eq(admin1.getPackageName()), 358 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT), 359 eq(PackageManager.DONT_KILL_APP), 360 eq(DpmMockContext.CALLER_USER_HANDLE), 361 anyString()); 362 363 // 4. Add the same admin1 again without replace, which should throw. 364 assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null, 365 () -> dpm.setActiveAdmin(admin1, /* replace =*/ false)); 366 367 // 5. Add the same admin1 again with replace, which should succeed. 368 dpm.setActiveAdmin(admin1, /* replace =*/ true); 369 370 // TODO make sure it's replaced. 371 372 // 6. Test getActiveAdmins() 373 List<ComponentName> admins = dpm.getActiveAdmins(); 374 assertEquals(2, admins.size()); 375 assertEquals(admin1, admins.get(0)); 376 assertEquals(admin2, admins.get(1)); 377 378 // Another user has no admins. 379 mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL"); 380 381 assertEquals(0, DpmTestUtils.getListSizeAllowingNull( 382 dpm.getActiveAdminsAsUser(DpmMockContext.CALLER_USER_HANDLE + 1))); 383 384 mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL"); 385 } 386 387 public void testSetActiveAdmin_multiUsers() throws Exception { 388 389 final int ANOTHER_USER_ID = 100; 390 final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 20456); 391 392 getServices().addUser(ANOTHER_USER_ID, 0); // Add one more user. 393 394 // Set up pacakge manager for the other user. 395 setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID); 396 397 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 398 399 dpm.setActiveAdmin(admin1, /* replace =*/ false); 400 401 mMockContext.binder.callingUid = ANOTHER_ADMIN_UID; 402 dpm.setActiveAdmin(admin2, /* replace =*/ false); 403 404 405 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 406 assertTrue(dpm.isAdminActive(admin1)); 407 assertFalse(dpm.isAdminActive(admin2)); 408 409 mMockContext.binder.callingUid = ANOTHER_ADMIN_UID; 410 assertFalse(dpm.isAdminActive(admin1)); 411 assertTrue(dpm.isAdminActive(admin2)); 412 } 413 414 /** 415 * Test for: 416 * {@link DevicePolicyManager#setActiveAdmin} 417 * with replace=false 418 */ 419 public void testSetActiveAdmin_twiceWithoutReplace() throws Exception { 420 // 1. Make sure the caller has proper permissions. 421 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 422 423 dpm.setActiveAdmin(admin1, /* replace =*/ false); 424 assertTrue(dpm.isAdminActive(admin1)); 425 426 // Add the same admin1 again without replace, which should throw. 427 assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null, 428 () -> dpm.setActiveAdmin(admin1, /* replace =*/ false)); 429 } 430 431 /** 432 * Test for: 433 * {@link DevicePolicyManager#setActiveAdmin} when the admin isn't protected with 434 * BIND_DEVICE_ADMIN. 435 */ 436 public void testSetActiveAdmin_permissionCheck() throws Exception { 437 // 1. Make sure the caller has proper permissions. 438 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 439 440 assertExpectException(IllegalArgumentException.class, 441 /* messageRegex= */ permission.BIND_DEVICE_ADMIN, 442 () -> dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false)); 443 assertFalse(dpm.isAdminActive(adminNoPerm)); 444 445 // Change the target API level to MNC. Now it can be set as DA. 446 setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID, null, 447 VERSION_CODES.M); 448 dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false); 449 assertTrue(dpm.isAdminActive(adminNoPerm)); 450 451 // TODO Test the "load from the file" case where DA will still be loaded even without 452 // BIND_DEVICE_ADMIN and target API is N. 453 } 454 455 /** 456 * Test for: 457 * {@link DevicePolicyManager#removeActiveAdmin} 458 */ 459 public void testRemoveActiveAdmin_SecurityException() { 460 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 461 462 // Add admin. 463 464 dpm.setActiveAdmin(admin1, /* replace =*/ false); 465 466 assertTrue(dpm.isAdminActive(admin1)); 467 468 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 469 470 // Directly call the DPMS method with a different userid, which should fail. 471 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 472 () -> dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1)); 473 474 // Try to remove active admin with a different caller userid should fail too, without 475 // having MANAGE_DEVICE_ADMINS. 476 mContext.callerPermissions.clear(); 477 478 // Change the caller, and call into DPMS directly with a different user-id. 479 480 mContext.binder.callingUid = 1234567; 481 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 482 () -> dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 483 } 484 485 /** 486 * {@link DevicePolicyManager#removeActiveAdmin} should fail with the user is not unlocked 487 * (because we can't send the remove broadcast). 488 */ 489 public void testRemoveActiveAdmin_userNotRunningOrLocked() { 490 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 491 492 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 493 494 // Add admin. 495 496 dpm.setActiveAdmin(admin1, /* replace =*/ false); 497 498 assertTrue(dpm.isAdminActive(admin1)); 499 500 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 501 502 // 1. User not unlocked. 503 when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE))) 504 .thenReturn(false); 505 assertExpectException(IllegalStateException.class, 506 /* messageRegex= */ "User must be running and unlocked", 507 () -> dpm.removeActiveAdmin(admin1)); 508 509 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 510 511 // 2. User unlocked. 512 when(getServices().userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE))) 513 .thenReturn(true); 514 515 dpm.removeActiveAdmin(admin1); 516 assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE)); 517 } 518 519 /** 520 * Test for: 521 * {@link DevicePolicyManager#removeActiveAdmin} 522 */ 523 public void testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL() { 524 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 525 526 // Add admin1. 527 528 dpm.setActiveAdmin(admin1, /* replace =*/ false); 529 530 assertTrue(dpm.isAdminActive(admin1)); 531 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 532 533 // Different user, but should work, because caller has proper permissions. 534 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 535 536 // Change the caller, and call into DPMS directly with a different user-id. 537 mContext.binder.callingUid = 1234567; 538 539 dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE); 540 assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE)); 541 542 // TODO DO Still can't be removed in this case. 543 } 544 545 /** 546 * Test for: 547 * {@link DevicePolicyManager#removeActiveAdmin} 548 */ 549 public void testRemoveActiveAdmin_sameUserNoMANAGE_DEVICE_ADMINS() { 550 // Need MANAGE_DEVICE_ADMINS for setActiveAdmin. We'll remove it later. 551 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 552 553 // Add admin1. 554 555 dpm.setActiveAdmin(admin1, /* replace =*/ false); 556 557 assertTrue(dpm.isAdminActive(admin1)); 558 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 559 560 // Broadcast from saveSettingsLocked(). 561 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 562 MockUtils.checkIntentAction( 563 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 564 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE)); 565 566 // Remove. No permissions, but same user, so it'll work. 567 mContext.callerPermissions.clear(); 568 dpm.removeActiveAdmin(admin1); 569 570 verify(mContext.spiedContext).sendOrderedBroadcastAsUser( 571 MockUtils.checkIntentAction( 572 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED), 573 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE), 574 isNull(String.class), 575 any(BroadcastReceiver.class), 576 eq(dpms.mHandler), 577 eq(Activity.RESULT_OK), 578 isNull(String.class), 579 isNull(Bundle.class)); 580 581 assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE)); 582 583 // Again broadcast from saveSettingsLocked(). 584 verify(mContext.spiedContext, times(2)).sendBroadcastAsUser( 585 MockUtils.checkIntentAction( 586 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 587 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE)); 588 589 // TODO Check other internal calls. 590 } 591 592 /** 593 * Test for: @{link DevicePolicyManager#setActivePasswordState} 594 * 595 * Validates that when the password for a user changes, the notification broadcast intent 596 * {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is sent to managed profile owners, in 597 * addition to ones in the original user. 598 */ 599 public void testSetActivePasswordState_sendToProfiles() throws Exception { 600 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 601 602 final int MANAGED_PROFILE_USER_ID = 78; 603 final int MANAGED_PROFILE_ADMIN_UID = 604 UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID); 605 606 // Setup device owner. 607 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 608 mContext.packageName = admin1.getPackageName(); 609 setupDeviceOwner(); 610 611 // Add a managed profile belonging to the system user. 612 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 613 614 // Change the parent user's password. 615 dpm.reportPasswordChanged(UserHandle.USER_SYSTEM); 616 617 // Both the device owner and the managed profile owner should receive this broadcast. 618 final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED); 619 intent.setComponent(admin1); 620 intent.putExtra(Intent.EXTRA_USER, UserHandle.of(UserHandle.USER_SYSTEM)); 621 622 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 623 MockUtils.checkIntent(intent), 624 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 625 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 626 MockUtils.checkIntent(intent), 627 MockUtils.checkUserHandle(MANAGED_PROFILE_USER_ID)); 628 } 629 630 /** 631 * Test for: @{link DevicePolicyManager#setActivePasswordState} 632 * 633 * Validates that when the password for a managed profile changes, the notification broadcast 634 * intent {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is only sent to the profile, not 635 * its parent. 636 */ 637 public void testSetActivePasswordState_notSentToParent() throws Exception { 638 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 639 640 final int MANAGED_PROFILE_USER_ID = 78; 641 final int MANAGED_PROFILE_ADMIN_UID = 642 UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID); 643 644 // Setup device owner. 645 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 646 mContext.packageName = admin1.getPackageName(); 647 doReturn(true).when(getServices().lockPatternUtils) 648 .isSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID); 649 setupDeviceOwner(); 650 651 // Add a managed profile belonging to the system user. 652 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 653 654 // Change the profile's password. 655 dpm.reportPasswordChanged(MANAGED_PROFILE_USER_ID); 656 657 // Both the device owner and the managed profile owner should receive this broadcast. 658 final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED); 659 intent.setComponent(admin1); 660 intent.putExtra(Intent.EXTRA_USER, UserHandle.of(MANAGED_PROFILE_USER_ID)); 661 662 verify(mContext.spiedContext, never()).sendBroadcastAsUser( 663 MockUtils.checkIntent(intent), 664 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 665 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 666 MockUtils.checkIntent(intent), 667 MockUtils.checkUserHandle(MANAGED_PROFILE_USER_ID)); 668 } 669 /** 670 * Test for: {@link DevicePolicyManager#setDeviceOwner} DO on system user installs successfully. 671 */ 672 public void testSetDeviceOwner() throws Exception { 673 setDeviceOwner(); 674 675 // Try to set a profile owner on the same user, which should fail. 676 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID); 677 dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM); 678 assertExpectException(IllegalStateException.class, 679 /* messageRegex= */ "already has a device owner", 680 () -> dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM)); 681 682 // DO admin can't be deactivated. 683 dpm.removeActiveAdmin(admin1); 684 assertTrue(dpm.isAdminActive(admin1)); 685 686 // TODO Test getDeviceOwnerName() too. To do so, we need to change 687 // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable. 688 } 689 690 private void setDeviceOwner() throws Exception { 691 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 692 mContext.callerPermissions.add(permission.MANAGE_USERS); 693 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 694 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 695 696 // In this test, change the caller user to "system". 697 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 698 699 // Make sure admin1 is installed on system user. 700 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 701 702 // Check various get APIs. 703 checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ false); 704 705 // DO needs to be an DA. 706 dpm.setActiveAdmin(admin1, /* replace =*/ false); 707 708 // Fire! 709 assertTrue(dpm.setDeviceOwner(admin1, "owner-name")); 710 711 // getDeviceOwnerComponent should return the admin1 component. 712 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 713 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 714 715 // Check various get APIs. 716 checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ true); 717 718 // getDeviceOwnerComponent should *NOT* return the admin1 component for other users. 719 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 720 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 721 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 722 723 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 724 725 // Verify internal calls. 726 verify(getServices().iactivityManager, times(1)).updateDeviceOwner( 727 eq(admin1.getPackageName())); 728 729 // TODO We should check if the caller has called clearCallerIdentity(). 730 verify(getServices().ibackupManager, times(1)).setBackupServiceActive( 731 eq(UserHandle.USER_SYSTEM), eq(false)); 732 733 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 734 MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED), 735 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 736 737 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 738 } 739 740 private void checkGetDeviceOwnerInfoApi(DevicePolicyManager dpm, boolean hasDeviceOwner) { 741 final int origCallingUser = mContext.binder.callingUid; 742 final List origPermissions = new ArrayList(mContext.callerPermissions); 743 mContext.callerPermissions.clear(); 744 745 mContext.callerPermissions.add(permission.MANAGE_USERS); 746 747 mContext.binder.callingUid = Process.SYSTEM_UID; 748 749 // TODO Test getDeviceOwnerName() too. To do so, we need to change 750 // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable. 751 if (hasDeviceOwner) { 752 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 753 assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 754 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 755 756 assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 757 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 758 assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId()); 759 } else { 760 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 761 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 762 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 763 764 assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 765 assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser()); 766 assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId()); 767 } 768 769 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 770 if (hasDeviceOwner) { 771 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 772 assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 773 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 774 775 assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 776 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 777 assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId()); 778 } else { 779 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 780 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 781 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 782 783 assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 784 assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser()); 785 assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId()); 786 } 787 788 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 789 // Still with MANAGE_USERS. 790 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 791 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 792 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 793 794 if (hasDeviceOwner) { 795 assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 796 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 797 assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId()); 798 } else { 799 assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 800 assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser()); 801 assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId()); 802 } 803 804 mContext.binder.callingUid = Process.SYSTEM_UID; 805 mContext.callerPermissions.remove(permission.MANAGE_USERS); 806 // System can still call "OnAnyUser" without MANAGE_USERS. 807 if (hasDeviceOwner) { 808 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 809 assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 810 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 811 812 assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 813 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 814 assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId()); 815 } else { 816 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 817 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 818 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 819 820 assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 821 assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser()); 822 assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId()); 823 } 824 825 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 826 // Still no MANAGE_USERS. 827 if (hasDeviceOwner) { 828 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 829 assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 830 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 831 } else { 832 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 833 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 834 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 835 } 836 837 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 838 () -> dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 839 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 840 dpm::getDeviceOwnerComponentOnAnyUser); 841 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 842 dpm::getDeviceOwnerUserId); 843 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 844 dpm::getDeviceOwnerNameOnAnyUser); 845 846 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 847 // Still no MANAGE_USERS. 848 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 849 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 850 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 851 852 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 853 () -> dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 854 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 855 dpm::getDeviceOwnerComponentOnAnyUser); 856 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 857 dpm::getDeviceOwnerUserId); 858 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 859 dpm::getDeviceOwnerNameOnAnyUser); 860 861 // Restore. 862 mContext.binder.callingUid = origCallingUser; 863 mContext.callerPermissions.addAll(origPermissions); 864 } 865 866 867 /** 868 * Test for: {@link DevicePolicyManager#setDeviceOwner} Package doesn't exist. 869 */ 870 public void testSetDeviceOwner_noSuchPackage() { 871 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 872 mContext.callerPermissions.add(permission.MANAGE_USERS); 873 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 874 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 875 876 // Call from a process on the system user. 877 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 878 879 assertExpectException(IllegalArgumentException.class, 880 /* messageRegex= */ "Invalid component", 881 () -> dpm.setDeviceOwner(new ComponentName("a.b.c", ".def"))); 882 } 883 884 public void testSetDeviceOwner_failures() throws Exception { 885 // TODO Test more failure cases. Basically test all chacks in enforceCanSetDeviceOwner(). 886 } 887 888 public void testClearDeviceOwner() throws Exception { 889 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 890 mContext.callerPermissions.add(permission.MANAGE_USERS); 891 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 892 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 893 894 // Set admin1 as a DA to the secondary user. 895 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 896 897 dpm.setActiveAdmin(admin1, /* replace =*/ false); 898 899 // Set admin 1 as the DO to the system user. 900 901 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 902 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 903 dpm.setActiveAdmin(admin1, /* replace =*/ false); 904 assertTrue(dpm.setDeviceOwner(admin1, "owner-name")); 905 906 // Verify internal calls. 907 verify(getServices().iactivityManager, times(1)).updateDeviceOwner( 908 eq(admin1.getPackageName())); 909 910 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 911 912 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 913 when(getServices().userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER), 914 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM))).thenReturn(true); 915 916 assertTrue(dpm.isAdminActive(admin1)); 917 assertFalse(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM)); 918 919 // Set up other mocks. 920 when(getServices().userManager.getUserRestrictions()).thenReturn(new Bundle()); 921 922 // Now call clear. 923 doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager). 924 getPackageUidAsUser(eq(admin1.getPackageName()), anyInt()); 925 926 // But first pretend the user is locked. Then it should fail. 927 when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(false); 928 assertExpectException(IllegalStateException.class, 929 /* messageRegex= */ "User must be running and unlocked", 930 () -> dpm.clearDeviceOwnerApp(admin1.getPackageName())); 931 932 when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true); 933 reset(getServices().userManagerInternal); 934 dpm.clearDeviceOwnerApp(admin1.getPackageName()); 935 936 // Now DO shouldn't be set. 937 assertNull(dpm.getDeviceOwnerComponentOnAnyUser()); 938 939 verify(getServices().userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER), 940 eq(false), 941 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 942 943 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 944 eq(UserHandle.USER_SYSTEM), 945 eq(null), 946 eq(true), eq(CAMERA_NOT_DISABLED)); 947 948 assertFalse(dpm.isAdminActiveAsUser(admin1, UserHandle.USER_SYSTEM)); 949 950 // ACTION_DEVICE_OWNER_CHANGED should be sent twice, once for setting the device owner 951 // and once for clearing it. 952 verify(mContext.spiedContext, times(2)).sendBroadcastAsUser( 953 MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED), 954 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 955 // TODO Check other calls. 956 } 957 958 public void testClearDeviceOwner_fromDifferentUser() throws Exception { 959 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 960 mContext.callerPermissions.add(permission.MANAGE_USERS); 961 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 962 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 963 964 // Set admin1 as a DA to the secondary user. 965 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 966 967 dpm.setActiveAdmin(admin1, /* replace =*/ false); 968 969 // Set admin 1 as the DO to the system user. 970 971 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 972 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 973 dpm.setActiveAdmin(admin1, /* replace =*/ false); 974 assertTrue(dpm.setDeviceOwner(admin1, "owner-name")); 975 976 // Verify internal calls. 977 verify(getServices().iactivityManager, times(1)).updateDeviceOwner( 978 eq(admin1.getPackageName())); 979 980 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 981 982 // Now call clear from the secondary user, which should throw. 983 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 984 985 // Now call clear. 986 doReturn(DpmMockContext.CALLER_UID).when(getServices().packageManager).getPackageUidAsUser( 987 eq(admin1.getPackageName()), 988 anyInt()); 989 assertExpectException(SecurityException.class, 990 /* messageRegex =*/ "clearDeviceOwner can only be called by the device owner", 991 () -> dpm.clearDeviceOwnerApp(admin1.getPackageName())); 992 993 // DO shouldn't be removed. 994 assertTrue(dpm.isDeviceManaged()); 995 } 996 997 public void testSetProfileOwner() throws Exception { 998 setAsProfileOwner(admin1); 999 1000 // PO admin can't be deactivated. 1001 dpm.removeActiveAdmin(admin1); 1002 assertTrue(dpm.isAdminActive(admin1)); 1003 1004 // Try setting DO on the same user, which should fail. 1005 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 1006 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 1007 runAsCaller(mServiceContext, dpms, dpm -> { 1008 dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE); 1009 assertExpectException(IllegalStateException.class, 1010 /* messageRegex= */ "already has a profile owner", 1011 () -> dpm.setDeviceOwner(admin2, "owner-name", 1012 DpmMockContext.CALLER_USER_HANDLE)); 1013 }); 1014 } 1015 1016 public void testClearProfileOwner() throws Exception { 1017 setAsProfileOwner(admin1); 1018 1019 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1020 1021 assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName())); 1022 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 1023 1024 // First try when the user is locked, which should fail. 1025 when(getServices().userManager.isUserUnlocked(anyInt())) 1026 .thenReturn(false); 1027 assertExpectException(IllegalStateException.class, 1028 /* messageRegex= */ "User must be running and unlocked", 1029 () -> dpm.clearProfileOwner(admin1)); 1030 1031 // Clear, really. 1032 when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true); 1033 dpm.clearProfileOwner(admin1); 1034 1035 // Check 1036 assertFalse(dpm.isProfileOwnerApp(admin1.getPackageName())); 1037 assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE)); 1038 } 1039 1040 public void testSetProfileOwner_failures() throws Exception { 1041 // TODO Test more failure cases. Basically test all chacks in enforceCanSetProfileOwner(). 1042 } 1043 1044 public void testGetDeviceOwnerAdminLocked() throws Exception { 1045 checkDeviceOwnerWithMultipleDeviceAdmins(); 1046 } 1047 1048 private void checkDeviceOwnerWithMultipleDeviceAdmins() throws Exception { 1049 // In ths test, we use 3 users (system + 2 secondary users), set some device admins to them, 1050 // set admin2 on CALLER_USER_HANDLE as DO, then call getDeviceOwnerAdminLocked() to 1051 // make sure it gets the right component from the right user. 1052 1053 final int ANOTHER_USER_ID = 100; 1054 final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 456); 1055 1056 getServices().addUser(ANOTHER_USER_ID, 0); // Add one more user. 1057 1058 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1059 mContext.callerPermissions.add(permission.MANAGE_USERS); 1060 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1061 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1062 1063 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1064 1065 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 1066 1067 // Make sure the admin packge is installed to each user. 1068 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1069 setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_SYSTEM_USER_UID); 1070 1071 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 1072 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 1073 1074 setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID); 1075 1076 1077 // Set active admins to the users. 1078 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1079 dpm.setActiveAdmin(admin3, /* replace =*/ false); 1080 1081 dpm.setActiveAdmin(admin1, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE); 1082 dpm.setActiveAdmin(admin2, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE); 1083 1084 dpm.setActiveAdmin(admin2, /* replace =*/ false, ANOTHER_USER_ID); 1085 1086 // Set DO on the first non-system user. 1087 getServices().setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true); 1088 assertTrue(dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE)); 1089 1090 assertEquals(admin2, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false)); 1091 1092 // Then check getDeviceOwnerAdminLocked(). 1093 assertEquals(admin2, dpms.getDeviceOwnerAdminLocked().info.getComponent()); 1094 assertEquals(DpmMockContext.CALLER_UID, dpms.getDeviceOwnerAdminLocked().getUid()); 1095 } 1096 1097 /** 1098 * This essentially tests 1099 * {@code DevicePolicyManagerService.findOwnerComponentIfNecessaryLocked()}. (which is 1100 * private.) 1101 * 1102 * We didn't use to persist the DO component class name, but now we do, and the above method 1103 * finds the right component from a package name upon migration. 1104 */ 1105 public void testDeviceOwnerMigration() throws Exception { 1106 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 1107 checkDeviceOwnerWithMultipleDeviceAdmins(); 1108 1109 // Overwrite the device owner setting and clears the clas name. 1110 dpms.mOwners.setDeviceOwner( 1111 new ComponentName(admin2.getPackageName(), ""), 1112 "owner-name", DpmMockContext.CALLER_USER_HANDLE); 1113 dpms.mOwners.writeDeviceOwner(); 1114 1115 // Make sure the DO component name doesn't have a class name. 1116 assertEquals("", dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false).getClassName()); 1117 1118 // Then create a new DPMS to have it load the settings from files. 1119 when(getServices().userManager.getUserRestrictions(any(UserHandle.class))) 1120 .thenReturn(new Bundle()); 1121 initializeDpms(); 1122 1123 // Now the DO component name is a full name. 1124 // *BUT* because both admin1 and admin2 belong to the same package, we think admin1 is the 1125 // DO. 1126 assertEquals(admin1, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false)); 1127 } 1128 1129 public void testSetGetApplicationRestriction() { 1130 setAsProfileOwner(admin1); 1131 mContext.packageName = admin1.getPackageName(); 1132 1133 { 1134 Bundle rest = new Bundle(); 1135 rest.putString("KEY_STRING", "Foo1"); 1136 dpm.setApplicationRestrictions(admin1, "pkg1", rest); 1137 } 1138 1139 { 1140 Bundle rest = new Bundle(); 1141 rest.putString("KEY_STRING", "Foo2"); 1142 dpm.setApplicationRestrictions(admin1, "pkg2", rest); 1143 } 1144 1145 { 1146 Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg1"); 1147 assertNotNull(returned); 1148 assertEquals(returned.size(), 1); 1149 assertEquals(returned.get("KEY_STRING"), "Foo1"); 1150 } 1151 1152 { 1153 Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg2"); 1154 assertNotNull(returned); 1155 assertEquals(returned.size(), 1); 1156 assertEquals(returned.get("KEY_STRING"), "Foo2"); 1157 } 1158 1159 dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle()); 1160 assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg2").size()); 1161 } 1162 1163 /** 1164 * Setup a package in the package manager mock for {@link DpmMockContext#CALLER_USER_HANDLE}. 1165 * Useful for faking installed applications. 1166 * 1167 * @param packageName the name of the package to be setup 1168 * @param appId the application ID to be given to the package 1169 * @return the UID of the package as known by the mock package manager 1170 */ 1171 private int setupPackageInPackageManager(final String packageName, final int appId) 1172 throws Exception { 1173 return setupPackageInPackageManager(packageName, DpmMockContext.CALLER_USER_HANDLE, appId, 1174 ApplicationInfo.FLAG_HAS_CODE); 1175 } 1176 1177 /** 1178 * Setup a package in the package manager mock. Useful for faking installed applications. 1179 * 1180 * @param packageName the name of the package to be setup 1181 * @param userId the user id where the package will be "installed" 1182 * @param appId the application ID to be given to the package 1183 * @param flags flags to set in the ApplicationInfo for this package 1184 * @return the UID of the package as known by the mock package manager 1185 */ 1186 private int setupPackageInPackageManager(final String packageName, int userId, final int appId, 1187 int flags) throws Exception { 1188 final int uid = UserHandle.getUid(userId, appId); 1189 // Make the PackageManager return the package instead of throwing NameNotFoundException 1190 final PackageInfo pi = new PackageInfo(); 1191 pi.applicationInfo = new ApplicationInfo(); 1192 pi.applicationInfo.flags = flags; 1193 doReturn(pi).when(getServices().ipackageManager).getPackageInfo( 1194 eq(packageName), 1195 anyInt(), 1196 eq(userId)); 1197 doReturn(pi.applicationInfo).when(getServices().ipackageManager).getApplicationInfo( 1198 eq(packageName), 1199 anyInt(), 1200 eq(userId)); 1201 // Setup application UID with the PackageManager 1202 doReturn(uid).when(getServices().packageManager).getPackageUidAsUser( 1203 eq(packageName), 1204 eq(userId)); 1205 // Associate packageName to uid 1206 doReturn(packageName).when(getServices().ipackageManager).getNameForUid(eq(uid)); 1207 doReturn(new String[]{packageName}) 1208 .when(getServices().ipackageManager).getPackagesForUid(eq(uid)); 1209 return uid; 1210 } 1211 1212 public void testCertificateDisclosure() throws Exception { 1213 final int userId = DpmMockContext.CALLER_USER_HANDLE; 1214 final UserHandle user = UserHandle.of(userId); 1215 1216 mContext.applicationInfo = new ApplicationInfo(); 1217 mContext.callerPermissions.add(permission.MANAGE_USERS); 1218 mContext.packageName = "com.android.frameworks.servicestests"; 1219 getServices().addPackageContext(user, mContext); 1220 when(mContext.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE); 1221 1222 StringParceledListSlice oneCert = asSlice(new String[] {"1"}); 1223 StringParceledListSlice fourCerts = asSlice(new String[] {"1", "2", "3", "4"}); 1224 1225 final String TEST_STRING = "Test for exactly 2 certs out of 4"; 1226 doReturn(TEST_STRING).when(mContext.resources).getQuantityText(anyInt(), eq(2)); 1227 1228 // Given that we have exactly one certificate installed, 1229 when(getServices().keyChainConnection.getService().getUserCaAliases()).thenReturn(oneCert); 1230 // when that certificate is approved, 1231 dpms.approveCaCert(oneCert.getList().get(0), userId, true); 1232 // a notification should not be shown. 1233 verify(getServices().notificationManager, timeout(1000)) 1234 .cancelAsUser(anyString(), anyInt(), eq(user)); 1235 1236 // Given that we have four certificates installed, 1237 when(getServices().keyChainConnection.getService().getUserCaAliases()).thenReturn(fourCerts); 1238 // when two of them are approved (one of them approved twice hence no action), 1239 dpms.approveCaCert(fourCerts.getList().get(0), userId, true); 1240 dpms.approveCaCert(fourCerts.getList().get(1), userId, true); 1241 // a notification should be shown saying that there are two certificates left to approve. 1242 verify(getServices().notificationManager, timeout(1000)) 1243 .notifyAsUser(anyString(), anyInt(), argThat( 1244 new BaseMatcher<Notification>() { 1245 @Override 1246 public boolean matches(Object item) { 1247 final Notification noti = (Notification) item; 1248 return TEST_STRING.equals( 1249 noti.extras.getString(Notification.EXTRA_TITLE)); 1250 } 1251 @Override 1252 public void describeTo(Description description) { 1253 description.appendText( 1254 "Notification{title=\"" + TEST_STRING + "\"}"); 1255 } 1256 }), eq(user)); 1257 } 1258 1259 /** 1260 * Simple test for delegate set/get and general delegation. Tests verifying that delegated 1261 * privileges can acually be exercised by a delegate are not covered here. 1262 */ 1263 public void testDelegation() throws Exception { 1264 setAsProfileOwner(admin1); 1265 1266 final int userHandle = DpmMockContext.CALLER_USER_HANDLE; 1267 1268 // Given two packages 1269 final String CERT_DELEGATE = "com.delegate.certs"; 1270 final String RESTRICTIONS_DELEGATE = "com.delegate.apprestrictions"; 1271 final int CERT_DELEGATE_UID = setupPackageInPackageManager(CERT_DELEGATE, 20988); 1272 final int RESTRICTIONS_DELEGATE_UID = setupPackageInPackageManager(RESTRICTIONS_DELEGATE, 1273 20989); 1274 1275 // On delegation 1276 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1277 mContext.packageName = admin1.getPackageName(); 1278 dpm.setCertInstallerPackage(admin1, CERT_DELEGATE); 1279 dpm.setApplicationRestrictionsManagingPackage(admin1, RESTRICTIONS_DELEGATE); 1280 1281 // DPMS correctly stores and retrieves the delegates 1282 DevicePolicyManagerService.DevicePolicyData policy = dpms.mUserData.get(userHandle); 1283 assertEquals(2, policy.mDelegationMap.size()); 1284 MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(CERT_DELEGATE), 1285 DELEGATION_CERT_INSTALL); 1286 MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, CERT_DELEGATE), 1287 DELEGATION_CERT_INSTALL); 1288 assertEquals(CERT_DELEGATE, dpm.getCertInstallerPackage(admin1)); 1289 MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(RESTRICTIONS_DELEGATE), 1290 DELEGATION_APP_RESTRICTIONS); 1291 MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, RESTRICTIONS_DELEGATE), 1292 DELEGATION_APP_RESTRICTIONS); 1293 assertEquals(RESTRICTIONS_DELEGATE, dpm.getApplicationRestrictionsManagingPackage(admin1)); 1294 1295 // On calling install certificate APIs from an unauthorized process 1296 mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID; 1297 mContext.packageName = RESTRICTIONS_DELEGATE; 1298 1299 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1300 () -> dpm.installCaCert(null, null)); 1301 1302 // On calling install certificate APIs from an authorized process 1303 mContext.binder.callingUid = CERT_DELEGATE_UID; 1304 mContext.packageName = CERT_DELEGATE; 1305 1306 // DPMS executes without a SecurityException 1307 try { 1308 dpm.installCaCert(null, null); 1309 } catch (SecurityException unexpected) { 1310 fail("Threw SecurityException on authorized access"); 1311 } catch (NullPointerException expected) { 1312 } 1313 1314 // On removing a delegate 1315 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1316 mContext.packageName = admin1.getPackageName(); 1317 dpm.setCertInstallerPackage(admin1, null); 1318 1319 // DPMS does not allow access to ex-delegate 1320 mContext.binder.callingUid = CERT_DELEGATE_UID; 1321 mContext.packageName = CERT_DELEGATE; 1322 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1323 () -> dpm.installCaCert(null, null)); 1324 1325 // But still allows access to other existing delegates 1326 mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID; 1327 mContext.packageName = RESTRICTIONS_DELEGATE; 1328 try { 1329 dpm.getApplicationRestrictions(null, "pkg"); 1330 } catch (SecurityException expected) { 1331 fail("Threw SecurityException on authorized access"); 1332 } 1333 } 1334 1335 public void testApplicationRestrictionsManagingApp() throws Exception { 1336 setAsProfileOwner(admin1); 1337 1338 final String nonExistAppRestrictionsManagerPackage = "com.google.app.restrictions.manager2"; 1339 final String appRestrictionsManagerPackage = "com.google.app.restrictions.manager"; 1340 final String nonDelegateExceptionMessageRegex = 1341 "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions."; 1342 final int appRestrictionsManagerAppId = 20987; 1343 final int appRestrictionsManagerUid = setupPackageInPackageManager( 1344 appRestrictionsManagerPackage, appRestrictionsManagerAppId); 1345 1346 // appRestrictionsManager package shouldn't be able to manage restrictions as the PO hasn't 1347 // delegated that permission yet. 1348 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1349 mContext.packageName = admin1.getPackageName(); 1350 assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage()); 1351 final Bundle rest = new Bundle(); 1352 rest.putString("KEY_STRING", "Foo1"); 1353 assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex, 1354 () -> dpm.setApplicationRestrictions(null, "pkg1", rest)); 1355 1356 // Check via the profile owner that no restrictions were set. 1357 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1358 mContext.packageName = admin1.getPackageName(); 1359 assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size()); 1360 1361 // Check the API does not allow setting a non-existent package 1362 assertExpectException(PackageManager.NameNotFoundException.class, 1363 /* messageRegex= */ nonExistAppRestrictionsManagerPackage, 1364 () -> dpm.setApplicationRestrictionsManagingPackage( 1365 admin1, nonExistAppRestrictionsManagerPackage)); 1366 1367 // Let appRestrictionsManagerPackage manage app restrictions 1368 dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage); 1369 assertEquals(appRestrictionsManagerPackage, 1370 dpm.getApplicationRestrictionsManagingPackage(admin1)); 1371 1372 // Now that package should be able to set and retrieve app restrictions. 1373 mContext.binder.callingUid = appRestrictionsManagerUid; 1374 mContext.packageName = appRestrictionsManagerPackage; 1375 assertTrue(dpm.isCallerApplicationRestrictionsManagingPackage()); 1376 dpm.setApplicationRestrictions(null, "pkg1", rest); 1377 Bundle returned = dpm.getApplicationRestrictions(null, "pkg1"); 1378 assertEquals(1, returned.size(), 1); 1379 assertEquals("Foo1", returned.get("KEY_STRING")); 1380 1381 // The same app running on a separate user shouldn't be able to manage app restrictions. 1382 mContext.binder.callingUid = UserHandle.getUid( 1383 UserHandle.USER_SYSTEM, appRestrictionsManagerAppId); 1384 assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage()); 1385 assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex, 1386 () -> dpm.setApplicationRestrictions(null, "pkg1", rest)); 1387 1388 // The DPM is still able to manage app restrictions, even if it allowed another app to do it 1389 // too. 1390 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1391 mContext.packageName = admin1.getPackageName(); 1392 assertEquals(returned, dpm.getApplicationRestrictions(admin1, "pkg1")); 1393 dpm.setApplicationRestrictions(admin1, "pkg1", null); 1394 assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size()); 1395 1396 // Removing the ability for the package to manage app restrictions. 1397 dpm.setApplicationRestrictionsManagingPackage(admin1, null); 1398 assertNull(dpm.getApplicationRestrictionsManagingPackage(admin1)); 1399 mContext.binder.callingUid = appRestrictionsManagerUid; 1400 mContext.packageName = appRestrictionsManagerPackage; 1401 assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage()); 1402 assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex, 1403 () -> dpm.setApplicationRestrictions(null, "pkg1", null)); 1404 } 1405 1406 public void testSetUserRestriction_asDo() throws Exception { 1407 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1408 mContext.callerPermissions.add(permission.MANAGE_USERS); 1409 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1410 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1411 1412 // First, set DO. 1413 1414 // Call from a process on the system user. 1415 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1416 1417 // Make sure admin1 is installed on system user. 1418 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1419 1420 // Call. 1421 dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); 1422 assertTrue(dpm.setDeviceOwner(admin1, "owner-name", 1423 UserHandle.USER_SYSTEM)); 1424 1425 // Check that the user restrictions that are enabled by default are set. Then unset them. 1426 final String[] defaultRestrictions = UserRestrictionsUtils 1427 .getDefaultEnabledForDeviceOwner().toArray(new String[0]); 1428 DpmTestUtils.assertRestrictions( 1429 DpmTestUtils.newRestrictions(defaultRestrictions), 1430 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1431 ); 1432 DpmTestUtils.assertRestrictions( 1433 DpmTestUtils.newRestrictions(defaultRestrictions), 1434 dpm.getUserRestrictions(admin1) 1435 ); 1436 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1437 eq(UserHandle.USER_SYSTEM), 1438 MockUtils.checkUserRestrictions(defaultRestrictions), 1439 eq(true) /* isDeviceOwner */, 1440 eq(CAMERA_NOT_DISABLED) 1441 ); 1442 reset(getServices().userManagerInternal); 1443 1444 for (String restriction : defaultRestrictions) { 1445 dpm.clearUserRestriction(admin1, restriction); 1446 } 1447 1448 assertNoDeviceOwnerRestrictions(); 1449 reset(getServices().userManagerInternal); 1450 1451 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 1452 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1453 eq(UserHandle.USER_SYSTEM), 1454 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER), 1455 eq(true), eq(CAMERA_NOT_DISABLED)); 1456 reset(getServices().userManagerInternal); 1457 1458 dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 1459 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1460 eq(UserHandle.USER_SYSTEM), 1461 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS, 1462 UserManager.DISALLOW_ADD_USER), 1463 eq(true), eq(CAMERA_NOT_DISABLED)); 1464 reset(getServices().userManagerInternal); 1465 1466 DpmTestUtils.assertRestrictions( 1467 DpmTestUtils.newRestrictions( 1468 UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS), 1469 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1470 ); 1471 DpmTestUtils.assertRestrictions( 1472 DpmTestUtils.newRestrictions( 1473 UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS), 1474 dpm.getUserRestrictions(admin1) 1475 ); 1476 1477 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 1478 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1479 eq(UserHandle.USER_SYSTEM), 1480 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 1481 eq(true), eq(CAMERA_NOT_DISABLED)); 1482 reset(getServices().userManagerInternal); 1483 1484 DpmTestUtils.assertRestrictions( 1485 DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 1486 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1487 ); 1488 DpmTestUtils.assertRestrictions( 1489 DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 1490 dpm.getUserRestrictions(admin1) 1491 ); 1492 1493 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 1494 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1495 eq(UserHandle.USER_SYSTEM), 1496 MockUtils.checkUserRestrictions(), 1497 eq(true), eq(CAMERA_NOT_DISABLED)); 1498 reset(getServices().userManagerInternal); 1499 1500 assertNoDeviceOwnerRestrictions(); 1501 1502 // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE are PO restrictions, but when 1503 // DO sets them, the scope is global. 1504 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); 1505 reset(getServices().userManagerInternal); 1506 dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE); 1507 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1508 eq(UserHandle.USER_SYSTEM), 1509 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME, 1510 UserManager.DISALLOW_UNMUTE_MICROPHONE), 1511 eq(true), eq(CAMERA_NOT_DISABLED)); 1512 reset(getServices().userManagerInternal); 1513 1514 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); 1515 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE); 1516 reset(getServices().userManagerInternal); 1517 1518 // More tests. 1519 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 1520 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1521 eq(UserHandle.USER_SYSTEM), 1522 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER), 1523 eq(true), eq(CAMERA_NOT_DISABLED)); 1524 reset(getServices().userManagerInternal); 1525 1526 dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN); 1527 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1528 eq(UserHandle.USER_SYSTEM), 1529 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, 1530 UserManager.DISALLOW_ADD_USER), 1531 eq(true), eq(CAMERA_NOT_DISABLED)); 1532 reset(getServices().userManagerInternal); 1533 1534 dpm.setCameraDisabled(admin1, true); 1535 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1536 eq(UserHandle.USER_SYSTEM), 1537 // DISALLOW_CAMERA will be applied to both local and global. 1538 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, 1539 UserManager.DISALLOW_ADD_USER), 1540 eq(true), eq(CAMERA_DISABLED_GLOBALLY)); 1541 reset(getServices().userManagerInternal); 1542 1543 // Set up another DA and let it disable camera. Now DISALLOW_CAMERA will only be applied 1544 // locally. 1545 dpm.setCameraDisabled(admin1, false); 1546 reset(getServices().userManagerInternal); 1547 1548 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID); 1549 dpm.setActiveAdmin(admin2, /* replace =*/ false, UserHandle.USER_SYSTEM); 1550 dpm.setCameraDisabled(admin2, true); 1551 1552 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1553 eq(UserHandle.USER_SYSTEM), 1554 // DISALLOW_CAMERA will be applied to both local and global. <- TODO: fix this 1555 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, 1556 UserManager.DISALLOW_ADD_USER), 1557 eq(true), eq(CAMERA_DISABLED_LOCALLY)); 1558 reset(getServices().userManagerInternal); 1559 // TODO Make sure restrictions are written to the file. 1560 } 1561 1562 public void testSetUserRestriction_asPo() { 1563 setAsProfileOwner(admin1); 1564 1565 DpmTestUtils.assertRestrictions( 1566 DpmTestUtils.newRestrictions(), 1567 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) 1568 .ensureUserRestrictions() 1569 ); 1570 1571 dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); 1572 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1573 eq(DpmMockContext.CALLER_USER_HANDLE), 1574 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES), 1575 eq(false), eq(CAMERA_NOT_DISABLED)); 1576 reset(getServices().userManagerInternal); 1577 1578 dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 1579 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1580 eq(DpmMockContext.CALLER_USER_HANDLE), 1581 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 1582 UserManager.DISALLOW_OUTGOING_CALLS), 1583 eq(false), eq(CAMERA_NOT_DISABLED)); 1584 reset(getServices().userManagerInternal); 1585 1586 DpmTestUtils.assertRestrictions( 1587 DpmTestUtils.newRestrictions( 1588 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 1589 UserManager.DISALLOW_OUTGOING_CALLS 1590 ), 1591 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) 1592 .ensureUserRestrictions() 1593 ); 1594 DpmTestUtils.assertRestrictions( 1595 DpmTestUtils.newRestrictions( 1596 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 1597 UserManager.DISALLOW_OUTGOING_CALLS 1598 ), 1599 dpm.getUserRestrictions(admin1) 1600 ); 1601 1602 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); 1603 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1604 eq(DpmMockContext.CALLER_USER_HANDLE), 1605 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 1606 eq(false), eq(CAMERA_NOT_DISABLED)); 1607 reset(getServices().userManagerInternal); 1608 1609 DpmTestUtils.assertRestrictions( 1610 DpmTestUtils.newRestrictions( 1611 UserManager.DISALLOW_OUTGOING_CALLS 1612 ), 1613 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) 1614 .ensureUserRestrictions() 1615 ); 1616 DpmTestUtils.assertRestrictions( 1617 DpmTestUtils.newRestrictions( 1618 UserManager.DISALLOW_OUTGOING_CALLS 1619 ), 1620 dpm.getUserRestrictions(admin1) 1621 ); 1622 1623 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 1624 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1625 eq(DpmMockContext.CALLER_USER_HANDLE), 1626 MockUtils.checkUserRestrictions(), 1627 eq(false), eq(CAMERA_NOT_DISABLED)); 1628 reset(getServices().userManagerInternal); 1629 1630 DpmTestUtils.assertRestrictions( 1631 DpmTestUtils.newRestrictions(), 1632 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) 1633 .ensureUserRestrictions() 1634 ); 1635 DpmTestUtils.assertRestrictions( 1636 DpmTestUtils.newRestrictions(), 1637 dpm.getUserRestrictions(admin1) 1638 ); 1639 1640 // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE can be set by PO too, even 1641 // though when DO sets them they'll be applied globally. 1642 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); 1643 reset(getServices().userManagerInternal); 1644 dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE); 1645 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1646 eq(DpmMockContext.CALLER_USER_HANDLE), 1647 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME, 1648 UserManager.DISALLOW_UNMUTE_MICROPHONE), 1649 eq(false), eq(CAMERA_NOT_DISABLED)); 1650 reset(getServices().userManagerInternal); 1651 1652 dpm.setCameraDisabled(admin1, true); 1653 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1654 eq(DpmMockContext.CALLER_USER_HANDLE), 1655 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME, 1656 UserManager.DISALLOW_UNMUTE_MICROPHONE), 1657 eq(false), eq(CAMERA_DISABLED_LOCALLY)); 1658 reset(getServices().userManagerInternal); 1659 1660 // TODO Make sure restrictions are written to the file. 1661 } 1662 1663 1664 public void testDefaultEnabledUserRestrictions() throws Exception { 1665 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1666 mContext.callerPermissions.add(permission.MANAGE_USERS); 1667 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1668 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1669 1670 // First, set DO. 1671 1672 // Call from a process on the system user. 1673 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1674 1675 // Make sure admin1 is installed on system user. 1676 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1677 1678 dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); 1679 assertTrue(dpm.setDeviceOwner(admin1, "owner-name", 1680 UserHandle.USER_SYSTEM)); 1681 1682 // Check that the user restrictions that are enabled by default are set. Then unset them. 1683 String[] defaultRestrictions = UserRestrictionsUtils 1684 .getDefaultEnabledForDeviceOwner().toArray(new String[0]); 1685 assertTrue(defaultRestrictions.length > 0); 1686 DpmTestUtils.assertRestrictions( 1687 DpmTestUtils.newRestrictions(defaultRestrictions), 1688 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1689 ); 1690 DpmTestUtils.assertRestrictions( 1691 DpmTestUtils.newRestrictions(defaultRestrictions), 1692 dpm.getUserRestrictions(admin1) 1693 ); 1694 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1695 eq(UserHandle.USER_SYSTEM), 1696 MockUtils.checkUserRestrictions(defaultRestrictions), 1697 eq(true) /* isDeviceOwner */, 1698 eq(CAMERA_NOT_DISABLED) 1699 ); 1700 reset(getServices().userManagerInternal); 1701 1702 for (String restriction : defaultRestrictions) { 1703 dpm.clearUserRestriction(admin1, restriction); 1704 } 1705 1706 assertNoDeviceOwnerRestrictions(); 1707 1708 // Initialize DPMS again and check that the user restriction wasn't enabled again. 1709 reset(getServices().userManagerInternal); 1710 initializeDpms(); 1711 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 1712 assertNotNull(dpms.getDeviceOwnerAdminLocked()); 1713 1714 assertNoDeviceOwnerRestrictions(); 1715 1716 // Add a new restriction to the default set, initialize DPMS, and check that the restriction 1717 // is set as it wasn't enabled during setDeviceOwner. 1718 final String newDefaultEnabledRestriction = UserManager.DISALLOW_REMOVE_MANAGED_PROFILE; 1719 assertFalse(UserRestrictionsUtils 1720 .getDefaultEnabledForDeviceOwner().contains(newDefaultEnabledRestriction)); 1721 UserRestrictionsUtils 1722 .getDefaultEnabledForDeviceOwner().add(newDefaultEnabledRestriction); 1723 try { 1724 reset(getServices().userManagerInternal); 1725 initializeDpms(); 1726 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 1727 assertNotNull(dpms.getDeviceOwnerAdminLocked()); 1728 1729 DpmTestUtils.assertRestrictions( 1730 DpmTestUtils.newRestrictions(newDefaultEnabledRestriction), 1731 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1732 ); 1733 DpmTestUtils.assertRestrictions( 1734 DpmTestUtils.newRestrictions(newDefaultEnabledRestriction), 1735 dpm.getUserRestrictions(admin1) 1736 ); 1737 verify(getServices().userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions( 1738 eq(UserHandle.USER_SYSTEM), 1739 MockUtils.checkUserRestrictions(newDefaultEnabledRestriction), 1740 eq(true) /* isDeviceOwner */, 1741 eq(CAMERA_NOT_DISABLED) 1742 ); 1743 reset(getServices().userManagerInternal); 1744 1745 // Remove the restriction. 1746 dpm.clearUserRestriction(admin1, newDefaultEnabledRestriction); 1747 1748 // Initialize DPMS again. The restriction shouldn't be enabled for a second time. 1749 initializeDpms(); 1750 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 1751 assertNotNull(dpms.getDeviceOwnerAdminLocked()); 1752 assertNoDeviceOwnerRestrictions(); 1753 } finally { 1754 UserRestrictionsUtils 1755 .getDefaultEnabledForDeviceOwner().remove(newDefaultEnabledRestriction); 1756 } 1757 } 1758 1759 private void assertNoDeviceOwnerRestrictions() { 1760 DpmTestUtils.assertRestrictions( 1761 DpmTestUtils.newRestrictions(), 1762 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1763 ); 1764 DpmTestUtils.assertRestrictions( 1765 DpmTestUtils.newRestrictions(), 1766 dpm.getUserRestrictions(admin1) 1767 ); 1768 } 1769 1770 public void testGetMacAddress() throws Exception { 1771 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1772 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1773 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1774 1775 // In this test, change the caller user to "system". 1776 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1777 1778 // Make sure admin1 is installed on system user. 1779 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1780 1781 // Test 1. Caller doesn't have DO or DA. 1782 assertExpectException(SecurityException.class, /* messageRegex= */ "No active admin", 1783 () -> dpm.getWifiMacAddress(admin1)); 1784 1785 // DO needs to be an DA. 1786 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1787 assertTrue(dpm.isAdminActive(admin1)); 1788 1789 // Test 2. Caller has DA, but not DO. 1790 assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG, 1791 () -> dpm.getWifiMacAddress(admin1)); 1792 1793 // Test 3. Caller has PO, but not DO. 1794 assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)); 1795 assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG, 1796 () -> dpm.getWifiMacAddress(admin1)); 1797 1798 // Remove PO. 1799 dpm.clearProfileOwner(admin1); 1800 dpm.setActiveAdmin(admin1, false); 1801 // Test 4, Caller is DO now. 1802 assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)); 1803 1804 // 4-1. But no WifiInfo. 1805 assertNull(dpm.getWifiMacAddress(admin1)); 1806 1807 // 4-2. Returns WifiInfo, but with the default MAC. 1808 when(getServices().wifiManager.getConnectionInfo()).thenReturn(new WifiInfo()); 1809 assertNull(dpm.getWifiMacAddress(admin1)); 1810 1811 // 4-3. With a real MAC address. 1812 final WifiInfo wi = new WifiInfo(); 1813 wi.setMacAddress("11:22:33:44:55:66"); 1814 when(getServices().wifiManager.getConnectionInfo()).thenReturn(wi); 1815 assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1)); 1816 } 1817 1818 public void testReboot() throws Exception { 1819 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1820 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1821 1822 // In this test, change the caller user to "system". 1823 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1824 1825 // Make sure admin1 is installed on system user. 1826 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1827 1828 // Set admin1 as DA. 1829 dpm.setActiveAdmin(admin1, false); 1830 assertTrue(dpm.isAdminActive(admin1)); 1831 assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG, 1832 () -> dpm.reboot(admin1)); 1833 1834 // Set admin1 as PO. 1835 assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)); 1836 assertExpectException(SecurityException.class, /* messageRegex= */ NOT_DEVICE_OWNER_MSG, 1837 () -> dpm.reboot(admin1)); 1838 1839 // Remove PO and add DO. 1840 dpm.clearProfileOwner(admin1); 1841 dpm.setActiveAdmin(admin1, false); 1842 assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)); 1843 1844 // admin1 is DO. 1845 // Set current call state of device to ringing. 1846 when(getServices().telephonyManager.getCallState()) 1847 .thenReturn(TelephonyManager.CALL_STATE_RINGING); 1848 assertExpectException(IllegalStateException.class, /* messageRegex= */ ONGOING_CALL_MSG, 1849 () -> dpm.reboot(admin1)); 1850 1851 // Set current call state of device to dialing/active. 1852 when(getServices().telephonyManager.getCallState()) 1853 .thenReturn(TelephonyManager.CALL_STATE_OFFHOOK); 1854 assertExpectException(IllegalStateException.class, /* messageRegex= */ ONGOING_CALL_MSG, 1855 () -> dpm.reboot(admin1)); 1856 1857 // Set current call state of device to idle. 1858 when(getServices().telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE); 1859 dpm.reboot(admin1); 1860 } 1861 1862 public void testSetGetSupportText() { 1863 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1864 dpm.setActiveAdmin(admin1, true); 1865 dpm.setActiveAdmin(admin2, true); 1866 mContext.callerPermissions.remove(permission.MANAGE_DEVICE_ADMINS); 1867 1868 // Null default support messages. 1869 { 1870 assertNull(dpm.getLongSupportMessage(admin1)); 1871 assertNull(dpm.getShortSupportMessage(admin1)); 1872 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 1873 assertNull(dpm.getShortSupportMessageForUser(admin1, 1874 DpmMockContext.CALLER_USER_HANDLE)); 1875 assertNull(dpm.getLongSupportMessageForUser(admin1, 1876 DpmMockContext.CALLER_USER_HANDLE)); 1877 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 1878 } 1879 1880 // Only system can call the per user versions. 1881 { 1882 assertExpectException(SecurityException.class, /* messageRegex= */ "message for user", 1883 () -> dpm.getShortSupportMessageForUser(admin1, 1884 DpmMockContext.CALLER_USER_HANDLE)); 1885 assertExpectException(SecurityException.class, /* messageRegex= */ "message for user", 1886 () -> dpm.getLongSupportMessageForUser(admin1, 1887 DpmMockContext.CALLER_USER_HANDLE)); 1888 } 1889 1890 // Can't set message for admin in another uid. 1891 { 1892 mContext.binder.callingUid = DpmMockContext.CALLER_UID + 1; 1893 assertExpectException(SecurityException.class, 1894 /* messageRegex= */ "is not owned by uid", 1895 () -> dpm.setShortSupportMessage(admin1, "Some text")); 1896 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1897 } 1898 1899 // Set/Get short returns what it sets and other admins text isn't changed. 1900 { 1901 final String supportText = "Some text to test with."; 1902 dpm.setShortSupportMessage(admin1, supportText); 1903 assertEquals(supportText, dpm.getShortSupportMessage(admin1)); 1904 assertNull(dpm.getLongSupportMessage(admin1)); 1905 assertNull(dpm.getShortSupportMessage(admin2)); 1906 1907 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 1908 assertEquals(supportText, dpm.getShortSupportMessageForUser(admin1, 1909 DpmMockContext.CALLER_USER_HANDLE)); 1910 assertNull(dpm.getShortSupportMessageForUser(admin2, 1911 DpmMockContext.CALLER_USER_HANDLE)); 1912 assertNull(dpm.getLongSupportMessageForUser(admin1, 1913 DpmMockContext.CALLER_USER_HANDLE)); 1914 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 1915 1916 dpm.setShortSupportMessage(admin1, null); 1917 assertNull(dpm.getShortSupportMessage(admin1)); 1918 } 1919 1920 // Set/Get long returns what it sets and other admins text isn't changed. 1921 { 1922 final String supportText = "Some text to test with.\nWith more text."; 1923 dpm.setLongSupportMessage(admin1, supportText); 1924 assertEquals(supportText, dpm.getLongSupportMessage(admin1)); 1925 assertNull(dpm.getShortSupportMessage(admin1)); 1926 assertNull(dpm.getLongSupportMessage(admin2)); 1927 1928 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 1929 assertEquals(supportText, dpm.getLongSupportMessageForUser(admin1, 1930 DpmMockContext.CALLER_USER_HANDLE)); 1931 assertNull(dpm.getLongSupportMessageForUser(admin2, 1932 DpmMockContext.CALLER_USER_HANDLE)); 1933 assertNull(dpm.getShortSupportMessageForUser(admin1, 1934 DpmMockContext.CALLER_USER_HANDLE)); 1935 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 1936 1937 dpm.setLongSupportMessage(admin1, null); 1938 assertNull(dpm.getLongSupportMessage(admin1)); 1939 } 1940 } 1941 1942 public void testCreateAdminSupportIntent() throws Exception { 1943 // Setup device owner. 1944 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1945 setupDeviceOwner(); 1946 1947 // Nonexisting permission returns null 1948 Intent intent = dpm.createAdminSupportIntent("disallow_nothing"); 1949 assertNull(intent); 1950 1951 // Existing permission that is not set returns null 1952 intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME); 1953 assertNull(intent); 1954 1955 // Existing permission that is not set by device/profile owner returns null 1956 when(getServices().userManager.hasUserRestriction( 1957 eq(UserManager.DISALLOW_ADJUST_VOLUME), 1958 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) 1959 .thenReturn(true); 1960 intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME); 1961 assertNull(intent); 1962 1963 // Permission that is set by device owner returns correct intent 1964 when(getServices().userManager.getUserRestrictionSource( 1965 eq(UserManager.DISALLOW_ADJUST_VOLUME), 1966 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) 1967 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 1968 intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME); 1969 assertNotNull(intent); 1970 assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction()); 1971 assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID), 1972 intent.getIntExtra(Intent.EXTRA_USER_ID, -1)); 1973 assertEquals(admin1, intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN)); 1974 assertEquals(UserManager.DISALLOW_ADJUST_VOLUME, 1975 intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION)); 1976 1977 // Try with POLICY_DISABLE_CAMERA and POLICY_DISABLE_SCREEN_CAPTURE, which are not 1978 // user restrictions 1979 1980 // Camera is not disabled 1981 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA); 1982 assertNull(intent); 1983 1984 // Camera is disabled 1985 dpm.setCameraDisabled(admin1, true); 1986 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA); 1987 assertNotNull(intent); 1988 assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA, 1989 intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION)); 1990 1991 // Screen capture is not disabled 1992 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); 1993 assertNull(intent); 1994 1995 // Screen capture is disabled 1996 dpm.setScreenCaptureDisabled(admin1, true); 1997 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); 1998 assertNotNull(intent); 1999 assertEquals(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE, 2000 intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION)); 2001 2002 // Same checks for different user 2003 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2004 // Camera should be disabled by device owner 2005 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA); 2006 assertNotNull(intent); 2007 assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA, 2008 intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION)); 2009 assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID), 2010 intent.getIntExtra(Intent.EXTRA_USER_ID, -1)); 2011 // ScreenCapture should not be disabled by device owner 2012 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); 2013 assertNull(intent); 2014 } 2015 2016 /** 2017 * Test for: 2018 * {@link DevicePolicyManager#setAffiliationIds} 2019 * {@link DevicePolicyManager#getAffiliationIds} 2020 * {@link DevicePolicyManager#isAffiliatedUser} 2021 */ 2022 public void testUserAffiliation() throws Exception { 2023 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 2024 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2025 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 2026 2027 // Check that the system user is unaffiliated. 2028 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2029 assertFalse(dpm.isAffiliatedUser()); 2030 2031 // Set a device owner on the system user. Check that the system user becomes affiliated. 2032 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 2033 dpm.setActiveAdmin(admin1, /* replace =*/ false); 2034 assertTrue(dpm.setDeviceOwner(admin1, "owner-name")); 2035 assertTrue(dpm.isAffiliatedUser()); 2036 assertTrue(dpm.getAffiliationIds(admin1).isEmpty()); 2037 2038 // Install a profile owner. Check that the test user is unaffiliated. 2039 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2040 setAsProfileOwner(admin2); 2041 assertFalse(dpm.isAffiliatedUser()); 2042 assertTrue(dpm.getAffiliationIds(admin2).isEmpty()); 2043 2044 // Have the profile owner specify a set of affiliation ids. Check that the test user remains 2045 // unaffiliated. 2046 final Set<String> userAffiliationIds = new ArraySet<>(); 2047 userAffiliationIds.add("red"); 2048 userAffiliationIds.add("green"); 2049 userAffiliationIds.add("blue"); 2050 dpm.setAffiliationIds(admin2, userAffiliationIds); 2051 MoreAsserts.assertContentsInAnyOrder(dpm.getAffiliationIds(admin2), "red", "green", "blue"); 2052 assertFalse(dpm.isAffiliatedUser()); 2053 2054 // Have the device owner specify a set of affiliation ids that do not intersect with those 2055 // specified by the profile owner. Check that the test user remains unaffiliated. 2056 final Set<String> deviceAffiliationIds = new ArraySet<>(); 2057 deviceAffiliationIds.add("cyan"); 2058 deviceAffiliationIds.add("yellow"); 2059 deviceAffiliationIds.add("magenta"); 2060 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2061 dpm.setAffiliationIds(admin1, deviceAffiliationIds); 2062 MoreAsserts.assertContentsInAnyOrder( 2063 dpm.getAffiliationIds(admin1), "cyan", "yellow", "magenta"); 2064 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2065 assertFalse(dpm.isAffiliatedUser()); 2066 2067 // Have the profile owner specify a set of affiliation ids that intersect with those 2068 // specified by the device owner. Check that the test user becomes affiliated. 2069 userAffiliationIds.add("yellow"); 2070 dpm.setAffiliationIds(admin2, userAffiliationIds); 2071 MoreAsserts.assertContentsInAnyOrder( 2072 dpm.getAffiliationIds(admin2), "red", "green", "blue", "yellow"); 2073 assertTrue(dpm.isAffiliatedUser()); 2074 2075 // Clear affiliation ids for the profile owner. The user becomes unaffiliated. 2076 dpm.setAffiliationIds(admin2, Collections.emptySet()); 2077 assertTrue(dpm.getAffiliationIds(admin2).isEmpty()); 2078 assertFalse(dpm.isAffiliatedUser()); 2079 2080 // Set affiliation ids again, then clear PO to check that the user becomes unaffiliated 2081 dpm.setAffiliationIds(admin2, userAffiliationIds); 2082 assertTrue(dpm.isAffiliatedUser()); 2083 dpm.clearProfileOwner(admin2); 2084 assertFalse(dpm.isAffiliatedUser()); 2085 2086 // Check that the system user remains affiliated. 2087 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2088 assertTrue(dpm.isAffiliatedUser()); 2089 2090 // Clear the device owner - the user becomes unaffiliated. 2091 clearDeviceOwner(); 2092 assertFalse(dpm.isAffiliatedUser()); 2093 } 2094 2095 public void testGetUserProvisioningState_defaultResult() { 2096 assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState()); 2097 } 2098 2099 public void testSetUserProvisioningState_permission() throws Exception { 2100 setupProfileOwner(); 2101 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2102 2103 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 2104 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 2105 } 2106 2107 public void testSetUserProvisioningState_unprivileged() throws Exception { 2108 setupProfileOwner(); 2109 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 2110 () -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 2111 DpmMockContext.CALLER_USER_HANDLE)); 2112 } 2113 2114 public void testSetUserProvisioningState_noManagement() { 2115 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2116 assertExpectException(IllegalStateException.class, 2117 /* messageRegex= */ "change provisioning state unless a .* owner is set", 2118 () -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 2119 DpmMockContext.CALLER_USER_HANDLE)); 2120 assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState()); 2121 } 2122 2123 public void testSetUserProvisioningState_deviceOwnerFromSetupWizard() throws Exception { 2124 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2125 setupDeviceOwner(); 2126 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2127 2128 exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM, 2129 DevicePolicyManager.STATE_USER_SETUP_COMPLETE, 2130 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 2131 } 2132 2133 public void testSetUserProvisioningState_deviceOwnerFromSetupWizardAlternative() 2134 throws Exception { 2135 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2136 setupDeviceOwner(); 2137 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2138 2139 exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM, 2140 DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE, 2141 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 2142 } 2143 2144 public void testSetUserProvisioningState_deviceOwnerWithoutSetupWizard() throws Exception { 2145 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2146 setupDeviceOwner(); 2147 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2148 2149 exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM, 2150 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 2151 } 2152 2153 public void testSetUserProvisioningState_managedProfileFromSetupWizard_primaryUser() 2154 throws Exception { 2155 setupProfileOwner(); 2156 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2157 2158 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 2159 DevicePolicyManager.STATE_USER_PROFILE_COMPLETE, 2160 DevicePolicyManager.STATE_USER_UNMANAGED); 2161 } 2162 2163 public void testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile() 2164 throws Exception { 2165 setupProfileOwner(); 2166 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2167 2168 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 2169 DevicePolicyManager.STATE_USER_SETUP_COMPLETE, 2170 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 2171 } 2172 2173 public void testSetUserProvisioningState_managedProfileWithoutSetupWizard() throws Exception { 2174 setupProfileOwner(); 2175 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2176 2177 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 2178 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 2179 } 2180 2181 public void testSetUserProvisioningState_illegalTransitionOutOfFinalized1() throws Exception { 2182 setupProfileOwner(); 2183 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2184 2185 assertExpectException(IllegalStateException.class, 2186 /* messageRegex= */ "Cannot move to user provisioning state", 2187 () -> exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 2188 DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 2189 DevicePolicyManager.STATE_USER_UNMANAGED)); 2190 } 2191 2192 public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState() 2193 throws Exception { 2194 setupProfileOwner(); 2195 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2196 2197 assertExpectException(IllegalStateException.class, 2198 /* messageRegex= */ "Cannot move to user provisioning state", 2199 () -> exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 2200 DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE, 2201 DevicePolicyManager.STATE_USER_SETUP_COMPLETE)); 2202 } 2203 2204 private void exerciseUserProvisioningTransitions(int userId, int... states) { 2205 assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState()); 2206 for (int state : states) { 2207 dpm.setUserProvisioningState(state, userId); 2208 assertEquals(state, dpm.getUserProvisioningState()); 2209 } 2210 } 2211 2212 private void setupProfileOwner() throws Exception { 2213 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 2214 2215 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 2216 dpm.setActiveAdmin(admin1, false); 2217 assertTrue(dpm.setProfileOwner(admin1, null, DpmMockContext.CALLER_USER_HANDLE)); 2218 2219 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 2220 } 2221 2222 private void setupDeviceOwner() throws Exception { 2223 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 2224 2225 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 2226 dpm.setActiveAdmin(admin1, false); 2227 assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)); 2228 2229 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 2230 } 2231 2232 public void testSetMaximumTimeToLock() { 2233 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 2234 2235 dpm.setActiveAdmin(admin1, /* replace =*/ false); 2236 dpm.setActiveAdmin(admin2, /* replace =*/ false); 2237 2238 reset(getServices().powerManagerInternal); 2239 reset(getServices().settings); 2240 2241 dpm.setMaximumTimeToLock(admin1, 0); 2242 verifyScreenTimeoutCall(null, false); 2243 reset(getServices().powerManagerInternal); 2244 reset(getServices().settings); 2245 2246 dpm.setMaximumTimeToLock(admin1, 1); 2247 verifyScreenTimeoutCall(1, true); 2248 reset(getServices().powerManagerInternal); 2249 reset(getServices().settings); 2250 2251 dpm.setMaximumTimeToLock(admin2, 10); 2252 verifyScreenTimeoutCall(null, false); 2253 reset(getServices().powerManagerInternal); 2254 reset(getServices().settings); 2255 2256 dpm.setMaximumTimeToLock(admin1, 5); 2257 verifyScreenTimeoutCall(5, true); 2258 reset(getServices().powerManagerInternal); 2259 reset(getServices().settings); 2260 2261 dpm.setMaximumTimeToLock(admin2, 4); 2262 verifyScreenTimeoutCall(4, true); 2263 reset(getServices().powerManagerInternal); 2264 reset(getServices().settings); 2265 2266 dpm.setMaximumTimeToLock(admin1, 0); 2267 reset(getServices().powerManagerInternal); 2268 reset(getServices().settings); 2269 2270 dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE); 2271 verifyScreenTimeoutCall(Integer.MAX_VALUE, true); 2272 reset(getServices().powerManagerInternal); 2273 reset(getServices().settings); 2274 2275 dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE + 1); 2276 verifyScreenTimeoutCall(Integer.MAX_VALUE, true); 2277 reset(getServices().powerManagerInternal); 2278 reset(getServices().settings); 2279 2280 dpm.setMaximumTimeToLock(admin2, 10); 2281 verifyScreenTimeoutCall(10, true); 2282 reset(getServices().powerManagerInternal); 2283 reset(getServices().settings); 2284 2285 // There's no restriction; shold be set to MAX. 2286 dpm.setMaximumTimeToLock(admin2, 0); 2287 verifyScreenTimeoutCall(Integer.MAX_VALUE, false); 2288 } 2289 2290 public void testSetRequiredStrongAuthTimeout_DeviceOwner() throws Exception { 2291 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2292 setupDeviceOwner(); 2293 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2294 2295 final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = TimeUnit.HOURS.toMillis(1); 2296 final long ONE_MINUTE = TimeUnit.MINUTES.toMillis(1); 2297 final long MIN_PLUS_ONE_MINUTE = MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE; 2298 final long MAX_MINUS_ONE_MINUTE = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS 2299 - ONE_MINUTE; 2300 2301 // verify that the minimum timeout cannot be modified on user builds (system property is 2302 // not being read) 2303 getServices().buildMock.isDebuggable = false; 2304 2305 dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE); 2306 assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE); 2307 assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE); 2308 2309 verify(getServices().systemProperties, never()).getLong(anyString(), anyLong()); 2310 2311 // restore to the debuggable build state 2312 getServices().buildMock.isDebuggable = true; 2313 2314 // reset to default (0 means the admin is not participating, so default should be returned) 2315 dpm.setRequiredStrongAuthTimeout(admin1, 0); 2316 2317 // aggregation should be the default if unset by any admin 2318 assertEquals(dpm.getRequiredStrongAuthTimeout(null), 2319 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); 2320 2321 // admin not participating by default 2322 assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); 2323 2324 //clamping from the top 2325 dpm.setRequiredStrongAuthTimeout(admin1, 2326 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); 2327 assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 2328 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); 2329 assertEquals(dpm.getRequiredStrongAuthTimeout(null), 2330 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); 2331 2332 // 0 means the admin is not participating, so default should be returned 2333 dpm.setRequiredStrongAuthTimeout(admin1, 0); 2334 assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); 2335 assertEquals(dpm.getRequiredStrongAuthTimeout(null), 2336 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); 2337 2338 // clamping from the bottom 2339 dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS - ONE_MINUTE); 2340 assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS); 2341 assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS); 2342 2343 // values within range 2344 dpm.setRequiredStrongAuthTimeout(admin1, MIN_PLUS_ONE_MINUTE); 2345 assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MIN_PLUS_ONE_MINUTE); 2346 assertEquals(dpm.getRequiredStrongAuthTimeout(null), MIN_PLUS_ONE_MINUTE); 2347 2348 dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE); 2349 assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE); 2350 assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE); 2351 2352 // reset to default 2353 dpm.setRequiredStrongAuthTimeout(admin1, 0); 2354 assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0); 2355 assertEquals(dpm.getRequiredStrongAuthTimeout(null), 2356 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS); 2357 2358 // negative value 2359 assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null, 2360 () -> dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE)); 2361 } 2362 2363 private void verifyScreenTimeoutCall(Integer expectedTimeout, 2364 boolean shouldStayOnWhilePluggedInBeCleared) { 2365 if (expectedTimeout == null) { 2366 verify(getServices().powerManagerInternal, times(0)) 2367 .setMaximumScreenOffTimeoutFromDeviceAdmin(anyInt()); 2368 } else { 2369 verify(getServices().powerManagerInternal, times(1)) 2370 .setMaximumScreenOffTimeoutFromDeviceAdmin(eq(expectedTimeout)); 2371 } 2372 // TODO Verify calls to settingsGlobalPutInt. Tried but somehow mockito threw 2373 // UnfinishedVerificationException. 2374 } 2375 2376 private void setup_DeviceAdminFeatureOff() throws Exception { 2377 when(getServices().packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) 2378 .thenReturn(false); 2379 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2380 .thenReturn(false); 2381 initializeDpms(); 2382 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false); 2383 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true)) 2384 .thenReturn(true); 2385 setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); 2386 2387 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2388 } 2389 2390 public void testIsProvisioningAllowed_DeviceAdminFeatureOff() throws Exception { 2391 setup_DeviceAdminFeatureOff(); 2392 mContext.packageName = admin1.getPackageName(); 2393 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2394 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false); 2395 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 2396 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2397 false); 2398 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false); 2399 } 2400 2401 public void testCheckProvisioningPreCondition_DeviceAdminFeatureOff() throws Exception { 2402 setup_DeviceAdminFeatureOff(); 2403 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2404 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2405 DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); 2406 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2407 DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); 2408 assertCheckProvisioningPreCondition( 2409 DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2410 DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); 2411 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2412 DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); 2413 } 2414 2415 private void setup_ManagedProfileFeatureOff() throws Exception { 2416 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2417 .thenReturn(false); 2418 initializeDpms(); 2419 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false); 2420 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true)) 2421 .thenReturn(true); 2422 setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); 2423 2424 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2425 } 2426 2427 public void testIsProvisioningAllowed_ManagedProfileFeatureOff() throws Exception { 2428 setup_ManagedProfileFeatureOff(); 2429 mContext.packageName = admin1.getPackageName(); 2430 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2431 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); 2432 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 2433 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2434 false); 2435 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false); 2436 2437 // Test again when split user is on 2438 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 2439 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); 2440 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 2441 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2442 true); 2443 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false); 2444 } 2445 2446 public void testCheckProvisioningPreCondition_ManagedProfileFeatureOff() throws Exception { 2447 setup_ManagedProfileFeatureOff(); 2448 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2449 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2450 DevicePolicyManager.CODE_OK); 2451 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2452 DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED); 2453 assertCheckProvisioningPreCondition( 2454 DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2455 DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); 2456 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2457 DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED); 2458 2459 // Test again when split user is on 2460 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 2461 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2462 DevicePolicyManager.CODE_OK); 2463 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2464 DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED); 2465 assertCheckProvisioningPreCondition( 2466 DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2467 DevicePolicyManager.CODE_OK); 2468 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2469 DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED); 2470 } 2471 2472 private void setup_nonSplitUser_firstBoot_primaryUser() throws Exception { 2473 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2474 .thenReturn(true); 2475 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false); 2476 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true)) 2477 .thenReturn(true); 2478 setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); 2479 2480 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2481 } 2482 2483 public void testIsProvisioningAllowed_nonSplitUser_firstBoot_primaryUser() throws Exception { 2484 setup_nonSplitUser_firstBoot_primaryUser(); 2485 mContext.packageName = admin1.getPackageName(); 2486 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2487 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); 2488 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 2489 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2490 false /* because of non-split user */); 2491 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2492 false /* because of non-split user */); 2493 } 2494 2495 public void testCheckProvisioningPreCondition_nonSplitUser_firstBoot_primaryUser() 2496 throws Exception { 2497 setup_nonSplitUser_firstBoot_primaryUser(); 2498 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2499 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2500 DevicePolicyManager.CODE_OK); 2501 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2502 DevicePolicyManager.CODE_OK); 2503 assertCheckProvisioningPreCondition( 2504 DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2505 DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); 2506 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2507 DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); 2508 } 2509 2510 private void setup_nonSplitUser_afterDeviceSetup_primaryUser() throws Exception { 2511 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2512 .thenReturn(true); 2513 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(false); 2514 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true)) 2515 .thenReturn(true); 2516 setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM); 2517 2518 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2519 } 2520 2521 private void setup_nonSplitUser_withDo_primaryUser() throws Exception { 2522 setDeviceOwner(); 2523 setup_nonSplitUser_afterDeviceSetup_primaryUser(); 2524 setUpPackageManagerForFakeAdmin(adminAnotherPackage, DpmMockContext.ANOTHER_UID, admin2); 2525 } 2526 2527 private void setup_nonSplitUser_withDo_primaryUser_ManagedProfile() throws Exception { 2528 setup_nonSplitUser_withDo_primaryUser(); 2529 final int MANAGED_PROFILE_USER_ID = 18; 2530 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 1308); 2531 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 2532 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, 2533 false /* we can't remove a managed profile */)).thenReturn(false); 2534 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, 2535 true)).thenReturn(true); 2536 } 2537 2538 public void testIsProvisioningAllowed_nonSplitUser_afterDeviceSetup_primaryUser() 2539 throws Exception { 2540 setup_nonSplitUser_afterDeviceSetup_primaryUser(); 2541 mContext.packageName = admin1.getPackageName(); 2542 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2543 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2544 false/* because of completed device setup */); 2545 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 2546 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2547 false/* because of non-split user */); 2548 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2549 false/* because of non-split user */); 2550 } 2551 2552 public void testCheckProvisioningPreCondition_nonSplitUser_afterDeviceSetup_primaryUser() 2553 throws Exception { 2554 setup_nonSplitUser_afterDeviceSetup_primaryUser(); 2555 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2556 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2557 DevicePolicyManager.CODE_USER_SETUP_COMPLETED); 2558 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2559 DevicePolicyManager.CODE_OK); 2560 assertCheckProvisioningPreCondition( 2561 DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2562 DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); 2563 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2564 DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT); 2565 } 2566 2567 public void testProvisioning_nonSplitUser_withDo_primaryUser() throws Exception { 2568 setup_nonSplitUser_withDo_primaryUser(); 2569 mContext.packageName = admin1.getPackageName(); 2570 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2571 2572 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2573 DevicePolicyManager.CODE_HAS_DEVICE_OWNER); 2574 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false); 2575 2576 // COMP mode is allowed. 2577 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2578 DevicePolicyManager.CODE_OK); 2579 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 2580 2581 // And other DPCs can also provision a managed profile (DO + BYOD case). 2582 assertCheckProvisioningPreCondition( 2583 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2584 DpmMockContext.ANOTHER_PACKAGE_NAME, 2585 DevicePolicyManager.CODE_OK); 2586 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true, 2587 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID); 2588 } 2589 2590 public void testProvisioning_nonSplitUser_withDo_primaryUser_restrictedByDo() throws Exception { 2591 setup_nonSplitUser_withDo_primaryUser(); 2592 mContext.packageName = admin1.getPackageName(); 2593 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2594 // The DO should be allowed to initiate provisioning if it set the restriction itself, but 2595 // other packages should be forbidden. 2596 when(getServices().userManager.hasUserRestriction( 2597 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE), 2598 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) 2599 .thenReturn(true); 2600 when(getServices().userManager.getUserRestrictionSource( 2601 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE), 2602 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) 2603 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 2604 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2605 DevicePolicyManager.CODE_OK); 2606 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 2607 assertCheckProvisioningPreCondition( 2608 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2609 DpmMockContext.ANOTHER_PACKAGE_NAME, 2610 DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED); 2611 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false, 2612 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID); 2613 } 2614 2615 public void testProvisioning_nonSplitUser_withDo_primaryUser_restrictedBySystem() 2616 throws Exception { 2617 setup_nonSplitUser_withDo_primaryUser(); 2618 mContext.packageName = admin1.getPackageName(); 2619 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2620 // The DO should not be allowed to initiate provisioning if the restriction is set by 2621 // another entity. 2622 when(getServices().userManager.hasUserRestriction( 2623 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE), 2624 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) 2625 .thenReturn(true); 2626 when(getServices().userManager.getUserRestrictionSource( 2627 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE), 2628 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) 2629 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 2630 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2631 DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED); 2632 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 2633 2634 assertCheckProvisioningPreCondition( 2635 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2636 DpmMockContext.ANOTHER_PACKAGE_NAME, 2637 DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED); 2638 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false, 2639 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID); 2640 } 2641 2642 public void testCheckProvisioningPreCondition_nonSplitUser_comp() throws Exception { 2643 setup_nonSplitUser_withDo_primaryUser_ManagedProfile(); 2644 mContext.packageName = admin1.getPackageName(); 2645 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2646 2647 // We can delete the managed profile to create a new one, so provisioning is allowed. 2648 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2649 DevicePolicyManager.CODE_OK); 2650 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 2651 assertCheckProvisioningPreCondition( 2652 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2653 DpmMockContext.ANOTHER_PACKAGE_NAME, 2654 DevicePolicyManager.CODE_OK); 2655 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true, 2656 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID); 2657 } 2658 2659 public void testCheckProvisioningPreCondition_nonSplitUser_comp_cannot_remove_profile() 2660 throws Exception { 2661 setup_nonSplitUser_withDo_primaryUser_ManagedProfile(); 2662 mContext.packageName = admin1.getPackageName(); 2663 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2664 when(getServices().userManager.hasUserRestriction( 2665 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE), 2666 eq(UserHandle.SYSTEM))) 2667 .thenReturn(true); 2668 when(getServices().userManager.getUserRestrictionSource( 2669 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE), 2670 eq(UserHandle.SYSTEM))) 2671 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 2672 2673 // We can't remove the profile to create a new one. 2674 assertCheckProvisioningPreCondition( 2675 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2676 DpmMockContext.ANOTHER_PACKAGE_NAME, 2677 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 2678 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false, 2679 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID); 2680 2681 // But the device owner can still do it because it has set the restriction itself. 2682 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2683 DevicePolicyManager.CODE_OK); 2684 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 2685 } 2686 2687 private void setup_splitUser_firstBoot_systemUser() throws Exception { 2688 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2689 .thenReturn(true); 2690 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 2691 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true)) 2692 .thenReturn(false); 2693 setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); 2694 2695 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2696 } 2697 2698 public void testIsProvisioningAllowed_splitUser_firstBoot_systemUser() throws Exception { 2699 setup_splitUser_firstBoot_systemUser(); 2700 mContext.packageName = admin1.getPackageName(); 2701 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2702 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); 2703 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2704 false /* because canAddMoreManagedProfiles returns false */); 2705 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2706 true); 2707 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2708 false/* because calling uid is system user */); 2709 } 2710 2711 public void testCheckProvisioningPreCondition_splitUser_firstBoot_systemUser() 2712 throws Exception { 2713 setup_splitUser_firstBoot_systemUser(); 2714 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2715 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2716 DevicePolicyManager.CODE_OK); 2717 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2718 DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER); 2719 assertCheckProvisioningPreCondition( 2720 DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2721 DevicePolicyManager.CODE_OK); 2722 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2723 DevicePolicyManager.CODE_SYSTEM_USER); 2724 } 2725 2726 private void setup_splitUser_afterDeviceSetup_systemUser() throws Exception { 2727 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2728 .thenReturn(true); 2729 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 2730 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true)) 2731 .thenReturn(false); 2732 setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM); 2733 2734 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2735 } 2736 2737 public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_systemUser() throws Exception { 2738 setup_splitUser_afterDeviceSetup_systemUser(); 2739 mContext.packageName = admin1.getPackageName(); 2740 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2741 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2742 true/* it's undefined behavior. Can be changed into false in the future */); 2743 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2744 false /* because canAddMoreManagedProfiles returns false */); 2745 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2746 true/* it's undefined behavior. Can be changed into false in the future */); 2747 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2748 false/* because calling uid is system user */); 2749 } 2750 2751 public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_systemUser() 2752 throws Exception { 2753 setup_splitUser_afterDeviceSetup_systemUser(); 2754 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2755 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2756 DevicePolicyManager.CODE_OK); 2757 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2758 DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER); 2759 assertCheckProvisioningPreCondition( 2760 DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2761 DevicePolicyManager.CODE_OK); 2762 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2763 DevicePolicyManager.CODE_SYSTEM_USER); 2764 } 2765 2766 private void setup_splitUser_firstBoot_primaryUser() throws Exception { 2767 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2768 .thenReturn(true); 2769 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 2770 when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE, 2771 true)).thenReturn(true); 2772 setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE); 2773 2774 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2775 } 2776 2777 public void testIsProvisioningAllowed_splitUser_firstBoot_primaryUser() throws Exception { 2778 setup_splitUser_firstBoot_primaryUser(); 2779 mContext.packageName = admin1.getPackageName(); 2780 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2781 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); 2782 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 2783 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2784 true); 2785 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, true); 2786 } 2787 2788 public void testCheckProvisioningPreCondition_splitUser_firstBoot_primaryUser() 2789 throws Exception { 2790 setup_splitUser_firstBoot_primaryUser(); 2791 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2792 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2793 DevicePolicyManager.CODE_OK); 2794 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2795 DevicePolicyManager.CODE_OK); 2796 assertCheckProvisioningPreCondition( 2797 DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2798 DevicePolicyManager.CODE_OK); 2799 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2800 DevicePolicyManager.CODE_OK); 2801 } 2802 2803 private void setup_splitUser_afterDeviceSetup_primaryUser() throws Exception { 2804 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2805 .thenReturn(true); 2806 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 2807 when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE, 2808 true)).thenReturn(true); 2809 setUserSetupCompleteForUser(true, DpmMockContext.CALLER_USER_HANDLE); 2810 2811 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2812 } 2813 2814 public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_primaryUser() 2815 throws Exception { 2816 setup_splitUser_afterDeviceSetup_primaryUser(); 2817 mContext.packageName = admin1.getPackageName(); 2818 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2819 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2820 true/* it's undefined behavior. Can be changed into false in the future */); 2821 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 2822 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2823 true/* it's undefined behavior. Can be changed into false in the future */); 2824 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2825 false/* because user setup completed */); 2826 } 2827 2828 public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_primaryUser() 2829 throws Exception { 2830 setup_splitUser_afterDeviceSetup_primaryUser(); 2831 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2832 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 2833 DevicePolicyManager.CODE_OK); 2834 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2835 DevicePolicyManager.CODE_OK); 2836 assertCheckProvisioningPreCondition( 2837 DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE, 2838 DevicePolicyManager.CODE_OK); 2839 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, 2840 DevicePolicyManager.CODE_USER_SETUP_COMPLETED); 2841 } 2842 2843 private void setup_provisionManagedProfileWithDeviceOwner_systemUser() throws Exception { 2844 setDeviceOwner(); 2845 2846 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2847 .thenReturn(true); 2848 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 2849 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true)) 2850 .thenReturn(false); 2851 setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM); 2852 2853 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2854 } 2855 2856 public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_systemUser() 2857 throws Exception { 2858 setup_provisionManagedProfileWithDeviceOwner_systemUser(); 2859 mContext.packageName = admin1.getPackageName(); 2860 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2861 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2862 false /* can't provision managed profile on system user */); 2863 } 2864 2865 public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_systemUser() 2866 throws Exception { 2867 setup_provisionManagedProfileWithDeviceOwner_systemUser(); 2868 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2869 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2870 DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER); 2871 } 2872 2873 private void setup_provisionManagedProfileWithDeviceOwner_primaryUser() throws Exception { 2874 setDeviceOwner(); 2875 2876 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2877 .thenReturn(true); 2878 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 2879 when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE, 2880 true)).thenReturn(true); 2881 setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE); 2882 2883 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2884 } 2885 2886 public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_primaryUser() 2887 throws Exception { 2888 setup_provisionManagedProfileWithDeviceOwner_primaryUser(); 2889 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2890 mContext.packageName = admin1.getPackageName(); 2891 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 2892 } 2893 2894 public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_primaryUser() 2895 throws Exception { 2896 setup_provisionManagedProfileWithDeviceOwner_primaryUser(); 2897 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2898 2899 // COMP mode is allowed. 2900 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2901 DevicePolicyManager.CODE_OK); 2902 } 2903 2904 private void setup_provisionManagedProfileCantRemoveUser_primaryUser() throws Exception { 2905 setDeviceOwner(); 2906 2907 when(getServices().ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)) 2908 .thenReturn(true); 2909 when(getServices().userManagerForMock.isSplitSystemUser()).thenReturn(true); 2910 when(getServices().userManager.hasUserRestriction( 2911 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE), 2912 eq(UserHandle.of(DpmMockContext.CALLER_USER_HANDLE)))) 2913 .thenReturn(true); 2914 when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE, 2915 false /* we can't remove a managed profile */)).thenReturn(false); 2916 when(getServices().userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE, 2917 true)).thenReturn(true); 2918 setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE); 2919 2920 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2921 } 2922 2923 public void testIsProvisioningAllowed_provisionManagedProfileCantRemoveUser_primaryUser() 2924 throws Exception { 2925 setup_provisionManagedProfileCantRemoveUser_primaryUser(); 2926 mContext.packageName = admin1.getPackageName(); 2927 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2928 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 2929 } 2930 2931 public void testCheckProvisioningPreCondition_provisionManagedProfileCantRemoveUser_primaryUser() 2932 throws Exception { 2933 setup_provisionManagedProfileCantRemoveUser_primaryUser(); 2934 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2935 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 2936 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 2937 } 2938 2939 public void testCheckProvisioningPreCondition_permission() { 2940 // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted 2941 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 2942 () -> dpm.checkProvisioningPreCondition( 2943 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, "some.package")); 2944 } 2945 2946 public void testForceUpdateUserSetupComplete_permission() { 2947 // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted 2948 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 2949 () -> dpm.forceUpdateUserSetupComplete()); 2950 } 2951 2952 public void testForceUpdateUserSetupComplete_systemUser() { 2953 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2954 // GIVEN calling from user 20 2955 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2956 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 2957 () -> dpm.forceUpdateUserSetupComplete()); 2958 } 2959 2960 public void testForceUpdateUserSetupComplete_userbuild() { 2961 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2962 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2963 2964 final int userId = UserHandle.USER_SYSTEM; 2965 // GIVEN userComplete is false in SettingsProvider 2966 setUserSetupCompleteForUser(false, userId); 2967 2968 // GIVEN userComplete is true in DPM 2969 DevicePolicyManagerService.DevicePolicyData userData = 2970 new DevicePolicyManagerService.DevicePolicyData(userId); 2971 userData.mUserSetupComplete = true; 2972 dpms.mUserData.put(UserHandle.USER_SYSTEM, userData); 2973 2974 // GIVEN it's user build 2975 getServices().buildMock.isDebuggable = false; 2976 2977 assertTrue(dpms.hasUserSetupCompleted()); 2978 2979 dpm.forceUpdateUserSetupComplete(); 2980 2981 // THEN the state in dpms is not changed 2982 assertTrue(dpms.hasUserSetupCompleted()); 2983 } 2984 2985 public void testForceUpdateUserSetupComplete_userDebugbuild() { 2986 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2987 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2988 2989 final int userId = UserHandle.USER_SYSTEM; 2990 // GIVEN userComplete is false in SettingsProvider 2991 setUserSetupCompleteForUser(false, userId); 2992 2993 // GIVEN userComplete is true in DPM 2994 DevicePolicyManagerService.DevicePolicyData userData = 2995 new DevicePolicyManagerService.DevicePolicyData(userId); 2996 userData.mUserSetupComplete = true; 2997 dpms.mUserData.put(UserHandle.USER_SYSTEM, userData); 2998 2999 // GIVEN it's userdebug build 3000 getServices().buildMock.isDebuggable = true; 3001 3002 assertTrue(dpms.hasUserSetupCompleted()); 3003 3004 dpm.forceUpdateUserSetupComplete(); 3005 3006 // THEN the state in dpms is not changed 3007 assertFalse(dpms.hasUserSetupCompleted()); 3008 } 3009 3010 private void clearDeviceOwner() throws Exception { 3011 doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager) 3012 .getPackageUidAsUser(eq(admin1.getPackageName()), anyInt()); 3013 3014 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3015 runAsCaller(mAdmin1Context, dpms, dpm -> { 3016 dpm.clearDeviceOwnerApp(admin1.getPackageName()); 3017 }); 3018 } 3019 3020 public void testGetLastSecurityLogRetrievalTime() throws Exception { 3021 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3022 setupDeviceOwner(); 3023 3024 // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the 3025 // feature is disabled because there are non-affiliated secondary users. 3026 getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE); 3027 when(mContext.resources.getBoolean(R.bool.config_supportPreRebootSecurityLogs)) 3028 .thenReturn(true); 3029 3030 // No logs were retrieved so far. 3031 assertEquals(-1, dpm.getLastSecurityLogRetrievalTime()); 3032 3033 // Enabling logging should not change the timestamp. 3034 dpm.setSecurityLoggingEnabled(admin1, true); 3035 verify(getServices().settings) 3036 .securityLogSetLoggingEnabledProperty(true); 3037 when(getServices().settings.securityLogGetLoggingEnabledProperty()) 3038 .thenReturn(true); 3039 assertEquals(-1, dpm.getLastSecurityLogRetrievalTime()); 3040 3041 // Retrieving the logs should update the timestamp. 3042 final long beforeRetrieval = System.currentTimeMillis(); 3043 dpm.retrieveSecurityLogs(admin1); 3044 final long firstSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime(); 3045 final long afterRetrieval = System.currentTimeMillis(); 3046 assertTrue(firstSecurityLogRetrievalTime >= beforeRetrieval); 3047 assertTrue(firstSecurityLogRetrievalTime <= afterRetrieval); 3048 3049 // Retrieving the pre-boot logs should update the timestamp. 3050 Thread.sleep(2); 3051 dpm.retrievePreRebootSecurityLogs(admin1); 3052 final long secondSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime(); 3053 assertTrue(secondSecurityLogRetrievalTime > firstSecurityLogRetrievalTime); 3054 3055 // Checking the timestamp again should not change it. 3056 Thread.sleep(2); 3057 assertEquals(secondSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime()); 3058 3059 // Retrieving the logs again should update the timestamp. 3060 dpm.retrieveSecurityLogs(admin1); 3061 final long thirdSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime(); 3062 assertTrue(thirdSecurityLogRetrievalTime > secondSecurityLogRetrievalTime); 3063 3064 // Disabling logging should not change the timestamp. 3065 Thread.sleep(2); 3066 dpm.setSecurityLoggingEnabled(admin1, false); 3067 assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime()); 3068 3069 // Restarting the DPMS should not lose the timestamp. 3070 initializeDpms(); 3071 assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime()); 3072 3073 // Any uid holding MANAGE_USERS permission can retrieve the timestamp. 3074 mContext.binder.callingUid = 1234567; 3075 mContext.callerPermissions.add(permission.MANAGE_USERS); 3076 assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime()); 3077 mContext.callerPermissions.remove(permission.MANAGE_USERS); 3078 3079 // System can retrieve the timestamp. 3080 mContext.binder.clearCallingIdentity(); 3081 assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime()); 3082 3083 // Removing the device owner should clear the timestamp. 3084 clearDeviceOwner(); 3085 assertEquals(-1, dpm.getLastSecurityLogRetrievalTime()); 3086 } 3087 3088 public void testGetLastBugReportRequestTime() throws Exception { 3089 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3090 setupDeviceOwner(); 3091 3092 mContext.packageName = admin1.getPackageName(); 3093 mContext.applicationInfo = new ApplicationInfo(); 3094 when(mContext.resources.getColor(eq(R.color.notification_action_list), anyObject())) 3095 .thenReturn(Color.WHITE); 3096 when(mContext.resources.getColor(eq(R.color.notification_material_background_color), 3097 anyObject())).thenReturn(Color.WHITE); 3098 3099 // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the 3100 // feature is disabled because there are non-affiliated secondary users. 3101 getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE); 3102 3103 // No bug reports were requested so far. 3104 assertEquals(-1, dpm.getLastBugReportRequestTime()); 3105 3106 // Requesting a bug report should update the timestamp. 3107 final long beforeRequest = System.currentTimeMillis(); 3108 dpm.requestBugreport(admin1); 3109 final long bugReportRequestTime = dpm.getLastBugReportRequestTime(); 3110 final long afterRequest = System.currentTimeMillis(); 3111 assertTrue(bugReportRequestTime >= beforeRequest); 3112 assertTrue(bugReportRequestTime <= afterRequest); 3113 3114 // Checking the timestamp again should not change it. 3115 Thread.sleep(2); 3116 assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime()); 3117 3118 // Restarting the DPMS should not lose the timestamp. 3119 initializeDpms(); 3120 assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime()); 3121 3122 // Any uid holding MANAGE_USERS permission can retrieve the timestamp. 3123 mContext.binder.callingUid = 1234567; 3124 mContext.callerPermissions.add(permission.MANAGE_USERS); 3125 assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime()); 3126 mContext.callerPermissions.remove(permission.MANAGE_USERS); 3127 3128 // System can retrieve the timestamp. 3129 mContext.binder.clearCallingIdentity(); 3130 assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime()); 3131 3132 // Removing the device owner should clear the timestamp. 3133 clearDeviceOwner(); 3134 assertEquals(-1, dpm.getLastBugReportRequestTime()); 3135 } 3136 3137 public void testGetLastNetworkLogRetrievalTime() throws Exception { 3138 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3139 setupDeviceOwner(); 3140 mContext.packageName = admin1.getPackageName(); 3141 mContext.applicationInfo = new ApplicationInfo(); 3142 when(mContext.resources.getColor(eq(R.color.notification_action_list), anyObject())) 3143 .thenReturn(Color.WHITE); 3144 when(mContext.resources.getColor(eq(R.color.notification_material_background_color), 3145 anyObject())).thenReturn(Color.WHITE); 3146 3147 // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the 3148 // feature is disabled because there are non-affiliated secondary users. 3149 getServices().removeUser(DpmMockContext.CALLER_USER_HANDLE); 3150 when(getServices().iipConnectivityMetrics.registerNetdEventCallback(anyObject())) 3151 .thenReturn(true); 3152 3153 // No logs were retrieved so far. 3154 assertEquals(-1, dpm.getLastNetworkLogRetrievalTime()); 3155 3156 // Attempting to retrieve logs without enabling logging should not change the timestamp. 3157 dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */); 3158 assertEquals(-1, dpm.getLastNetworkLogRetrievalTime()); 3159 3160 // Enabling logging should not change the timestamp. 3161 dpm.setNetworkLoggingEnabled(admin1, true); 3162 assertEquals(-1, dpm.getLastNetworkLogRetrievalTime()); 3163 3164 // Retrieving the logs should update the timestamp. 3165 final long beforeRetrieval = System.currentTimeMillis(); 3166 dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */); 3167 final long firstNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime(); 3168 final long afterRetrieval = System.currentTimeMillis(); 3169 assertTrue(firstNetworkLogRetrievalTime >= beforeRetrieval); 3170 assertTrue(firstNetworkLogRetrievalTime <= afterRetrieval); 3171 3172 // Checking the timestamp again should not change it. 3173 Thread.sleep(2); 3174 assertEquals(firstNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime()); 3175 3176 // Retrieving the logs again should update the timestamp. 3177 dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */); 3178 final long secondNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime(); 3179 assertTrue(secondNetworkLogRetrievalTime > firstNetworkLogRetrievalTime); 3180 3181 // Disabling logging should not change the timestamp. 3182 Thread.sleep(2); 3183 dpm.setNetworkLoggingEnabled(admin1, false); 3184 assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime()); 3185 3186 // Restarting the DPMS should not lose the timestamp. 3187 initializeDpms(); 3188 assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime()); 3189 3190 // Any uid holding MANAGE_USERS permission can retrieve the timestamp. 3191 mContext.binder.callingUid = 1234567; 3192 mContext.callerPermissions.add(permission.MANAGE_USERS); 3193 assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime()); 3194 mContext.callerPermissions.remove(permission.MANAGE_USERS); 3195 3196 // System can retrieve the timestamp. 3197 mContext.binder.clearCallingIdentity(); 3198 assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime()); 3199 3200 // Removing the device owner should clear the timestamp. 3201 clearDeviceOwner(); 3202 assertEquals(-1, dpm.getLastNetworkLogRetrievalTime()); 3203 } 3204 3205 public void testGetBindDeviceAdminTargetUsers() throws Exception { 3206 // Setup device owner. 3207 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3208 setupDeviceOwner(); 3209 3210 // Only device owner is setup, the result list should be empty. 3211 List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 3212 MoreAsserts.assertEmpty(targetUsers); 3213 3214 // Setup a managed profile managed by the same admin. 3215 final int MANAGED_PROFILE_USER_ID = 15; 3216 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456); 3217 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 3218 3219 // Add a secondary user, it should never talk with. 3220 final int ANOTHER_USER_ID = 36; 3221 getServices().addUser(ANOTHER_USER_ID, 0); 3222 3223 // Since the managed profile is not affiliated, they should not be allowed to talk to each 3224 // other. 3225 targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 3226 MoreAsserts.assertEmpty(targetUsers); 3227 3228 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3229 targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 3230 MoreAsserts.assertEmpty(targetUsers); 3231 3232 // Setting affiliation ids 3233 final Set<String> userAffiliationIds = Collections.singleton("some.affiliation-id"); 3234 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3235 dpm.setAffiliationIds(admin1, userAffiliationIds); 3236 3237 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3238 dpm.setAffiliationIds(admin1, userAffiliationIds); 3239 3240 // Calling from device owner admin, the result list should just contain the managed 3241 // profile user id. 3242 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3243 targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 3244 MoreAsserts.assertContentsInAnyOrder(targetUsers, UserHandle.of(MANAGED_PROFILE_USER_ID)); 3245 3246 // Calling from managed profile admin, the result list should just contain the system 3247 // user id. 3248 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3249 targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 3250 MoreAsserts.assertContentsInAnyOrder(targetUsers, UserHandle.SYSTEM); 3251 3252 // Changing affiliation ids in one 3253 dpm.setAffiliationIds(admin1, Collections.singleton("some-different-affiliation-id")); 3254 3255 // Since the managed profile is not affiliated any more, they should not be allowed to talk 3256 // to each other. 3257 targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 3258 MoreAsserts.assertEmpty(targetUsers); 3259 3260 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3261 targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 3262 MoreAsserts.assertEmpty(targetUsers); 3263 } 3264 3265 public void testGetBindDeviceAdminTargetUsers_differentPackage() throws Exception { 3266 // Setup a device owner. 3267 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3268 setupDeviceOwner(); 3269 3270 // Set up a managed profile managed by different package. 3271 final int MANAGED_PROFILE_USER_ID = 15; 3272 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456); 3273 final ComponentName adminDifferentPackage = 3274 new ComponentName("another.package", "whatever.class"); 3275 addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2); 3276 3277 // Setting affiliation ids 3278 final Set<String> userAffiliationIds = Collections.singleton("some-affiliation-id"); 3279 dpm.setAffiliationIds(admin1, userAffiliationIds); 3280 3281 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3282 dpm.setAffiliationIds(adminDifferentPackage, userAffiliationIds); 3283 3284 // Calling from device owner admin, we should get zero bind device admin target users as 3285 // their packages are different. 3286 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3287 List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 3288 MoreAsserts.assertEmpty(targetUsers); 3289 3290 // Calling from managed profile admin, we should still get zero target users for the same 3291 // reason. 3292 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3293 targetUsers = dpm.getBindDeviceAdminTargetUsers(adminDifferentPackage); 3294 MoreAsserts.assertEmpty(targetUsers); 3295 } 3296 3297 public void testLockTaskPackagesAllowedForAffiliatedUsers() throws Exception { 3298 // Setup a device owner. 3299 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3300 setupDeviceOwner(); 3301 // Lock task packages are updated when loading user data. 3302 verify(getServices().iactivityManager) 3303 .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(new String[0])); 3304 3305 // Set up a managed profile managed by different package (package name shouldn't matter) 3306 final int MANAGED_PROFILE_USER_ID = 15; 3307 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456); 3308 final ComponentName adminDifferentPackage = 3309 new ComponentName("another.package", "whatever.class"); 3310 addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2); 3311 verify(getServices().iactivityManager) 3312 .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0])); 3313 3314 // The DO can still set lock task packages 3315 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3316 final String[] doPackages = {"doPackage1", "doPackage2"}; 3317 dpm.setLockTaskPackages(admin1, doPackages); 3318 MoreAsserts.assertEquals(doPackages, dpm.getLockTaskPackages(admin1)); 3319 assertTrue(dpm.isLockTaskPermitted("doPackage1")); 3320 assertFalse(dpm.isLockTaskPermitted("anotherPackage")); 3321 verify(getServices().iactivityManager) 3322 .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(doPackages)); 3323 3324 // Managed profile is unaffiliated - shouldn't be able to setLockTaskPackages. 3325 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3326 final String[] poPackages = {"poPackage1", "poPackage2"}; 3327 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 3328 () -> dpm.setLockTaskPackages(adminDifferentPackage, poPackages)); 3329 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 3330 () -> dpm.getLockTaskPackages(adminDifferentPackage)); 3331 assertFalse(dpm.isLockTaskPermitted("doPackage1")); 3332 3333 // Setting same affiliation ids 3334 final Set<String> userAffiliationIds = Collections.singleton("some-affiliation-id"); 3335 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3336 dpm.setAffiliationIds(admin1, userAffiliationIds); 3337 3338 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3339 dpm.setAffiliationIds(adminDifferentPackage, userAffiliationIds); 3340 3341 // Now the managed profile can set lock task packages. 3342 dpm.setLockTaskPackages(adminDifferentPackage, poPackages); 3343 MoreAsserts.assertEquals(poPackages, dpm.getLockTaskPackages(adminDifferentPackage)); 3344 assertTrue(dpm.isLockTaskPermitted("poPackage1")); 3345 assertFalse(dpm.isLockTaskPermitted("doPackage2")); 3346 verify(getServices().iactivityManager) 3347 .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(poPackages)); 3348 3349 // Unaffiliate the profile, lock task mode no longer available on the profile. 3350 dpm.setAffiliationIds(adminDifferentPackage, Collections.emptySet()); 3351 assertFalse(dpm.isLockTaskPermitted("poPackage1")); 3352 // Lock task packages cleared when loading user data and when the user becomes unaffiliated. 3353 verify(getServices().iactivityManager, times(2)) 3354 .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0])); 3355 3356 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3357 assertTrue(dpm.isLockTaskPermitted("doPackage1")); 3358 } 3359 3360 public void testIsDeviceManaged() throws Exception { 3361 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3362 setupDeviceOwner(); 3363 3364 // The device owner itself, any uid holding MANAGE_USERS permission and the system can 3365 // find out that the device has a device owner. 3366 assertTrue(dpm.isDeviceManaged()); 3367 mContext.binder.callingUid = 1234567; 3368 mContext.callerPermissions.add(permission.MANAGE_USERS); 3369 assertTrue(dpm.isDeviceManaged()); 3370 mContext.callerPermissions.remove(permission.MANAGE_USERS); 3371 mContext.binder.clearCallingIdentity(); 3372 assertTrue(dpm.isDeviceManaged()); 3373 3374 clearDeviceOwner(); 3375 3376 // Any uid holding MANAGE_USERS permission and the system can find out that the device does 3377 // not have a device owner. 3378 mContext.binder.callingUid = 1234567; 3379 mContext.callerPermissions.add(permission.MANAGE_USERS); 3380 assertFalse(dpm.isDeviceManaged()); 3381 mContext.callerPermissions.remove(permission.MANAGE_USERS); 3382 mContext.binder.clearCallingIdentity(); 3383 assertFalse(dpm.isDeviceManaged()); 3384 } 3385 3386 public void testDeviceOwnerOrganizationName() throws Exception { 3387 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3388 setupDeviceOwner(); 3389 3390 dpm.setOrganizationName(admin1, "organization"); 3391 3392 // Device owner can retrieve organization managing the device. 3393 assertEquals("organization", dpm.getDeviceOwnerOrganizationName()); 3394 3395 // Any uid holding MANAGE_USERS permission can retrieve organization managing the device. 3396 mContext.binder.callingUid = 1234567; 3397 mContext.callerPermissions.add(permission.MANAGE_USERS); 3398 assertEquals("organization", dpm.getDeviceOwnerOrganizationName()); 3399 mContext.callerPermissions.remove(permission.MANAGE_USERS); 3400 3401 // System can retrieve organization managing the device. 3402 mContext.binder.clearCallingIdentity(); 3403 assertEquals("organization", dpm.getDeviceOwnerOrganizationName()); 3404 3405 // Removing the device owner clears the organization managing the device. 3406 clearDeviceOwner(); 3407 assertNull(dpm.getDeviceOwnerOrganizationName()); 3408 } 3409 3410 public void testWipeDataManagedProfile() throws Exception { 3411 final int MANAGED_PROFILE_USER_ID = 15; 3412 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 3413 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 3414 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3415 3416 // Even if the caller is the managed profile, the current user is the user 0 3417 when(getServices().iactivityManager.getCurrentUser()) 3418 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 3419 3420 dpm.wipeData(0); 3421 verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed( 3422 MANAGED_PROFILE_USER_ID); 3423 } 3424 3425 public void testWipeDataManagedProfileDisallowed() throws Exception { 3426 final int MANAGED_PROFILE_USER_ID = 15; 3427 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 3428 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 3429 3430 // Even if the caller is the managed profile, the current user is the user 0 3431 when(getServices().iactivityManager.getCurrentUser()) 3432 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 3433 3434 when(getServices().userManager.getUserRestrictionSource( 3435 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, 3436 UserHandle.of(MANAGED_PROFILE_USER_ID))) 3437 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 3438 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3439 // The PO is not allowed to remove the profile if the user restriction was set on the 3440 // profile by the system 3441 assertExpectException(SecurityException.class, /* messageRegex= */ null, 3442 () -> dpm.wipeData(0)); 3443 } 3444 3445 public void testWipeDataDeviceOwner() throws Exception { 3446 setDeviceOwner(); 3447 when(getServices().userManager.getUserRestrictionSource( 3448 UserManager.DISALLOW_FACTORY_RESET, 3449 UserHandle.SYSTEM)) 3450 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 3451 3452 dpm.wipeData(0); 3453 verify(getServices().recoverySystem).rebootWipeUserData( 3454 /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true), 3455 /*wipeEuicc=*/ eq(false)); 3456 } 3457 3458 public void testWipeEuiccDataEnabled() throws Exception { 3459 setDeviceOwner(); 3460 when(getServices().userManager.getUserRestrictionSource( 3461 UserManager.DISALLOW_FACTORY_RESET, 3462 UserHandle.SYSTEM)) 3463 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 3464 3465 dpm.wipeData(WIPE_EUICC); 3466 verify(getServices().recoverySystem).rebootWipeUserData( 3467 /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true), 3468 /*wipeEuicc=*/ eq(true)); 3469 } 3470 3471 public void testWipeDataDeviceOwnerDisallowed() throws Exception { 3472 setDeviceOwner(); 3473 when(getServices().userManager.getUserRestrictionSource( 3474 UserManager.DISALLOW_FACTORY_RESET, 3475 UserHandle.SYSTEM)) 3476 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 3477 // The DO is not allowed to wipe the device if the user restriction was set 3478 // by the system 3479 assertExpectException(SecurityException.class, /* messageRegex= */ null, 3480 () -> dpm.wipeData(0)); 3481 } 3482 3483 public void testMaximumFailedPasswordAttemptsReachedManagedProfile() throws Exception { 3484 final int MANAGED_PROFILE_USER_ID = 15; 3485 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 3486 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 3487 3488 // Even if the caller is the managed profile, the current user is the user 0 3489 when(getServices().iactivityManager.getCurrentUser()) 3490 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 3491 3492 when(getServices().userManager.getUserRestrictionSource( 3493 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, 3494 UserHandle.of(MANAGED_PROFILE_USER_ID))) 3495 .thenReturn(UserManager.RESTRICTION_SOURCE_PROFILE_OWNER); 3496 3497 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3498 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 3499 3500 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 3501 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 3502 // Failed password attempts on the parent user are taken into account, as there isn't a 3503 // separate work challenge. 3504 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3505 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3506 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3507 3508 // The profile should be wiped even if DISALLOW_REMOVE_MANAGED_PROFILE is enabled, because 3509 // both the user restriction and the policy were set by the PO. 3510 verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed( 3511 MANAGED_PROFILE_USER_ID); 3512 verifyZeroInteractions(getServices().recoverySystem); 3513 } 3514 3515 public void testMaximumFailedPasswordAttemptsReachedManagedProfileDisallowed() 3516 throws Exception { 3517 final int MANAGED_PROFILE_USER_ID = 15; 3518 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 3519 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 3520 3521 // Even if the caller is the managed profile, the current user is the user 0 3522 when(getServices().iactivityManager.getCurrentUser()) 3523 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 3524 3525 when(getServices().userManager.getUserRestrictionSource( 3526 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, 3527 UserHandle.of(MANAGED_PROFILE_USER_ID))) 3528 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 3529 3530 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3531 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 3532 3533 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 3534 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 3535 // Failed password attempts on the parent user are taken into account, as there isn't a 3536 // separate work challenge. 3537 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3538 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3539 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3540 3541 // DISALLOW_REMOVE_MANAGED_PROFILE was set by the system, not the PO, so the profile is 3542 // not wiped. 3543 verify(getServices().userManagerInternal, never()) 3544 .removeUserEvenWhenDisallowed(anyInt()); 3545 verifyZeroInteractions(getServices().recoverySystem); 3546 } 3547 3548 public void testMaximumFailedPasswordAttemptsReachedDeviceOwner() throws Exception { 3549 setDeviceOwner(); 3550 when(getServices().userManager.getUserRestrictionSource( 3551 UserManager.DISALLOW_FACTORY_RESET, 3552 UserHandle.SYSTEM)) 3553 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 3554 3555 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 3556 3557 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 3558 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 3559 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3560 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3561 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3562 3563 // The device should be wiped even if DISALLOW_FACTORY_RESET is enabled, because both the 3564 // user restriction and the policy were set by the DO. 3565 verify(getServices().recoverySystem).rebootWipeUserData( 3566 /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true), 3567 /*wipeEuicc=*/ eq(false)); 3568 } 3569 3570 public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception { 3571 setDeviceOwner(); 3572 when(getServices().userManager.getUserRestrictionSource( 3573 UserManager.DISALLOW_FACTORY_RESET, 3574 UserHandle.SYSTEM)) 3575 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 3576 3577 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 3578 3579 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 3580 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 3581 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3582 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3583 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 3584 3585 // DISALLOW_FACTORY_RESET was set by the system, not the DO, so the device is not wiped. 3586 verifyZeroInteractions(getServices().recoverySystem); 3587 verify(getServices().userManagerInternal, never()) 3588 .removeUserEvenWhenDisallowed(anyInt()); 3589 } 3590 3591 public void testGetPermissionGrantState() throws Exception { 3592 final String permission = "some.permission"; 3593 final String app1 = "com.example.app1"; 3594 final String app2 = "com.example.app2"; 3595 3596 when(getServices().ipackageManager.checkPermission(eq(permission), eq(app1), anyInt())) 3597 .thenReturn(PackageManager.PERMISSION_GRANTED); 3598 doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(getServices().packageManager) 3599 .getPermissionFlags(permission, app1, UserHandle.SYSTEM); 3600 when(getServices().packageManager.getPermissionFlags(permission, app1, 3601 UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))) 3602 .thenReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED); 3603 when(getServices().ipackageManager.checkPermission(eq(permission), eq(app2), anyInt())) 3604 .thenReturn(PackageManager.PERMISSION_DENIED); 3605 doReturn(0).when(getServices().packageManager).getPermissionFlags(permission, app2, 3606 UserHandle.SYSTEM); 3607 when(getServices().packageManager.getPermissionFlags(permission, app2, 3608 UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(0); 3609 3610 // System can retrieve permission grant state. 3611 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 3612 mContext.packageName = "com.example.system"; 3613 assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED, 3614 dpm.getPermissionGrantState(null, app1, permission)); 3615 assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT, 3616 dpm.getPermissionGrantState(null, app2, permission)); 3617 3618 // A regular app cannot retrieve permission grant state. 3619 mContext.binder.callingUid = setupPackageInPackageManager(app1, 1); 3620 mContext.packageName = app1; 3621 assertExpectException(SecurityException.class, /* messageRegex= */ null, 3622 () -> dpm.getPermissionGrantState(null, app1, permission)); 3623 3624 // Profile owner can retrieve permission grant state. 3625 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 3626 mContext.packageName = admin1.getPackageName(); 3627 setAsProfileOwner(admin1); 3628 assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED, 3629 dpm.getPermissionGrantState(admin1, app1, permission)); 3630 assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT, 3631 dpm.getPermissionGrantState(admin1, app2, permission)); 3632 } 3633 3634 public void testResetPasswordWithToken() throws Exception { 3635 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3636 setupDeviceOwner(); 3637 // test token validation 3638 assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null, 3639 () -> dpm.setResetPasswordToken(admin1, new byte[31])); 3640 3641 // test adding a token 3642 final byte[] token = new byte[32]; 3643 final long handle = 123456; 3644 final String password = "password"; 3645 when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM))) 3646 .thenReturn(handle); 3647 assertTrue(dpm.setResetPasswordToken(admin1, token)); 3648 3649 // test password activation 3650 when(getServices().lockPatternUtils.isEscrowTokenActive(eq(handle), eq(UserHandle.USER_SYSTEM))) 3651 .thenReturn(true); 3652 assertTrue(dpm.isResetPasswordTokenActive(admin1)); 3653 3654 // test reset password with token 3655 when(getServices().lockPatternUtils.setLockCredentialWithToken(eq(password), 3656 eq(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), 3657 eq(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED), eq(handle), eq(token), 3658 eq(UserHandle.USER_SYSTEM))) 3659 .thenReturn(true); 3660 assertTrue(dpm.resetPasswordWithToken(admin1, password, token, 0)); 3661 3662 // test removing a token 3663 when(getServices().lockPatternUtils.removeEscrowToken(eq(handle), eq(UserHandle.USER_SYSTEM))) 3664 .thenReturn(true); 3665 assertTrue(dpm.clearResetPasswordToken(admin1)); 3666 } 3667 3668 public void testIsActivePasswordSufficient() throws Exception { 3669 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3670 mContext.packageName = admin1.getPackageName(); 3671 setupDeviceOwner(); 3672 3673 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX); 3674 dpm.setPasswordMinimumLength(admin1, 8); 3675 dpm.setPasswordMinimumLetters(admin1, 6); 3676 dpm.setPasswordMinimumLowerCase(admin1, 3); 3677 dpm.setPasswordMinimumUpperCase(admin1, 1); 3678 dpm.setPasswordMinimumNonLetter(admin1, 1); 3679 dpm.setPasswordMinimumNumeric(admin1, 1); 3680 dpm.setPasswordMinimumSymbols(admin1, 0); 3681 3682 PasswordMetrics passwordMetricsNoSymbols = new PasswordMetrics( 3683 DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 9, 3684 8, 2, 3685 6, 1, 3686 0, 1); 3687 3688 setActivePasswordState(passwordMetricsNoSymbols); 3689 assertTrue(dpm.isActivePasswordSufficient()); 3690 3691 initializeDpms(); 3692 reset(mContext.spiedContext); 3693 assertTrue(dpm.isActivePasswordSufficient()); 3694 3695 // This call simulates the user entering the password for the first time after a reboot. 3696 // This causes password metrics to be reloaded into memory. Until this happens, 3697 // dpm.isActivePasswordSufficient() will continue to return its last checkpointed value, 3698 // even if the DPC changes password requirements so that the password no longer meets the 3699 // requirements. This is a known limitation of the current implementation of 3700 // isActivePasswordSufficient() - see b/34218769. 3701 setActivePasswordState(passwordMetricsNoSymbols); 3702 assertTrue(dpm.isActivePasswordSufficient()); 3703 3704 dpm.setPasswordMinimumSymbols(admin1, 1); 3705 // This assertion would fail if we had not called setActivePasswordState() again after 3706 // initializeDpms() - see previous comment. 3707 assertFalse(dpm.isActivePasswordSufficient()); 3708 3709 initializeDpms(); 3710 reset(mContext.spiedContext); 3711 assertFalse(dpm.isActivePasswordSufficient()); 3712 3713 PasswordMetrics passwordMetricsWithSymbols = new PasswordMetrics( 3714 DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, 9, 3715 7, 2, 3716 5, 1, 3717 1, 2); 3718 3719 setActivePasswordState(passwordMetricsWithSymbols); 3720 assertTrue(dpm.isActivePasswordSufficient()); 3721 } 3722 3723 private void setActivePasswordState(PasswordMetrics passwordMetrics) 3724 throws Exception { 3725 final int userHandle = UserHandle.getUserId(mContext.binder.callingUid); 3726 final long ident = mContext.binder.clearCallingIdentity(); 3727 3728 dpm.setActivePasswordState(passwordMetrics, userHandle); 3729 dpm.reportPasswordChanged(userHandle); 3730 3731 final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED); 3732 intent.setComponent(admin1); 3733 intent.putExtra(Intent.EXTRA_USER, UserHandle.of(mContext.binder.callingUid)); 3734 3735 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 3736 MockUtils.checkIntent(intent), 3737 MockUtils.checkUserHandle(userHandle)); 3738 3739 // CertificateMonitor.updateInstalledCertificates is called on the background thread, 3740 // let it finish with system uid, otherwise it will throw and crash. 3741 flushTasks(); 3742 3743 mContext.binder.restoreCallingIdentity(ident); 3744 } 3745 3746 public void testIsCurrentInputMethodSetByOwnerForDeviceOwner() throws Exception { 3747 final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD; 3748 final Uri currentImeUri = Settings.Secure.getUriFor(currentIme); 3749 final int deviceOwnerUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3750 final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM, 3751 DpmMockContext.SYSTEM_UID); 3752 final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, 3753 DpmMockContext.SYSTEM_UID); 3754 3755 // Set up a device owner. 3756 mContext.binder.callingUid = deviceOwnerUid; 3757 setupDeviceOwner(); 3758 3759 // First and second user set IMEs manually. 3760 mContext.binder.callingUid = firstUserSystemUid; 3761 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3762 mContext.binder.callingUid = secondUserSystemUid; 3763 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3764 3765 // Device owner changes IME for first user. 3766 mContext.binder.callingUid = deviceOwnerUid; 3767 when(getServices().settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM)) 3768 .thenReturn("ime1"); 3769 dpm.setSecureSetting(admin1, currentIme, "ime2"); 3770 verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2", 3771 UserHandle.USER_SYSTEM); 3772 reset(getServices().settings); 3773 dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); 3774 mContext.binder.callingUid = firstUserSystemUid; 3775 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3776 mContext.binder.callingUid = secondUserSystemUid; 3777 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3778 3779 // Second user changes IME manually. 3780 dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); 3781 mContext.binder.callingUid = firstUserSystemUid; 3782 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3783 mContext.binder.callingUid = secondUserSystemUid; 3784 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3785 3786 // First user changes IME manually. 3787 dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); 3788 mContext.binder.callingUid = firstUserSystemUid; 3789 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3790 mContext.binder.callingUid = secondUserSystemUid; 3791 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3792 3793 // Device owner changes IME for first user again. 3794 mContext.binder.callingUid = deviceOwnerUid; 3795 when(getServices().settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM)) 3796 .thenReturn("ime2"); 3797 dpm.setSecureSetting(admin1, currentIme, "ime3"); 3798 verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3", 3799 UserHandle.USER_SYSTEM); 3800 dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); 3801 mContext.binder.callingUid = firstUserSystemUid; 3802 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3803 mContext.binder.callingUid = secondUserSystemUid; 3804 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3805 3806 // Restarting the DPMS should not lose information. 3807 initializeDpms(); 3808 mContext.binder.callingUid = firstUserSystemUid; 3809 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3810 mContext.binder.callingUid = secondUserSystemUid; 3811 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3812 3813 // Device owner can find out whether it set the current IME itself. 3814 mContext.binder.callingUid = deviceOwnerUid; 3815 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3816 3817 // Removing the device owner should clear the information that it set the current IME. 3818 clearDeviceOwner(); 3819 mContext.binder.callingUid = firstUserSystemUid; 3820 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3821 mContext.binder.callingUid = secondUserSystemUid; 3822 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3823 } 3824 3825 public void testIsCurrentInputMethodSetByOwnerForProfileOwner() throws Exception { 3826 final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD; 3827 final Uri currentImeUri = Settings.Secure.getUriFor(currentIme); 3828 final int profileOwnerUid = DpmMockContext.CALLER_UID; 3829 final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM, 3830 DpmMockContext.SYSTEM_UID); 3831 final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, 3832 DpmMockContext.SYSTEM_UID); 3833 3834 // Set up a profile owner. 3835 mContext.binder.callingUid = profileOwnerUid; 3836 setupProfileOwner(); 3837 3838 // First and second user set IMEs manually. 3839 mContext.binder.callingUid = firstUserSystemUid; 3840 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3841 mContext.binder.callingUid = secondUserSystemUid; 3842 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3843 3844 // Profile owner changes IME for second user. 3845 mContext.binder.callingUid = profileOwnerUid; 3846 when(getServices().settings.settingsSecureGetStringForUser(currentIme, 3847 DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime1"); 3848 dpm.setSecureSetting(admin1, currentIme, "ime2"); 3849 verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2", 3850 DpmMockContext.CALLER_USER_HANDLE); 3851 reset(getServices().settings); 3852 dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); 3853 mContext.binder.callingUid = firstUserSystemUid; 3854 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3855 mContext.binder.callingUid = secondUserSystemUid; 3856 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3857 3858 // First user changes IME manually. 3859 dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); 3860 mContext.binder.callingUid = firstUserSystemUid; 3861 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3862 mContext.binder.callingUid = secondUserSystemUid; 3863 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3864 3865 // Second user changes IME manually. 3866 dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); 3867 mContext.binder.callingUid = firstUserSystemUid; 3868 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3869 mContext.binder.callingUid = secondUserSystemUid; 3870 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3871 3872 // Profile owner changes IME for second user again. 3873 mContext.binder.callingUid = profileOwnerUid; 3874 when(getServices().settings.settingsSecureGetStringForUser(currentIme, 3875 DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime2"); 3876 dpm.setSecureSetting(admin1, currentIme, "ime3"); 3877 verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3", 3878 DpmMockContext.CALLER_USER_HANDLE); 3879 dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); 3880 mContext.binder.callingUid = firstUserSystemUid; 3881 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3882 mContext.binder.callingUid = secondUserSystemUid; 3883 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3884 3885 // Restarting the DPMS should not lose information. 3886 initializeDpms(); 3887 mContext.binder.callingUid = firstUserSystemUid; 3888 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3889 mContext.binder.callingUid = secondUserSystemUid; 3890 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3891 3892 // Profile owner can find out whether it set the current IME itself. 3893 mContext.binder.callingUid = profileOwnerUid; 3894 assertTrue(dpm.isCurrentInputMethodSetByOwner()); 3895 3896 // Removing the profile owner should clear the information that it set the current IME. 3897 dpm.clearProfileOwner(admin1); 3898 mContext.binder.callingUid = firstUserSystemUid; 3899 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3900 mContext.binder.callingUid = secondUserSystemUid; 3901 assertFalse(dpm.isCurrentInputMethodSetByOwner()); 3902 } 3903 3904 public void testSetPermittedCrossProfileNotificationListeners_unavailableForDo() 3905 throws Exception { 3906 // Set up a device owner. 3907 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3908 setupDeviceOwner(); 3909 assertSetPermittedCrossProfileNotificationListenersUnavailable(mContext.binder.callingUid); 3910 } 3911 3912 public void testSetPermittedCrossProfileNotificationListeners_unavailableForPoOnUser() 3913 throws Exception { 3914 // Set up a profile owner. 3915 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 3916 setupProfileOwner(); 3917 assertSetPermittedCrossProfileNotificationListenersUnavailable(mContext.binder.callingUid); 3918 } 3919 3920 private void assertSetPermittedCrossProfileNotificationListenersUnavailable( 3921 int adminUid) throws Exception { 3922 mContext.binder.callingUid = adminUid; 3923 final int userId = UserHandle.getUserId(adminUid); 3924 3925 final String packageName = "some.package"; 3926 assertFalse(dpms.setPermittedCrossProfileNotificationListeners( 3927 admin1, Collections.singletonList(packageName))); 3928 assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1)); 3929 3930 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 3931 assertTrue(dpms.isNotificationListenerServicePermitted(packageName, userId)); 3932 3933 // Attempt to set to empty list (which means no listener is whitelisted) 3934 mContext.binder.callingUid = adminUid; 3935 assertFalse(dpms.setPermittedCrossProfileNotificationListeners( 3936 admin1, Collections.emptyList())); 3937 assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1)); 3938 3939 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 3940 assertTrue(dpms.isNotificationListenerServicePermitted(packageName, userId)); 3941 } 3942 3943 public void testIsNotificationListenerServicePermitted_onlySystemCanCall() throws Exception { 3944 // Set up a managed profile 3945 final int MANAGED_PROFILE_USER_ID = 15; 3946 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 3947 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 3948 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3949 3950 final String permittedListener = "some.package"; 3951 setupPackageInPackageManager( 3952 permittedListener, 3953 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 3954 /*appId=*/ 12345, /*flags=*/ 0); 3955 3956 assertTrue(dpms.setPermittedCrossProfileNotificationListeners( 3957 admin1, Collections.singletonList(permittedListener))); 3958 3959 // isNotificationListenerServicePermitted should throw if not called from System. 3960 assertExpectException(SecurityException.class, /* messageRegex= */ null, 3961 () -> dpms.isNotificationListenerServicePermitted( 3962 permittedListener, MANAGED_PROFILE_USER_ID)); 3963 3964 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 3965 assertTrue(dpms.isNotificationListenerServicePermitted( 3966 permittedListener, MANAGED_PROFILE_USER_ID)); 3967 } 3968 3969 public void testSetPermittedCrossProfileNotificationListeners_managedProfile() 3970 throws Exception { 3971 // Set up a managed profile 3972 final int MANAGED_PROFILE_USER_ID = 15; 3973 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 3974 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 3975 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 3976 3977 final String permittedListener = "permitted.package"; 3978 int appId = 12345; 3979 setupPackageInPackageManager( 3980 permittedListener, 3981 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 3982 appId, /*flags=*/ 0); 3983 3984 final String notPermittedListener = "not.permitted.package"; 3985 setupPackageInPackageManager( 3986 notPermittedListener, 3987 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 3988 ++appId, /*flags=*/ 0); 3989 3990 final String systemListener = "system.package"; 3991 setupPackageInPackageManager( 3992 systemListener, 3993 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 3994 ++appId, ApplicationInfo.FLAG_SYSTEM); 3995 3996 // By default all packages are allowed 3997 assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1)); 3998 3999 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4000 assertTrue(dpms.isNotificationListenerServicePermitted( 4001 permittedListener, MANAGED_PROFILE_USER_ID)); 4002 assertTrue(dpms.isNotificationListenerServicePermitted( 4003 notPermittedListener, MANAGED_PROFILE_USER_ID)); 4004 assertTrue(dpms.isNotificationListenerServicePermitted( 4005 systemListener, MANAGED_PROFILE_USER_ID)); 4006 4007 // Setting only one package in the whitelist 4008 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4009 assertTrue(dpms.setPermittedCrossProfileNotificationListeners( 4010 admin1, Collections.singletonList(permittedListener))); 4011 final List<String> permittedListeners = 4012 dpms.getPermittedCrossProfileNotificationListeners(admin1); 4013 assertEquals(1, permittedListeners.size()); 4014 assertEquals(permittedListener, permittedListeners.get(0)); 4015 4016 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4017 assertTrue(dpms.isNotificationListenerServicePermitted( 4018 permittedListener, MANAGED_PROFILE_USER_ID)); 4019 assertFalse(dpms.isNotificationListenerServicePermitted( 4020 notPermittedListener, MANAGED_PROFILE_USER_ID)); 4021 // System packages are always allowed (even if not in the whitelist) 4022 assertTrue(dpms.isNotificationListenerServicePermitted( 4023 systemListener, MANAGED_PROFILE_USER_ID)); 4024 4025 // Setting an empty whitelist - only system listeners allowed 4026 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4027 assertTrue(dpms.setPermittedCrossProfileNotificationListeners( 4028 admin1, Collections.emptyList())); 4029 assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size()); 4030 4031 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4032 assertFalse(dpms.isNotificationListenerServicePermitted( 4033 permittedListener, MANAGED_PROFILE_USER_ID)); 4034 assertFalse(dpms.isNotificationListenerServicePermitted( 4035 notPermittedListener, MANAGED_PROFILE_USER_ID)); 4036 // System packages are always allowed (even if not in the whitelist) 4037 assertTrue(dpms.isNotificationListenerServicePermitted( 4038 systemListener, MANAGED_PROFILE_USER_ID)); 4039 4040 // Setting a null whitelist - all listeners allowed 4041 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4042 assertTrue(dpms.setPermittedCrossProfileNotificationListeners(admin1, null)); 4043 assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1)); 4044 4045 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4046 assertTrue(dpms.isNotificationListenerServicePermitted( 4047 permittedListener, MANAGED_PROFILE_USER_ID)); 4048 assertTrue(dpms.isNotificationListenerServicePermitted( 4049 notPermittedListener, MANAGED_PROFILE_USER_ID)); 4050 assertTrue(dpms.isNotificationListenerServicePermitted( 4051 systemListener, MANAGED_PROFILE_USER_ID)); 4052 } 4053 4054 public void testSetPermittedCrossProfileNotificationListeners_doesNotAffectPrimaryProfile() 4055 throws Exception { 4056 // Set up a managed profile 4057 final int MANAGED_PROFILE_USER_ID = 15; 4058 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 4059 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 4060 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4061 4062 final String nonSystemPackage = "non.system.package"; 4063 int appId = 12345; 4064 setupPackageInPackageManager( 4065 nonSystemPackage, 4066 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 4067 appId, /*flags=*/ 0); 4068 4069 final String systemListener = "system.package"; 4070 setupPackageInPackageManager( 4071 systemListener, 4072 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 4073 ++appId, ApplicationInfo.FLAG_SYSTEM); 4074 4075 // By default all packages are allowed (for all profiles) 4076 assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1)); 4077 4078 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4079 assertTrue(dpms.isNotificationListenerServicePermitted( 4080 nonSystemPackage, MANAGED_PROFILE_USER_ID)); 4081 assertTrue(dpms.isNotificationListenerServicePermitted( 4082 systemListener, MANAGED_PROFILE_USER_ID)); 4083 assertTrue(dpms.isNotificationListenerServicePermitted( 4084 nonSystemPackage, UserHandle.USER_SYSTEM)); 4085 assertTrue(dpms.isNotificationListenerServicePermitted( 4086 systemListener, UserHandle.USER_SYSTEM)); 4087 4088 // Setting an empty whitelist - only system listeners allowed in managed profile, but 4089 // all allowed in primary profile 4090 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4091 assertTrue(dpms.setPermittedCrossProfileNotificationListeners( 4092 admin1, Collections.emptyList())); 4093 assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size()); 4094 4095 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4096 assertFalse(dpms.isNotificationListenerServicePermitted( 4097 nonSystemPackage, MANAGED_PROFILE_USER_ID)); 4098 assertTrue(dpms.isNotificationListenerServicePermitted( 4099 systemListener, MANAGED_PROFILE_USER_ID)); 4100 assertTrue(dpms.isNotificationListenerServicePermitted( 4101 nonSystemPackage, UserHandle.USER_SYSTEM)); 4102 assertTrue(dpms.isNotificationListenerServicePermitted( 4103 systemListener, UserHandle.USER_SYSTEM)); 4104 } 4105 4106 public void testGetOwnerInstalledCaCertsForDeviceOwner() throws Exception { 4107 mServiceContext.packageName = mRealTestContext.getPackageName(); 4108 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4109 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4110 setDeviceOwner(); 4111 4112 verifyCanGetOwnerInstalledCaCerts(admin1, mAdmin1Context); 4113 } 4114 4115 public void testGetOwnerInstalledCaCertsForProfileOwner() throws Exception { 4116 mServiceContext.packageName = mRealTestContext.getPackageName(); 4117 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4118 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID; 4119 setAsProfileOwner(admin1); 4120 4121 verifyCanGetOwnerInstalledCaCerts(admin1, mAdmin1Context); 4122 verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(admin1, mAdmin1Context); 4123 } 4124 4125 public void testGetOwnerInstalledCaCertsForDelegate() throws Exception { 4126 mServiceContext.packageName = mRealTestContext.getPackageName(); 4127 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4128 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID; 4129 setAsProfileOwner(admin1); 4130 4131 final DpmMockContext caller = new DpmMockContext(getServices(), mRealTestContext); 4132 caller.packageName = "com.example.delegate"; 4133 caller.binder.callingUid = setupPackageInPackageManager(caller.packageName, 4134 DpmMockContext.CALLER_USER_HANDLE, 20988, ApplicationInfo.FLAG_HAS_CODE); 4135 4136 // Make caller a delegated cert installer. 4137 runAsCaller(mAdmin1Context, dpms, 4138 dpm -> dpm.setCertInstallerPackage(admin1, caller.packageName)); 4139 4140 verifyCanGetOwnerInstalledCaCerts(null, caller); 4141 verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(null, caller); 4142 } 4143 4144 private void verifyCanGetOwnerInstalledCaCerts( 4145 final ComponentName caller, final DpmMockContext callerContext) throws Exception { 4146 final String alias = "cert"; 4147 final byte[] caCert = TEST_CA.getBytes(); 4148 4149 // device admin (used for posting the tls notification) 4150 DpmMockContext admin1Context = mAdmin1Context; 4151 if (admin1.getPackageName().equals(callerContext.getPackageName())) { 4152 admin1Context = callerContext; 4153 } 4154 when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE); 4155 4156 // caller: device admin or delegated certificate installer 4157 callerContext.applicationInfo = new ApplicationInfo(); 4158 final UserHandle callerUser = callerContext.binder.getCallingUserHandle(); 4159 4160 // system_server 4161 final DpmMockContext serviceContext = mContext; 4162 serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4163 getServices().addPackageContext(callerUser, admin1Context); 4164 getServices().addPackageContext(callerUser, callerContext); 4165 4166 // Install a CA cert. 4167 runAsCaller(callerContext, dpms, (dpm) -> { 4168 when(getServices().keyChainConnection.getService().installCaCertificate(caCert)) 4169 .thenReturn(alias); 4170 assertTrue(dpm.installCaCert(caller, caCert)); 4171 when(getServices().keyChainConnection.getService().getUserCaAliases()) 4172 .thenReturn(asSlice(new String[] {alias})); 4173 }); 4174 4175 getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED) 4176 .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()), 4177 callerUser.getIdentifier()); 4178 flushTasks(); 4179 4180 final List<String> ownerInstalledCaCerts = new ArrayList<>(); 4181 4182 // Device Owner / Profile Owner can find out which CA certs were installed by itself. 4183 runAsCaller(admin1Context, dpms, (dpm) -> { 4184 final List<String> installedCaCerts = dpm.getOwnerInstalledCaCerts(callerUser); 4185 assertEquals(Collections.singletonList(alias), installedCaCerts); 4186 ownerInstalledCaCerts.addAll(installedCaCerts); 4187 }); 4188 4189 // Restarting the DPMS should not lose information. 4190 initializeDpms(); 4191 runAsCaller(admin1Context, dpms, (dpm) -> 4192 assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser))); 4193 4194 // System can find out which CA certs were installed by the Device Owner / Profile Owner. 4195 runAsCaller(serviceContext, dpms, (dpm) -> { 4196 assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser)); 4197 4198 // Remove the CA cert. 4199 reset(getServices().keyChainConnection.getService()); 4200 }); 4201 4202 getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED) 4203 .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()), 4204 callerUser.getIdentifier()); 4205 flushTasks(); 4206 4207 // Verify that the CA cert is no longer reported as installed by the Device Owner / Profile 4208 // Owner. 4209 runAsCaller(admin1Context, dpms, (dpm) -> { 4210 MoreAsserts.assertEmpty(dpm.getOwnerInstalledCaCerts(callerUser)); 4211 }); 4212 } 4213 4214 private void verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval( 4215 final ComponentName callerName, final DpmMockContext callerContext) throws Exception { 4216 final String alias = "cert"; 4217 final byte[] caCert = TEST_CA.getBytes(); 4218 4219 // device admin (used for posting the tls notification) 4220 DpmMockContext admin1Context = mAdmin1Context; 4221 if (admin1.getPackageName().equals(callerContext.getPackageName())) { 4222 admin1Context = callerContext; 4223 } 4224 when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE); 4225 4226 // caller: device admin or delegated certificate installer 4227 callerContext.applicationInfo = new ApplicationInfo(); 4228 final UserHandle callerUser = callerContext.binder.getCallingUserHandle(); 4229 4230 // system_server 4231 final DpmMockContext serviceContext = mContext; 4232 serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4233 getServices().addPackageContext(callerUser, admin1Context); 4234 getServices().addPackageContext(callerUser, callerContext); 4235 4236 // Install a CA cert as caller 4237 runAsCaller(callerContext, dpms, (dpm) -> { 4238 when(getServices().keyChainConnection.getService().installCaCertificate(caCert)) 4239 .thenReturn(alias); 4240 assertTrue(dpm.installCaCert(callerName, caCert)); 4241 }); 4242 4243 // Fake the CA cert as having been installed 4244 when(getServices().keyChainConnection.getService().getUserCaAliases()) 4245 .thenReturn(asSlice(new String[] {alias})); 4246 getServices().injectBroadcast(mServiceContext, new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED) 4247 .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()), 4248 callerUser.getIdentifier()); 4249 flushTasks(); 4250 4251 // Removing the Profile Owner should clear the information on which CA certs were installed 4252 runAsCaller(admin1Context, dpms, dpm -> dpm.clearProfileOwner(admin1)); 4253 4254 runAsCaller(serviceContext, dpms, (dpm) -> { 4255 final List<String> ownerInstalledCaCerts = dpm.getOwnerInstalledCaCerts(callerUser); 4256 assertNotNull(ownerInstalledCaCerts); 4257 assertTrue(ownerInstalledCaCerts.isEmpty()); 4258 }); 4259 } 4260 4261 private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) { 4262 when(getServices().settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0, 4263 userhandle)).thenReturn(isUserSetupComplete ? 1 : 0); 4264 dpms.notifyChangeToContentObserver( 4265 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), userhandle); 4266 } 4267 4268 private void assertProvisioningAllowed(String action, boolean expected) { 4269 assertEquals("isProvisioningAllowed(" + action + ") returning unexpected result", expected, 4270 dpm.isProvisioningAllowed(action)); 4271 } 4272 4273 private void assertProvisioningAllowed(String action, boolean expected, String packageName, 4274 int uid) { 4275 final String previousPackageName = mContext.packageName; 4276 final int previousUid = mMockContext.binder.callingUid; 4277 4278 // Call assertProvisioningAllowed with the packageName / uid passed as arguments. 4279 mContext.packageName = packageName; 4280 mMockContext.binder.callingUid = uid; 4281 assertProvisioningAllowed(action, expected); 4282 4283 // Set the previous package name / calling uid to go back to the initial state. 4284 mContext.packageName = previousPackageName; 4285 mMockContext.binder.callingUid = previousUid; 4286 } 4287 4288 private void assertCheckProvisioningPreCondition(String action, int provisioningCondition) { 4289 assertCheckProvisioningPreCondition(action, admin1.getPackageName(), provisioningCondition); 4290 } 4291 4292 private void assertCheckProvisioningPreCondition( 4293 String action, String packageName, int provisioningCondition) { 4294 assertEquals("checkProvisioningPreCondition(" 4295 + action + ", " + packageName + ") returning unexpected result", 4296 provisioningCondition, dpm.checkProvisioningPreCondition(action, packageName)); 4297 } 4298 4299 /** 4300 * Setup a managed profile with the specified admin and its uid. 4301 * @param admin ComponentName that's visible to the test code, which doesn't have to exist. 4302 * @param adminUid uid of the admin package. 4303 * @param copyFromAdmin package information for {@code admin} will be built based on this 4304 * component's information. 4305 */ 4306 private void addManagedProfile( 4307 ComponentName admin, int adminUid, ComponentName copyFromAdmin) throws Exception { 4308 final int userId = UserHandle.getUserId(adminUid); 4309 getServices().addUser(userId, UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_SYSTEM); 4310 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 4311 setUpPackageManagerForFakeAdmin(admin, adminUid, copyFromAdmin); 4312 dpm.setActiveAdmin(admin, false, userId); 4313 assertTrue(dpm.setProfileOwner(admin, null, userId)); 4314 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 4315 } 4316 4317 /** 4318 * Convert String[] to StringParceledListSlice. 4319 */ 4320 private static StringParceledListSlice asSlice(String[] s) { 4321 return new StringParceledListSlice(Arrays.asList(s)); 4322 } 4323 4324 private void flushTasks() throws Exception { 4325 dpms.mHandler.runWithScissors(() -> {}, 0 /*now*/); 4326 dpms.mBackgroundHandler.runWithScissors(() -> {}, 0 /*now*/); 4327 4328 // We can't let exceptions happen on the background thread. Throw them here if they happen 4329 // so they still cause the test to fail despite being suppressed. 4330 getServices().rethrowBackgroundBroadcastExceptions(); 4331 } 4332 } 4333