DevicePolicyManagerTest.java revision 97e89c624e19c0a0ebe3d76506a493cfe29c0558
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 */ 16package com.android.server.devicepolicy; 17 18import android.Manifest.permission; 19import android.app.Activity; 20import android.app.admin.DeviceAdminReceiver; 21import android.app.admin.DevicePolicyManager; 22import android.app.admin.DevicePolicyManagerInternal; 23import android.content.BroadcastReceiver; 24import android.content.ComponentName; 25import android.content.pm.ApplicationInfo; 26import android.content.pm.PackageInfo; 27import android.content.pm.PackageManager; 28import android.net.wifi.WifiInfo; 29import android.os.Build.VERSION_CODES; 30import android.os.Build; 31import android.os.Bundle; 32import android.os.Process; 33import android.os.UserHandle; 34import android.os.UserManager; 35import android.provider.Settings; 36import android.test.MoreAsserts; 37import android.test.suitebuilder.annotation.SmallTest; 38import android.util.ArraySet; 39import android.util.Pair; 40 41import com.android.server.LocalServices; 42import com.android.server.SystemService; 43 44import org.mockito.ArgumentCaptor; 45import org.mockito.invocation.InvocationOnMock; 46import org.mockito.stubbing.Answer; 47 48import java.util.ArrayList; 49import java.util.Arrays; 50import java.util.HashMap; 51import java.util.List; 52import java.util.Map; 53import java.util.Set; 54 55import static org.mockito.Matchers.any; 56import static org.mockito.Matchers.anyInt; 57import static org.mockito.Matchers.anyString; 58import static org.mockito.Matchers.eq; 59import static org.mockito.Matchers.isNull; 60import static org.mockito.Mockito.doAnswer; 61import static org.mockito.Mockito.doReturn; 62import static org.mockito.Mockito.reset; 63import static org.mockito.Mockito.times; 64import static org.mockito.Mockito.validateMockitoUsage; 65import static org.mockito.Mockito.verify; 66import static org.mockito.Mockito.when; 67 68/** 69 * Tests for DevicePolicyManager( and DevicePolicyManagerService). 70 * 71 m FrameworksServicesTests && 72 adb install \ 73 -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && 74 adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest \ 75 -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner 76 77 (mmma frameworks/base/services/tests/servicestests/ for non-ninja build) 78 */ 79@SmallTest 80public class DevicePolicyManagerTest extends DpmTestBase { 81 private static final List<String> OWNER_SETUP_PERMISSIONS = Arrays.asList( 82 permission.MANAGE_DEVICE_ADMINS, permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, 83 permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL); 84 85 private DpmMockContext mContext; 86 public DevicePolicyManager dpm; 87 public DevicePolicyManagerServiceTestable dpms; 88 89 @Override 90 protected void setUp() throws Exception { 91 super.setUp(); 92 93 mContext = getContext(); 94 95 when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN))) 96 .thenReturn(true); 97 98 // By default, pretend all users are running and unlocked. 99 when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true); 100 101 initializeDpms(); 102 103 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 104 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 105 setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID); 106 setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID); 107 108 setUpUserManager(); 109 } 110 111 private void initializeDpms() { 112 // Need clearCallingIdentity() to pass permission checks. 113 final long ident = mContext.binder.clearCallingIdentity(); 114 try { 115 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); 116 117 dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir); 118 119 dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY); 120 dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED); 121 122 dpm = new DevicePolicyManagerTestable(mContext, dpms); 123 } finally { 124 mContext.binder.restoreCallingIdentity(ident); 125 } 126 } 127 128 private void setUpUserManager() { 129 // Emulate UserManager.set/getApplicationRestriction(). 130 final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>(); 131 132 // UM.setApplicationRestrictions() will save to appRestrictions. 133 doAnswer(new Answer<Void>() { 134 @Override 135 public Void answer(InvocationOnMock invocation) throws Throwable { 136 String pkg = (String) invocation.getArguments()[0]; 137 Bundle bundle = (Bundle) invocation.getArguments()[1]; 138 UserHandle user = (UserHandle) invocation.getArguments()[2]; 139 140 appRestrictions.put(Pair.create(pkg, user), bundle); 141 142 return null; 143 } 144 }).when(mContext.userManager).setApplicationRestrictions( 145 anyString(), any(Bundle.class), any(UserHandle.class)); 146 147 // UM.getApplicationRestrictions() will read from appRestrictions. 148 doAnswer(new Answer<Bundle>() { 149 @Override 150 public Bundle answer(InvocationOnMock invocation) throws Throwable { 151 String pkg = (String) invocation.getArguments()[0]; 152 UserHandle user = (UserHandle) invocation.getArguments()[1]; 153 154 return appRestrictions.get(Pair.create(pkg, user)); 155 } 156 }).when(mContext.userManager).getApplicationRestrictions( 157 anyString(), any(UserHandle.class)); 158 159 // Add the first secondary user. 160 mContext.addUser(DpmMockContext.CALLER_USER_HANDLE, 0); 161 } 162 163 private void setAsProfileOwner(ComponentName admin) { 164 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 165 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 166 167 // PO needs to be an DA. 168 dpm.setActiveAdmin(admin, /* replace =*/ false); 169 170 // Fire! 171 assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE)); 172 173 // Check 174 assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE)); 175 } 176 177 public void testHasNoFeature() throws Exception { 178 when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN))) 179 .thenReturn(false); 180 181 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); 182 new DevicePolicyManagerServiceTestable(mContext, dataDir); 183 184 // If the device has no DPMS feature, it shouldn't register the local service. 185 assertNull(LocalServices.getService(DevicePolicyManagerInternal.class)); 186 } 187 188 /** 189 * Caller doesn't have proper permissions. 190 */ 191 public void testSetActiveAdmin_SecurityException() { 192 // 1. Failure cases. 193 194 // Caller doesn't have MANAGE_DEVICE_ADMINS. 195 try { 196 dpm.setActiveAdmin(admin1, false); 197 fail("Didn't throw SecurityException"); 198 } catch (SecurityException expected) { 199 } 200 201 // Caller has MANAGE_DEVICE_ADMINS, but for different user. 202 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 203 try { 204 dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1); 205 fail("Didn't throw SecurityException"); 206 } catch (SecurityException expected) { 207 } 208 } 209 210 /** 211 * Test for: 212 * {@link DevicePolicyManager#setActiveAdmin} 213 * with replace=false and replace=true 214 * {@link DevicePolicyManager#isAdminActive} 215 * {@link DevicePolicyManager#isAdminActiveAsUser} 216 * {@link DevicePolicyManager#getActiveAdmins} 217 * {@link DevicePolicyManager#getActiveAdminsAsUser} 218 */ 219 public void testSetActiveAdmin() throws Exception { 220 // 1. Make sure the caller has proper permissions. 221 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 222 223 // 2. Call the API. 224 dpm.setActiveAdmin(admin1, /* replace =*/ false); 225 226 // 3. Verify internal calls. 227 228 // Check if the boradcast is sent. 229 verify(mContext.spiedContext).sendBroadcastAsUser( 230 MockUtils.checkIntentAction( 231 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 232 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE)); 233 verify(mContext.spiedContext).sendBroadcastAsUser( 234 MockUtils.checkIntentAction( 235 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED), 236 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE)); 237 238 verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting( 239 eq(admin1.getPackageName()), 240 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT), 241 eq(PackageManager.DONT_KILL_APP), 242 eq(DpmMockContext.CALLER_USER_HANDLE), 243 anyString()); 244 245 // TODO Verify other calls too. 246 247 // Make sure it's active admin1. 248 assertTrue(dpm.isAdminActive(admin1)); 249 assertFalse(dpm.isAdminActive(admin2)); 250 assertFalse(dpm.isAdminActive(admin3)); 251 252 // But not admin1 for a different user. 253 254 // For this to work, caller needs android.permission.INTERACT_ACROSS_USERS_FULL. 255 // (Because we're checking a different user's status from CALLER_USER_HANDLE.) 256 mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL"); 257 258 assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE + 1)); 259 assertFalse(dpm.isAdminActiveAsUser(admin2, DpmMockContext.CALLER_USER_HANDLE + 1)); 260 261 mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL"); 262 263 // Next, add one more admin. 264 // Before doing so, update the application info, now it's enabled. 265 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID, 266 PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 267 268 dpm.setActiveAdmin(admin2, /* replace =*/ false); 269 270 // Now we have two admins. 271 assertTrue(dpm.isAdminActive(admin1)); 272 assertTrue(dpm.isAdminActive(admin2)); 273 assertFalse(dpm.isAdminActive(admin3)); 274 275 // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called 276 // again. (times(1) because it was previously called for admin1) 277 verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting( 278 eq(admin1.getPackageName()), 279 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT), 280 eq(PackageManager.DONT_KILL_APP), 281 eq(DpmMockContext.CALLER_USER_HANDLE), 282 anyString()); 283 284 // 4. Add the same admin1 again without replace, which should throw. 285 try { 286 dpm.setActiveAdmin(admin1, /* replace =*/ false); 287 fail("Didn't throw"); 288 } catch (IllegalArgumentException expected) { 289 } 290 291 // 5. Add the same admin1 again with replace, which should succeed. 292 dpm.setActiveAdmin(admin1, /* replace =*/ true); 293 294 // TODO make sure it's replaced. 295 296 // 6. Test getActiveAdmins() 297 List<ComponentName> admins = dpm.getActiveAdmins(); 298 assertEquals(2, admins.size()); 299 assertEquals(admin1, admins.get(0)); 300 assertEquals(admin2, admins.get(1)); 301 302 // Another user has no admins. 303 mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL"); 304 305 assertEquals(0, DpmTestUtils.getListSizeAllowingNull( 306 dpm.getActiveAdminsAsUser(DpmMockContext.CALLER_USER_HANDLE + 1))); 307 308 mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL"); 309 } 310 311 public void testSetActiveAdmin_multiUsers() throws Exception { 312 313 final int ANOTHER_USER_ID = 100; 314 final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 20456); 315 316 mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user. 317 318 // Set up pacakge manager for the other user. 319 setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID); 320 321 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 322 323 dpm.setActiveAdmin(admin1, /* replace =*/ false); 324 325 mMockContext.binder.callingUid = ANOTHER_ADMIN_UID; 326 dpm.setActiveAdmin(admin2, /* replace =*/ false); 327 328 329 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 330 assertTrue(dpm.isAdminActive(admin1)); 331 assertFalse(dpm.isAdminActive(admin2)); 332 333 mMockContext.binder.callingUid = ANOTHER_ADMIN_UID; 334 assertFalse(dpm.isAdminActive(admin1)); 335 assertTrue(dpm.isAdminActive(admin2)); 336 } 337 338 /** 339 * Test for: 340 * {@link DevicePolicyManager#setActiveAdmin} 341 * with replace=false 342 */ 343 public void testSetActiveAdmin_twiceWithoutReplace() throws Exception { 344 // 1. Make sure the caller has proper permissions. 345 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 346 347 dpm.setActiveAdmin(admin1, /* replace =*/ false); 348 assertTrue(dpm.isAdminActive(admin1)); 349 350 // Add the same admin1 again without replace, which should throw. 351 try { 352 dpm.setActiveAdmin(admin1, /* replace =*/ false); 353 fail("Didn't throw"); 354 } catch (IllegalArgumentException expected) { 355 } 356 } 357 358 /** 359 * Test for: 360 * {@link DevicePolicyManager#setActiveAdmin} when the admin isn't protected with 361 * BIND_DEVICE_ADMIN. 362 */ 363 public void testSetActiveAdmin_permissionCheck() throws Exception { 364 // 1. Make sure the caller has proper permissions. 365 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 366 367 try { 368 dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false); 369 fail(); 370 } catch (IllegalArgumentException expected) { 371 assertTrue(expected.getMessage().contains(permission.BIND_DEVICE_ADMIN)); 372 } 373 assertFalse(dpm.isAdminActive(adminNoPerm)); 374 375 // Change the target API level to MNC. Now it can be set as DA. 376 setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID, null, 377 VERSION_CODES.M); 378 dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false); 379 assertTrue(dpm.isAdminActive(adminNoPerm)); 380 381 // TODO Test the "load from the file" case where DA will still be loaded even without 382 // BIND_DEVICE_ADMIN and target API is N. 383 } 384 385 /** 386 * Test for: 387 * {@link DevicePolicyManager#removeActiveAdmin} 388 */ 389 public void testRemoveActiveAdmin_SecurityException() { 390 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 391 392 // Add admin. 393 394 dpm.setActiveAdmin(admin1, /* replace =*/ false); 395 396 assertTrue(dpm.isAdminActive(admin1)); 397 398 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 399 400 // Directly call the DPMS method with a different userid, which should fail. 401 try { 402 dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1); 403 fail("Didn't throw SecurityException"); 404 } catch (SecurityException expected) { 405 } 406 407 // Try to remove active admin with a different caller userid should fail too, without 408 // having MANAGE_DEVICE_ADMINS. 409 mContext.callerPermissions.clear(); 410 411 // Change the caller, and call into DPMS directly with a different user-id. 412 413 mContext.binder.callingUid = 1234567; 414 try { 415 dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE); 416 fail("Didn't throw SecurityException"); 417 } catch (SecurityException expected) { 418 } 419 } 420 421 /** 422 * {@link DevicePolicyManager#removeActiveAdmin} should fail with the user is not unlocked 423 * (because we can't send the remove broadcast). 424 */ 425 public void testRemoveActiveAdmin_userNotRunningOrLocked() { 426 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 427 428 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 429 430 // Add admin. 431 432 dpm.setActiveAdmin(admin1, /* replace =*/ false); 433 434 assertTrue(dpm.isAdminActive(admin1)); 435 436 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 437 438 // 1. User not unlocked. 439 when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE))) 440 .thenReturn(false); 441 try { 442 dpm.removeActiveAdmin(admin1); 443 fail("Didn't throw IllegalStateException"); 444 } catch (IllegalStateException expected) { 445 MoreAsserts.assertContainsRegex( 446 "User must be running and unlocked", expected.getMessage()); 447 } 448 449 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 450 451 // 2. User unlocked. 452 when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE))) 453 .thenReturn(true); 454 455 dpm.removeActiveAdmin(admin1); 456 457 assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 458 } 459 460 /** 461 * Test for: 462 * {@link DevicePolicyManager#removeActiveAdmin} 463 */ 464 public void testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL() { 465 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 466 467 // Add admin1. 468 469 dpm.setActiveAdmin(admin1, /* replace =*/ false); 470 471 assertTrue(dpm.isAdminActive(admin1)); 472 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 473 474 // Different user, but should work, because caller has proper permissions. 475 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 476 477 // Change the caller, and call into DPMS directly with a different user-id. 478 mContext.binder.callingUid = 1234567; 479 480 dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE); 481 482 assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 483 484 // TODO DO Still can't be removed in this case. 485 } 486 487 /** 488 * Test for: 489 * {@link DevicePolicyManager#removeActiveAdmin} 490 */ 491 public void testRemoveActiveAdmin_sameUserNoMANAGE_DEVICE_ADMINS() { 492 // Need MANAGE_DEVICE_ADMINS for setActiveAdmin. We'll remove it later. 493 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 494 495 // Add admin1. 496 497 dpm.setActiveAdmin(admin1, /* replace =*/ false); 498 499 assertTrue(dpm.isAdminActive(admin1)); 500 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 501 502 // Broadcast from saveSettingsLocked(). 503 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 504 MockUtils.checkIntentAction( 505 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 506 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE)); 507 508 // Remove. No permissions, but same user, so it'll work. 509 mContext.callerPermissions.clear(); 510 dpm.removeActiveAdmin(admin1); 511 512 final ArgumentCaptor<BroadcastReceiver> brCap = 513 ArgumentCaptor.forClass(BroadcastReceiver.class); 514 515 // Is removing now, but not removed yet. 516 assertTrue(dpm.isAdminActive(admin1)); 517 assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 518 519 verify(mContext.spiedContext).sendOrderedBroadcastAsUser( 520 MockUtils.checkIntentAction( 521 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED), 522 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE), 523 isNull(String.class), 524 brCap.capture(), 525 eq(dpms.mHandler), 526 eq(Activity.RESULT_OK), 527 isNull(String.class), 528 isNull(Bundle.class)); 529 530 brCap.getValue().onReceive(mContext, null); 531 532 assertFalse(dpm.isAdminActive(admin1)); 533 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 534 535 // Again broadcast from saveSettingsLocked(). 536 verify(mContext.spiedContext, times(2)).sendBroadcastAsUser( 537 MockUtils.checkIntentAction( 538 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 539 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE)); 540 541 // TODO Check other internal calls. 542 } 543 544 /** 545 * Test for: {@link DevicePolicyManager#setDeviceOwner} DO on system user installs 546 * successfully. 547 */ 548 public void testSetDeviceOwner() throws Exception { 549 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 550 mContext.callerPermissions.add(permission.MANAGE_USERS); 551 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 552 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 553 554 // In this test, change the caller user to "system". 555 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 556 557 // Make sure admin1 is installed on system user. 558 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 559 560 // Check various get APIs. 561 checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ false); 562 563 // DO needs to be an DA. 564 dpm.setActiveAdmin(admin1, /* replace =*/ false); 565 566 // Fire! 567 assertTrue(dpm.setDeviceOwner(admin1, "owner-name")); 568 569 // getDeviceOwnerComponent should return the admin1 component. 570 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 571 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 572 573 // Check various get APIs. 574 checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ true); 575 576 // getDeviceOwnerComponent should *NOT* return the admin1 component for other users. 577 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 578 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 579 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 580 581 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 582 583 // Verify internal calls. 584 verify(mContext.iactivityManager, times(1)).updateDeviceOwner( 585 eq(admin1.getPackageName())); 586 587 // TODO We should check if the caller has called clearCallerIdentity(). 588 verify(mContext.ibackupManager, times(1)).setBackupServiceActive( 589 eq(UserHandle.USER_SYSTEM), eq(false)); 590 591 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 592 MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED), 593 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 594 595 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 596 597 // Try to set a profile owner on the same user, which should fail. 598 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID); 599 dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM); 600 try { 601 dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM); 602 fail("IllegalStateException not thrown"); 603 } catch (IllegalStateException expected) { 604 assertTrue("Message was: " + expected.getMessage(), 605 expected.getMessage().contains("already has a device owner")); 606 } 607 608 // DO admin can't be deactivated. 609 dpm.removeActiveAdmin(admin1); 610 assertTrue(dpm.isAdminActive(admin1)); 611 612 // TODO Test getDeviceOwnerName() too. To do so, we need to change 613 // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable. 614 } 615 616 private void checkGetDeviceOwnerInfoApi(DevicePolicyManager dpm, boolean hasDeviceOwner) { 617 final int origCallingUser = mContext.binder.callingUid; 618 final List origPermissions = new ArrayList(mContext.callerPermissions); 619 mContext.callerPermissions.clear(); 620 621 mContext.callerPermissions.add(permission.MANAGE_USERS); 622 623 mContext.binder.callingUid = Process.SYSTEM_UID; 624 625 // TODO Test getDeviceOwnerName() too. To do so, we need to change 626 // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable. 627 if (hasDeviceOwner) { 628 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 629 assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 630 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 631 632 assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 633 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 634 assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId()); 635 } else { 636 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 637 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 638 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 639 640 assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 641 assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser()); 642 assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId()); 643 } 644 645 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 646 if (hasDeviceOwner) { 647 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 648 assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 649 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 650 651 assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 652 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 653 assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId()); 654 } else { 655 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 656 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 657 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 658 659 assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 660 assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser()); 661 assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId()); 662 } 663 664 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 665 // Still with MANAGE_USERS. 666 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 667 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 668 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 669 670 if (hasDeviceOwner) { 671 assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 672 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 673 assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId()); 674 } else { 675 assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 676 assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser()); 677 assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId()); 678 } 679 680 mContext.binder.callingUid = Process.SYSTEM_UID; 681 mContext.callerPermissions.remove(permission.MANAGE_USERS); 682 // System can still call "OnAnyUser" without MANAGE_USERS. 683 if (hasDeviceOwner) { 684 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 685 assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 686 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 687 688 assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 689 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 690 assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId()); 691 } else { 692 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 693 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 694 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 695 696 assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 697 assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser()); 698 assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId()); 699 } 700 701 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 702 // Still no MANAGE_USERS. 703 if (hasDeviceOwner) { 704 assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName())); 705 assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 706 assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser()); 707 } else { 708 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 709 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 710 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 711 } 712 713 try { 714 dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()); 715 fail(); 716 } catch (SecurityException expected) { 717 } 718 try { 719 dpm.getDeviceOwnerComponentOnAnyUser(); 720 fail(); 721 } catch (SecurityException expected) { 722 } 723 try { 724 dpm.getDeviceOwnerUserId(); 725 fail(); 726 } catch (SecurityException expected) { 727 } 728 try { 729 dpm.getDeviceOwnerNameOnAnyUser(); 730 fail(); 731 } catch (SecurityException expected) { 732 } 733 734 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 735 // Still no MANAGE_USERS. 736 assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName())); 737 assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())); 738 assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser()); 739 740 try { 741 dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()); 742 fail(); 743 } catch (SecurityException expected) { 744 } 745 try { 746 dpm.getDeviceOwnerComponentOnAnyUser(); 747 fail(); 748 } catch (SecurityException expected) { 749 } 750 try { 751 dpm.getDeviceOwnerUserId(); 752 fail(); 753 } catch (SecurityException expected) { 754 } 755 try { 756 dpm.getDeviceOwnerNameOnAnyUser(); 757 fail(); 758 } catch (SecurityException expected) { 759 } 760 761 // Restore. 762 mContext.binder.callingUid = origCallingUser; 763 mContext.callerPermissions.addAll(origPermissions); 764 } 765 766 767 /** 768 * Test for: {@link DevicePolicyManager#setDeviceOwner} Package doesn't exist. 769 */ 770 public void testSetDeviceOwner_noSuchPackage() { 771 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 772 mContext.callerPermissions.add(permission.MANAGE_USERS); 773 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 774 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 775 776 // Call from a process on the system user. 777 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 778 779 try { 780 dpm.setDeviceOwner(new ComponentName("a.b.c", ".def")); 781 fail("Didn't throw IllegalArgumentException"); 782 } catch (IllegalArgumentException expected) { 783 assertTrue("Message was: " + expected.getMessage(), 784 expected.getMessage().contains("Invalid component")); 785 } 786 } 787 788 public void testSetDeviceOwner_failures() throws Exception { 789 // TODO Test more failure cases. Basically test all chacks in enforceCanSetDeviceOwner(). 790 } 791 792 public void testClearDeviceOwner() throws Exception { 793 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 794 mContext.callerPermissions.add(permission.MANAGE_USERS); 795 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 796 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 797 798 // Set admin1 as a DA to the secondary user. 799 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 800 801 dpm.setActiveAdmin(admin1, /* replace =*/ false); 802 803 // Set admin 1 as the DO to the system user. 804 805 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 806 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 807 dpm.setActiveAdmin(admin1, /* replace =*/ false); 808 assertTrue(dpm.setDeviceOwner(admin1, "owner-name")); 809 810 // Verify internal calls. 811 verify(mContext.iactivityManager, times(1)).updateDeviceOwner( 812 eq(admin1.getPackageName())); 813 814 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 815 816 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 817 818 assertTrue(dpm.isAdminActive(admin1)); 819 assertFalse(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM)); 820 821 // Set up other mocks. 822 when(mContext.userManager.getUserRestrictions()).thenReturn(new Bundle()); 823 824 // Now call clear. 825 doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager).getPackageUidAsUser( 826 eq(admin1.getPackageName()), 827 anyInt()); 828 829 // But first pretend the user is locked. Then it should fail. 830 when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(false); 831 try { 832 dpm.clearDeviceOwnerApp(admin1.getPackageName()); 833 fail("Didn't throw IllegalStateException"); 834 } catch (IllegalStateException expected) { 835 MoreAsserts.assertContainsRegex( 836 "User must be running and unlocked", expected.getMessage()); 837 } 838 839 when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true); 840 reset(mContext.userManagerInternal); 841 dpm.clearDeviceOwnerApp(admin1.getPackageName()); 842 843 // Now DO shouldn't be set. 844 assertNull(dpm.getDeviceOwnerComponentOnAnyUser()); 845 846 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 847 eq(UserHandle.USER_SYSTEM), 848 MockUtils.checkUserRestrictions(), 849 MockUtils.checkUserRestrictions() 850 ); 851 852 assertTrue(dpm.isAdminActive(admin1)); 853 assertTrue(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM)); 854 855 // TODO Check other calls. 856 } 857 858 public void testClearDeviceOwner_fromDifferentUser() throws Exception { 859 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 860 mContext.callerPermissions.add(permission.MANAGE_USERS); 861 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 862 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 863 864 // Set admin1 as a DA to the secondary user. 865 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 866 867 dpm.setActiveAdmin(admin1, /* replace =*/ false); 868 869 // Set admin 1 as the DO to the system user. 870 871 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 872 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 873 dpm.setActiveAdmin(admin1, /* replace =*/ false); 874 assertTrue(dpm.setDeviceOwner(admin1, "owner-name")); 875 876 // Verify internal calls. 877 verify(mContext.iactivityManager, times(1)).updateDeviceOwner( 878 eq(admin1.getPackageName())); 879 880 assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser()); 881 882 // Now call clear from the secondary user, which should throw. 883 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 884 885 // Now call clear. 886 doReturn(DpmMockContext.CALLER_UID).when(mContext.packageManager).getPackageUidAsUser( 887 eq(admin1.getPackageName()), 888 anyInt()); 889 try { 890 dpm.clearDeviceOwnerApp(admin1.getPackageName()); 891 fail("Didn't throw"); 892 } catch (SecurityException e) { 893 assertEquals("clearDeviceOwner can only be called by the device owner", e.getMessage()); 894 } 895 896 // DO shouldn't be removed. 897 assertTrue(dpm.isDeviceManaged()); 898 } 899 900 public void testSetProfileOwner() throws Exception { 901 setAsProfileOwner(admin1); 902 903 // PO admin can't be deactivated. 904 dpm.removeActiveAdmin(admin1); 905 assertTrue(dpm.isAdminActive(admin1)); 906 907 // Try setting DO on the same user, which should fail. 908 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 909 dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE); 910 try { 911 dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE); 912 fail("IllegalStateException not thrown"); 913 } catch (IllegalStateException expected) { 914 assertTrue("Message was: " + expected.getMessage(), 915 expected.getMessage().contains("already has a profile owner")); 916 } 917 } 918 919 public void testClearProfileOwner() throws Exception { 920 setAsProfileOwner(admin1); 921 922 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 923 924 assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName())); 925 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 926 927 // First try when the user is locked, which should fail. 928 when(mContext.userManager.isUserUnlocked(anyInt())) 929 .thenReturn(false); 930 try { 931 dpm.clearProfileOwner(admin1); 932 fail("Didn't throw IllegalStateException"); 933 } catch (IllegalStateException expected) { 934 MoreAsserts.assertContainsRegex( 935 "User must be running and unlocked", expected.getMessage()); 936 } 937 // Clear, really. 938 when(mContext.userManager.isUserUnlocked(anyInt())) 939 .thenReturn(true); 940 dpm.clearProfileOwner(admin1); 941 942 // Check 943 assertFalse(dpm.isProfileOwnerApp(admin1.getPackageName())); 944 assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE)); 945 } 946 947 public void testSetProfileOwner_failures() throws Exception { 948 // TODO Test more failure cases. Basically test all chacks in enforceCanSetProfileOwner(). 949 } 950 951 public void testGetDeviceOwnerAdminLocked() throws Exception { 952 checkDeviceOwnerWithMultipleDeviceAdmins(); 953 } 954 955 private void checkDeviceOwnerWithMultipleDeviceAdmins() throws Exception { 956 // In ths test, we use 3 users (system + 2 secondary users), set some device admins to them, 957 // set admin2 on CALLER_USER_HANDLE as DO, then call getDeviceOwnerAdminLocked() to 958 // make sure it gets the right component from the right user. 959 960 final int ANOTHER_USER_ID = 100; 961 final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 456); 962 963 mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user. 964 965 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 966 mContext.callerPermissions.add(permission.MANAGE_USERS); 967 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 968 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 969 970 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 971 972 when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true); 973 974 // Make sure the admin packge is installed to each user. 975 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 976 setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_SYSTEM_USER_UID); 977 978 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 979 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 980 981 setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID); 982 983 984 // Set active admins to the users. 985 dpm.setActiveAdmin(admin1, /* replace =*/ false); 986 dpm.setActiveAdmin(admin3, /* replace =*/ false); 987 988 dpm.setActiveAdmin(admin1, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE); 989 dpm.setActiveAdmin(admin2, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE); 990 991 dpm.setActiveAdmin(admin2, /* replace =*/ false, ANOTHER_USER_ID); 992 993 // Set DO on the first non-system user. 994 mContext.setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true); 995 assertTrue(dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE)); 996 997 assertEquals(admin2, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false)); 998 999 // Then check getDeviceOwnerAdminLocked(). 1000 assertEquals(admin2, dpms.getDeviceOwnerAdminLocked().info.getComponent()); 1001 assertEquals(DpmMockContext.CALLER_UID, dpms.getDeviceOwnerAdminLocked().getUid()); 1002 } 1003 1004 /** 1005 * This essentially tests 1006 * {@code DevicePolicyManagerService.findOwnerComponentIfNecessaryLocked()}. (which is 1007 * private.) 1008 * 1009 * We didn't use to persist the DO component class name, but now we do, and the above method 1010 * finds the right component from a package name upon migration. 1011 */ 1012 public void testDeviceOwnerMigration() throws Exception { 1013 when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true); 1014 checkDeviceOwnerWithMultipleDeviceAdmins(); 1015 1016 // Overwrite the device owner setting and clears the clas name. 1017 dpms.mOwners.setDeviceOwner( 1018 new ComponentName(admin2.getPackageName(), ""), 1019 "owner-name", DpmMockContext.CALLER_USER_HANDLE); 1020 dpms.mOwners.writeDeviceOwner(); 1021 1022 // Make sure the DO component name doesn't have a class name. 1023 assertEquals("", dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false).getClassName()); 1024 1025 // Then create a new DPMS to have it load the settings from files. 1026 when(mContext.userManager.getUserRestrictions(any(UserHandle.class))) 1027 .thenReturn(new Bundle()); 1028 initializeDpms(); 1029 1030 // Now the DO component name is a full name. 1031 // *BUT* because both admin1 and admin2 belong to the same package, we think admin1 is the 1032 // DO. 1033 assertEquals(admin1, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false)); 1034 } 1035 1036 public void testSetGetApplicationRestriction() { 1037 setAsProfileOwner(admin1); 1038 1039 { 1040 Bundle rest = new Bundle(); 1041 rest.putString("KEY_STRING", "Foo1"); 1042 dpm.setApplicationRestrictions(admin1, "pkg1", rest); 1043 } 1044 1045 { 1046 Bundle rest = new Bundle(); 1047 rest.putString("KEY_STRING", "Foo2"); 1048 dpm.setApplicationRestrictions(admin1, "pkg2", rest); 1049 } 1050 1051 { 1052 Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg1"); 1053 assertNotNull(returned); 1054 assertEquals(returned.size(), 1); 1055 assertEquals(returned.get("KEY_STRING"), "Foo1"); 1056 } 1057 1058 { 1059 Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg2"); 1060 assertNotNull(returned); 1061 assertEquals(returned.size(), 1); 1062 assertEquals(returned.get("KEY_STRING"), "Foo2"); 1063 } 1064 1065 dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle()); 1066 assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg2").size()); 1067 } 1068 1069 public void testApplicationRestrictionsManagingApp() throws Exception { 1070 setAsProfileOwner(admin1); 1071 1072 final String nonExistAppRestrictionsManagerPackage = "com.google.app.restrictions.manager2"; 1073 final String appRestrictionsManagerPackage = "com.google.app.restrictions.manager"; 1074 final int appRestrictionsManagerAppId = 20987; 1075 final int appRestrictionsManagerUid = UserHandle.getUid( 1076 DpmMockContext.CALLER_USER_HANDLE, appRestrictionsManagerAppId); 1077 doReturn(appRestrictionsManagerUid).when(mContext.packageManager).getPackageUidAsUser( 1078 eq(appRestrictionsManagerPackage), 1079 eq(DpmMockContext.CALLER_USER_HANDLE)); 1080 mContext.binder.callingUid = appRestrictionsManagerUid; 1081 1082 final PackageInfo pi = new PackageInfo(); 1083 pi.applicationInfo = new ApplicationInfo(); 1084 pi.applicationInfo.flags = ApplicationInfo.FLAG_HAS_CODE; 1085 doReturn(pi).when(mContext.ipackageManager).getPackageInfo( 1086 eq(appRestrictionsManagerPackage), 1087 anyInt(), 1088 eq(DpmMockContext.CALLER_USER_HANDLE)); 1089 1090 // appRestrictionsManager package shouldn't be able to manage restrictions as the PO hasn't 1091 // delegated that permission yet. 1092 assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage()); 1093 Bundle rest = new Bundle(); 1094 rest.putString("KEY_STRING", "Foo1"); 1095 try { 1096 dpm.setApplicationRestrictions(null, "pkg1", rest); 1097 fail("Didn't throw expected SecurityException"); 1098 } catch (SecurityException expected) { 1099 MoreAsserts.assertContainsRegex( 1100 "caller cannot manage application restrictions", expected.getMessage()); 1101 } 1102 try { 1103 dpm.getApplicationRestrictions(null, "pkg1"); 1104 fail("Didn't throw expected SecurityException"); 1105 } catch (SecurityException expected) { 1106 MoreAsserts.assertContainsRegex( 1107 "caller cannot manage application restrictions", expected.getMessage()); 1108 } 1109 1110 // Check via the profile owner that no restrictions were set. 1111 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1112 assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size()); 1113 1114 // Check the API does not allow setting a non-existent package 1115 try { 1116 dpm.setApplicationRestrictionsManagingPackage(admin1, 1117 nonExistAppRestrictionsManagerPackage); 1118 fail("Non-existent app set as app restriction manager."); 1119 } catch (IllegalArgumentException expected) { 1120 MoreAsserts.assertContainsRegex( 1121 "is not installed on the current user", expected.getMessage()); 1122 } 1123 1124 // Let appRestrictionsManagerPackage manage app restrictions 1125 dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage); 1126 assertEquals(appRestrictionsManagerPackage, 1127 dpm.getApplicationRestrictionsManagingPackage(admin1)); 1128 1129 // Now that package should be able to set and retrieve app restrictions. 1130 mContext.binder.callingUid = appRestrictionsManagerUid; 1131 assertTrue(dpm.isCallerApplicationRestrictionsManagingPackage()); 1132 dpm.setApplicationRestrictions(null, "pkg1", rest); 1133 Bundle returned = dpm.getApplicationRestrictions(null, "pkg1"); 1134 assertEquals(1, returned.size(), 1); 1135 assertEquals("Foo1", returned.get("KEY_STRING")); 1136 1137 // The same app running on a separate user shouldn't be able to manage app restrictions. 1138 mContext.binder.callingUid = UserHandle.getUid( 1139 UserHandle.USER_SYSTEM, appRestrictionsManagerAppId); 1140 assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage()); 1141 try { 1142 dpm.setApplicationRestrictions(null, "pkg1", rest); 1143 fail("Didn't throw expected SecurityException"); 1144 } catch (SecurityException expected) { 1145 MoreAsserts.assertContainsRegex( 1146 "caller cannot manage application restrictions", expected.getMessage()); 1147 } 1148 1149 // The DPM is still able to manage app restrictions, even if it allowed another app to do it 1150 // too. 1151 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1152 assertEquals(returned, dpm.getApplicationRestrictions(admin1, "pkg1")); 1153 dpm.setApplicationRestrictions(admin1, "pkg1", null); 1154 assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size()); 1155 1156 // Removing the ability for the package to manage app restrictions. 1157 dpm.setApplicationRestrictionsManagingPackage(admin1, null); 1158 assertNull(dpm.getApplicationRestrictionsManagingPackage(admin1)); 1159 mContext.binder.callingUid = appRestrictionsManagerUid; 1160 assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage()); 1161 try { 1162 dpm.setApplicationRestrictions(null, "pkg1", null); 1163 fail("Didn't throw expected SecurityException"); 1164 } catch (SecurityException expected) { 1165 MoreAsserts.assertContainsRegex( 1166 "caller cannot manage application restrictions", expected.getMessage()); 1167 } 1168 } 1169 1170 public void testSetUserRestriction_asDo() throws Exception { 1171 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1172 mContext.callerPermissions.add(permission.MANAGE_USERS); 1173 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1174 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1175 1176 // First, set DO. 1177 1178 // Call from a process on the system user. 1179 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1180 1181 // Make sure admin1 is installed on system user. 1182 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1183 1184 // Call. 1185 dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); 1186 assertTrue(dpm.setDeviceOwner(admin1, "owner-name", 1187 UserHandle.USER_SYSTEM)); 1188 1189 DpmTestUtils.assertRestrictions( 1190 DpmTestUtils.newRestrictions(), 1191 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1192 ); 1193 DpmTestUtils.assertRestrictions( 1194 DpmTestUtils.newRestrictions(), 1195 dpm.getUserRestrictions(admin1) 1196 ); 1197 1198 reset(mContext.userManagerInternal); 1199 1200 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 1201 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1202 eq(UserHandle.USER_SYSTEM), 1203 MockUtils.checkUserRestrictions(), 1204 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER) 1205 ); 1206 reset(mContext.userManagerInternal); 1207 1208 dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 1209 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1210 eq(UserHandle.USER_SYSTEM), 1211 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 1212 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER) 1213 ); 1214 reset(mContext.userManagerInternal); 1215 1216 DpmTestUtils.assertRestrictions( 1217 DpmTestUtils.newRestrictions( 1218 UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS), 1219 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1220 ); 1221 DpmTestUtils.assertRestrictions( 1222 DpmTestUtils.newRestrictions( 1223 UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS), 1224 dpm.getUserRestrictions(admin1) 1225 ); 1226 1227 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 1228 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1229 eq(UserHandle.USER_SYSTEM), 1230 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 1231 MockUtils.checkUserRestrictions() 1232 ); 1233 reset(mContext.userManagerInternal); 1234 1235 DpmTestUtils.assertRestrictions( 1236 DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 1237 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1238 ); 1239 DpmTestUtils.assertRestrictions( 1240 DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 1241 dpm.getUserRestrictions(admin1) 1242 ); 1243 1244 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 1245 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1246 eq(UserHandle.USER_SYSTEM), 1247 MockUtils.checkUserRestrictions(), 1248 MockUtils.checkUserRestrictions() 1249 ); 1250 reset(mContext.userManagerInternal); 1251 1252 DpmTestUtils.assertRestrictions( 1253 DpmTestUtils.newRestrictions(), 1254 dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions() 1255 ); 1256 DpmTestUtils.assertRestrictions( 1257 DpmTestUtils.newRestrictions(), 1258 dpm.getUserRestrictions(admin1) 1259 ); 1260 1261 // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE are PO restrictions, but when 1262 // DO sets them, the scope is global. 1263 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); 1264 reset(mContext.userManagerInternal); 1265 dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE); 1266 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1267 eq(UserHandle.USER_SYSTEM), 1268 MockUtils.checkUserRestrictions(), 1269 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME, 1270 UserManager.DISALLOW_UNMUTE_MICROPHONE) 1271 ); 1272 reset(mContext.userManagerInternal); 1273 1274 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); 1275 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE); 1276 1277 1278 // More tests. 1279 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 1280 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1281 eq(UserHandle.USER_SYSTEM), 1282 MockUtils.checkUserRestrictions(), 1283 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER) 1284 ); 1285 reset(mContext.userManagerInternal); 1286 1287 dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN); 1288 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1289 eq(UserHandle.USER_SYSTEM), 1290 MockUtils.checkUserRestrictions(), 1291 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, 1292 UserManager.DISALLOW_ADD_USER) 1293 ); 1294 reset(mContext.userManagerInternal); 1295 1296 dpm.setCameraDisabled(admin1, true); 1297 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1298 eq(UserHandle.USER_SYSTEM), 1299 // DISALLOW_CAMERA will be applied to both local and global. 1300 MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA), 1301 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, 1302 UserManager.DISALLOW_CAMERA, UserManager.DISALLOW_ADD_USER) 1303 ); 1304 reset(mContext.userManagerInternal); 1305 1306 // Set up another DA and let it disable camera. Now DISALLOW_CAMERA will only be applied 1307 // locally. 1308 dpm.setCameraDisabled(admin1, false); 1309 reset(mContext.userManagerInternal); 1310 1311 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID); 1312 dpm.setActiveAdmin(admin2, /* replace =*/ false, UserHandle.USER_SYSTEM); 1313 dpm.setCameraDisabled(admin2, true); 1314 1315 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1316 eq(UserHandle.USER_SYSTEM), 1317 // DISALLOW_CAMERA will be applied to both local and global. 1318 MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA), 1319 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, 1320 UserManager.DISALLOW_ADD_USER) 1321 ); 1322 reset(mContext.userManagerInternal); 1323 // TODO Make sure restrictions are written to the file. 1324 } 1325 1326 public void testSetUserRestriction_asPo() { 1327 setAsProfileOwner(admin1); 1328 1329 DpmTestUtils.assertRestrictions( 1330 DpmTestUtils.newRestrictions(), 1331 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) 1332 .ensureUserRestrictions() 1333 ); 1334 1335 dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); 1336 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1337 eq(DpmMockContext.CALLER_USER_HANDLE), 1338 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES), 1339 isNull(Bundle.class) 1340 ); 1341 reset(mContext.userManagerInternal); 1342 1343 dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 1344 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1345 eq(DpmMockContext.CALLER_USER_HANDLE), 1346 MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 1347 UserManager.DISALLOW_OUTGOING_CALLS), 1348 isNull(Bundle.class) 1349 ); 1350 reset(mContext.userManagerInternal); 1351 1352 DpmTestUtils.assertRestrictions( 1353 DpmTestUtils.newRestrictions( 1354 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 1355 UserManager.DISALLOW_OUTGOING_CALLS 1356 ), 1357 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) 1358 .ensureUserRestrictions() 1359 ); 1360 DpmTestUtils.assertRestrictions( 1361 DpmTestUtils.newRestrictions( 1362 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 1363 UserManager.DISALLOW_OUTGOING_CALLS 1364 ), 1365 dpm.getUserRestrictions(admin1) 1366 ); 1367 1368 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); 1369 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1370 eq(DpmMockContext.CALLER_USER_HANDLE), 1371 MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 1372 isNull(Bundle.class) 1373 ); 1374 reset(mContext.userManagerInternal); 1375 1376 DpmTestUtils.assertRestrictions( 1377 DpmTestUtils.newRestrictions( 1378 UserManager.DISALLOW_OUTGOING_CALLS 1379 ), 1380 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) 1381 .ensureUserRestrictions() 1382 ); 1383 DpmTestUtils.assertRestrictions( 1384 DpmTestUtils.newRestrictions( 1385 UserManager.DISALLOW_OUTGOING_CALLS 1386 ), 1387 dpm.getUserRestrictions(admin1) 1388 ); 1389 1390 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 1391 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1392 eq(DpmMockContext.CALLER_USER_HANDLE), 1393 MockUtils.checkUserRestrictions(), 1394 isNull(Bundle.class) 1395 ); 1396 reset(mContext.userManagerInternal); 1397 1398 DpmTestUtils.assertRestrictions( 1399 DpmTestUtils.newRestrictions(), 1400 dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE) 1401 .ensureUserRestrictions() 1402 ); 1403 DpmTestUtils.assertRestrictions( 1404 DpmTestUtils.newRestrictions(), 1405 dpm.getUserRestrictions(admin1) 1406 ); 1407 1408 // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE can be set by PO too, even 1409 // though when DO sets them they'll be applied globally. 1410 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); 1411 reset(mContext.userManagerInternal); 1412 dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE); 1413 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1414 eq(DpmMockContext.CALLER_USER_HANDLE), 1415 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME, 1416 UserManager.DISALLOW_UNMUTE_MICROPHONE), 1417 isNull(Bundle.class) 1418 ); 1419 reset(mContext.userManagerInternal); 1420 1421 dpm.setCameraDisabled(admin1, true); 1422 verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions( 1423 eq(DpmMockContext.CALLER_USER_HANDLE), 1424 MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA, 1425 UserManager.DISALLOW_ADJUST_VOLUME, 1426 UserManager.DISALLOW_UNMUTE_MICROPHONE), 1427 isNull(Bundle.class) 1428 ); 1429 reset(mContext.userManagerInternal); 1430 1431 // TODO Make sure restrictions are written to the file. 1432 } 1433 1434 public void testGetMacAddress() throws Exception { 1435 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1436 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1437 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1438 1439 // In this test, change the caller user to "system". 1440 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1441 1442 // Make sure admin1 is installed on system user. 1443 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1444 1445 // Test 1. Caller doesn't have DO or DA. 1446 try { 1447 dpm.getWifiMacAddress(admin1); 1448 fail(); 1449 } catch (SecurityException e) { 1450 MoreAsserts.assertContainsRegex("No active admin", e.getMessage()); 1451 } 1452 1453 // DO needs to be an DA. 1454 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1455 assertTrue(dpm.isAdminActive(admin1)); 1456 1457 // Test 2. Caller has DA, but not DO. 1458 try { 1459 dpm.getWifiMacAddress(admin1); 1460 fail(); 1461 } catch (SecurityException e) { 1462 MoreAsserts.assertContainsRegex("does not own the device", e.getMessage()); 1463 } 1464 1465 // Test 3. Caller has PO, but not DO. 1466 assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)); 1467 try { 1468 dpm.getWifiMacAddress(admin1); 1469 fail(); 1470 } catch (SecurityException e) { 1471 MoreAsserts.assertContainsRegex("does not own the device", e.getMessage()); 1472 } 1473 1474 // Remove PO. 1475 dpm.clearProfileOwner(admin1); 1476 1477 // Test 4, Caller is DO now. 1478 assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)); 1479 1480 // 4-1. But no WifiInfo. 1481 assertNull(dpm.getWifiMacAddress(admin1)); 1482 1483 // 4-2. Returns WifiInfo, but with the default MAC. 1484 when(mContext.wifiManager.getConnectionInfo()).thenReturn(new WifiInfo()); 1485 assertNull(dpm.getWifiMacAddress(admin1)); 1486 1487 // 4-3. With a real MAC address. 1488 final WifiInfo wi = new WifiInfo(); 1489 wi.setMacAddress("11:22:33:44:55:66"); 1490 when(mContext.wifiManager.getConnectionInfo()).thenReturn(wi); 1491 assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1)); 1492 } 1493 1494 public void testRebootCanOnlyBeCalledByDeviceOwner() throws Exception { 1495 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1496 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1497 1498 // In this test, change the caller user to "system". 1499 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1500 1501 // Make sure admin1 is installed on system user. 1502 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1503 1504 // Set admin1 as DA. 1505 dpm.setActiveAdmin(admin1, false); 1506 assertTrue(dpm.isAdminActive(admin1)); 1507 try { 1508 dpm.reboot(admin1); 1509 fail("DA calls DPM.reboot(), did not throw expected SecurityException"); 1510 } catch (SecurityException expected) { 1511 MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage()); 1512 } 1513 1514 // Set admin1 as PO. 1515 assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)); 1516 try { 1517 dpm.reboot(admin1); 1518 fail("PO calls DPM.reboot(), did not throw expected SecurityException"); 1519 } catch (SecurityException expected) { 1520 MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage()); 1521 } 1522 1523 // Remove PO and add DO. 1524 dpm.clearProfileOwner(admin1); 1525 assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)); 1526 1527 dpm.reboot(admin1); 1528 } 1529 1530 public void testSetGetSupportText() { 1531 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1532 dpm.setActiveAdmin(admin1, true); 1533 dpm.setActiveAdmin(admin2, true); 1534 mContext.callerPermissions.remove(permission.MANAGE_DEVICE_ADMINS); 1535 1536 // Null default support messages. 1537 { 1538 assertNull(dpm.getLongSupportMessage(admin1)); 1539 assertNull(dpm.getShortSupportMessage(admin1)); 1540 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 1541 assertNull(dpm.getShortSupportMessageForUser(admin1, 1542 DpmMockContext.CALLER_USER_HANDLE)); 1543 assertNull(dpm.getLongSupportMessageForUser(admin1, 1544 DpmMockContext.CALLER_USER_HANDLE)); 1545 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 1546 } 1547 1548 // Only system can call the per user versions. 1549 { 1550 try { 1551 dpm.getShortSupportMessageForUser(admin1, 1552 DpmMockContext.CALLER_USER_HANDLE); 1553 fail("Only system should be able to call getXXXForUser versions"); 1554 } catch (SecurityException expected) { 1555 MoreAsserts.assertContainsRegex("message for user", expected.getMessage()); 1556 } 1557 try { 1558 dpm.getLongSupportMessageForUser(admin1, 1559 DpmMockContext.CALLER_USER_HANDLE); 1560 fail("Only system should be able to call getXXXForUser versions"); 1561 } catch (SecurityException expected) { 1562 MoreAsserts.assertContainsRegex("message for user", expected.getMessage()); 1563 } 1564 } 1565 1566 // Can't set message for admin in another uid. 1567 { 1568 mContext.binder.callingUid = DpmMockContext.CALLER_UID + 1; 1569 try { 1570 dpm.setShortSupportMessage(admin1, "Some text"); 1571 fail("Admins should only be able to change their own support text."); 1572 } catch (SecurityException expected) { 1573 MoreAsserts.assertContainsRegex("is not owned by uid", expected.getMessage()); 1574 } 1575 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1576 } 1577 1578 // Set/Get short returns what it sets and other admins text isn't changed. 1579 { 1580 final String supportText = "Some text to test with."; 1581 dpm.setShortSupportMessage(admin1, supportText); 1582 assertEquals(supportText, dpm.getShortSupportMessage(admin1)); 1583 assertNull(dpm.getLongSupportMessage(admin1)); 1584 assertNull(dpm.getShortSupportMessage(admin2)); 1585 1586 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 1587 assertEquals(supportText, dpm.getShortSupportMessageForUser(admin1, 1588 DpmMockContext.CALLER_USER_HANDLE)); 1589 assertNull(dpm.getShortSupportMessageForUser(admin2, 1590 DpmMockContext.CALLER_USER_HANDLE)); 1591 assertNull(dpm.getLongSupportMessageForUser(admin1, 1592 DpmMockContext.CALLER_USER_HANDLE)); 1593 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 1594 1595 dpm.setShortSupportMessage(admin1, null); 1596 assertNull(dpm.getShortSupportMessage(admin1)); 1597 } 1598 1599 // Set/Get long returns what it sets and other admins text isn't changed. 1600 { 1601 final String supportText = "Some text to test with.\nWith more text."; 1602 dpm.setLongSupportMessage(admin1, supportText); 1603 assertEquals(supportText, dpm.getLongSupportMessage(admin1)); 1604 assertNull(dpm.getShortSupportMessage(admin1)); 1605 assertNull(dpm.getLongSupportMessage(admin2)); 1606 1607 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 1608 assertEquals(supportText, dpm.getLongSupportMessageForUser(admin1, 1609 DpmMockContext.CALLER_USER_HANDLE)); 1610 assertNull(dpm.getLongSupportMessageForUser(admin2, 1611 DpmMockContext.CALLER_USER_HANDLE)); 1612 assertNull(dpm.getShortSupportMessageForUser(admin1, 1613 DpmMockContext.CALLER_USER_HANDLE)); 1614 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 1615 1616 dpm.setLongSupportMessage(admin1, null); 1617 assertNull(dpm.getLongSupportMessage(admin1)); 1618 } 1619 } 1620 1621 /** 1622 * Test for: 1623 * {@link DevicePolicyManager#setAffiliationIds} 1624 * {@link DevicePolicyManager#isAffiliatedUser} 1625 */ 1626 public void testUserAffiliation() throws Exception { 1627 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1628 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1629 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1630 1631 // Check that the system user is unaffiliated. 1632 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1633 assertFalse(dpm.isAffiliatedUser()); 1634 1635 // Set a device owner on the system user. Check that the system user becomes affiliated. 1636 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1637 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1638 assertTrue(dpm.setDeviceOwner(admin1, "owner-name")); 1639 assertTrue(dpm.isAffiliatedUser()); 1640 1641 // Install a profile owner whose package name matches the device owner on a test user. Check 1642 // that the test user is unaffiliated. 1643 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1644 setAsProfileOwner(admin2); 1645 assertFalse(dpm.isAffiliatedUser()); 1646 1647 // Have the profile owner specify a set of affiliation ids. Check that the test user remains 1648 // unaffiliated. 1649 final Set<String> userAffiliationIds = new ArraySet<>(); 1650 userAffiliationIds.add("red"); 1651 userAffiliationIds.add("green"); 1652 userAffiliationIds.add("blue"); 1653 dpm.setAffiliationIds(admin2, userAffiliationIds); 1654 assertFalse(dpm.isAffiliatedUser()); 1655 1656 // Have the device owner specify a set of affiliation ids that do not intersect with those 1657 // specified by the profile owner. Check that the test user remains unaffiliated. 1658 final Set<String> deviceAffiliationIds = new ArraySet<>(); 1659 deviceAffiliationIds.add("cyan"); 1660 deviceAffiliationIds.add("yellow"); 1661 deviceAffiliationIds.add("magenta"); 1662 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1663 dpm.setAffiliationIds(admin1, deviceAffiliationIds); 1664 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1665 assertFalse(dpm.isAffiliatedUser()); 1666 1667 // Have the profile owner specify a set of affiliation ids that intersect with those 1668 // specified by the device owner. Check that the test user becomes affiliated. 1669 userAffiliationIds.add("yellow"); 1670 dpm.setAffiliationIds(admin2, userAffiliationIds); 1671 assertTrue(dpm.isAffiliatedUser()); 1672 1673 // Change the profile owner to one whose package name does not match the device owner. Check 1674 // that the test user is not affiliated anymore. 1675 dpm.clearProfileOwner(admin2); 1676 final ComponentName admin = new ComponentName("test", "test"); 1677 1678 setUpPackageManagerForFakeAdmin(admin, DpmMockContext.CALLER_UID, 1679 /* enabledSetting =*/ PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 1680 /* appTargetSdk = */ null, admin2); 1681 1682 dpm.setActiveAdmin(admin, /* refreshing =*/ true, DpmMockContext.CALLER_USER_HANDLE); 1683 assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE)); 1684 assertFalse(dpm.isAffiliatedUser()); 1685 1686 // Check that the system user remains affiliated. 1687 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1688 assertTrue(dpm.isAffiliatedUser()); 1689 } 1690 1691 public void testGetUserProvisioningState_defaultResult() { 1692 assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState()); 1693 } 1694 1695 public void testSetUserProvisioningState_permission() throws Exception { 1696 setupProfileOwner(); 1697 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1698 1699 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 1700 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 1701 } 1702 1703 public void testSetUserProvisioningState_unprivileged() throws Exception { 1704 setupProfileOwner(); 1705 try { 1706 dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 1707 DpmMockContext.CALLER_USER_HANDLE); 1708 fail("Expected SecurityException"); 1709 } catch (SecurityException expected) { 1710 } 1711 } 1712 1713 public void testSetUserProvisioningState_noManagement() { 1714 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1715 try { 1716 dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 1717 DpmMockContext.CALLER_USER_HANDLE); 1718 fail("IllegalStateException expected"); 1719 } catch (IllegalStateException e) { 1720 MoreAsserts.assertContainsRegex("change provisioning state unless a .* owner is set", 1721 e.getMessage()); 1722 } 1723 assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState()); 1724 } 1725 1726 public void testSetUserProvisioningState_deviceOwnerFromSetupWizard() throws Exception { 1727 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1728 setupDeviceOwner(); 1729 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1730 1731 exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM, 1732 DevicePolicyManager.STATE_USER_SETUP_COMPLETE, 1733 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 1734 } 1735 1736 public void testSetUserProvisioningState_deviceOwnerFromSetupWizardAlternative() 1737 throws Exception { 1738 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1739 setupDeviceOwner(); 1740 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1741 1742 exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM, 1743 DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE, 1744 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 1745 } 1746 1747 public void testSetUserProvisioningState_deviceOwnerWithoutSetupWizard() throws Exception { 1748 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1749 setupDeviceOwner(); 1750 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1751 1752 exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM, 1753 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 1754 } 1755 1756 public void testSetUserProvisioningState_managedProfileFromSetupWizard_primaryUser() 1757 throws Exception { 1758 setupProfileOwner(); 1759 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1760 1761 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 1762 DevicePolicyManager.STATE_USER_PROFILE_COMPLETE, 1763 DevicePolicyManager.STATE_USER_UNMANAGED); 1764 } 1765 1766 public void testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile() 1767 throws Exception { 1768 setupProfileOwner(); 1769 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1770 1771 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 1772 DevicePolicyManager.STATE_USER_SETUP_COMPLETE, 1773 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 1774 } 1775 1776 public void testSetUserProvisioningState_managedProfileWithoutSetupWizard() throws Exception { 1777 setupProfileOwner(); 1778 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1779 1780 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 1781 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 1782 } 1783 1784 public void testSetUserProvisioningState_illegalTransitionOutOfFinalized1() throws Exception { 1785 setupProfileOwner(); 1786 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1787 1788 try { 1789 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 1790 DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 1791 DevicePolicyManager.STATE_USER_UNMANAGED); 1792 fail("Expected IllegalStateException"); 1793 } catch (IllegalStateException e) { 1794 MoreAsserts.assertContainsRegex("Cannot move to user provisioning state", 1795 e.getMessage()); 1796 } 1797 } 1798 1799 public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState() 1800 throws Exception { 1801 setupProfileOwner(); 1802 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1803 1804 try { 1805 exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE, 1806 DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE, 1807 DevicePolicyManager.STATE_USER_SETUP_COMPLETE); 1808 fail("Expected IllegalStateException"); 1809 } catch (IllegalStateException e) { 1810 MoreAsserts.assertContainsRegex("Cannot move to user provisioning state", 1811 e.getMessage()); 1812 } 1813 } 1814 1815 private void exerciseUserProvisioningTransitions(int userId, int... states) { 1816 assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState()); 1817 for (int state : states) { 1818 dpm.setUserProvisioningState(state, userId); 1819 assertEquals(state, dpm.getUserProvisioningState()); 1820 } 1821 } 1822 1823 private void setupProfileOwner() throws Exception { 1824 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 1825 1826 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 1827 dpm.setActiveAdmin(admin1, false); 1828 assertTrue(dpm.setProfileOwner(admin1, null, DpmMockContext.CALLER_USER_HANDLE)); 1829 1830 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 1831 } 1832 1833 private void setupDeviceOwner() throws Exception { 1834 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 1835 1836 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1837 dpm.setActiveAdmin(admin1, false); 1838 assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)); 1839 1840 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 1841 } 1842 1843 public void testSetMaximumTimeToLock() { 1844 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 1845 1846 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1847 dpm.setActiveAdmin(admin2, /* replace =*/ false); 1848 1849 reset(mMockContext.powerManagerInternal); 1850 reset(mMockContext.settings); 1851 1852 dpm.setMaximumTimeToLock(admin1, 0); 1853 verifyScreenTimeoutCall(null, false); 1854 reset(mMockContext.powerManagerInternal); 1855 reset(mMockContext.settings); 1856 1857 dpm.setMaximumTimeToLock(admin1, 1); 1858 verifyScreenTimeoutCall(1, true); 1859 reset(mMockContext.powerManagerInternal); 1860 reset(mMockContext.settings); 1861 1862 dpm.setMaximumTimeToLock(admin2, 10); 1863 verifyScreenTimeoutCall(null, false); 1864 reset(mMockContext.powerManagerInternal); 1865 reset(mMockContext.settings); 1866 1867 dpm.setMaximumTimeToLock(admin1, 5); 1868 verifyScreenTimeoutCall(5, true); 1869 reset(mMockContext.powerManagerInternal); 1870 reset(mMockContext.settings); 1871 1872 dpm.setMaximumTimeToLock(admin2, 4); 1873 verifyScreenTimeoutCall(4, true); 1874 reset(mMockContext.powerManagerInternal); 1875 reset(mMockContext.settings); 1876 1877 dpm.setMaximumTimeToLock(admin1, 0); 1878 reset(mMockContext.powerManagerInternal); 1879 reset(mMockContext.settings); 1880 1881 dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE); 1882 verifyScreenTimeoutCall(Integer.MAX_VALUE, true); 1883 reset(mMockContext.powerManagerInternal); 1884 reset(mMockContext.settings); 1885 1886 dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE + 1); 1887 verifyScreenTimeoutCall(Integer.MAX_VALUE, true); 1888 reset(mMockContext.powerManagerInternal); 1889 reset(mMockContext.settings); 1890 1891 dpm.setMaximumTimeToLock(admin2, 10); 1892 verifyScreenTimeoutCall(10, true); 1893 reset(mMockContext.powerManagerInternal); 1894 reset(mMockContext.settings); 1895 1896 // There's no restriction; shold be set to MAX. 1897 dpm.setMaximumTimeToLock(admin2, 0); 1898 verifyScreenTimeoutCall(Integer.MAX_VALUE, false); 1899 } 1900 1901 private void verifyScreenTimeoutCall(Integer expectedTimeout, 1902 boolean shouldStayOnWhilePluggedInBeCleared) { 1903 if (expectedTimeout == null) { 1904 verify(mMockContext.powerManagerInternal, times(0)) 1905 .setMaximumScreenOffTimeoutFromDeviceAdmin(anyInt()); 1906 } else { 1907 verify(mMockContext.powerManagerInternal, times(1)) 1908 .setMaximumScreenOffTimeoutFromDeviceAdmin(eq(expectedTimeout)); 1909 } 1910 // TODO Verify calls to settingsGlobalPutInt. Tried but somehow mockito threw 1911 // UnfinishedVerificationException. 1912 } 1913} 1914 1915