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 package android.multiuser; 17 18 import static org.junit.Assume.assumeTrue; 19 20 import android.annotation.NonNull; 21 import android.app.ActivityManager; 22 import android.app.ActivityTaskManager; 23 import android.app.AppGlobals; 24 import android.app.IActivityManager; 25 import android.app.IStopUserCallback; 26 import android.app.UserSwitchObserver; 27 import android.app.WaitResult; 28 import android.content.BroadcastReceiver; 29 import android.content.Context; 30 import android.content.IIntentReceiver; 31 import android.content.IIntentSender; 32 import android.content.Intent; 33 import android.content.IntentFilter; 34 import android.content.IntentSender; 35 import android.content.pm.IPackageInstaller; 36 import android.content.pm.PackageManager; 37 import android.content.pm.UserInfo; 38 import android.os.Bundle; 39 import android.os.IBinder; 40 import android.os.IProgressListener; 41 import android.os.RemoteException; 42 import android.os.SystemClock; 43 import android.os.SystemProperties; 44 import android.os.UserHandle; 45 import android.os.UserManager; 46 import android.perftests.utils.ShellHelper; 47 import android.util.Log; 48 import android.view.WindowManagerGlobal; 49 50 import androidx.test.InstrumentationRegistry; 51 import androidx.test.filters.LargeTest; 52 import androidx.test.runner.AndroidJUnit4; 53 54 import org.junit.After; 55 import org.junit.Before; 56 import org.junit.Rule; 57 import org.junit.Test; 58 import org.junit.runner.RunWith; 59 60 import java.util.ArrayList; 61 import java.util.concurrent.CountDownLatch; 62 import java.util.concurrent.TimeUnit; 63 64 /** 65 * Perf tests for user life cycle events. 66 * 67 * To run the tests: atest UserLifecycleTests 68 * 69 * 70 * Old methods for running the tests: 71 * 72 * make MultiUserPerfTests && 73 * adb install -r \ 74 * ${ANDROID_PRODUCT_OUT}/data/app/MultiUserPerfTests/MultiUserPerfTests.apk && 75 * adb shell am instrument -e class android.multiuser.UserLifecycleTests \ 76 * -w com.android.perftests.multiuser/androidx.test.runner.AndroidJUnitRunner 77 * 78 * or 79 * 80 * bit MultiUserPerfTests:android.multiuser.UserLifecycleTests 81 * 82 * Note: If you use bit for running the tests, benchmark results won't be printed on the host side. 83 * But in either case, results can be checked on the device side 'adb logcat -s UserLifecycleTests' 84 */ 85 @LargeTest 86 @RunWith(AndroidJUnit4.class) 87 public class UserLifecycleTests { 88 private static final String TAG = UserLifecycleTests.class.getSimpleName(); 89 90 private static final int TIMEOUT_IN_SECOND = 30; 91 private static final int CHECK_USER_REMOVED_INTERVAL_MS = 200; 92 93 /** Name of users/profiles in the test. Users with this name may be freely removed. */ 94 private static final String TEST_USER_NAME = "UserLifecycleTests_test_user"; 95 96 /** Name of dummy package used when timing how long app launches take. */ 97 private static final String DUMMY_PACKAGE_NAME = "perftests.multiuser.apps.dummyapp"; 98 99 // Copy of UserSystemPackageInstaller whitelist mode constants. 100 private static final String PACKAGE_WHITELIST_MODE_PROP = 101 "persist.debug.user.package_whitelist_mode"; 102 private static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE = 0; 103 private static final int USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE = 0b001; 104 private static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST = 0b100; 105 private static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT = -1; 106 107 private UserManager mUm; 108 private ActivityManager mAm; 109 private IActivityManager mIam; 110 private PackageManager mPm; 111 private ArrayList<Integer> mUsersToRemove; 112 private boolean mHasManagedUserFeature; 113 114 private final BenchmarkRunner mRunner = new BenchmarkRunner(); 115 @Rule 116 public BenchmarkResultsReporter mReporter = new BenchmarkResultsReporter(mRunner); 117 118 @Before setUp()119 public void setUp() { 120 final Context context = InstrumentationRegistry.getContext(); 121 mUm = UserManager.get(context); 122 mAm = context.getSystemService(ActivityManager.class); 123 mIam = ActivityManager.getService(); 124 mUsersToRemove = new ArrayList<>(); 125 mPm = context.getPackageManager(); 126 mHasManagedUserFeature = mPm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS); 127 removeAnyPreviousTestUsers(); 128 if (mAm.getCurrentUser() != UserHandle.USER_SYSTEM) { 129 Log.w(TAG, "WARNING: Tests are being run from user " + mAm.getCurrentUser() 130 + " rather than the system user"); 131 } 132 } 133 134 @After tearDown()135 public void tearDown() { 136 for (int userId : mUsersToRemove) { 137 try { 138 mUm.removeUser(userId); 139 } catch (Exception e) { 140 // Ignore 141 } 142 } 143 } 144 145 @Test createUser()146 public void createUser() { 147 while (mRunner.keepRunning()) { 148 final int userId = createUserNoFlags(); 149 150 mRunner.pauseTiming(); 151 removeUser(userId); 152 mRunner.resumeTiming(); 153 } 154 } 155 156 @Test createAndStartUser()157 public void createAndStartUser() throws RemoteException { 158 while (mRunner.keepRunning()) { 159 final int userId = createUserNoFlags(); 160 161 final CountDownLatch latch = new CountDownLatch(1); 162 registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userId); 163 // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until 164 // ACTION_USER_STARTED. 165 mIam.startUserInBackground(userId); 166 waitForLatch("Failed to achieve ACTION_USER_STARTED for user " + userId, latch); 167 168 mRunner.pauseTiming(); 169 removeUser(userId); 170 mRunner.resumeTiming(); 171 } 172 } 173 174 /** 175 * Measures the time until ACTION_USER_STARTED is received. 176 */ 177 @Test startUser()178 public void startUser() throws RemoteException { 179 while (mRunner.keepRunning()) { 180 mRunner.pauseTiming(); 181 final int userId = createUserNoFlags(); 182 final CountDownLatch latch = new CountDownLatch(1); 183 registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userId); 184 mRunner.resumeTiming(); 185 186 mIam.startUserInBackground(userId); 187 waitForLatch("Failed to achieve ACTION_USER_STARTED for user " + userId, latch); 188 189 mRunner.pauseTiming(); 190 removeUser(userId); 191 mRunner.resumeTiming(); 192 } 193 } 194 195 /** 196 * Measures the time until unlock listener is triggered and user is unlocked. 197 */ 198 @Test startAndUnlockUser()199 public void startAndUnlockUser() { 200 while (mRunner.keepRunning()) { 201 mRunner.pauseTiming(); 202 final int userId = createUserNoFlags(); 203 mRunner.resumeTiming(); 204 205 // Waits for UserState.mUnlockProgress.finish(). 206 startUserInBackgroundAndWaitForUnlock(userId); 207 208 mRunner.pauseTiming(); 209 removeUser(userId); 210 mRunner.resumeTiming(); 211 } 212 } 213 214 @Test switchUser()215 public void switchUser() throws RemoteException { 216 while (mRunner.keepRunning()) { 217 mRunner.pauseTiming(); 218 final int startUser = mAm.getCurrentUser(); 219 final int userId = createUserNoFlags(); 220 mRunner.resumeTiming(); 221 222 switchUser(userId); 223 224 mRunner.pauseTiming(); 225 switchUserNoCheck(startUser); 226 removeUser(userId); 227 mRunner.resumeTiming(); 228 } 229 } 230 231 /** Tests switching to an already-created, but no-longer-running, user. */ 232 @Test switchUser_stopped()233 public void switchUser_stopped() throws RemoteException { 234 while (mRunner.keepRunning()) { 235 mRunner.pauseTiming(); 236 final int startUser = mAm.getCurrentUser(); 237 final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ true); 238 final CountDownLatch latch = new CountDownLatch(1); 239 registerBroadcastReceiver(Intent.ACTION_USER_UNLOCKED, latch, testUser); 240 mRunner.resumeTiming(); 241 242 mAm.switchUser(testUser); 243 waitForLatch("Failed to achieve 2nd ACTION_USER_UNLOCKED for user " + testUser, latch); 244 245 246 mRunner.pauseTiming(); 247 switchUserNoCheck(startUser); 248 removeUser(testUser); 249 mRunner.resumeTiming(); 250 } 251 } 252 253 /** Tests switching to an already-created already-running non-owner user. */ 254 @Test switchUser_running()255 public void switchUser_running() throws RemoteException { 256 while (mRunner.keepRunning()) { 257 mRunner.pauseTiming(); 258 final int startUser = mAm.getCurrentUser(); 259 final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false); 260 mRunner.resumeTiming(); 261 262 switchUser(testUser); 263 264 mRunner.pauseTiming(); 265 switchUserNoCheck(startUser); 266 removeUser(testUser); 267 mRunner.resumeTiming(); 268 } 269 } 270 271 @Test stopUser()272 public void stopUser() throws RemoteException { 273 while (mRunner.keepRunning()) { 274 mRunner.pauseTiming(); 275 final int userId = createUserNoFlags(); 276 final CountDownLatch latch = new CountDownLatch(1); 277 registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userId); 278 mIam.startUserInBackground(userId); 279 waitForLatch("Failed to achieve ACTION_USER_STARTED for user " + userId, latch); 280 mRunner.resumeTiming(); 281 282 stopUser(userId, false); 283 284 mRunner.pauseTiming(); 285 removeUser(userId); 286 mRunner.resumeTiming(); 287 } 288 } 289 290 @Test lockedBootCompleted()291 public void lockedBootCompleted() throws RemoteException { 292 while (mRunner.keepRunning()) { 293 mRunner.pauseTiming(); 294 final int startUser = mAm.getCurrentUser(); 295 final int userId = createUserNoFlags(); 296 final CountDownLatch latch = new CountDownLatch(1); 297 registerUserSwitchObserver(null, latch, userId); 298 mRunner.resumeTiming(); 299 300 mAm.switchUser(userId); 301 waitForLatch("Failed to achieve onLockedBootComplete for user " + userId, latch); 302 303 mRunner.pauseTiming(); 304 switchUserNoCheck(startUser); 305 removeUser(userId); 306 mRunner.resumeTiming(); 307 } 308 } 309 310 @Test ephemeralUserStopped()311 public void ephemeralUserStopped() throws RemoteException { 312 while (mRunner.keepRunning()) { 313 mRunner.pauseTiming(); 314 final int startUser = mAm.getCurrentUser(); 315 final int userId = createUserWithFlags(UserInfo.FLAG_EPHEMERAL | UserInfo.FLAG_DEMO); 316 switchUser(userId); 317 final CountDownLatch latch = new CountDownLatch(1); 318 InstrumentationRegistry.getContext().registerReceiver(new BroadcastReceiver() { 319 @Override 320 public void onReceive(Context context, Intent intent) { 321 if (Intent.ACTION_USER_STOPPED.equals(intent.getAction()) && intent.getIntExtra( 322 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL) == userId) { 323 latch.countDown(); 324 } 325 } 326 }, new IntentFilter(Intent.ACTION_USER_STOPPED)); 327 final CountDownLatch switchLatch = new CountDownLatch(1); 328 registerUserSwitchObserver(switchLatch, null, startUser); 329 mRunner.resumeTiming(); 330 331 mAm.switchUser(startUser); 332 waitForLatch("Failed to achieve ACTION_USER_STOPPED for user " + userId, latch); 333 334 mRunner.pauseTiming(); 335 try { 336 switchLatch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS); 337 } catch (InterruptedException e) { 338 Log.e(TAG, "Thread interrupted unexpectedly while waiting for switch.", e); 339 } 340 removeUser(userId); 341 mRunner.resumeTiming(); 342 } 343 } 344 345 /** Tests creating a new profile. */ 346 @Test managedProfileCreate()347 public void managedProfileCreate() { 348 assumeTrue(mHasManagedUserFeature); 349 350 while (mRunner.keepRunning()) { 351 final int userId = createManagedProfile(); 352 353 mRunner.pauseTiming(); 354 attestTrue("Failed creating profile " + userId, mUm.isManagedProfile(userId)); 355 removeUser(userId); 356 mRunner.resumeTiming(); 357 } 358 } 359 360 /** Tests starting (unlocking) a newly-created profile. */ 361 @Test managedProfileUnlock()362 public void managedProfileUnlock() { 363 assumeTrue(mHasManagedUserFeature); 364 365 while (mRunner.keepRunning()) { 366 mRunner.pauseTiming(); 367 final int userId = createManagedProfile(); 368 mRunner.resumeTiming(); 369 370 startUserInBackgroundAndWaitForUnlock(userId); 371 372 mRunner.pauseTiming(); 373 removeUser(userId); 374 mRunner.resumeTiming(); 375 } 376 } 377 378 /** Tests starting (unlocking) an already-created, but no-longer-running, profile. */ 379 @Test managedProfileUnlock_stopped()380 public void managedProfileUnlock_stopped() throws RemoteException { 381 assumeTrue(mHasManagedUserFeature); 382 383 while (mRunner.keepRunning()) { 384 mRunner.pauseTiming(); 385 final int userId = createManagedProfile(); 386 // Start the profile initially, then stop it. Similar to setQuietModeEnabled. 387 startUserInBackgroundAndWaitForUnlock(userId); 388 stopUser(userId, true); 389 mRunner.resumeTiming(); 390 391 startUserInBackgroundAndWaitForUnlock(userId); 392 393 mRunner.pauseTiming(); 394 removeUser(userId); 395 mRunner.resumeTiming(); 396 } 397 } 398 399 /** 400 * Tests starting (unlocking) and launching an already-installed app in a newly-created profile. 401 */ 402 @Test managedProfileUnlockAndLaunchApp()403 public void managedProfileUnlockAndLaunchApp() throws RemoteException { 404 assumeTrue(mHasManagedUserFeature); 405 406 while (mRunner.keepRunning()) { 407 mRunner.pauseTiming(); 408 final int userId = createManagedProfile(); 409 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null); 410 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 411 mRunner.resumeTiming(); 412 413 startUserInBackgroundAndWaitForUnlock(userId); 414 startApp(userId, DUMMY_PACKAGE_NAME); 415 416 mRunner.pauseTiming(); 417 removeUser(userId); 418 mRunner.resumeTiming(); 419 } 420 } 421 422 /** 423 * Tests starting (unlocking) and launching a previously-launched app 424 * in an already-created, but no-longer-running, profile. 425 * A sort of combination of {@link #managedProfileUnlockAndLaunchApp} and 426 * {@link #managedProfileUnlock_stopped}}. 427 */ 428 @Test managedProfileUnlockAndLaunchApp_stopped()429 public void managedProfileUnlockAndLaunchApp_stopped() throws RemoteException { 430 assumeTrue(mHasManagedUserFeature); 431 432 while (mRunner.keepRunning()) { 433 mRunner.pauseTiming(); 434 final int userId = createManagedProfile(); 435 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null); 436 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 437 startUserInBackgroundAndWaitForUnlock(userId); 438 startApp(userId, DUMMY_PACKAGE_NAME); 439 stopUser(userId, true); 440 SystemClock.sleep(1_000); // 1 second cool-down before re-starting profile. 441 mRunner.resumeTiming(); 442 443 startUserInBackgroundAndWaitForUnlock(userId); 444 startApp(userId, DUMMY_PACKAGE_NAME); 445 446 mRunner.pauseTiming(); 447 removeUser(userId); 448 mRunner.resumeTiming(); 449 } 450 } 451 452 /** Tests installing a pre-existing app in a newly-created profile. */ 453 @Test managedProfileInstall()454 public void managedProfileInstall() throws RemoteException { 455 assumeTrue(mHasManagedUserFeature); 456 457 while (mRunner.keepRunning()) { 458 mRunner.pauseTiming(); 459 final int userId = createManagedProfile(); 460 mRunner.resumeTiming(); 461 462 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 463 464 mRunner.pauseTiming(); 465 removeUser(userId); 466 mRunner.resumeTiming(); 467 } 468 } 469 470 /** 471 * Tests creating a new profile, starting (unlocking) it, installing an app, 472 * and launching that app in it. 473 */ 474 @Test managedProfileCreateUnlockInstallAndLaunchApp()475 public void managedProfileCreateUnlockInstallAndLaunchApp() throws RemoteException { 476 assumeTrue(mHasManagedUserFeature); 477 478 while (mRunner.keepRunning()) { 479 mRunner.pauseTiming(); 480 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null); 481 mRunner.resumeTiming(); 482 483 final int userId = createManagedProfile(); 484 startUserInBackgroundAndWaitForUnlock(userId); 485 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 486 startApp(userId, DUMMY_PACKAGE_NAME); 487 488 mRunner.pauseTiming(); 489 removeUser(userId); 490 mRunner.resumeTiming(); 491 } 492 } 493 494 /** Tests stopping a profile. */ 495 @Test managedProfileStopped()496 public void managedProfileStopped() throws RemoteException { 497 assumeTrue(mHasManagedUserFeature); 498 499 while (mRunner.keepRunning()) { 500 mRunner.pauseTiming(); 501 final int userId = createManagedProfile(); 502 startUserInBackgroundAndWaitForUnlock(userId); 503 mRunner.resumeTiming(); 504 505 stopUser(userId, true); 506 507 mRunner.pauseTiming(); 508 removeUser(userId); 509 mRunner.resumeTiming(); 510 } 511 } 512 513 // TODO: This is just a POC. Do this properly and add more. 514 /** Tests starting (unlocking) a newly-created profile using the user-type-pkg-whitelist. */ 515 @Test managedProfileUnlock_usingWhitelist()516 public void managedProfileUnlock_usingWhitelist() { 517 assumeTrue(mHasManagedUserFeature); 518 final int origMode = getUserTypePackageWhitelistMode(); 519 setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE 520 | USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST); 521 522 try { 523 while (mRunner.keepRunning()) { 524 mRunner.pauseTiming(); 525 final int userId = createManagedProfile(); 526 mRunner.resumeTiming(); 527 528 startUserInBackgroundAndWaitForUnlock(userId); 529 530 mRunner.pauseTiming(); 531 removeUser(userId); 532 mRunner.resumeTiming(); 533 } 534 } finally { 535 setUserTypePackageWhitelistMode(origMode); 536 } 537 } 538 /** Tests starting (unlocking) a newly-created profile NOT using the user-type-pkg-whitelist. */ 539 @Test managedProfileUnlock_notUsingWhitelist()540 public void managedProfileUnlock_notUsingWhitelist() { 541 assumeTrue(mHasManagedUserFeature); 542 final int origMode = getUserTypePackageWhitelistMode(); 543 setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE); 544 545 try { 546 while (mRunner.keepRunning()) { 547 mRunner.pauseTiming(); 548 final int userId = createManagedProfile(); 549 mRunner.resumeTiming(); 550 551 startUserInBackgroundAndWaitForUnlock(userId); 552 553 mRunner.pauseTiming(); 554 removeUser(userId); 555 mRunner.resumeTiming(); 556 } 557 } finally { 558 setUserTypePackageWhitelistMode(origMode); 559 } 560 } 561 562 /** Creates a new user, returning its userId. */ createUserNoFlags()563 private int createUserNoFlags() { 564 return createUserWithFlags(/* flags= */ 0); 565 } 566 567 /** Creates a new user with the given flags, returning its userId. */ createUserWithFlags(int flags)568 private int createUserWithFlags(int flags) { 569 int userId = mUm.createUser(TEST_USER_NAME, flags).id; 570 mUsersToRemove.add(userId); 571 return userId; 572 } 573 574 /** Creates a managed (work) profile under the current user, returning its userId. */ createManagedProfile()575 private int createManagedProfile() { 576 final UserInfo userInfo = mUm.createProfileForUser(TEST_USER_NAME, 577 UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, mAm.getCurrentUser()); 578 attestFalse("Creating managed profile failed. Most likely there is " 579 + "already a pre-existing profile on the device.", userInfo == null); 580 mUsersToRemove.add(userInfo.id); 581 return userInfo.id; 582 } 583 584 /** 585 * Start user in background and wait for it to unlock by waiting for 586 * UserState.mUnlockProgress.finish(). 587 * <p> To start in foreground instead, see {@link #switchUser(int)}. 588 * <p> This should always be used for profiles since profiles cannot be started in foreground. 589 */ startUserInBackgroundAndWaitForUnlock(int userId)590 private void startUserInBackgroundAndWaitForUnlock(int userId) { 591 final ProgressWaiter waiter = new ProgressWaiter(); 592 boolean success = false; 593 try { 594 mIam.startUserInBackgroundWithListener(userId, waiter); 595 success = waiter.waitForFinish(TIMEOUT_IN_SECOND); 596 } catch (RemoteException e) { 597 Log.e(TAG, "startUserInBackgroundAndWaitForUnlock failed", e); 598 } 599 attestTrue("Failed to start user " + userId + " in background.", success); 600 } 601 602 /** Starts the given user in the foreground. */ switchUser(int userId)603 private void switchUser(int userId) throws RemoteException { 604 boolean success = switchUserNoCheck(userId); 605 attestTrue("Failed to properly switch to user " + userId, success); 606 } 607 608 /** 609 * Starts the given user in the foreground. 610 * Returns true if successful. Does not fail the test if unsuccessful. 611 * If lack of success should fail the test, use {@link #switchUser(int)} instead. 612 */ switchUserNoCheck(int userId)613 private boolean switchUserNoCheck(int userId) throws RemoteException { 614 final CountDownLatch latch = new CountDownLatch(1); 615 registerUserSwitchObserver(latch, null, userId); 616 mAm.switchUser(userId); 617 try { 618 return latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS); 619 } catch (InterruptedException e) { 620 Log.e(TAG, "Thread interrupted unexpectedly.", e); 621 return false; 622 } 623 } 624 stopUser(int userId, boolean force)625 private void stopUser(int userId, boolean force) throws RemoteException { 626 final CountDownLatch latch = new CountDownLatch(1); 627 mIam.stopUser(userId, force /* force */, new IStopUserCallback.Stub() { 628 @Override 629 public void userStopped(int userId) throws RemoteException { 630 latch.countDown(); 631 } 632 633 @Override 634 public void userStopAborted(int userId) throws RemoteException { 635 } 636 }); 637 waitForLatch("Failed to properly stop user " + userId, latch); 638 } 639 640 /** 641 * Creates a user and waits for its ACTION_USER_UNLOCKED. 642 * Then switches to back to the original user and waits for its switchUser() to finish. 643 * 644 * @param stopNewUser whether to stop the new user after switching to otherUser. 645 * @return userId of the newly created user. 646 */ initializeNewUserAndSwitchBack(boolean stopNewUser)647 private int initializeNewUserAndSwitchBack(boolean stopNewUser) throws RemoteException { 648 final int origUser = mAm.getCurrentUser(); 649 // First, create and switch to testUser, waiting for its ACTION_USER_UNLOCKED 650 final int testUser = createUserNoFlags(); 651 final CountDownLatch latch1 = new CountDownLatch(1); 652 registerBroadcastReceiver(Intent.ACTION_USER_UNLOCKED, latch1, testUser); 653 mAm.switchUser(testUser); 654 waitForLatch("Failed to achieve initial ACTION_USER_UNLOCKED for user " + testUser, latch1); 655 656 // Second, switch back to origUser, waiting merely for switchUser() to finish 657 switchUser(origUser); 658 attestTrue("Didn't switch back to user, " + origUser, origUser == mAm.getCurrentUser()); 659 660 if (stopNewUser) { 661 stopUser(testUser, true); 662 attestFalse("Failed to stop user " + testUser, mAm.isUserRunning(testUser)); 663 } 664 665 return testUser; 666 } 667 668 /** 669 * Installs the given package in the given user. 670 */ installPreexistingApp(int userId, String packageName)671 private void installPreexistingApp(int userId, String packageName) throws RemoteException { 672 final CountDownLatch latch = new CountDownLatch(1); 673 674 final IntentSender sender = new IntentSender((IIntentSender) new IIntentSender.Stub() { 675 @Override 676 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, 677 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 678 latch.countDown(); 679 } 680 }); 681 682 final IPackageInstaller installer = AppGlobals.getPackageManager().getPackageInstaller(); 683 installer.installExistingPackage(packageName, 684 PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS, 685 PackageManager.INSTALL_REASON_UNKNOWN, sender, userId, null); 686 687 waitForLatch("Failed to install app " + packageName + " on user " + userId, latch); 688 } 689 690 /** 691 * Launches the given package in the given user. 692 * Make sure the keyguard has been dismissed prior to calling. 693 */ startApp(int userId, String packageName)694 private void startApp(int userId, String packageName) throws RemoteException { 695 final Context context = InstrumentationRegistry.getContext(); 696 final WaitResult result = ActivityTaskManager.getService().startActivityAndWait(null, 697 context.getPackageName(), context.getAttributionTag(), 698 context.getPackageManager().getLaunchIntentForPackage(packageName), null, null, 699 null, 0, 0, null, null, userId); 700 attestTrue("User " + userId + " failed to start " + packageName, 701 result.result == ActivityManager.START_SUCCESS); 702 } 703 registerUserSwitchObserver(final CountDownLatch switchLatch, final CountDownLatch bootCompleteLatch, final int userId)704 private void registerUserSwitchObserver(final CountDownLatch switchLatch, 705 final CountDownLatch bootCompleteLatch, final int userId) throws RemoteException { 706 ActivityManager.getService().registerUserSwitchObserver( 707 new UserSwitchObserver() { 708 @Override 709 public void onUserSwitchComplete(int newUserId) throws RemoteException { 710 if (switchLatch != null && userId == newUserId) { 711 switchLatch.countDown(); 712 } 713 } 714 715 @Override 716 public void onLockedBootComplete(int newUserId) { 717 if (bootCompleteLatch != null && userId == newUserId) { 718 bootCompleteLatch.countDown(); 719 } 720 } 721 }, TAG); 722 } 723 registerBroadcastReceiver(final String action, final CountDownLatch latch, final int userId)724 private void registerBroadcastReceiver(final String action, final CountDownLatch latch, 725 final int userId) { 726 InstrumentationRegistry.getContext().registerReceiverAsUser(new BroadcastReceiver() { 727 @Override 728 public void onReceive(Context context, Intent intent) { 729 if (action.equals(intent.getAction()) && intent.getIntExtra( 730 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL) == userId) { 731 latch.countDown(); 732 } 733 } 734 }, UserHandle.of(userId), new IntentFilter(action), null, null); 735 } 736 737 private class ProgressWaiter extends IProgressListener.Stub { 738 private final CountDownLatch mFinishedLatch = new CountDownLatch(1); 739 740 @Override onStarted(int id, Bundle extras)741 public void onStarted(int id, Bundle extras) {} 742 743 @Override onProgress(int id, int progress, Bundle extras)744 public void onProgress(int id, int progress, Bundle extras) {} 745 746 @Override onFinished(int id, Bundle extras)747 public void onFinished(int id, Bundle extras) { 748 mFinishedLatch.countDown(); 749 } 750 waitForFinish(long timeoutSecs)751 public boolean waitForFinish(long timeoutSecs) { 752 try { 753 return mFinishedLatch.await(timeoutSecs, TimeUnit.SECONDS); 754 } catch (InterruptedException e) { 755 Log.e(TAG, "Thread interrupted unexpectedly.", e); 756 return false; 757 } 758 } 759 } 760 761 /** Waits TIMEOUT_IN_SECOND for the latch to complete, otherwise declares the given error. */ waitForLatch(String errMsg, CountDownLatch latch)762 private void waitForLatch(String errMsg, CountDownLatch latch) { 763 boolean success = false; 764 try { 765 success = latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS); 766 } catch (InterruptedException e) { 767 Log.e(TAG, "Thread interrupted unexpectedly.", e); 768 } 769 attestTrue(errMsg, success); 770 } 771 772 /** Gets the PACKAGE_WHITELIST_MODE_PROP System Property. */ getUserTypePackageWhitelistMode()773 private int getUserTypePackageWhitelistMode() { 774 return SystemProperties.getInt(PACKAGE_WHITELIST_MODE_PROP, 775 USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT); 776 } 777 778 /** Sets the PACKAGE_WHITELIST_MODE_PROP System Property to the given value. */ setUserTypePackageWhitelistMode(int mode)779 private void setUserTypePackageWhitelistMode(int mode) { 780 String result = ShellHelper.runShellCommand( 781 String.format("setprop %s %d", PACKAGE_WHITELIST_MODE_PROP, mode)); 782 attestFalse("Failed to set sysprop " + PACKAGE_WHITELIST_MODE_PROP + ": " + result, 783 result != null && result.contains("Failed")); 784 } 785 removeUser(int userId)786 private void removeUser(int userId) { 787 try { 788 mUm.removeUser(userId); 789 final long startTime = System.currentTimeMillis(); 790 final long timeoutInMs = TIMEOUT_IN_SECOND * 1000; 791 while (mUm.getUserInfo(userId) != null && 792 System.currentTimeMillis() - startTime < timeoutInMs) { 793 TimeUnit.MILLISECONDS.sleep(CHECK_USER_REMOVED_INTERVAL_MS); 794 } 795 } catch (InterruptedException e) { 796 Thread.currentThread().interrupt(); 797 } catch (Exception e) { 798 // Ignore 799 } 800 if (mUm.getUserInfo(userId) != null) { 801 mUsersToRemove.add(userId); 802 } 803 } 804 removeAnyPreviousTestUsers()805 private void removeAnyPreviousTestUsers() { 806 for (UserInfo user : mUm.getUsers()) { 807 if (TEST_USER_NAME.equals(user.name)) { 808 Log.i(TAG, "Found previous test user " + user.id + ". Removing it."); 809 if (mAm.getCurrentUser() == user.id) { 810 try { 811 switchUserNoCheck(UserHandle.USER_SYSTEM); 812 } catch (RemoteException e) { 813 Log.e(TAG, "Failed to correctly switch to system user", e); 814 } 815 } 816 mUm.removeUser(user.id); 817 } 818 } 819 } 820 attestTrue(@onNull String message, boolean assertion)821 private void attestTrue(@NonNull String message, boolean assertion) { 822 if (!assertion) { 823 Log.e(TAG, "Test failed on iteration #" + mRunner.getIteration() + ": " + message); 824 mRunner.markAsFailed(new AssertionError(message)); 825 } 826 } 827 attestFalse(@onNull String message, boolean assertion)828 private void attestFalse(@NonNull String message, boolean assertion) { 829 attestTrue(message, !assertion); 830 } 831 } 832