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 android.app.WallpaperManager.FLAG_LOCK; 19 import static android.app.WallpaperManager.FLAG_SYSTEM; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertTrue; 23 import static org.junit.Assume.assumeTrue; 24 25 import android.annotation.NonNull; 26 import android.app.ActivityManager; 27 import android.app.AppGlobals; 28 import android.app.IActivityManager; 29 import android.app.IStopUserCallback; 30 import android.app.WallpaperManager; 31 import android.content.BroadcastReceiver; 32 import android.content.Context; 33 import android.content.IIntentReceiver; 34 import android.content.IIntentSender; 35 import android.content.Intent; 36 import android.content.IntentSender; 37 import android.content.pm.IPackageInstaller; 38 import android.content.pm.PackageManager; 39 import android.content.pm.UserInfo; 40 import android.graphics.Bitmap; 41 import android.os.Bundle; 42 import android.os.IBinder; 43 import android.os.IProgressListener; 44 import android.os.RemoteException; 45 import android.os.SystemClock; 46 import android.os.SystemProperties; 47 import android.os.UserHandle; 48 import android.os.UserManager; 49 import android.perftests.utils.ShellHelper; 50 import android.text.TextUtils; 51 import android.util.Log; 52 import android.view.WindowManagerGlobal; 53 54 import androidx.test.InstrumentationRegistry; 55 import androidx.test.filters.LargeTest; 56 import androidx.test.runner.AndroidJUnit4; 57 58 import com.android.internal.util.FunctionalUtils; 59 60 import org.junit.After; 61 import org.junit.Before; 62 import org.junit.Rule; 63 import org.junit.Test; 64 import org.junit.runner.RunWith; 65 66 import java.io.IOException; 67 import java.util.ArrayList; 68 import java.util.concurrent.CountDownLatch; 69 import java.util.concurrent.TimeUnit; 70 import java.util.concurrent.TimeoutException; 71 72 /** 73 * Perf tests for user life cycle events. 74 * 75 * To run the tests: atest UserLifecycleTests 76 * 77 * 78 * Old methods for running the tests: 79 * 80 * make MultiUserPerfTests && 81 * adb install -r \ 82 * ${ANDROID_PRODUCT_OUT}/data/app/MultiUserPerfTests/MultiUserPerfTests.apk && 83 * adb shell am instrument -e class android.multiuser.UserLifecycleTests \ 84 * -w com.android.perftests.multiuser/androidx.test.runner.AndroidJUnitRunner 85 * 86 * or 87 * 88 * bit MultiUserPerfTests:android.multiuser.UserLifecycleTests 89 * 90 * Note: If you use bit for running the tests, benchmark results won't be printed on the host side. 91 * But in either case, results can be checked on the device side 'adb logcat -s UserLifecycleTests' 92 */ 93 @LargeTest 94 @RunWith(AndroidJUnit4.class) 95 public class UserLifecycleTests { 96 private static final String TAG = UserLifecycleTests.class.getSimpleName(); 97 98 /** Max runtime for each test (including all runs within that test). */ 99 // Must be less than the AndroidTest.xml test-timeout to avoid being considered non-responsive. 100 private static final long TIMEOUT_MAX_TEST_TIME_MS = 24 * 60_000; 101 102 private static final int TIMEOUT_IN_SECOND = 30; 103 104 /** Name of users/profiles in the test. Users with this name may be freely removed. */ 105 private static final String TEST_USER_NAME = "UserLifecycleTests_test_user"; 106 107 /** Name of dummy package used when timing how long app launches take. */ 108 private static final String DUMMY_PACKAGE_NAME = "perftests.multiuser.apps.dummyapp"; 109 110 // Copy of UserSystemPackageInstaller whitelist mode constants. 111 private static final String PACKAGE_WHITELIST_MODE_PROP = 112 "persist.debug.user.package_whitelist_mode"; 113 private static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE = 0; 114 private static final int USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE = 0b001; 115 private static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST = 0b100; 116 private static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT = -1; 117 118 private UserManager mUm; 119 private ActivityManager mAm; 120 private IActivityManager mIam; 121 private PackageManager mPm; 122 private WallpaperManager mWm; 123 private ArrayList<Integer> mUsersToRemove; 124 private boolean mHasManagedUserFeature; 125 private BroadcastWaiter mBroadcastWaiter; 126 private UserSwitchWaiter mUserSwitchWaiter; 127 private String mUserSwitchTimeoutMs; 128 private String mDisableUserSwitchingDialogAnimations; 129 130 private final BenchmarkRunner mRunner = new BenchmarkRunner(); 131 @Rule 132 public BenchmarkResultsReporter mReporter = new BenchmarkResultsReporter(mRunner); 133 134 @Before setUp()135 public void setUp() throws Exception { 136 final Context context = InstrumentationRegistry.getContext(); 137 mUm = UserManager.get(context); 138 mAm = context.getSystemService(ActivityManager.class); 139 mIam = ActivityManager.getService(); 140 mUsersToRemove = new ArrayList<>(); 141 mPm = context.getPackageManager(); 142 mWm = WallpaperManager.getInstance(context); 143 mHasManagedUserFeature = mPm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS); 144 mBroadcastWaiter = new BroadcastWaiter(context, TAG, TIMEOUT_IN_SECOND, 145 Intent.ACTION_USER_STARTED, 146 Intent.ACTION_MEDIA_MOUNTED, 147 Intent.ACTION_USER_UNLOCKED, 148 Intent.ACTION_USER_STOPPED); 149 mUserSwitchWaiter = new UserSwitchWaiter(TAG, TIMEOUT_IN_SECOND); 150 removeAnyPreviousTestUsers(); 151 if (mAm.getCurrentUser() != UserHandle.USER_SYSTEM) { 152 Log.w(TAG, "WARNING: Tests are being run from user " + mAm.getCurrentUser() 153 + " rather than the system user"); 154 } 155 mUserSwitchTimeoutMs = setSystemProperty( 156 "debug.usercontroller.user_switch_timeout_ms", "100000"); 157 mDisableUserSwitchingDialogAnimations = setSystemProperty( 158 "debug.usercontroller.disable_user_switching_dialog_animations", "true"); 159 } 160 161 @After tearDown()162 public void tearDown() throws Exception { 163 setSystemProperty("debug.usercontroller.user_switch_timeout_ms", mUserSwitchTimeoutMs); 164 setSystemProperty("debug.usercontroller.disable_user_switching_dialog_animations", 165 mDisableUserSwitchingDialogAnimations); 166 mBroadcastWaiter.close(); 167 mUserSwitchWaiter.close(); 168 for (int userId : mUsersToRemove) { 169 try { 170 mUm.removeUser(userId); 171 } catch (Exception e) { 172 // Ignore 173 } 174 } 175 } 176 177 /** Tests creating a new user. */ 178 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) createUser()179 public void createUser() throws RemoteException { 180 while (mRunner.keepRunning()) { 181 Log.i(TAG, "Starting timer"); 182 final int userId = createUserNoFlags(); 183 184 mRunner.pauseTiming(); 185 Log.i(TAG, "Stopping timer"); 186 removeUser(userId); 187 mRunner.resumeTimingForNextIteration(); 188 } 189 } 190 191 /** Tests creating a new user, with wait times between iterations. */ 192 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) createUser_realistic()193 public void createUser_realistic() throws RemoteException { 194 while (mRunner.keepRunning()) { 195 Log.i(TAG, "Starting timer"); 196 final int userId = createUserNoFlags(); 197 198 mRunner.pauseTiming(); 199 Log.i(TAG, "Stopping timer"); 200 removeUser(userId); 201 waitCoolDownPeriod(); 202 mRunner.resumeTimingForNextIteration(); 203 } 204 } 205 206 /** Tests creating and starting a new user. */ 207 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) createAndStartUser()208 public void createAndStartUser() throws RemoteException { 209 while (mRunner.keepRunning()) { 210 Log.i(TAG, "Starting timer"); 211 final int userId = createUserNoFlags(); 212 213 // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until 214 // ACTION_USER_STARTED. 215 runThenWaitForBroadcasts(userId, () -> { 216 mIam.startUserInBackground(userId); 217 }, Intent.ACTION_USER_STARTED); 218 219 mRunner.pauseTiming(); 220 Log.i(TAG, "Stopping timer"); 221 removeUser(userId); 222 mRunner.resumeTimingForNextIteration(); 223 } 224 } 225 226 /** Tests creating and starting a new user. */ 227 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) createAndStartUser_realistic()228 public void createAndStartUser_realistic() throws RemoteException { 229 while (mRunner.keepRunning()) { 230 Log.d(TAG, "Starting timer"); 231 final int userId = createUserNoFlags(); 232 233 // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until 234 // ACTION_USER_STARTED. 235 runThenWaitForBroadcasts(userId, () -> { 236 mIam.startUserInBackground(userId); 237 }, Intent.ACTION_USER_STARTED); 238 239 mRunner.pauseTiming(); 240 Log.d(TAG, "Stopping timer"); 241 removeUser(userId); 242 waitCoolDownPeriod(); 243 mRunner.resumeTimingForNextIteration(); 244 } 245 } 246 247 /** 248 * Tests starting an uninitialized user. 249 * Measures the time until ACTION_USER_STARTED is received. 250 */ 251 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) startUser()252 public void startUser() throws RemoteException { 253 while (mRunner.keepRunning()) { 254 mRunner.pauseTiming(); 255 final int userId = createUserNoFlags(); 256 257 waitForBroadcastIdle(); 258 runThenWaitForBroadcasts(userId, () -> { 259 mRunner.resumeTiming(); 260 Log.i(TAG, "Starting timer"); 261 262 mIam.startUserInBackground(userId); 263 }, Intent.ACTION_USER_STARTED); 264 265 mRunner.pauseTiming(); 266 Log.i(TAG, "Stopping timer"); 267 removeUser(userId); 268 mRunner.resumeTimingForNextIteration(); 269 } 270 } 271 272 /** 273 * Tests starting an uninitialized user, with wait times in between iterations. 274 * 275 * The first iteration will take longer due to the process of setting policy permissions for 276 * a new user. 277 */ 278 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) startUser_uninitializedUser()279 public void startUser_uninitializedUser() throws RemoteException { 280 startUser_measuresAfterFirstIterations(/* numberOfIterationsToSkip */0); 281 } 282 283 /** 284 * Tests the second iteration of start user that has a problem that it takes too long to run, a 285 * bug has been created (b/266574680) and after investigating or fix this problem, 286 * this test can be removed. 287 */ 288 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) startUser_startedOnceBefore()289 public void startUser_startedOnceBefore() throws RemoteException { 290 startUser_measuresAfterFirstIterations(/* numberOfIterationsToSkip */1); 291 } 292 293 /** 294 * Tests a specific iteration of the start user process. 295 * Measures the time until ACTION_USER_STARTED is received. 296 * @param numberOfIterationsToSkip number of iterations that must be skipped in the preStartUser 297 * method. 298 */ startUser_measuresAfterFirstIterations(int numberOfIterationsToSkip)299 private void startUser_measuresAfterFirstIterations(int numberOfIterationsToSkip) 300 throws RemoteException { 301 /** 302 * Run start user and stop for the next iteration, measures time while mRunner.keepRunning() 303 * return true. 304 */ 305 while (mRunner.keepRunning()) { 306 mRunner.pauseTiming(); 307 308 final int userId = createUserNoFlags(); 309 310 preStartUser(userId, numberOfIterationsToSkip); 311 312 waitForBroadcastIdle(); 313 waitCoolDownPeriod(); 314 315 runThenWaitForBroadcasts(userId, () -> { 316 mRunner.resumeTiming(); 317 Log.i(TAG, "Starting timer"); 318 319 mIam.startUserInBackground(userId); 320 }, Intent.ACTION_USER_STARTED); 321 322 mRunner.pauseTiming(); 323 Log.i(TAG, "Stopping timer"); 324 325 removeUser(userId); 326 mRunner.resumeTimingForNextIteration(); 327 } 328 } 329 330 /** 331 * Tests starting an initialized user, with wait times in between iterations stopping between 332 * iterations,this test will skip the first two iterations and only measure the next ones. 333 * 334 * The first iteration will take longer due to the process of setting policy permissions for 335 * a new user. 336 * 337 * The second iteration takes longer than expected and has a bug (b/266574680) to investigate 338 * it. 339 * 340 * The next iterations take the expected time to start a user. 341 */ 342 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) startUser_startedTwiceBefore()343 public void startUser_startedTwiceBefore() throws RemoteException { 344 final int userId = createUserNoFlags(); 345 346 //TODO(b/266681181) Reduce iteration number by 1 after investigation and possible fix. 347 preStartUser(userId, /* numberOfIterations */2); 348 349 /** 350 * Run start user and stop for the next iteration, measures time while mRunner.keepRunning() 351 * return true. 352 */ 353 while (mRunner.keepRunning()) { 354 mRunner.pauseTiming(); 355 356 waitForBroadcastIdle(); 357 waitCoolDownPeriod(); 358 359 runThenWaitForBroadcasts(userId, () -> { 360 mRunner.resumeTiming(); 361 Log.i(TAG, "Starting timer"); 362 363 mIam.startUserInBackground(userId); 364 }, Intent.ACTION_USER_STARTED); 365 366 mRunner.pauseTiming(); 367 Log.i(TAG, "Stopping timer"); 368 369 stopUser(userId, /* force */true); 370 mRunner.resumeTimingForNextIteration(); 371 } 372 373 removeUser(userId); 374 } 375 376 377 /** 378 * Tests starting & unlocking an uninitialized user. 379 * Measures the time until unlock listener is triggered and user is unlocked. 380 */ 381 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) startAndUnlockUser()382 public void startAndUnlockUser() throws RemoteException { 383 while (mRunner.keepRunning()) { 384 mRunner.pauseTiming(); 385 final int userId = createUserNoFlags(); 386 mRunner.resumeTiming(); 387 Log.i(TAG, "Starting timer"); 388 389 // Waits for UserState.mUnlockProgress.finish(). 390 startUserInBackgroundAndWaitForUnlock(userId); 391 392 mRunner.pauseTiming(); 393 Log.i(TAG, "Stopping timer"); 394 removeUser(userId); 395 mRunner.resumeTimingForNextIteration(); 396 } 397 } 398 399 /** 400 * Tests starting & unlocking an initialized user, stopping the user at the end simulating real 401 * usage where the user is not removed after created and initialized. 402 * Measures the time until unlock listener is triggered and user is unlocked. 403 * This test will skip the first two iterations and only measure the next ones. 404 * 405 * The first iteration will take longer due to the process of setting policy permissions for a 406 * new user. 407 * 408 * The second iteration takes longer than expected and has a bug (b/266574680) to investigate 409 * it. 410 * 411 * The next iterations take the expected time to start a user. 412 */ 413 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) startAndUnlockUser_startedTwiceBefore()414 public void startAndUnlockUser_startedTwiceBefore() throws RemoteException { 415 final int userId = createUserNoFlags(); 416 417 //TODO(b/266681181) Reduce iteration number by 1 after investigation and possible fix. 418 preStartUser(userId, /* numberOfIterations */2); 419 420 while (mRunner.keepRunning()) { 421 mRunner.pauseTiming(); 422 423 waitCoolDownPeriod(); 424 mRunner.resumeTiming(); 425 Log.i(TAG, "Starting timer"); 426 427 // Waits for UserState.mUnlockProgress.finish(). 428 startUserInBackgroundAndWaitForUnlock(userId); 429 430 mRunner.pauseTiming(); 431 Log.i(TAG, "Stopping timer"); 432 stopUser(userId, /* force */true); 433 mRunner.resumeTimingForNextIteration(); 434 } 435 436 removeUser(userId); 437 } 438 439 /** 440 * Tests starting & unlocking an uninitialized user. 441 * Measures the time until unlock listener is triggered and user is unlocked. 442 */ 443 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) startAndUnlockUser_realistic()444 public void startAndUnlockUser_realistic() throws RemoteException { 445 while (mRunner.keepRunning()) { 446 mRunner.pauseTiming(); 447 final int userId = createUserNoFlags(); 448 mRunner.resumeTiming(); 449 Log.d(TAG, "Starting timer"); 450 451 // Waits for UserState.mUnlockProgress.finish(). 452 startUserInBackgroundAndWaitForUnlock(userId); 453 454 mRunner.pauseTiming(); 455 Log.d(TAG, "Stopping timer"); 456 removeUser(userId); 457 waitCoolDownPeriod(); 458 mRunner.resumeTimingForNextIteration(); 459 } 460 } 461 462 /** Tests switching to an uninitialized user. */ 463 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) switchUser()464 public void switchUser() throws Exception { 465 while (mRunner.keepRunning()) { 466 mRunner.pauseTiming(); 467 final int startUser = mAm.getCurrentUser(); 468 final int userId = createUserNoFlags(); 469 mRunner.resumeTiming(); 470 Log.i(TAG, "Starting timer"); 471 472 switchUser(userId); 473 474 mRunner.pauseTiming(); 475 Log.i(TAG, "Stopping timer"); 476 switchUserNoCheck(startUser); 477 removeUser(userId); 478 mRunner.resumeTimingForNextIteration(); 479 } 480 } 481 482 /** Tests switching to an uninitialized user with wait times between iterations. */ 483 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) switchUser_realistic()484 public void switchUser_realistic() throws Exception { 485 while (mRunner.keepRunning()) { 486 mRunner.pauseTiming(); 487 final int startUser = ActivityManager.getCurrentUser(); 488 final int userId = createUserNoFlags(); 489 waitCoolDownPeriod(); 490 Log.d(TAG, "Starting timer"); 491 mRunner.resumeTiming(); 492 493 switchUser(userId); 494 495 mRunner.pauseTiming(); 496 Log.d(TAG, "Stopping timer"); 497 switchUserNoCheck(startUser); 498 removeUser(userId); 499 mRunner.resumeTimingForNextIteration(); 500 } 501 } 502 503 /** Tests switching to a previously-started, but no-longer-running, user. */ 504 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) switchUser_stopped()505 public void switchUser_stopped() throws RemoteException { 506 while (mRunner.keepRunning()) { 507 mRunner.pauseTiming(); 508 final int startUser = mAm.getCurrentUser(); 509 final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ true); 510 mRunner.resumeTiming(); 511 Log.i(TAG, "Starting timer"); 512 513 switchUser(testUser); 514 515 mRunner.pauseTiming(); 516 Log.i(TAG, "Stopping timer"); 517 switchUserNoCheck(startUser); 518 removeUser(testUser); 519 mRunner.resumeTimingForNextIteration(); 520 } 521 } 522 523 /** 524 * Tests switching to a previously-started, but no-longer-running, user with wait 525 * times between iterations 526 **/ 527 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) switchUser_stopped_realistic()528 public void switchUser_stopped_realistic() throws RemoteException { 529 final int currentUserId = ActivityManager.getCurrentUser(); 530 final int userId = initializeNewUserAndSwitchBack(/* stopNewUser */ true); 531 532 /** 533 * Skip the second iteration of start user process that is taking a long time to finish. 534 */ 535 preStartUser(userId, /* numberOfIterations */1); 536 537 while (mRunner.keepRunning()) { 538 mRunner.pauseTiming(); 539 waitCoolDownPeriod(); 540 Log.d(TAG, "Starting timer"); 541 mRunner.resumeTiming(); 542 543 switchUser(userId); 544 545 mRunner.pauseTiming(); 546 Log.d(TAG, "Stopping timer"); 547 switchUserNoCheck(currentUserId); 548 stopUserAfterWaitingForBroadcastIdle(userId, /* force */true); 549 attestFalse("Failed to stop user " + userId, mAm.isUserRunning(userId)); 550 mRunner.resumeTimingForNextIteration(); 551 } 552 removeUser(userId); 553 } 554 555 /** Tests switching to a previously-started, but no-longer-running, user with wait 556 * times between iterations and using a static wallpaper */ 557 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) switchUser_stopped_staticWallpaper()558 public void switchUser_stopped_staticWallpaper() throws RemoteException { 559 assumeTrue(mWm.isWallpaperSupported() && mWm.isSetWallpaperAllowed()); 560 final int startUser = ActivityManager.getCurrentUser(); 561 final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ true, 562 /* useStaticWallpaper */true); 563 while (mRunner.keepRunning()) { 564 mRunner.pauseTiming(); 565 waitCoolDownPeriod(); 566 Log.d(TAG, "Starting timer"); 567 mRunner.resumeTiming(); 568 569 switchUser(testUser); 570 571 mRunner.pauseTiming(); 572 Log.d(TAG, "Stopping timer"); 573 switchUserNoCheck(startUser); 574 stopUserAfterWaitingForBroadcastIdle(testUser, true); 575 attestFalse("Failed to stop user " + testUser, mAm.isUserRunning(testUser)); 576 mRunner.resumeTimingForNextIteration(); 577 } 578 removeUser(testUser); 579 } 580 581 /** Tests switching to an already-created already-running non-owner background user. */ 582 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) switchUser_running()583 public void switchUser_running() throws RemoteException { 584 while (mRunner.keepRunning()) { 585 mRunner.pauseTiming(); 586 final int startUser = mAm.getCurrentUser(); 587 final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false); 588 mRunner.resumeTiming(); 589 Log.i(TAG, "Starting timer"); 590 591 switchUser(testUser); 592 593 mRunner.pauseTiming(); 594 Log.i(TAG, "Stopping timer"); 595 switchUserNoCheck(startUser); 596 removeUser(testUser); 597 mRunner.resumeTimingForNextIteration(); 598 } 599 } 600 601 /** Tests switching to an already-created already-running non-owner background user, with wait 602 * times between iterations */ 603 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) switchUser_running_initializedUser()604 public void switchUser_running_initializedUser() throws RemoteException { 605 final int startUser = ActivityManager.getCurrentUser(); 606 final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false); 607 while (mRunner.keepRunning()) { 608 mRunner.pauseTiming(); 609 waitCoolDownPeriod(); 610 Log.d(TAG, "Starting timer"); 611 mRunner.resumeTiming(); 612 613 switchUser(testUser); 614 615 mRunner.pauseTiming(); 616 Log.d(TAG, "Stopping timer"); 617 waitForBroadcastIdle(); 618 switchUserNoCheck(startUser); 619 mRunner.resumeTimingForNextIteration(); 620 } 621 removeUser(testUser); 622 } 623 624 /** Tests switching to an already-created already-running non-owner background user, with wait 625 * times between iterations and using a default static wallpaper */ 626 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) switchUser_running_staticWallpaper()627 public void switchUser_running_staticWallpaper() throws RemoteException { 628 assumeTrue(mWm.isWallpaperSupported() && mWm.isSetWallpaperAllowed()); 629 final int startUser = ActivityManager.getCurrentUser(); 630 final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false, 631 /* useStaticWallpaper */ true); 632 while (mRunner.keepRunning()) { 633 mRunner.pauseTiming(); 634 waitCoolDownPeriod(); 635 Log.d(TAG, "Starting timer"); 636 mRunner.resumeTiming(); 637 638 switchUser(testUser); 639 640 mRunner.pauseTiming(); 641 Log.d(TAG, "Stopping timer"); 642 waitForBroadcastIdle(); 643 switchUserNoCheck(startUser); 644 mRunner.resumeTimingForNextIteration(); 645 } 646 removeUser(testUser); 647 } 648 649 /** Tests stopping a background user. */ 650 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) stopUser()651 public void stopUser() throws RemoteException { 652 while (mRunner.keepRunning()) { 653 mRunner.pauseTiming(); 654 final int userId = createUserNoFlags(); 655 656 runThenWaitForBroadcasts(userId, ()-> { 657 mIam.startUserInBackground(userId); 658 }, Intent.ACTION_USER_STARTED, Intent.ACTION_MEDIA_MOUNTED); 659 660 mRunner.resumeTiming(); 661 Log.i(TAG, "Starting timer"); 662 663 stopUser(userId, false); 664 665 mRunner.pauseTiming(); 666 Log.i(TAG, "Stopping timer"); 667 removeUser(userId); 668 mRunner.resumeTimingForNextIteration(); 669 } 670 } 671 672 /** Tests stopping a background user, with wait times between iterations. The hypothesis is 673 * that the effects of the user creation could impact the measured times, so in this variant we 674 * create one user per run, instead of one per iteration */ 675 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) stopUser_realistic()676 public void stopUser_realistic() throws RemoteException { 677 final int userId = createUserNoFlags(); 678 waitCoolDownPeriod(); 679 while (mRunner.keepRunning()) { 680 mRunner.pauseTiming(); 681 runThenWaitForBroadcasts(userId, ()-> { 682 mIam.startUserInBackground(userId); 683 }, Intent.ACTION_USER_STARTED, Intent.ACTION_MEDIA_MOUNTED); 684 waitCoolDownPeriod(); 685 Log.d(TAG, "Starting timer"); 686 mRunner.resumeTiming(); 687 688 stopUser(userId, false); 689 690 mRunner.pauseTiming(); 691 Log.d(TAG, "Stopping timer"); 692 693 mRunner.resumeTimingForNextIteration(); 694 } 695 removeUser(userId); 696 } 697 698 /** Tests reaching LOCKED_BOOT_COMPLETE when switching to uninitialized user. */ 699 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) lockedBootCompleted()700 public void lockedBootCompleted() throws RemoteException { 701 while (mRunner.keepRunning()) { 702 mRunner.pauseTiming(); 703 final int startUser = mAm.getCurrentUser(); 704 final int userId = createUserNoFlags(); 705 706 waitForBroadcastIdle(); 707 mUserSwitchWaiter.runThenWaitUntilBootCompleted(userId, () -> { 708 mRunner.resumeTiming(); 709 Log.i(TAG, "Starting timer"); 710 mAm.switchUser(userId); 711 }, () -> fail("Failed to achieve onLockedBootComplete for user " + userId)); 712 713 mRunner.pauseTiming(); 714 Log.i(TAG, "Stopping timer"); 715 switchUserNoCheck(startUser); 716 removeUser(userId); 717 mRunner.resumeTimingForNextIteration(); 718 } 719 } 720 721 /** Tests reaching LOCKED_BOOT_COMPLETE when switching to uninitialized user. */ 722 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) lockedBootCompleted_realistic()723 public void lockedBootCompleted_realistic() throws RemoteException { 724 while (mRunner.keepRunning()) { 725 mRunner.pauseTiming(); 726 final int startUser = ActivityManager.getCurrentUser(); 727 final int userId = createUserNoFlags(); 728 729 waitCoolDownPeriod(); 730 mUserSwitchWaiter.runThenWaitUntilBootCompleted(userId, () -> { 731 mRunner.resumeTiming(); 732 Log.d(TAG, "Starting timer"); 733 mAm.switchUser(userId); 734 }, () -> fail("Failed to achieve onLockedBootComplete for user " + userId)); 735 736 mRunner.pauseTiming(); 737 Log.d(TAG, "Stopping timer"); 738 switchUserNoCheck(startUser); 739 removeUser(userId); 740 mRunner.resumeTimingForNextIteration(); 741 } 742 } 743 744 /** Tests stopping an ephemeral foreground user. */ 745 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) ephemeralUserStopped()746 public void ephemeralUserStopped() throws RemoteException { 747 while (mRunner.keepRunning()) { 748 mRunner.pauseTiming(); 749 final int startUser = mAm.getCurrentUser(); 750 final int userId = createUserWithFlags(UserInfo.FLAG_EPHEMERAL | UserInfo.FLAG_DEMO); 751 runThenWaitForBroadcasts(userId, () -> { 752 switchUser(userId); 753 }, Intent.ACTION_MEDIA_MOUNTED); 754 755 waitForBroadcastIdle(); 756 mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(startUser, () -> { 757 runThenWaitForBroadcasts(userId, () -> { 758 mRunner.resumeTiming(); 759 Log.i(TAG, "Starting timer"); 760 761 mAm.switchUser(startUser); 762 }, Intent.ACTION_USER_STOPPED); 763 764 mRunner.pauseTiming(); 765 Log.i(TAG, "Stopping timer"); 766 }, null); 767 768 removeUser(userId); 769 mRunner.resumeTimingForNextIteration(); 770 } 771 } 772 773 /** Tests stopping an ephemeral foreground user. */ 774 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) ephemeralUserStopped_realistic()775 public void ephemeralUserStopped_realistic() throws RemoteException { 776 while (mRunner.keepRunning()) { 777 mRunner.pauseTiming(); 778 final int startUser = ActivityManager.getCurrentUser(); 779 final int userId = createUserWithFlags(UserInfo.FLAG_EPHEMERAL | UserInfo.FLAG_DEMO); 780 runThenWaitForBroadcasts(userId, () -> { 781 switchUser(userId); 782 }, Intent.ACTION_MEDIA_MOUNTED); 783 784 waitCoolDownPeriod(); 785 mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(startUser, () -> { 786 runThenWaitForBroadcasts(userId, () -> { 787 mRunner.resumeTiming(); 788 Log.d(TAG, "Starting timer"); 789 790 mAm.switchUser(startUser); 791 }, Intent.ACTION_USER_STOPPED); 792 793 mRunner.pauseTiming(); 794 Log.d(TAG, "Stopping timer"); 795 }, null); 796 mRunner.resumeTimingForNextIteration(); 797 } 798 } 799 800 /** Tests creating a new profile. */ 801 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileCreate()802 public void managedProfileCreate() throws RemoteException { 803 assumeTrue(mHasManagedUserFeature); 804 805 while (mRunner.keepRunning()) { 806 Log.i(TAG, "Starting timer"); 807 final int userId = createManagedProfile(); 808 809 mRunner.pauseTiming(); 810 Log.i(TAG, "Stopping timer"); 811 attestTrue("Failed creating profile " + userId, mUm.isManagedProfile(userId)); 812 removeUser(userId); 813 mRunner.resumeTimingForNextIteration(); 814 } 815 } 816 817 /** Tests creating a new profile. */ 818 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileCreate_realistic()819 public void managedProfileCreate_realistic() throws RemoteException { 820 assumeTrue(mHasManagedUserFeature); 821 822 while (mRunner.keepRunning()) { 823 Log.d(TAG, "Starting timer"); 824 final int userId = createManagedProfile(); 825 826 mRunner.pauseTiming(); 827 Log.d(TAG, "Stopping timer"); 828 attestTrue("Failed creating profile " + userId, mUm.isManagedProfile(userId)); 829 removeUser(userId); 830 waitCoolDownPeriod(); 831 mRunner.resumeTimingForNextIteration(); 832 } 833 } 834 835 /** Tests starting (unlocking) an uninitialized profile. */ 836 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlock()837 public void managedProfileUnlock() throws RemoteException { 838 assumeTrue(mHasManagedUserFeature); 839 840 while (mRunner.keepRunning()) { 841 mRunner.pauseTiming(); 842 final int userId = createManagedProfile(); 843 mRunner.resumeTiming(); 844 Log.i(TAG, "Starting timer"); 845 846 startUserInBackgroundAndWaitForUnlock(userId); 847 848 mRunner.pauseTiming(); 849 Log.i(TAG, "Stopping timer"); 850 removeUser(userId); 851 mRunner.resumeTimingForNextIteration(); 852 } 853 } 854 855 /** Tests starting (unlocking) an uninitialized profile. */ 856 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlock_realistic()857 public void managedProfileUnlock_realistic() throws RemoteException { 858 assumeTrue(mHasManagedUserFeature); 859 860 while (mRunner.keepRunning()) { 861 mRunner.pauseTiming(); 862 final int userId = createManagedProfile(); 863 mRunner.resumeTiming(); 864 Log.d(TAG, "Starting timer"); 865 866 startUserInBackgroundAndWaitForUnlock(userId); 867 868 mRunner.pauseTiming(); 869 Log.d(TAG, "Stopping timer"); 870 removeUser(userId); 871 waitCoolDownPeriod(); 872 mRunner.resumeTimingForNextIteration(); 873 } 874 } 875 876 /** Tests starting (unlocking) a previously-started, but no-longer-running, profile. */ 877 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlock_stopped()878 public void managedProfileUnlock_stopped() throws RemoteException { 879 assumeTrue(mHasManagedUserFeature); 880 881 while (mRunner.keepRunning()) { 882 mRunner.pauseTiming(); 883 final int userId = createManagedProfile(); 884 // Start the profile initially, then stop it. Similar to setQuietModeEnabled. 885 startUserInBackgroundAndWaitForUnlock(userId); 886 stopUserAfterWaitingForBroadcastIdle(userId, true); 887 mRunner.resumeTiming(); 888 Log.i(TAG, "Starting timer"); 889 890 startUserInBackgroundAndWaitForUnlock(userId); 891 892 mRunner.pauseTiming(); 893 Log.i(TAG, "Stopping timer"); 894 removeUser(userId); 895 mRunner.resumeTimingForNextIteration(); 896 } 897 } 898 899 /** Tests starting (unlocking) a previously-started, but no-longer-running, profile. */ 900 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlock_stopped_realistic()901 public void managedProfileUnlock_stopped_realistic() throws RemoteException { 902 assumeTrue(mHasManagedUserFeature); 903 final int userId = createManagedProfile(); 904 // Start the profile initially, then stop it. Similar to setQuietModeEnabled. 905 startUserInBackgroundAndWaitForUnlock(userId); 906 while (mRunner.keepRunning()) { 907 mRunner.pauseTiming(); 908 stopUserAfterWaitingForBroadcastIdle(userId, true); 909 mRunner.resumeTiming(); 910 Log.d(TAG, "Starting timer"); 911 912 startUserInBackgroundAndWaitForUnlock(userId); 913 914 mRunner.pauseTiming(); 915 Log.d(TAG, "Stopping timer"); 916 waitCoolDownPeriod(); 917 mRunner.resumeTimingForNextIteration(); 918 } 919 removeUser(userId); 920 } 921 922 /** 923 * Tests starting (unlocking) & launching an already-installed app in an uninitialized profile. 924 */ 925 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlockAndLaunchApp()926 public void managedProfileUnlockAndLaunchApp() throws RemoteException { 927 assumeTrue(mHasManagedUserFeature); 928 929 while (mRunner.keepRunning()) { 930 mRunner.pauseTiming(); 931 final int userId = createManagedProfile(); 932 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null); 933 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 934 mRunner.resumeTiming(); 935 Log.i(TAG, "Starting timer"); 936 937 startUserInBackgroundAndWaitForUnlock(userId); 938 startApp(userId, DUMMY_PACKAGE_NAME); 939 940 mRunner.pauseTiming(); 941 Log.i(TAG, "Stopping timer"); 942 removeUser(userId); 943 mRunner.resumeTimingForNextIteration(); 944 } 945 } 946 947 /** 948 * Tests starting (unlocking) & launching an already-installed app in an uninitialized profile. 949 */ 950 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlockAndLaunchApp_realistic()951 public void managedProfileUnlockAndLaunchApp_realistic() throws RemoteException { 952 assumeTrue(mHasManagedUserFeature); 953 954 while (mRunner.keepRunning()) { 955 mRunner.pauseTiming(); 956 final int userId = createManagedProfile(); 957 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null); 958 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 959 mRunner.resumeTiming(); 960 Log.d(TAG, "Starting timer"); 961 962 startUserInBackgroundAndWaitForUnlock(userId); 963 startApp(userId, DUMMY_PACKAGE_NAME); 964 965 mRunner.pauseTiming(); 966 Log.d(TAG, "Stopping timer"); 967 removeUser(userId); 968 waitCoolDownPeriod(); 969 mRunner.resumeTimingForNextIteration(); 970 } 971 } 972 973 /** 974 * Tests starting (unlocking) and launching a previously-launched app 975 * in a previously-started, but no-longer-running, profile. 976 * A sort of combination of {@link #managedProfileUnlockAndLaunchApp} and 977 * {@link #managedProfileUnlock_stopped}}. 978 */ 979 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlockAndLaunchApp_stopped()980 public void managedProfileUnlockAndLaunchApp_stopped() throws RemoteException { 981 assumeTrue(mHasManagedUserFeature); 982 983 while (mRunner.keepRunning()) { 984 mRunner.pauseTiming(); 985 final int userId = createManagedProfile(); 986 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null); 987 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 988 startUserInBackgroundAndWaitForUnlock(userId); 989 startApp(userId, DUMMY_PACKAGE_NAME); 990 stopUserAfterWaitingForBroadcastIdle(userId, true); 991 SystemClock.sleep(1_000); // 1 second cool-down before re-starting profile. 992 mRunner.resumeTiming(); 993 Log.i(TAG, "Starting timer"); 994 995 startUserInBackgroundAndWaitForUnlock(userId); 996 startApp(userId, DUMMY_PACKAGE_NAME); 997 998 mRunner.pauseTiming(); 999 Log.i(TAG, "Stopping timer"); 1000 removeUser(userId); 1001 mRunner.resumeTimingForNextIteration(); 1002 } 1003 } 1004 1005 /** 1006 * Tests starting (unlocking) and launching a previously-launched app 1007 * in a previously-started, but no-longer-running, profile. 1008 * A sort of combination of {@link #managedProfileUnlockAndLaunchApp} and 1009 * {@link #managedProfileUnlock_stopped}}. 1010 */ 1011 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlockAndLaunchApp_stopped_realistic()1012 public void managedProfileUnlockAndLaunchApp_stopped_realistic() throws RemoteException { 1013 assumeTrue(mHasManagedUserFeature); 1014 1015 while (mRunner.keepRunning()) { 1016 mRunner.pauseTiming(); 1017 final int userId = createManagedProfile(); 1018 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null); 1019 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 1020 startUserInBackgroundAndWaitForUnlock(userId); 1021 startApp(userId, DUMMY_PACKAGE_NAME); 1022 stopUserAfterWaitingForBroadcastIdle(userId, true); 1023 SystemClock.sleep(1_000); // 1 second cool-down before re-starting profile. 1024 mRunner.resumeTiming(); 1025 Log.d(TAG, "Starting timer"); 1026 1027 startUserInBackgroundAndWaitForUnlock(userId); 1028 startApp(userId, DUMMY_PACKAGE_NAME); 1029 1030 mRunner.pauseTiming(); 1031 Log.d(TAG, "Stopping timer"); 1032 removeUser(userId); 1033 waitCoolDownPeriod(); 1034 mRunner.resumeTimingForNextIteration(); 1035 } 1036 } 1037 1038 /** Tests installing a pre-existing app in an uninitialized profile. */ 1039 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileInstall()1040 public void managedProfileInstall() throws RemoteException { 1041 assumeTrue(mHasManagedUserFeature); 1042 1043 while (mRunner.keepRunning()) { 1044 mRunner.pauseTiming(); 1045 final int userId = createManagedProfile(); 1046 mRunner.resumeTiming(); 1047 Log.i(TAG, "Starting timer"); 1048 1049 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 1050 1051 mRunner.pauseTiming(); 1052 Log.i(TAG, "Stopping timer"); 1053 removeUser(userId); 1054 mRunner.resumeTimingForNextIteration(); 1055 } 1056 } 1057 1058 /** Tests installing a pre-existing app in an uninitialized profile. */ 1059 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileInstall_realistic()1060 public void managedProfileInstall_realistic() throws RemoteException { 1061 assumeTrue(mHasManagedUserFeature); 1062 1063 while (mRunner.keepRunning()) { 1064 mRunner.pauseTiming(); 1065 final int userId = createManagedProfile(); 1066 mRunner.resumeTiming(); 1067 Log.d(TAG, "Starting timer"); 1068 1069 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 1070 1071 mRunner.pauseTiming(); 1072 Log.d(TAG, "Stopping timer"); 1073 removeUser(userId); 1074 waitCoolDownPeriod(); 1075 mRunner.resumeTimingForNextIteration(); 1076 } 1077 } 1078 1079 /** 1080 * Tests creating a new profile, starting (unlocking) it, installing an app, 1081 * and launching that app in it. 1082 */ 1083 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileCreateUnlockInstallAndLaunchApp()1084 public void managedProfileCreateUnlockInstallAndLaunchApp() throws RemoteException { 1085 assumeTrue(mHasManagedUserFeature); 1086 1087 while (mRunner.keepRunning()) { 1088 mRunner.pauseTiming(); 1089 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null); 1090 mRunner.resumeTiming(); 1091 Log.i(TAG, "Starting timer"); 1092 1093 final int userId = createManagedProfile(); 1094 startUserInBackgroundAndWaitForUnlock(userId); 1095 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 1096 startApp(userId, DUMMY_PACKAGE_NAME); 1097 1098 mRunner.pauseTiming(); 1099 Log.i(TAG, "Stopping timer"); 1100 removeUser(userId); 1101 mRunner.resumeTimingForNextIteration(); 1102 } 1103 } 1104 1105 /** 1106 * Tests creating a new profile, starting (unlocking) it, installing an app, 1107 * and launching that app in it. 1108 */ 1109 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileCreateUnlockInstallAndLaunchApp_realistic()1110 public void managedProfileCreateUnlockInstallAndLaunchApp_realistic() throws RemoteException { 1111 assumeTrue(mHasManagedUserFeature); 1112 1113 while (mRunner.keepRunning()) { 1114 mRunner.pauseTiming(); 1115 WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null); 1116 mRunner.resumeTiming(); 1117 Log.d(TAG, "Starting timer"); 1118 1119 final int userId = createManagedProfile(); 1120 startUserInBackgroundAndWaitForUnlock(userId); 1121 installPreexistingApp(userId, DUMMY_PACKAGE_NAME); 1122 startApp(userId, DUMMY_PACKAGE_NAME); 1123 1124 mRunner.pauseTiming(); 1125 Log.d(TAG, "Stopping timer"); 1126 removeUser(userId); 1127 waitCoolDownPeriod(); 1128 mRunner.resumeTimingForNextIteration(); 1129 } 1130 } 1131 1132 /** Tests stopping a profile. */ 1133 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileStopped()1134 public void managedProfileStopped() throws RemoteException { 1135 assumeTrue(mHasManagedUserFeature); 1136 1137 while (mRunner.keepRunning()) { 1138 mRunner.pauseTiming(); 1139 final int userId = createManagedProfile(); 1140 runThenWaitForBroadcasts(userId, () -> { 1141 startUserInBackgroundAndWaitForUnlock(userId); 1142 }, Intent.ACTION_MEDIA_MOUNTED); 1143 1144 mRunner.resumeTiming(); 1145 Log.i(TAG, "Starting timer"); 1146 1147 stopUser(userId, true); 1148 1149 mRunner.pauseTiming(); 1150 Log.i(TAG, "Stopping timer"); 1151 removeUser(userId); 1152 mRunner.resumeTimingForNextIteration(); 1153 } 1154 } 1155 1156 /** Tests stopping a profile. */ 1157 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileStopped_realistic()1158 public void managedProfileStopped_realistic() throws RemoteException { 1159 assumeTrue(mHasManagedUserFeature); 1160 final int userId = createManagedProfile(); 1161 while (mRunner.keepRunning()) { 1162 mRunner.pauseTiming(); 1163 1164 runThenWaitForBroadcasts(userId, () -> { 1165 startUserInBackgroundAndWaitForUnlock(userId); 1166 }, Intent.ACTION_MEDIA_MOUNTED); 1167 waitCoolDownPeriod(); 1168 mRunner.resumeTiming(); 1169 Log.d(TAG, "Starting timer"); 1170 1171 stopUser(userId, true); 1172 1173 mRunner.pauseTiming(); 1174 Log.d(TAG, "Stopping timer"); 1175 mRunner.resumeTimingForNextIteration(); 1176 } 1177 removeUser(userId); 1178 } 1179 1180 // TODO: This is just a POC. Do this properly and add more. 1181 /** Tests starting (unlocking) a newly-created profile using the user-type-pkg-whitelist. */ 1182 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlock_usingWhitelist()1183 public void managedProfileUnlock_usingWhitelist() throws RemoteException { 1184 assumeTrue(mHasManagedUserFeature); 1185 final int origMode = getUserTypePackageWhitelistMode(); 1186 setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE 1187 | USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST); 1188 1189 try { 1190 while (mRunner.keepRunning()) { 1191 mRunner.pauseTiming(); 1192 final int userId = createManagedProfile(); 1193 mRunner.resumeTiming(); 1194 Log.i(TAG, "Starting timer"); 1195 1196 startUserInBackgroundAndWaitForUnlock(userId); 1197 1198 mRunner.pauseTiming(); 1199 Log.i(TAG, "Stopping timer"); 1200 removeUser(userId); 1201 mRunner.resumeTimingForNextIteration(); 1202 } 1203 } finally { 1204 setUserTypePackageWhitelistMode(origMode); 1205 } 1206 } 1207 /** Tests starting (unlocking) a newly-created profile NOT using the user-type-pkg-whitelist. */ 1208 @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) managedProfileUnlock_notUsingWhitelist()1209 public void managedProfileUnlock_notUsingWhitelist() throws RemoteException { 1210 assumeTrue(mHasManagedUserFeature); 1211 final int origMode = getUserTypePackageWhitelistMode(); 1212 setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE); 1213 1214 try { 1215 while (mRunner.keepRunning()) { 1216 mRunner.pauseTiming(); 1217 final int userId = createManagedProfile(); 1218 mRunner.resumeTiming(); 1219 Log.i(TAG, "Starting timer"); 1220 1221 startUserInBackgroundAndWaitForUnlock(userId); 1222 1223 mRunner.pauseTiming(); 1224 Log.i(TAG, "Stopping timer"); 1225 removeUser(userId); 1226 mRunner.resumeTimingForNextIteration(); 1227 } 1228 } finally { 1229 setUserTypePackageWhitelistMode(origMode); 1230 } 1231 } 1232 1233 /** Creates a new user, returning its userId. */ createUserNoFlags()1234 private int createUserNoFlags() { 1235 return createUserWithFlags(/* flags= */ 0); 1236 } 1237 1238 /** Creates a new user with the given flags, returning its userId. */ createUserWithFlags(int flags)1239 private int createUserWithFlags(int flags) { 1240 int userId = mUm.createUser(TEST_USER_NAME, flags).id; 1241 mUsersToRemove.add(userId); 1242 return userId; 1243 } 1244 1245 /** Creates a managed (work) profile under the current user, returning its userId. */ createManagedProfile()1246 private int createManagedProfile() { 1247 final UserInfo userInfo = mUm.createProfileForUser(TEST_USER_NAME, 1248 UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, mAm.getCurrentUser()); 1249 attestFalse("Creating managed profile failed. Most likely there is " 1250 + "already a pre-existing profile on the device.", userInfo == null); 1251 mUsersToRemove.add(userInfo.id); 1252 return userInfo.id; 1253 } 1254 1255 /** 1256 * Start user in background and wait for it to unlock by waiting for 1257 * UserState.mUnlockProgress.finish(). 1258 * <p> To start in foreground instead, see {@link #switchUser(int)}. 1259 * <p> This should always be used for profiles since profiles cannot be started in foreground. 1260 */ startUserInBackgroundAndWaitForUnlock(int userId)1261 private void startUserInBackgroundAndWaitForUnlock(int userId) { 1262 try { 1263 attestTrue("Failed to start user " + userId + " in background.", 1264 ShellHelper.runShellCommandWithTimeout("am start-user -w " + userId, 1265 TIMEOUT_IN_SECOND).startsWith("Success:")); 1266 } catch (TimeoutException e) { 1267 fail("Could not start user " + userId + " in " + TIMEOUT_IN_SECOND + " seconds"); 1268 } 1269 } 1270 1271 /** Starts the given user in the foreground. */ switchUser(int userId)1272 private void switchUser(int userId) throws RemoteException { 1273 boolean success = switchUserNoCheck(userId); 1274 attestTrue("Failed to properly switch to user " + userId, success); 1275 } 1276 1277 /** 1278 * Starts the given user in the foreground. 1279 * Returns true if successful. Does not fail the test if unsuccessful. 1280 * If lack of success should fail the test, use {@link #switchUser(int)} instead. 1281 */ switchUserNoCheck(int userId)1282 private boolean switchUserNoCheck(int userId) throws RemoteException { 1283 final boolean[] success = {true}; 1284 mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(userId, () -> { 1285 mAm.switchUser(userId); 1286 }, () -> success[0] = false); 1287 return success[0]; 1288 } 1289 1290 /** 1291 * Waits for broadcast idle before stopping a user, to prevent timeouts on stop user. 1292 * Stopping a user heavily depends on broadcast queue, and that gets crowded after user creation 1293 * or user switches, which leads to a timeout on stopping user and cause the tests to be flaky. 1294 * Do not call this method while timing is on. i.e. between mRunner.resumeTiming() and 1295 * mRunner.pauseTiming(). Otherwise it would cause the test results to be spiky. 1296 */ stopUserAfterWaitingForBroadcastIdle(int userId, boolean force)1297 private void stopUserAfterWaitingForBroadcastIdle(int userId, boolean force) 1298 throws RemoteException { 1299 waitForBroadcastIdle(); 1300 stopUser(userId, force); 1301 } 1302 stopUser(int userId, boolean force)1303 private void stopUser(int userId, boolean force) throws RemoteException { 1304 final CountDownLatch latch = new CountDownLatch(1); 1305 mIam.stopUser(userId, force /* force */, new IStopUserCallback.Stub() { 1306 @Override 1307 public void userStopped(int userId) throws RemoteException { 1308 latch.countDown(); 1309 } 1310 1311 @Override 1312 public void userStopAborted(int userId) throws RemoteException { 1313 } 1314 }); 1315 waitForLatch("Failed to properly stop user " + userId, latch); 1316 } 1317 initializeNewUserAndSwitchBack(boolean stopNewUser)1318 private int initializeNewUserAndSwitchBack(boolean stopNewUser) throws RemoteException { 1319 return initializeNewUserAndSwitchBack(stopNewUser, /* useStaticWallpaper */ false); 1320 } 1321 1322 /** 1323 * Creates a user and waits for its ACTION_USER_UNLOCKED. 1324 * Then switches to back to the original user and waits for its switchUser() to finish. 1325 * 1326 * @param stopNewUser whether to stop the new user after switching to otherUser. 1327 * @param useStaticWallpaper whether to switch the wallpaper of the default user to a static. 1328 * @return userId of the newly created user. 1329 */ initializeNewUserAndSwitchBack(boolean stopNewUser, boolean useStaticWallpaper)1330 private int initializeNewUserAndSwitchBack(boolean stopNewUser, boolean useStaticWallpaper) 1331 throws RemoteException { 1332 final int origUser = mAm.getCurrentUser(); 1333 // First, create and switch to testUser, waiting for its ACTION_USER_UNLOCKED 1334 final int testUser = createUserNoFlags(); 1335 runThenWaitForBroadcasts(testUser, () -> { 1336 mAm.switchUser(testUser); 1337 }, Intent.ACTION_USER_UNLOCKED, Intent.ACTION_MEDIA_MOUNTED); 1338 1339 if (useStaticWallpaper) { 1340 assertTrue(mWm.isWallpaperSupported() && mWm.isSetWallpaperAllowed()); 1341 try { 1342 Bitmap blank = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); 1343 mWm.setBitmap(blank, /* visibleCropHint */ null, /* allowBackup */ true, 1344 /* which */ FLAG_SYSTEM | FLAG_LOCK, testUser); 1345 } catch (IOException exception) { 1346 fail("Unable to set static wallpaper."); 1347 } 1348 } 1349 1350 // Second, switch back to origUser, waiting merely for switchUser() to finish 1351 switchUser(origUser); 1352 attestTrue("Didn't switch back to user, " + origUser, origUser == mAm.getCurrentUser()); 1353 1354 if (stopNewUser) { 1355 stopUserAfterWaitingForBroadcastIdle(testUser, true); 1356 attestFalse("Failed to stop user " + testUser, mAm.isUserRunning(testUser)); 1357 } 1358 1359 return testUser; 1360 } 1361 1362 /** 1363 * Installs the given package in the given user. 1364 */ installPreexistingApp(int userId, String packageName)1365 private void installPreexistingApp(int userId, String packageName) throws RemoteException { 1366 final CountDownLatch latch = new CountDownLatch(1); 1367 1368 final IntentSender sender = new IntentSender((IIntentSender) new IIntentSender.Stub() { 1369 @Override 1370 public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, 1371 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { 1372 latch.countDown(); 1373 } 1374 }); 1375 1376 final IPackageInstaller installer = AppGlobals.getPackageManager().getPackageInstaller(); 1377 installer.installExistingPackage(packageName, 1378 PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS, 1379 PackageManager.INSTALL_REASON_UNKNOWN, sender, userId, null); 1380 1381 waitForLatch("Failed to install app " + packageName + " on user " + userId, latch); 1382 } 1383 1384 /** 1385 * Launches the given package in the given user. 1386 * Make sure the keyguard has been dismissed prior to calling. 1387 */ startApp(int userId, String packageName)1388 private void startApp(int userId, String packageName) { 1389 final String failMessage = "User " + userId + " failed to start " + packageName; 1390 final String component = InstrumentationRegistry.getContext().getPackageManager() 1391 .getLaunchIntentForPackage(packageName).getComponent().flattenToShortString(); 1392 try { 1393 final String result = ShellHelper.runShellCommandWithTimeout( 1394 "am start -W -n " + component + " --user " + userId, TIMEOUT_IN_SECOND); 1395 assertTrue(failMessage + ", component=" + component + ", result=" + result, 1396 result.contains("Status: ok") 1397 && !result.contains("Warning:") 1398 && !result.contains("Error:")); 1399 } catch (TimeoutException e) { 1400 fail(failMessage + " in " + TIMEOUT_IN_SECOND + " seconds"); 1401 } 1402 } 1403 1404 private class ProgressWaiter extends IProgressListener.Stub { 1405 private final CountDownLatch mFinishedLatch = new CountDownLatch(1); 1406 1407 @Override onStarted(int id, Bundle extras)1408 public void onStarted(int id, Bundle extras) {} 1409 1410 @Override onProgress(int id, int progress, Bundle extras)1411 public void onProgress(int id, int progress, Bundle extras) {} 1412 1413 @Override onFinished(int id, Bundle extras)1414 public void onFinished(int id, Bundle extras) { 1415 mFinishedLatch.countDown(); 1416 } 1417 waitForFinish(long timeoutSecs)1418 public boolean waitForFinish(long timeoutSecs) { 1419 try { 1420 return mFinishedLatch.await(timeoutSecs, TimeUnit.SECONDS); 1421 } catch (InterruptedException e) { 1422 Log.e(TAG, "Thread interrupted unexpectedly.", e); 1423 return false; 1424 } 1425 } 1426 } 1427 1428 /** 1429 * Waits TIMEOUT_IN_SECOND for the broadcast to be received, otherwise declares the given error. 1430 * It only works for the broadcasts provided in {@link #mBroadcastWaiter}'s instantiation above. 1431 * @param userId userId associated with the broadcast. It is {@link Intent#EXTRA_USER_HANDLE} 1432 * or in case that is null, then it is {@link BroadcastReceiver#getSendingUserId}. 1433 * @param runnable function to be run after clearing any possible previously received broadcasts 1434 * and before waiting for the new broadcasts. This function should typically do 1435 * something to trigger broadcasts to be sent. Like starting or stopping a user. 1436 * @param actions actions of the broadcasts, i.e. {@link Intent#ACTION_USER_STARTED}. 1437 * If multiple actions are provided, they will be waited in given order. 1438 */ runThenWaitForBroadcasts(int userId, FunctionalUtils.ThrowingRunnable runnable, String... actions)1439 private void runThenWaitForBroadcasts(int userId, FunctionalUtils.ThrowingRunnable runnable, 1440 String... actions) { 1441 final String unreceivedAction = 1442 mBroadcastWaiter.runThenWaitForBroadcasts(userId, runnable, actions); 1443 1444 attestTrue("Failed to achieve " + unreceivedAction + " for user " + userId, 1445 unreceivedAction == null); 1446 } 1447 1448 /** Waits TIMEOUT_IN_SECOND for the latch to complete, otherwise declares the given error. */ waitForLatch(String errMsg, CountDownLatch latch)1449 private void waitForLatch(String errMsg, CountDownLatch latch) { 1450 boolean success = false; 1451 try { 1452 success = latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS); 1453 } catch (InterruptedException e) { 1454 Log.e(TAG, "Thread interrupted unexpectedly.", e); 1455 } 1456 attestTrue(errMsg, success); 1457 } 1458 1459 /** Gets the PACKAGE_WHITELIST_MODE_PROP System Property. */ getUserTypePackageWhitelistMode()1460 private int getUserTypePackageWhitelistMode() { 1461 return SystemProperties.getInt(PACKAGE_WHITELIST_MODE_PROP, 1462 USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT); 1463 } 1464 1465 /** Sets the PACKAGE_WHITELIST_MODE_PROP System Property to the given value. */ setUserTypePackageWhitelistMode(int mode)1466 private void setUserTypePackageWhitelistMode(int mode) { 1467 String result = ShellHelper.runShellCommand( 1468 String.format("setprop %s %d", PACKAGE_WHITELIST_MODE_PROP, mode)); 1469 attestFalse("Failed to set sysprop " + PACKAGE_WHITELIST_MODE_PROP + ": " + result, 1470 result != null && result.contains("Failed")); 1471 } 1472 removeUser(int userId)1473 private void removeUser(int userId) throws RemoteException { 1474 stopUserAfterWaitingForBroadcastIdle(userId, true); 1475 try { 1476 ShellHelper.runShellCommandWithTimeout("pm remove-user -w " + userId, 1477 TIMEOUT_IN_SECOND); 1478 } catch (TimeoutException e) { 1479 Log.e(TAG, String.format("Could not remove user %d in %d seconds", 1480 userId, TIMEOUT_IN_SECOND), e); 1481 } 1482 if (mUm.getUserInfo(userId) != null) { 1483 mUsersToRemove.add(userId); 1484 } 1485 } 1486 removeAnyPreviousTestUsers()1487 private void removeAnyPreviousTestUsers() { 1488 for (UserInfo user : mUm.getUsers()) { 1489 if (TEST_USER_NAME.equals(user.name)) { 1490 Log.i(TAG, "Found previous test user " + user.id + ". Removing it."); 1491 if (mAm.getCurrentUser() == user.id) { 1492 try { 1493 switchUserNoCheck(UserHandle.USER_SYSTEM); 1494 } catch (RemoteException e) { 1495 Log.e(TAG, "Failed to correctly switch to system user", e); 1496 } 1497 } 1498 mUm.removeUser(user.id); 1499 } 1500 } 1501 } 1502 1503 /** 1504 * Start the user and stop after that, will repeat numberOfIterations times. 1505 * Make sure the user is started before proceeding with the test. 1506 * @param userId identifier of the user that will be started. 1507 * @param numberOfIterations number of iterations that must be skipped. 1508 */ preStartUser(int userId, int numberOfIterations)1509 private void preStartUser(int userId, int numberOfIterations) throws RemoteException { 1510 for (int i = 0; i < numberOfIterations; i++) { 1511 final ProgressWaiter preWaiter = new ProgressWaiter(); 1512 1513 final boolean preStartComplete = mIam.startUserInBackgroundWithListener(userId, 1514 preWaiter) && preWaiter.waitForFinish(TIMEOUT_IN_SECOND * 1000); 1515 stopUserAfterWaitingForBroadcastIdle(userId, /* force */true); 1516 1517 assertTrue("Pre start was not performed for user" + userId, preStartComplete); 1518 } 1519 } 1520 fail(@onNull String message)1521 private void fail(@NonNull String message) { 1522 Log.e(TAG, "Test failed on iteration #" + mRunner.getIteration() + ": " + message); 1523 mRunner.markAsFailed(new AssertionError(message)); 1524 } 1525 attestTrue(@onNull String message, boolean assertion)1526 private void attestTrue(@NonNull String message, boolean assertion) { 1527 if (!assertion) { 1528 fail(message); 1529 } 1530 } 1531 attestFalse(@onNull String message, boolean assertion)1532 private void attestFalse(@NonNull String message, boolean assertion) { 1533 attestTrue(message, !assertion); 1534 } 1535 setSystemProperty(String name, String value)1536 private String setSystemProperty(String name, String value) throws Exception { 1537 final String oldValue = ShellHelper.runShellCommand("getprop " + name); 1538 assertEquals("", ShellHelper.runShellCommand("setprop " + name + " " + value)); 1539 return TextUtils.firstNotEmpty(oldValue, "invalid"); 1540 } 1541 waitForBroadcastIdle()1542 private void waitForBroadcastIdle() { 1543 try { 1544 ShellHelper.runShellCommandWithTimeout( 1545 "am wait-for-broadcast-idle --flush-broadcast-loopers", TIMEOUT_IN_SECOND); 1546 } catch (TimeoutException e) { 1547 Log.e(TAG, "Ending waitForBroadcastIdle because it is taking too long", e); 1548 } 1549 } 1550 sleep(long ms)1551 private void sleep(long ms) { 1552 try { 1553 Thread.sleep(ms); 1554 } catch (InterruptedException e) { 1555 // Ignore 1556 } 1557 } 1558 waitCoolDownPeriod()1559 private void waitCoolDownPeriod() { 1560 final int tenSeconds = 1000 * 10; 1561 waitForBroadcastIdle(); 1562 sleep(tenSeconds); 1563 } 1564 } 1565