1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.cts.deviceowner; 18 19 import static com.google.common.truth.Truth.assertWithMessage; 20 21 import static org.testng.Assert.expectThrows; 22 23 import android.app.ActivityManager; 24 import android.app.Service; 25 import android.app.admin.DeviceAdminReceiver; 26 import android.app.admin.DevicePolicyManager; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.ServiceConnection; 31 import android.content.pm.PackageManager; 32 import android.os.IBinder; 33 import android.os.PersistableBundle; 34 import android.os.RemoteException; 35 import android.os.UserHandle; 36 import android.os.UserManager; 37 import android.provider.Settings; 38 import android.util.DebugUtils; 39 import android.util.Log; 40 41 import com.android.compatibility.common.util.SystemUtil; 42 43 import java.lang.reflect.InvocationTargetException; 44 import java.lang.reflect.Method; 45 import java.util.Collections; 46 import java.util.HashSet; 47 import java.util.Iterator; 48 import java.util.List; 49 import java.util.Set; 50 import java.util.concurrent.Semaphore; 51 import java.util.concurrent.TimeUnit; 52 import java.util.function.Predicate; 53 import java.util.stream.Collectors; 54 55 /** 56 * Test {@link DevicePolicyManager#createAndManageUser}. 57 */ 58 public class CreateAndManageUserTest extends BaseDeviceOwnerTest { 59 private static final String TAG = "CreateAndManageUserTest"; 60 61 private static final int BROADCAST_TIMEOUT = 300_000; 62 63 private static final String AFFILIATION_ID = "affiliation.id"; 64 private static final String EXTRA_AFFILIATION_ID = "affiliationIdExtra"; 65 private static final String EXTRA_CURRENT_USER_PACKAGES = "currentUserPackages"; 66 private static final String EXTRA_METHOD_NAME = "methodName"; 67 private static final long ON_ENABLED_TIMEOUT_SECONDS = 120; 68 69 @Override tearDown()70 protected void tearDown() throws Exception { 71 mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_ADD_USER); 72 mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_REMOVE_USER); 73 super.tearDown(); 74 } 75 testCreateAndManageUser()76 public void testCreateAndManageUser() throws Exception { 77 UserHandle userHandle = createAndManageUser(); 78 79 assertWithMessage("New user").that(userHandle).isNotNull(); 80 } 81 testCreateAndManageUser_LowStorage()82 public void testCreateAndManageUser_LowStorage() throws Exception { 83 UserManager.UserOperationException e = expectThrows( 84 UserManager.UserOperationException.class, () -> createAndManageUser()); 85 86 assertUserOperationResult(e.getUserOperationResult(), 87 UserManager.USER_OPERATION_ERROR_LOW_STORAGE, 88 "user creation on low storage"); 89 } 90 testCreateAndManageUser_MaxUsers()91 public void testCreateAndManageUser_MaxUsers() throws Exception { 92 UserManager.UserOperationException e = expectThrows( 93 UserManager.UserOperationException.class, () -> createAndManageUser()); 94 95 assertUserOperationResult(e.getUserOperationResult(), 96 UserManager.USER_OPERATION_ERROR_MAX_USERS, 97 "user creation when max users is reached"); 98 } 99 100 @SuppressWarnings("unused") assertSkipSetupWizard(Context context, DevicePolicyManager devicePolicyManager, ComponentName componentName)101 private static void assertSkipSetupWizard(Context context, 102 DevicePolicyManager devicePolicyManager, ComponentName componentName) throws Exception { 103 assertWithMessage("user setup settings (%s)", Settings.Secure.USER_SETUP_COMPLETE) 104 .that(Settings.Secure.getInt(context.getContentResolver(), 105 Settings.Secure.USER_SETUP_COMPLETE)) 106 .isEqualTo(1); 107 } 108 testCreateAndManageUser_SkipSetupWizard()109 public void testCreateAndManageUser_SkipSetupWizard() throws Exception { 110 runCrossUserVerification(DevicePolicyManager.SKIP_SETUP_WIZARD, "assertSkipSetupWizard"); 111 112 PrimaryUserService.assertCrossUserCallArrived(); 113 } 114 testCreateAndManageUser_GetSecondaryUsers()115 public void testCreateAndManageUser_GetSecondaryUsers() throws Exception { 116 UserHandle newUserHandle = createAndManageUser(); 117 118 List<UserHandle> secondaryUsers = mDevicePolicyManager.getSecondaryUsers(getWho()); 119 if (isHeadlessSystemUserMode()) { 120 assertWithMessage("secondary users").that(secondaryUsers) 121 .containsExactly(getCurrentUser(), newUserHandle); 122 } else { 123 assertWithMessage("secondary users").that(secondaryUsers) 124 .containsExactly(newUserHandle); 125 } 126 } 127 testCreateAndManageUser_SwitchUser()128 public void testCreateAndManageUser_SwitchUser() throws Exception { 129 UserHandle userHandle = createAndManageUser(); 130 131 List<UserHandle> usersOnBroadcasts = switchUserAndWaitForBroadcasts(userHandle); 132 133 assertWithMessage("user on broadcasts").that(usersOnBroadcasts).containsExactly(userHandle, 134 userHandle); 135 } 136 testCreateAndManageUser_CannotStopCurrentUser()137 public void testCreateAndManageUser_CannotStopCurrentUser() throws Exception { 138 UserHandle userHandle = createAndManageUser(); 139 140 switchUserAndWaitForBroadcasts(userHandle); 141 142 stopUserAndCheckResult(userHandle, UserManager.USER_OPERATION_ERROR_CURRENT_USER); 143 } 144 testCreateAndManageUser_StartInBackground()145 public void testCreateAndManageUser_StartInBackground() throws Exception { 146 UserHandle userHandle = createAndManageUser(); 147 148 List<UserHandle> usersOnBroadcasts = startUserInBackgroundAndWaitForBroadcasts(userHandle); 149 150 assertWithMessage("user on broadcasts").that(usersOnBroadcasts).containsExactly(userHandle); 151 } 152 testCreateAndManageUser_StartInBackground_MaxRunningUsers()153 public void testCreateAndManageUser_StartInBackground_MaxRunningUsers() throws Exception { 154 UserHandle userHandle = createAndManageUser(); 155 156 // Start user in background and should receive max running users error 157 startUserInBackgroundAndCheckResult(userHandle, 158 UserManager.USER_OPERATION_ERROR_MAX_RUNNING_USERS); 159 } 160 testCreateAndManageUser_StopUser()161 public void testCreateAndManageUser_StopUser() throws Exception { 162 UserHandle userHandle = createAndManageUser(); 163 startUserInBackgroundAndWaitForBroadcasts(userHandle); 164 165 List<UserHandle> usersOnBroadcasts = stopUserAndWaitForBroadcasts(userHandle); 166 167 assertWithMessage("user on broadcasts").that(usersOnBroadcasts).containsExactly(userHandle); 168 } 169 testCreateAndManageUser_StopEphemeralUser_DisallowRemoveUser()170 public void testCreateAndManageUser_StopEphemeralUser_DisallowRemoveUser() throws Exception { 171 // Set DISALLOW_REMOVE_USER restriction 172 mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_REMOVE_USER); 173 174 UserHandle userHandle = createAndManageUser(DevicePolicyManager.MAKE_USER_EPHEMERAL); 175 startUserInBackgroundAndWaitForBroadcasts(userHandle); 176 UserActionCallback callback = UserActionCallback.getCallbackForBroadcastActions( 177 getContext(), 178 BasicAdminReceiver.ACTION_USER_STOPPED, BasicAdminReceiver.ACTION_USER_REMOVED); 179 180 callback.runAndUnregisterSelf( 181 () -> stopUserAndCheckResult(userHandle, UserManager.USER_OPERATION_SUCCESS)); 182 183 // It's running just one operation (which issues a ACTION_USER_STOPPED), but as the 184 // user is ephemeral, it will be automatically removed (which issues a 185 // ACTION_USER_REMOVED). 186 assertWithMessage("user on broadcasts").that(callback.getUsersOnReceivedBroadcasts()) 187 .containsExactly(userHandle, userHandle); 188 } 189 190 @SuppressWarnings("unused") logoutUser(Context context, DevicePolicyManager devicePolicyManager, ComponentName componentName)191 private static void logoutUser(Context context, DevicePolicyManager devicePolicyManager, 192 ComponentName componentName) { 193 assertUserOperationResult(devicePolicyManager.logoutUser(componentName), 194 UserManager.USER_OPERATION_SUCCESS, "cannot logout user"); 195 } 196 testCreateAndManageUser_LogoutUser()197 public void testCreateAndManageUser_LogoutUser() throws Exception { 198 UserActionCallback callback = UserActionCallback.getCallbackForBroadcastActions( 199 getContext(), 200 BasicAdminReceiver.ACTION_USER_STARTED, BasicAdminReceiver.ACTION_USER_STOPPED); 201 202 UserHandle userHandle = runCrossUserVerification(callback, 203 /* createAndManageUserFlags= */ 0, "logoutUser", /* currentUserPackages= */ null); 204 205 assertWithMessage("user on broadcasts").that(callback.getUsersOnReceivedBroadcasts()) 206 .containsExactly(userHandle, userHandle); 207 } 208 209 @SuppressWarnings("unused") assertAffiliatedUser(Context context, DevicePolicyManager devicePolicyManager, ComponentName componentName)210 private static void assertAffiliatedUser(Context context, 211 DevicePolicyManager devicePolicyManager, ComponentName componentName) { 212 assertWithMessage("affiliated user").that(devicePolicyManager.isAffiliatedUser()).isTrue(); 213 } 214 testCreateAndManageUser_Affiliated()215 public void testCreateAndManageUser_Affiliated() throws Exception { 216 runCrossUserVerification(/* createAndManageUserFlags= */ 0, "assertAffiliatedUser"); 217 PrimaryUserService.assertCrossUserCallArrived(); 218 } 219 220 @SuppressWarnings("unused") assertEphemeralUser(Context context, DevicePolicyManager devicePolicyManager, ComponentName componentName)221 private static void assertEphemeralUser(Context context, 222 DevicePolicyManager devicePolicyManager, ComponentName componentName) { 223 assertWithMessage("ephemeral user").that(devicePolicyManager.isEphemeralUser(componentName)) 224 .isTrue(); 225 } 226 testCreateAndManageUser_Ephemeral()227 public void testCreateAndManageUser_Ephemeral() throws Exception { 228 runCrossUserVerification(DevicePolicyManager.MAKE_USER_EPHEMERAL, "assertEphemeralUser"); 229 PrimaryUserService.assertCrossUserCallArrived(); 230 } 231 232 @SuppressWarnings("unused") assertAllSystemAppsInstalled(Context context, DevicePolicyManager devicePolicyManager, ComponentName componentName, Set<String> preInstalledSystemPackages)233 private static void assertAllSystemAppsInstalled(Context context, 234 DevicePolicyManager devicePolicyManager, ComponentName componentName, 235 Set<String> preInstalledSystemPackages) { 236 Log.d(TAG, "assertAllSystemAppsInstalled(): checking apps for user " + context.getUserId()); 237 238 PackageManager packageManager = context.getPackageManager(); 239 // First get a set of installed package names 240 Set<String> installedPackageNames = packageManager 241 .getInstalledApplications(/* flags= */ 0) 242 .stream() 243 .map(applicationInfo -> applicationInfo.packageName) 244 .collect(Collectors.toSet()); 245 // Then filter all package names by those that are not installed 246 Set<String> uninstalledPackageNames = packageManager 247 .getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES) 248 .stream() 249 .map(applicationInfo -> applicationInfo.packageName) 250 .filter(((Predicate<String>) installedPackageNames::contains).negate()) 251 .collect(Collectors.toSet()); 252 253 // Finally, filter out packages that are not pre-installed for the user 254 Iterator<String> iterator = uninstalledPackageNames.iterator(); 255 while (iterator.hasNext()) { 256 String pkg = iterator.next(); 257 if (!preInstalledSystemPackages.contains(pkg)) { 258 Log.i(TAG, "assertAllSystemAppsInstalled(): ignoring package " + pkg 259 + " as it's not pre-installed on current user"); 260 iterator.remove(); 261 } 262 } 263 264 // Assert that all expected apps are installed 265 assertWithMessage("uninstalled system apps").that(uninstalledPackageNames).isEmpty(); 266 } 267 testCreateAndManageUser_LeaveAllSystemApps()268 public void testCreateAndManageUser_LeaveAllSystemApps() throws Exception { 269 int currentUserId = ActivityManager.getCurrentUser(); 270 // TODO: instead of hard-coding the user type, calling getPreInstallableSystemPackages(), 271 // and passing the packages to runCrossUserVerification() / assertAllSystemAppsInstalled(), 272 // ideally the later should call um.getPreInstallableSystemPackages(um.getUsertype()) 273 // (where um is the UserManager with the context of the newly created user), 274 // but currently the list of pre-installed apps is passed to the new user in the bundle. 275 // Given that these tests will be refactored anyways, it's not worth to try to change it. 276 String newUserType = UserManager.USER_TYPE_FULL_SECONDARY; 277 Set<String> preInstalledSystemPackages = SystemUtil.callWithShellPermissionIdentity( 278 () -> UserManager.get(mContext).getPreInstallableSystemPackages(newUserType)); 279 if (preInstalledSystemPackages != null) { 280 Log.d(TAG, preInstalledSystemPackages.size() + " pre-installed system apps for " 281 + "new user of type " + newUserType + ": " + preInstalledSystemPackages); 282 } else { 283 Log.d(TAG, "no pre-installed system apps allowlist for new user of type" + newUserType); 284 } 285 286 runCrossUserVerification(/* callback= */ null, 287 DevicePolicyManager.LEAVE_ALL_SYSTEM_APPS_ENABLED, "assertAllSystemAppsInstalled", 288 preInstalledSystemPackages); 289 PrimaryUserService.assertCrossUserCallArrived(); 290 } 291 runCrossUserVerification(int createAndManageUserFlags, String methodName)292 private UserHandle runCrossUserVerification(int createAndManageUserFlags, String methodName) 293 throws Exception { 294 return runCrossUserVerification(/* callback= */ null, createAndManageUserFlags, methodName, 295 /* currentUserPackages= */ null); 296 } 297 runCrossUserVerification(UserActionCallback callback, int createAndManageUserFlags, String methodName, Set<String> currentUserPackages)298 private UserHandle runCrossUserVerification(UserActionCallback callback, 299 int createAndManageUserFlags, String methodName, 300 Set<String> currentUserPackages) throws Exception { 301 Log.d(TAG, "runCrossUserVerification(): flags=" + createAndManageUserFlags 302 + ", method=" + methodName); 303 String testUserName = "TestUser_" + System.currentTimeMillis(); 304 305 // Set affiliation id to allow communication. 306 mDevicePolicyManager.setAffiliationIds(getWho(), Collections.singleton(AFFILIATION_ID)); 307 308 ComponentName profileOwner = SecondaryUserAdminReceiver.getComponentName(getContext()); 309 310 // Pack the affiliation id in a bundle so the secondary user can get it. 311 PersistableBundle bundle = new PersistableBundle(); 312 bundle.putString(EXTRA_AFFILIATION_ID, AFFILIATION_ID); 313 bundle.putString(EXTRA_METHOD_NAME, methodName); 314 if (currentUserPackages != null) { 315 String[] array = new String[currentUserPackages.size()]; 316 currentUserPackages.toArray(array); 317 bundle.putStringArray(EXTRA_CURRENT_USER_PACKAGES, array); 318 } 319 320 Log.d(TAG, "creating user with PO " + profileOwner); 321 322 UserHandle userHandle = createAndManageUser(profileOwner, bundle, createAndManageUserFlags); 323 if (callback != null) { 324 startUserInBackgroundAndWaitForBroadcasts(callback, userHandle); 325 } else { 326 startUserInBackgroundAndWaitForBroadcasts(userHandle); 327 } 328 return userHandle; 329 } 330 331 // createAndManageUser should circumvent the DISALLOW_ADD_USER restriction testCreateAndManageUser_AddRestrictionSet()332 public void testCreateAndManageUser_AddRestrictionSet() throws Exception { 333 mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_ADD_USER); 334 335 createAndManageUser(); 336 } 337 testCreateAndManageUser_RemoveRestrictionSet()338 public void testCreateAndManageUser_RemoveRestrictionSet() throws Exception { 339 mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_REMOVE_USER); 340 341 UserHandle userHandle = createAndManageUser(); 342 343 // When the device owner itself has set the user restriction, it should still be allowed 344 // to remove a user. 345 List<UserHandle> usersOnBroadcasts = removeUserAndWaitForBroadcasts(userHandle); 346 347 assertWithMessage("user on broadcasts").that(usersOnBroadcasts).containsExactly(userHandle); 348 } 349 testUserAddedOrRemovedBroadcasts()350 public void testUserAddedOrRemovedBroadcasts() throws Exception { 351 UserHandle userHandle = createAndManageUser(); 352 353 List<UserHandle> userHandles = removeUserAndWaitForBroadcasts(userHandle); 354 355 assertWithMessage("user on broadcasts").that(userHandles).containsExactly(userHandle); 356 } 357 createAndManageUser()358 private UserHandle createAndManageUser() throws Exception { 359 return createAndManageUser(/* flags= */ 0); 360 } 361 createAndManageUser(int flags)362 private UserHandle createAndManageUser(int flags) throws Exception { 363 return createAndManageUser(/* profileOwner= */ getWho(), /* adminExtras= */ null, flags); 364 } 365 createAndManageUser(ComponentName profileOwner, PersistableBundle adminExtras, int flags)366 private UserHandle createAndManageUser(ComponentName profileOwner, 367 PersistableBundle adminExtras, int flags) throws Exception { 368 String testUserName = "TestUser_" + System.currentTimeMillis(); 369 370 UserActionCallback callback = UserActionCallback.getCallbackForBroadcastActions( 371 getContext(), BasicAdminReceiver.ACTION_USER_ADDED); 372 373 UserHandle userHandle = callback.callAndUnregisterSelf(() -> 374 mDevicePolicyManager.createAndManageUser( 375 /* admin= */ getWho(), 376 testUserName, 377 profileOwner, 378 adminExtras, 379 flags)); 380 Log.d(TAG, "User '" + testUserName + "' created: " + userHandle); 381 return userHandle; 382 } 383 384 /** 385 * Switches to the given user, or fails if the user could not be switched or if the expected 386 * broadcasts were not received in time. 387 * 388 * @return users received in the broadcasts 389 */ switchUserAndWaitForBroadcasts(UserHandle userHandle)390 private List<UserHandle> switchUserAndWaitForBroadcasts(UserHandle userHandle) 391 throws Exception { 392 Log.d(TAG, "Switching to user " + userHandle); 393 394 UserActionCallback callback = UserActionCallback.getCallbackForBroadcastActions( 395 getContext(), 396 BasicAdminReceiver.ACTION_USER_STARTED, BasicAdminReceiver.ACTION_USER_SWITCHED); 397 398 callback.runAndUnregisterSelf(() -> { 399 boolean switched = mDevicePolicyManager.switchUser(getWho(), userHandle); 400 assertWithMessage("switched to user %s", userHandle).that(switched).isTrue(); 401 }); 402 return callback.getUsersOnReceivedBroadcasts(); 403 } 404 405 /** 406 * Removes the given user, or fails if the user could not be removed or if the expected 407 * broadcasts were not received in time. 408 * 409 * @return users received in the broadcasts 410 */ removeUserAndWaitForBroadcasts(UserHandle userHandle)411 private List<UserHandle> removeUserAndWaitForBroadcasts(UserHandle userHandle) 412 throws Exception { 413 UserActionCallback callback = UserActionCallback.getCallbackForBroadcastActions( 414 getContext(), BasicAdminReceiver.ACTION_USER_REMOVED); 415 416 callback.runAndUnregisterSelf(() -> { 417 boolean removed = mDevicePolicyManager.removeUser(getWho(), userHandle); 418 assertWithMessage("removed user %s", userHandle).that(removed).isTrue(); 419 }); 420 421 return callback.getUsersOnReceivedBroadcasts(); 422 } 423 userOperationResultToString(int result)424 private static String userOperationResultToString(int result) { 425 return DebugUtils.constantToString(UserManager.class, "USER_OPERATION_", result); 426 } 427 assertUserOperationResult(int actualResult, int expectedResult, String operationFormat, Object... operationArgs)428 private static void assertUserOperationResult(int actualResult, int expectedResult, 429 String operationFormat, Object... operationArgs) { 430 String operation = String.format(operationFormat, operationArgs); 431 assertWithMessage("result for %s (%s instead of %s)", operation, 432 userOperationResultToString(actualResult), 433 userOperationResultToString(expectedResult)) 434 .that(actualResult).isEqualTo(expectedResult); 435 } 436 startUserInBackgroundAndCheckResult(UserHandle userHandle, int expectedResult)437 private void startUserInBackgroundAndCheckResult(UserHandle userHandle, int expectedResult) { 438 int actualResult = mDevicePolicyManager.startUserInBackground(getWho(), userHandle); 439 assertUserOperationResult(actualResult, expectedResult, "starting user %s in background", 440 userHandle); 441 } 442 443 /** 444 * Starts the given user in background, or fails if the user could not be started or if the 445 * expected broadcasts were not received in time. 446 * 447 * @return users received in the broadcasts 448 */ startUserInBackgroundAndWaitForBroadcasts(UserHandle userHandle)449 private List<UserHandle> startUserInBackgroundAndWaitForBroadcasts(UserHandle userHandle) 450 throws Exception { 451 UserActionCallback callback = UserActionCallback.getCallbackForBroadcastActions( 452 getContext(), BasicAdminReceiver.ACTION_USER_STARTED); 453 return startUserInBackgroundAndWaitForBroadcasts(callback, userHandle); 454 } 455 startUserInBackgroundAndWaitForBroadcasts(UserActionCallback callback, UserHandle userHandle)456 private List<UserHandle> startUserInBackgroundAndWaitForBroadcasts(UserActionCallback callback, 457 UserHandle userHandle) throws Exception { 458 callback.runAndUnregisterSelf(() -> startUserInBackgroundAndCheckResult(userHandle, 459 UserManager.USER_OPERATION_SUCCESS)); 460 return callback.getUsersOnReceivedBroadcasts(); 461 } 462 stopUserAndCheckResult(UserHandle userHandle, int expectedResult)463 private void stopUserAndCheckResult(UserHandle userHandle, int expectedResult) { 464 int actualResult = mDevicePolicyManager.stopUser(getWho(), userHandle); 465 assertUserOperationResult(actualResult, expectedResult, "stopping user %s", userHandle); 466 } 467 468 /** 469 * Stops the given user, or fails if the user could not be stop or if the expected broadcasts 470 * were not received in time. 471 * 472 * @return users received in the broadcasts 473 */ stopUserAndWaitForBroadcasts(UserHandle userHandle)474 private List<UserHandle> stopUserAndWaitForBroadcasts(UserHandle userHandle) throws Exception { 475 UserActionCallback callback = UserActionCallback.getCallbackForBroadcastActions( 476 getContext(), BasicAdminReceiver.ACTION_USER_STOPPED); 477 callback.runAndUnregisterSelf( 478 () -> stopUserAndCheckResult(userHandle, UserManager.USER_OPERATION_SUCCESS)); 479 return callback.getUsersOnReceivedBroadcasts(); 480 } 481 482 public static final class PrimaryUserService extends Service { 483 private static final Semaphore sSemaphore = new Semaphore(0); 484 private static String sError = null; 485 486 private final ICrossUserService.Stub mBinder = new ICrossUserService.Stub() { 487 public void onEnabledCalled(String error) { 488 Log.d(TAG, "PrimaryUserService.onEnabledCalled() on user " 489 + getApplicationContext().getUserId() + " with error " + error); 490 sError = error; 491 sSemaphore.release(); 492 } 493 }; 494 495 @Override onBind(Intent intent)496 public IBinder onBind(Intent intent) { 497 Log.d(TAG, "PrimaryUserService.onBind() on user " 498 + getApplicationContext().getUserId() + ": " + intent); 499 return mBinder; 500 } 501 assertCrossUserCallArrived()502 static void assertCrossUserCallArrived() throws Exception { 503 assertWithMessage("cross-user call arrived in %ss", ON_ENABLED_TIMEOUT_SECONDS) 504 .that(sSemaphore.tryAcquire(ON_ENABLED_TIMEOUT_SECONDS, TimeUnit.SECONDS)) 505 .isTrue(); 506 if (sError != null) { 507 Log.e(TAG, "assertCrossUserCallArrived() had error: " + sError); 508 throw new Exception(sError); 509 } 510 } 511 } 512 513 public static final class SecondaryUserAdminReceiver extends DeviceAdminReceiver { 514 515 @Override onEnabled(Context context, Intent intent)516 public void onEnabled(Context context, Intent intent) { 517 Log.d(TAG, "SecondaryUserAdminReceiver.onEnabled() called on user " 518 + context.getUserId()); 519 520 DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class); 521 ComponentName who = getComponentName(context); 522 523 // Set affiliation ids 524 Set<String> ids = Collections.singleton(intent.getStringExtra(EXTRA_AFFILIATION_ID)); 525 Log.d(TAG, "setting affiliation ids as " + ids); 526 dpm.setAffiliationIds(who, ids); 527 528 String error = null; 529 try { 530 Method method; 531 if (intent.hasExtra(EXTRA_CURRENT_USER_PACKAGES)) { 532 method = CreateAndManageUserTest.class.getDeclaredMethod( 533 intent.getStringExtra(EXTRA_METHOD_NAME), Context.class, 534 DevicePolicyManager.class, ComponentName.class, Set.class); 535 } else { 536 method = CreateAndManageUserTest.class.getDeclaredMethod( 537 intent.getStringExtra(EXTRA_METHOD_NAME), Context.class, 538 DevicePolicyManager.class, ComponentName.class); 539 } 540 method.setAccessible(true); 541 Log.d(TAG, "Calling method " + method); 542 if (intent.hasExtra(EXTRA_CURRENT_USER_PACKAGES)) { 543 String[] pkgsArray = intent.getStringArrayExtra(EXTRA_CURRENT_USER_PACKAGES); 544 Set<String> pkgs = new HashSet<>(pkgsArray.length); 545 for (String pkg : pkgsArray) { 546 pkgs.add(pkg); 547 } 548 method.invoke(null, context, dpm, who, pkgs); 549 } else { 550 method.invoke(null, context, dpm, who); 551 } 552 } catch (NoSuchMethodException | IllegalAccessException e) { 553 error = e.toString(); 554 } catch (InvocationTargetException e) { 555 error = e.getCause().toString(); 556 } 557 558 // Call all affiliated users 559 final List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(who); 560 assertWithMessage("target users").that(targetUsers).hasSize(1); 561 562 pingTargetUser(context, dpm, targetUsers.get(0), error); 563 } 564 pingTargetUser(Context context, DevicePolicyManager dpm, UserHandle target, String error)565 private void pingTargetUser(Context context, DevicePolicyManager dpm, 566 UserHandle target, String error) { 567 Log.d(TAG, "Pinging target " + target + " with error " + error); 568 final ServiceConnection serviceConnection = new ServiceConnection() { 569 @Override 570 public void onServiceConnected(ComponentName name, IBinder service) { 571 Log.d(TAG, "onServiceConnected() is called in " + Thread.currentThread()); 572 ICrossUserService crossUserService = ICrossUserService 573 .Stub.asInterface(service); 574 try { 575 crossUserService.onEnabledCalled(error); 576 } catch (RemoteException re) { 577 Log.e(TAG, "Error when calling primary user", re); 578 // Do nothing, primary user will time out 579 } 580 } 581 582 @Override 583 public void onServiceDisconnected(ComponentName name) { 584 Log.d(TAG, "onServiceDisconnected() is called"); 585 } 586 }; 587 Intent serviceIntent = new Intent(context, PrimaryUserService.class); 588 boolean bound = dpm.bindDeviceAdminServiceAsUser( 589 getComponentName(context), 590 serviceIntent, 591 serviceConnection, 592 Context.BIND_AUTO_CREATE, 593 target); 594 assertWithMessage("bound to user %s using intent %s", target, serviceIntent).that(bound) 595 .isTrue(); 596 } 597 getComponentName(Context context)598 public static ComponentName getComponentName(Context context) { 599 return new ComponentName(context, SecondaryUserAdminReceiver.class); 600 } 601 } 602 } 603