• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 placeholder 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 allowlist mode constants.
111     private static final String PACKAGE_ALLOWLIST_MODE_PROP =
112             "persist.debug.user.package_whitelist_mode";
113     private static final int USER_TYPE_PACKAGE_ALLOWLIST_MODE_DISABLE = 0;
114     private static final int USER_TYPE_PACKAGE_ALLOWLIST_MODE_ENFORCE = 0b001;
115     private static final int USER_TYPE_PACKAGE_ALLOWLIST_MODE_IMPLICIT_ALLOWLIST = 0b100;
116     private static final int USER_TYPE_PACKAGE_ALLOWLIST_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                 Intent.ACTION_PROFILE_AVAILABLE,
150                 Intent.ACTION_PROFILE_UNAVAILABLE);
151         mUserSwitchWaiter = new UserSwitchWaiter(TAG, TIMEOUT_IN_SECOND);
152         removeAnyPreviousTestUsers();
153         if (mAm.getCurrentUser() != UserHandle.USER_SYSTEM) {
154             Log.w(TAG, "WARNING: Tests are being run from user " + mAm.getCurrentUser()
155                     + " rather than the system user");
156         }
157         mUserSwitchTimeoutMs = setSystemProperty(
158                 "debug.usercontroller.user_switch_timeout_ms", "100000");
159         mDisableUserSwitchingDialogAnimations = setSystemProperty(
160                 "debug.usercontroller.disable_user_switching_dialog_animations", "true");
161     }
162 
163     @After
tearDown()164     public void tearDown() throws Exception {
165         setSystemProperty("debug.usercontroller.user_switch_timeout_ms", mUserSwitchTimeoutMs);
166         setSystemProperty("debug.usercontroller.disable_user_switching_dialog_animations",
167                 mDisableUserSwitchingDialogAnimations);
168         mBroadcastWaiter.close();
169         mUserSwitchWaiter.close();
170         for (int userId : mUsersToRemove) {
171             try {
172                 mUm.removeUser(userId);
173             } catch (Exception e) {
174                 // Ignore
175             }
176         }
177     }
178 
179     /** Tests creating a new user. */
180     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
createUser()181     public void createUser() throws RemoteException {
182         while (mRunner.keepRunning()) {
183             Log.i(TAG, "Starting timer");
184             final int userId = createUserNoFlags();
185 
186             mRunner.pauseTiming();
187             Log.i(TAG, "Stopping timer");
188             removeUser(userId);
189             mRunner.resumeTimingForNextIteration();
190         }
191     }
192 
193     /** Tests creating a new user, with wait times between iterations. */
194     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
createUser_realistic()195     public void createUser_realistic() throws RemoteException {
196         while (mRunner.keepRunning()) {
197             Log.i(TAG, "Starting timer");
198             final int userId = createUserNoFlags();
199 
200             mRunner.pauseTiming();
201             Log.i(TAG, "Stopping timer");
202             removeUser(userId);
203             waitCoolDownPeriod();
204             mRunner.resumeTimingForNextIteration();
205         }
206     }
207 
208     /** Tests creating and starting a new user. */
209     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
createAndStartUser()210     public void createAndStartUser() throws RemoteException {
211         while (mRunner.keepRunning()) {
212             Log.i(TAG, "Starting timer");
213             final int userId = createUserNoFlags();
214 
215             // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
216             // ACTION_USER_STARTED.
217             runThenWaitForBroadcasts(userId, () -> {
218                 mIam.startUserInBackground(userId);
219             }, Intent.ACTION_USER_STARTED);
220 
221             mRunner.pauseTiming();
222             Log.i(TAG, "Stopping timer");
223             removeUser(userId);
224             mRunner.resumeTimingForNextIteration();
225         }
226     }
227 
228     /** Tests creating and starting a new user. */
229     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
createAndStartUser_realistic()230     public void createAndStartUser_realistic() throws RemoteException {
231         while (mRunner.keepRunning()) {
232             Log.d(TAG, "Starting timer");
233             final int userId = createUserNoFlags();
234 
235             // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
236             // ACTION_USER_STARTED.
237             runThenWaitForBroadcasts(userId, () -> {
238                 mIam.startUserInBackground(userId);
239             }, Intent.ACTION_USER_STARTED);
240 
241             mRunner.pauseTiming();
242             Log.d(TAG, "Stopping timer");
243             removeUser(userId);
244             waitCoolDownPeriod();
245             mRunner.resumeTimingForNextIteration();
246         }
247     }
248 
249     /**
250      * Tests starting an uninitialized user.
251      * Measures the time until ACTION_USER_STARTED is received.
252      */
253     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
startUser()254     public void startUser() throws RemoteException {
255         while (mRunner.keepRunning()) {
256             mRunner.pauseTiming();
257             final int userId = createUserNoFlags();
258 
259             waitForBroadcastIdle();
260             runThenWaitForBroadcasts(userId, () -> {
261                 mRunner.resumeTiming();
262                 Log.i(TAG, "Starting timer");
263 
264                 mIam.startUserInBackground(userId);
265             }, Intent.ACTION_USER_STARTED);
266 
267             mRunner.pauseTiming();
268             Log.i(TAG, "Stopping timer");
269             removeUser(userId);
270             mRunner.resumeTimingForNextIteration();
271         }
272     }
273 
274     /**
275      * Tests starting an uninitialized user, with wait times in between iterations.
276      *
277      * The first iteration will take longer due to the process of setting policy permissions for
278      * a new user.
279      */
280     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
startUser_uninitializedUser()281     public void startUser_uninitializedUser() throws RemoteException {
282         startUser_measuresAfterFirstIterations(/* numberOfIterationsToSkip */0);
283     }
284 
285     /**
286      * Tests the second iteration of start user that has a problem that it takes too long to run, a
287      * bug has been created (b/266574680) and after investigating or fix this problem,
288      * this test can be removed.
289      */
290     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
startUser_startedOnceBefore()291     public void startUser_startedOnceBefore() throws RemoteException {
292         startUser_measuresAfterFirstIterations(/* numberOfIterationsToSkip */1);
293     }
294 
295     /**
296      * Tests a specific iteration of the start user process.
297      * Measures the time until ACTION_USER_STARTED is received.
298      * @param numberOfIterationsToSkip number of iterations that must be skipped in the preStartUser
299      *                                 method.
300      */
startUser_measuresAfterFirstIterations(int numberOfIterationsToSkip)301     private void startUser_measuresAfterFirstIterations(int numberOfIterationsToSkip)
302             throws RemoteException {
303         /**
304          * Run start user and stop for the next iteration, measures time while mRunner.keepRunning()
305          * return true.
306          */
307         while (mRunner.keepRunning()) {
308             mRunner.pauseTiming();
309 
310             final int userId = createUserNoFlags();
311 
312             preStartUser(userId, numberOfIterationsToSkip);
313 
314             waitForBroadcastIdle();
315             waitCoolDownPeriod();
316 
317             runThenWaitForBroadcasts(userId, () -> {
318                 mRunner.resumeTiming();
319                 Log.i(TAG, "Starting timer");
320 
321                 mIam.startUserInBackground(userId);
322             }, Intent.ACTION_USER_STARTED);
323 
324             mRunner.pauseTiming();
325             Log.i(TAG, "Stopping timer");
326 
327             removeUser(userId);
328             mRunner.resumeTimingForNextIteration();
329         }
330     }
331 
332     /**
333      * Tests starting an initialized user, with wait times in between iterations stopping between
334      * iterations,this test will skip the first two iterations and only measure the next ones.
335      *
336      * The first iteration will take longer due to the process of setting policy permissions for
337      * a new user.
338      *
339      * The second iteration takes longer than expected and has a bug (b/266574680) to investigate
340      * it.
341      *
342      * The next iterations take the expected time to start a user.
343      */
344     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
startUser_startedTwiceBefore()345     public void startUser_startedTwiceBefore() throws RemoteException {
346         final int userId = createUserNoFlags();
347 
348         //TODO(b/266681181) Reduce iteration number by 1 after investigation and possible fix.
349         preStartUser(userId, /* numberOfIterations */2);
350 
351         /**
352          * Run start user and stop for the next iteration, measures time while mRunner.keepRunning()
353          * return true.
354          */
355         while (mRunner.keepRunning()) {
356             mRunner.pauseTiming();
357 
358             waitForBroadcastIdle();
359             waitCoolDownPeriod();
360 
361             runThenWaitForBroadcasts(userId, () -> {
362                 mRunner.resumeTiming();
363                 Log.i(TAG, "Starting timer");
364 
365                 mIam.startUserInBackground(userId);
366             }, Intent.ACTION_USER_STARTED);
367 
368             mRunner.pauseTiming();
369             Log.i(TAG, "Stopping timer");
370 
371             stopUser(userId);
372             mRunner.resumeTimingForNextIteration();
373         }
374 
375         removeUser(userId);
376     }
377 
378 
379     /**
380      * Tests starting & unlocking an uninitialized user.
381      * Measures the time until unlock listener is triggered and user is unlocked.
382      */
383     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
startAndUnlockUser()384     public void startAndUnlockUser() throws RemoteException {
385         while (mRunner.keepRunning()) {
386             mRunner.pauseTiming();
387             final int userId = createUserNoFlags();
388             mRunner.resumeTiming();
389             Log.i(TAG, "Starting timer");
390 
391             // Waits for UserState.mUnlockProgress.finish().
392             startUserInBackgroundAndWaitForUnlock(userId);
393 
394             mRunner.pauseTiming();
395             Log.i(TAG, "Stopping timer");
396             removeUser(userId);
397             mRunner.resumeTimingForNextIteration();
398         }
399     }
400 
401     /**
402      * Tests starting & unlocking an initialized user, stopping the user at the end simulating real
403      * usage where the user is not removed after created and initialized.
404      * Measures the time until unlock listener is triggered and user is unlocked.
405      * This test will skip the first two iterations and only measure the next ones.
406      *
407      * The first iteration will take longer due to the process of setting policy permissions for a
408      * new user.
409      *
410      * The second iteration takes longer than expected and has a bug (b/266574680) to investigate
411      * it.
412      *
413      * The next iterations take the expected time to start a user.
414      */
415     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
startAndUnlockUser_startedTwiceBefore()416     public void startAndUnlockUser_startedTwiceBefore() throws RemoteException {
417         final int userId = createUserNoFlags();
418 
419         //TODO(b/266681181) Reduce iteration number by 1 after investigation and possible fix.
420         preStartUser(userId, /* numberOfIterations */2);
421 
422         while (mRunner.keepRunning()) {
423             mRunner.pauseTiming();
424 
425             waitCoolDownPeriod();
426             mRunner.resumeTiming();
427             Log.i(TAG, "Starting timer");
428 
429             // Waits for UserState.mUnlockProgress.finish().
430             startUserInBackgroundAndWaitForUnlock(userId);
431 
432             mRunner.pauseTiming();
433             Log.i(TAG, "Stopping timer");
434             stopUser(userId);
435             mRunner.resumeTimingForNextIteration();
436         }
437 
438         removeUser(userId);
439     }
440 
441     /**
442      * Tests starting & unlocking an uninitialized user.
443      * Measures the time until unlock listener is triggered and user is unlocked.
444      */
445     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
startAndUnlockUser_realistic()446     public void startAndUnlockUser_realistic() throws RemoteException {
447         while (mRunner.keepRunning()) {
448             mRunner.pauseTiming();
449             final int userId = createUserNoFlags();
450             mRunner.resumeTiming();
451             Log.d(TAG, "Starting timer");
452 
453             // Waits for UserState.mUnlockProgress.finish().
454             startUserInBackgroundAndWaitForUnlock(userId);
455 
456             mRunner.pauseTiming();
457             Log.d(TAG, "Stopping timer");
458             removeUser(userId);
459             waitCoolDownPeriod();
460             mRunner.resumeTimingForNextIteration();
461         }
462     }
463 
464     /** Tests switching to an uninitialized user. */
465     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
switchUser()466     public void switchUser() throws Exception {
467         while (mRunner.keepRunning()) {
468             mRunner.pauseTiming();
469             final int startUser = mAm.getCurrentUser();
470             final int userId = createUserNoFlags();
471             mRunner.resumeTiming();
472             Log.i(TAG, "Starting timer");
473 
474             switchUser(userId);
475 
476             mRunner.pauseTiming();
477             Log.i(TAG, "Stopping timer");
478             switchUserNoCheck(startUser);
479             removeUser(userId);
480             mRunner.resumeTimingForNextIteration();
481         }
482     }
483 
484     /** Tests switching to an uninitialized user with wait times between iterations. */
485     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
switchUser_realistic()486     public void switchUser_realistic() throws Exception {
487         while (mRunner.keepRunning()) {
488             mRunner.pauseTiming();
489             final int startUser = ActivityManager.getCurrentUser();
490             final int userId = createUserNoFlags();
491             waitCoolDownPeriod();
492             Log.d(TAG, "Starting timer");
493             mRunner.resumeTiming();
494 
495             switchUser(userId);
496 
497             mRunner.pauseTiming();
498             Log.d(TAG, "Stopping timer");
499             switchUserNoCheck(startUser);
500             removeUser(userId);
501             mRunner.resumeTimingForNextIteration();
502         }
503     }
504 
505     /** Tests switching to a previously-started, but no-longer-running, user. */
506     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
switchUser_stopped()507     public void switchUser_stopped() throws RemoteException {
508         while (mRunner.keepRunning()) {
509             mRunner.pauseTiming();
510             final int startUser = mAm.getCurrentUser();
511             final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ true);
512             mRunner.resumeTiming();
513             Log.i(TAG, "Starting timer");
514 
515             switchUser(testUser);
516 
517             mRunner.pauseTiming();
518             Log.i(TAG, "Stopping timer");
519             switchUserNoCheck(startUser);
520             removeUser(testUser);
521             mRunner.resumeTimingForNextIteration();
522         }
523     }
524 
525     /**
526      * Tests switching to a previously-started, but no-longer-running, user with wait
527      * times between iterations
528      **/
529     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
switchUser_stopped_realistic()530     public void switchUser_stopped_realistic() throws RemoteException {
531         final int currentUserId = ActivityManager.getCurrentUser();
532         final int userId = initializeNewUserAndSwitchBack(/* stopNewUser */ true);
533 
534         /**
535          * Skip the second iteration of start user process that is taking a long time to finish.
536          */
537         preStartUser(userId, /* numberOfIterations */1);
538 
539         while (mRunner.keepRunning()) {
540             mRunner.pauseTiming();
541             waitCoolDownPeriod();
542             Log.d(TAG, "Starting timer");
543             mRunner.resumeTiming();
544 
545             switchUser(userId);
546 
547             mRunner.pauseTiming();
548             Log.d(TAG, "Stopping timer");
549             switchUserNoCheck(currentUserId);
550             stopUserAfterWaitingForBroadcastIdle(userId);
551             attestFalse("Failed to stop user " + userId, mAm.isUserRunning(userId));
552             mRunner.resumeTimingForNextIteration();
553         }
554         removeUser(userId);
555     }
556 
557     /** Tests switching to a previously-started, but no-longer-running, user with wait
558      * times between iterations and using a static wallpaper */
559     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
switchUser_stopped_staticWallpaper()560     public void switchUser_stopped_staticWallpaper() throws RemoteException {
561         assumeTrue(mWm.isWallpaperSupported() && mWm.isSetWallpaperAllowed());
562         final int startUser = ActivityManager.getCurrentUser();
563         final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ true,
564                 /* useStaticWallpaper */true);
565         while (mRunner.keepRunning()) {
566             mRunner.pauseTiming();
567             waitCoolDownPeriod();
568             Log.d(TAG, "Starting timer");
569             mRunner.resumeTiming();
570 
571             switchUser(testUser);
572 
573             mRunner.pauseTiming();
574             Log.d(TAG, "Stopping timer");
575             switchUserNoCheck(startUser);
576             stopUserAfterWaitingForBroadcastIdle(testUser);
577             attestFalse("Failed to stop user " + testUser, mAm.isUserRunning(testUser));
578             mRunner.resumeTimingForNextIteration();
579         }
580         removeUser(testUser);
581     }
582 
583     /** Tests switching to an already-created already-running non-owner background user. */
584     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
switchUser_running()585     public void switchUser_running() throws RemoteException {
586         while (mRunner.keepRunning()) {
587             mRunner.pauseTiming();
588             final int startUser = mAm.getCurrentUser();
589             final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false);
590             mRunner.resumeTiming();
591             Log.i(TAG, "Starting timer");
592 
593             switchUser(testUser);
594 
595             mRunner.pauseTiming();
596             Log.i(TAG, "Stopping timer");
597             switchUserNoCheck(startUser);
598             removeUser(testUser);
599             mRunner.resumeTimingForNextIteration();
600         }
601     }
602 
603     /** Tests switching to an already-created already-running non-owner background user, with wait
604      * times between iterations */
605     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
switchUser_running_initializedUser()606     public void switchUser_running_initializedUser() throws RemoteException {
607         final int startUser = ActivityManager.getCurrentUser();
608         final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false);
609         while (mRunner.keepRunning()) {
610             mRunner.pauseTiming();
611             waitCoolDownPeriod();
612             Log.d(TAG, "Starting timer");
613             mRunner.resumeTiming();
614 
615             switchUser(testUser);
616 
617             mRunner.pauseTiming();
618             Log.d(TAG, "Stopping timer");
619             waitForBroadcastIdle();
620             switchUserNoCheck(startUser);
621             mRunner.resumeTimingForNextIteration();
622         }
623         removeUser(testUser);
624     }
625 
626     /** Tests switching to an already-created already-running non-owner background user, with wait
627      * times between iterations and using a default static wallpaper */
628     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
switchUser_running_staticWallpaper()629     public void switchUser_running_staticWallpaper() throws RemoteException {
630         assumeTrue(mWm.isWallpaperSupported() && mWm.isSetWallpaperAllowed());
631         final int startUser = ActivityManager.getCurrentUser();
632         final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false,
633                 /* useStaticWallpaper */ true);
634         while (mRunner.keepRunning()) {
635             mRunner.pauseTiming();
636             waitCoolDownPeriod();
637             Log.d(TAG, "Starting timer");
638             mRunner.resumeTiming();
639 
640             switchUser(testUser);
641 
642             mRunner.pauseTiming();
643             Log.d(TAG, "Stopping timer");
644             waitForBroadcastIdle();
645             switchUserNoCheck(startUser);
646             mRunner.resumeTimingForNextIteration();
647         }
648         removeUser(testUser);
649     }
650 
651     /** Tests stopping a background user. */
652     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
stopUser()653     public void stopUser() throws RemoteException {
654         while (mRunner.keepRunning()) {
655             mRunner.pauseTiming();
656             final int userId = createUserNoFlags();
657 
658             runThenWaitForBroadcasts(userId, ()-> {
659                 mIam.startUserInBackground(userId);
660             }, Intent.ACTION_USER_STARTED, Intent.ACTION_MEDIA_MOUNTED);
661 
662             mRunner.resumeTiming();
663             Log.i(TAG, "Starting timer");
664 
665             stopUser(userId);
666 
667             mRunner.pauseTiming();
668             Log.i(TAG, "Stopping timer");
669             removeUser(userId);
670             mRunner.resumeTimingForNextIteration();
671         }
672     }
673 
674     /** Tests stopping a background user, with wait times between iterations. The hypothesis is
675      * that the effects of the user creation could impact the measured times, so in this variant we
676      * create one user per run, instead of one per iteration */
677     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
stopUser_realistic()678     public void stopUser_realistic() throws RemoteException {
679         final int userId = createUserNoFlags();
680         waitCoolDownPeriod();
681         while (mRunner.keepRunning()) {
682             mRunner.pauseTiming();
683             runThenWaitForBroadcasts(userId, ()-> {
684                 mIam.startUserInBackground(userId);
685             }, Intent.ACTION_USER_STARTED, Intent.ACTION_MEDIA_MOUNTED);
686             waitCoolDownPeriod();
687             Log.d(TAG, "Starting timer");
688             mRunner.resumeTiming();
689 
690             stopUser(userId);
691 
692             mRunner.pauseTiming();
693             Log.d(TAG, "Stopping timer");
694 
695             mRunner.resumeTimingForNextIteration();
696         }
697         removeUser(userId);
698     }
699 
700     /** Tests reaching LOCKED_BOOT_COMPLETE when switching to uninitialized user. */
701     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
lockedBootCompleted()702     public void lockedBootCompleted() throws RemoteException {
703         while (mRunner.keepRunning()) {
704             mRunner.pauseTiming();
705             final int startUser = mAm.getCurrentUser();
706             final int userId = createUserNoFlags();
707 
708             waitForBroadcastIdle();
709             mUserSwitchWaiter.runThenWaitUntilBootCompleted(userId, () -> {
710                 mRunner.resumeTiming();
711                 Log.i(TAG, "Starting timer");
712                 mAm.switchUser(userId);
713             }, () -> fail("Failed to achieve onLockedBootComplete for user " + userId));
714 
715             mRunner.pauseTiming();
716             Log.i(TAG, "Stopping timer");
717             switchUserNoCheck(startUser);
718             removeUser(userId);
719             mRunner.resumeTimingForNextIteration();
720         }
721     }
722 
723     /** Tests reaching LOCKED_BOOT_COMPLETE when switching to uninitialized user. */
724     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
lockedBootCompleted_realistic()725     public void lockedBootCompleted_realistic() throws RemoteException {
726         while (mRunner.keepRunning()) {
727             mRunner.pauseTiming();
728             final int startUser = ActivityManager.getCurrentUser();
729             final int userId = createUserNoFlags();
730 
731             waitCoolDownPeriod();
732             mUserSwitchWaiter.runThenWaitUntilBootCompleted(userId, () -> {
733                 mRunner.resumeTiming();
734                 Log.d(TAG, "Starting timer");
735                 mAm.switchUser(userId);
736             }, () -> fail("Failed to achieve onLockedBootComplete for user " + userId));
737 
738             mRunner.pauseTiming();
739             Log.d(TAG, "Stopping timer");
740             switchUserNoCheck(startUser);
741             removeUser(userId);
742             mRunner.resumeTimingForNextIteration();
743         }
744     }
745 
746     /** Tests stopping an ephemeral foreground user. */
747     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
ephemeralUserStopped()748     public void ephemeralUserStopped() throws RemoteException {
749         while (mRunner.keepRunning()) {
750             mRunner.pauseTiming();
751             final int startUser = mAm.getCurrentUser();
752             final int userId = createUserWithFlags(UserInfo.FLAG_EPHEMERAL | UserInfo.FLAG_DEMO);
753             runThenWaitForBroadcasts(userId, () -> {
754                 switchUser(userId);
755             }, Intent.ACTION_MEDIA_MOUNTED);
756 
757             waitForBroadcastIdle();
758             mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(startUser, () -> {
759                 runThenWaitForBroadcasts(userId, () -> {
760                     mRunner.resumeTiming();
761                     Log.i(TAG, "Starting timer");
762 
763                     mAm.switchUser(startUser);
764                 }, Intent.ACTION_USER_STOPPED);
765 
766                 mRunner.pauseTiming();
767                 Log.i(TAG, "Stopping timer");
768             }, null);
769 
770             removeUser(userId);
771             mRunner.resumeTimingForNextIteration();
772         }
773     }
774 
775     /** Tests stopping an ephemeral foreground user. */
776     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
ephemeralUserStopped_realistic()777     public void ephemeralUserStopped_realistic() throws RemoteException {
778         while (mRunner.keepRunning()) {
779             mRunner.pauseTiming();
780             final int startUser = ActivityManager.getCurrentUser();
781             final int userId = createUserWithFlags(UserInfo.FLAG_EPHEMERAL | UserInfo.FLAG_DEMO);
782             runThenWaitForBroadcasts(userId, () -> {
783                 switchUser(userId);
784             }, Intent.ACTION_MEDIA_MOUNTED);
785 
786             waitCoolDownPeriod();
787             mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(startUser, () -> {
788                 runThenWaitForBroadcasts(userId, () -> {
789                     mRunner.resumeTiming();
790                     Log.d(TAG, "Starting timer");
791 
792                     mAm.switchUser(startUser);
793                 }, Intent.ACTION_USER_STOPPED);
794 
795                 mRunner.pauseTiming();
796                 Log.d(TAG, "Stopping timer");
797             }, null);
798             mRunner.resumeTimingForNextIteration();
799         }
800     }
801 
802     /** Tests creating a new profile. */
803     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileCreate()804     public void managedProfileCreate() throws RemoteException {
805         assumeTrue(mHasManagedUserFeature);
806 
807         while (mRunner.keepRunning()) {
808             Log.i(TAG, "Starting timer");
809             final int userId = createManagedProfile();
810 
811             mRunner.pauseTiming();
812             Log.i(TAG, "Stopping timer");
813             attestTrue("Failed creating profile " + userId, mUm.isManagedProfile(userId));
814             removeUser(userId);
815             mRunner.resumeTimingForNextIteration();
816         }
817     }
818 
819     /** Tests creating a new profile. */
820     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileCreate_realistic()821     public void managedProfileCreate_realistic() throws RemoteException {
822         assumeTrue(mHasManagedUserFeature);
823 
824         while (mRunner.keepRunning()) {
825             Log.d(TAG, "Starting timer");
826             final int userId = createManagedProfile();
827 
828             mRunner.pauseTiming();
829             Log.d(TAG, "Stopping timer");
830             attestTrue("Failed creating profile " + userId, mUm.isManagedProfile(userId));
831             removeUser(userId);
832             waitCoolDownPeriod();
833             mRunner.resumeTimingForNextIteration();
834         }
835     }
836 
837     /** Tests starting (unlocking) an uninitialized profile. */
838     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlock()839     public void managedProfileUnlock() throws RemoteException {
840         assumeTrue(mHasManagedUserFeature);
841 
842         while (mRunner.keepRunning()) {
843             mRunner.pauseTiming();
844             final int userId = createManagedProfile();
845             mRunner.resumeTiming();
846             Log.i(TAG, "Starting timer");
847 
848             startUserInBackgroundAndWaitForUnlock(userId);
849 
850             mRunner.pauseTiming();
851             Log.i(TAG, "Stopping timer");
852             removeUser(userId);
853             mRunner.resumeTimingForNextIteration();
854         }
855     }
856 
857     /** Tests starting (unlocking) an uninitialized profile. */
858     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlock_realistic()859     public void managedProfileUnlock_realistic() throws RemoteException {
860         assumeTrue(mHasManagedUserFeature);
861 
862         while (mRunner.keepRunning()) {
863             mRunner.pauseTiming();
864             final int userId = createManagedProfile();
865             mRunner.resumeTiming();
866             Log.d(TAG, "Starting timer");
867 
868             startUserInBackgroundAndWaitForUnlock(userId);
869 
870             mRunner.pauseTiming();
871             Log.d(TAG, "Stopping timer");
872             removeUser(userId);
873             waitCoolDownPeriod();
874             mRunner.resumeTimingForNextIteration();
875         }
876     }
877 
878     /** Tests starting (unlocking) a previously-started, but no-longer-running, profile. */
879     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlock_stopped()880     public void managedProfileUnlock_stopped() throws RemoteException {
881         assumeTrue(mHasManagedUserFeature);
882 
883         while (mRunner.keepRunning()) {
884             mRunner.pauseTiming();
885             final int userId = createManagedProfile();
886             // Start the profile initially, then stop it. Similar to setQuietModeEnabled.
887             startUserInBackgroundAndWaitForUnlock(userId);
888             stopUserAfterWaitingForBroadcastIdle(userId);
889             mRunner.resumeTiming();
890             Log.i(TAG, "Starting timer");
891 
892             startUserInBackgroundAndWaitForUnlock(userId);
893 
894             mRunner.pauseTiming();
895             Log.i(TAG, "Stopping timer");
896             removeUser(userId);
897             mRunner.resumeTimingForNextIteration();
898         }
899     }
900 
901     /** Tests starting (unlocking) a previously-started, but no-longer-running, profile. */
902     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlock_stopped_realistic()903     public void managedProfileUnlock_stopped_realistic() throws RemoteException {
904         assumeTrue(mHasManagedUserFeature);
905         final int userId = createManagedProfile();
906         // Start the profile initially, then stop it. Similar to setQuietModeEnabled.
907         startUserInBackgroundAndWaitForUnlock(userId);
908         while (mRunner.keepRunning()) {
909             mRunner.pauseTiming();
910             stopUserAfterWaitingForBroadcastIdle(userId);
911             mRunner.resumeTiming();
912             Log.d(TAG, "Starting timer");
913 
914             startUserInBackgroundAndWaitForUnlock(userId);
915 
916             mRunner.pauseTiming();
917             Log.d(TAG, "Stopping timer");
918             waitCoolDownPeriod();
919             mRunner.resumeTimingForNextIteration();
920         }
921         removeUser(userId);
922     }
923 
924     /**
925      * Tests starting (unlocking) & launching an already-installed app in an uninitialized profile.
926      */
927     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlockAndLaunchApp()928     public void managedProfileUnlockAndLaunchApp() throws RemoteException {
929         assumeTrue(mHasManagedUserFeature);
930 
931         while (mRunner.keepRunning()) {
932             mRunner.pauseTiming();
933             final int userId = createManagedProfile();
934             WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
935             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
936             mRunner.resumeTiming();
937             Log.i(TAG, "Starting timer");
938 
939             startUserInBackgroundAndWaitForUnlock(userId);
940             startApp(userId, DUMMY_PACKAGE_NAME);
941 
942             mRunner.pauseTiming();
943             Log.i(TAG, "Stopping timer");
944             removeUser(userId);
945             mRunner.resumeTimingForNextIteration();
946         }
947     }
948 
949     /**
950      * Tests starting (unlocking) & launching an already-installed app in an uninitialized profile.
951      */
952     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlockAndLaunchApp_realistic()953     public void managedProfileUnlockAndLaunchApp_realistic() throws RemoteException {
954         assumeTrue(mHasManagedUserFeature);
955 
956         while (mRunner.keepRunning()) {
957             mRunner.pauseTiming();
958             final int userId = createManagedProfile();
959             WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
960             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
961             mRunner.resumeTiming();
962             Log.d(TAG, "Starting timer");
963 
964             startUserInBackgroundAndWaitForUnlock(userId);
965             startApp(userId, DUMMY_PACKAGE_NAME);
966 
967             mRunner.pauseTiming();
968             Log.d(TAG, "Stopping timer");
969             removeUser(userId);
970             waitCoolDownPeriod();
971             mRunner.resumeTimingForNextIteration();
972         }
973     }
974 
975     /**
976      * Tests starting (unlocking) and launching a previously-launched app
977      * in a previously-started, but no-longer-running, profile.
978      * A sort of combination of {@link #managedProfileUnlockAndLaunchApp} and
979      * {@link #managedProfileUnlock_stopped}}.
980      */
981     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlockAndLaunchApp_stopped()982     public void managedProfileUnlockAndLaunchApp_stopped() throws RemoteException {
983         assumeTrue(mHasManagedUserFeature);
984 
985         while (mRunner.keepRunning()) {
986             mRunner.pauseTiming();
987             final int userId = createManagedProfile();
988             WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
989             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
990             startUserInBackgroundAndWaitForUnlock(userId);
991             startApp(userId, DUMMY_PACKAGE_NAME);
992             stopUserAfterWaitingForBroadcastIdle(userId);
993             SystemClock.sleep(1_000); // 1 second cool-down before re-starting profile.
994             mRunner.resumeTiming();
995             Log.i(TAG, "Starting timer");
996 
997             startUserInBackgroundAndWaitForUnlock(userId);
998             startApp(userId, DUMMY_PACKAGE_NAME);
999 
1000             mRunner.pauseTiming();
1001             Log.i(TAG, "Stopping timer");
1002             removeUser(userId);
1003             mRunner.resumeTimingForNextIteration();
1004         }
1005     }
1006 
1007     /**
1008      * Tests starting (unlocking) and launching a previously-launched app
1009      * in a previously-started, but no-longer-running, profile.
1010      * A sort of combination of {@link #managedProfileUnlockAndLaunchApp} and
1011      * {@link #managedProfileUnlock_stopped}}.
1012      */
1013     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlockAndLaunchApp_stopped_realistic()1014     public void managedProfileUnlockAndLaunchApp_stopped_realistic() throws RemoteException {
1015         assumeTrue(mHasManagedUserFeature);
1016 
1017         while (mRunner.keepRunning()) {
1018             mRunner.pauseTiming();
1019             final int userId = createManagedProfile();
1020             WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
1021             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
1022             startUserInBackgroundAndWaitForUnlock(userId);
1023             startApp(userId, DUMMY_PACKAGE_NAME);
1024             stopUserAfterWaitingForBroadcastIdle(userId);
1025             SystemClock.sleep(1_000); // 1 second cool-down before re-starting profile.
1026             mRunner.resumeTiming();
1027             Log.d(TAG, "Starting timer");
1028 
1029             startUserInBackgroundAndWaitForUnlock(userId);
1030             startApp(userId, DUMMY_PACKAGE_NAME);
1031 
1032             mRunner.pauseTiming();
1033             Log.d(TAG, "Stopping timer");
1034             removeUser(userId);
1035             waitCoolDownPeriod();
1036             mRunner.resumeTimingForNextIteration();
1037         }
1038     }
1039 
1040     /** Tests installing a pre-existing app in an uninitialized profile. */
1041     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileInstall()1042     public void managedProfileInstall() throws RemoteException {
1043         assumeTrue(mHasManagedUserFeature);
1044 
1045         while (mRunner.keepRunning()) {
1046             mRunner.pauseTiming();
1047             final int userId = createManagedProfile();
1048             mRunner.resumeTiming();
1049             Log.i(TAG, "Starting timer");
1050 
1051             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
1052 
1053             mRunner.pauseTiming();
1054             Log.i(TAG, "Stopping timer");
1055             removeUser(userId);
1056             mRunner.resumeTimingForNextIteration();
1057         }
1058     }
1059 
1060     /** Tests installing a pre-existing app in an uninitialized profile. */
1061     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileInstall_realistic()1062     public void managedProfileInstall_realistic() throws RemoteException {
1063         assumeTrue(mHasManagedUserFeature);
1064 
1065         while (mRunner.keepRunning()) {
1066             mRunner.pauseTiming();
1067             final int userId = createManagedProfile();
1068             mRunner.resumeTiming();
1069             Log.d(TAG, "Starting timer");
1070 
1071             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
1072 
1073             mRunner.pauseTiming();
1074             Log.d(TAG, "Stopping timer");
1075             removeUser(userId);
1076             waitCoolDownPeriod();
1077             mRunner.resumeTimingForNextIteration();
1078         }
1079     }
1080 
1081     /**
1082      * Tests creating a new profile, starting (unlocking) it, installing an app,
1083      * and launching that app in it.
1084      */
1085     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileCreateUnlockInstallAndLaunchApp()1086     public void managedProfileCreateUnlockInstallAndLaunchApp() throws RemoteException {
1087         assumeTrue(mHasManagedUserFeature);
1088 
1089         while (mRunner.keepRunning()) {
1090             mRunner.pauseTiming();
1091             WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
1092             mRunner.resumeTiming();
1093             Log.i(TAG, "Starting timer");
1094 
1095             final int userId = createManagedProfile();
1096             startUserInBackgroundAndWaitForUnlock(userId);
1097             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
1098             startApp(userId, DUMMY_PACKAGE_NAME);
1099 
1100             mRunner.pauseTiming();
1101             Log.i(TAG, "Stopping timer");
1102             removeUser(userId);
1103             mRunner.resumeTimingForNextIteration();
1104         }
1105     }
1106 
1107     /**
1108      * Tests creating a new profile, starting (unlocking) it, installing an app,
1109      * and launching that app in it.
1110      */
1111     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileCreateUnlockInstallAndLaunchApp_realistic()1112     public void managedProfileCreateUnlockInstallAndLaunchApp_realistic() throws RemoteException {
1113         assumeTrue(mHasManagedUserFeature);
1114 
1115         while (mRunner.keepRunning()) {
1116             mRunner.pauseTiming();
1117             WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
1118             mRunner.resumeTiming();
1119             Log.d(TAG, "Starting timer");
1120 
1121             final int userId = createManagedProfile();
1122             startUserInBackgroundAndWaitForUnlock(userId);
1123             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
1124             startApp(userId, DUMMY_PACKAGE_NAME);
1125 
1126             mRunner.pauseTiming();
1127             Log.d(TAG, "Stopping timer");
1128             removeUser(userId);
1129             waitCoolDownPeriod();
1130             mRunner.resumeTimingForNextIteration();
1131         }
1132     }
1133 
1134     /** Tests stopping a profile. */
1135     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileStopped()1136     public void managedProfileStopped() throws RemoteException {
1137         assumeTrue(mHasManagedUserFeature);
1138 
1139         while (mRunner.keepRunning()) {
1140             mRunner.pauseTiming();
1141             final int userId = createManagedProfile();
1142             runThenWaitForBroadcasts(userId, () -> {
1143                 startUserInBackgroundAndWaitForUnlock(userId);
1144             }, Intent.ACTION_MEDIA_MOUNTED);
1145 
1146             mRunner.resumeTiming();
1147             Log.i(TAG, "Starting timer");
1148 
1149             stopUser(userId);
1150 
1151             mRunner.pauseTiming();
1152             Log.i(TAG, "Stopping timer");
1153             removeUser(userId);
1154             mRunner.resumeTimingForNextIteration();
1155         }
1156     }
1157 
1158     /** Tests stopping a profile. */
1159     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileStopped_realistic()1160     public void managedProfileStopped_realistic() throws RemoteException {
1161         assumeTrue(mHasManagedUserFeature);
1162         final int userId = createManagedProfile();
1163         while (mRunner.keepRunning()) {
1164             mRunner.pauseTiming();
1165 
1166             runThenWaitForBroadcasts(userId, () -> {
1167                 startUserInBackgroundAndWaitForUnlock(userId);
1168             }, Intent.ACTION_MEDIA_MOUNTED);
1169             waitCoolDownPeriod();
1170             mRunner.resumeTiming();
1171             Log.d(TAG, "Starting timer");
1172 
1173             stopUser(userId);
1174 
1175             mRunner.pauseTiming();
1176             Log.d(TAG, "Stopping timer");
1177             mRunner.resumeTimingForNextIteration();
1178         }
1179         removeUser(userId);
1180     }
1181 
1182     // TODO: This is just a POC. Do this properly and add more.
1183     /** Tests starting (unlocking) a newly-created profile using the user-type-pkg-allowlist. */
1184     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlock_usingWhitelist()1185     public void managedProfileUnlock_usingWhitelist() throws RemoteException {
1186         assumeTrue(mHasManagedUserFeature);
1187         final int origMode = getUserTypePackageAllowlistMode();
1188         setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_ALLOWLIST_MODE_ENFORCE
1189                 | USER_TYPE_PACKAGE_ALLOWLIST_MODE_IMPLICIT_ALLOWLIST);
1190 
1191         try {
1192             while (mRunner.keepRunning()) {
1193                 mRunner.pauseTiming();
1194                 final int userId = createManagedProfile();
1195                 mRunner.resumeTiming();
1196                 Log.i(TAG, "Starting timer");
1197 
1198                 startUserInBackgroundAndWaitForUnlock(userId);
1199 
1200                 mRunner.pauseTiming();
1201                 Log.i(TAG, "Stopping timer");
1202                 removeUser(userId);
1203                 mRunner.resumeTimingForNextIteration();
1204             }
1205         } finally {
1206             setUserTypePackageAllowlistMode(origMode);
1207         }
1208     }
1209     /** Tests starting (unlocking) a newly-created profile NOT using the user-type-pkg-allowlist. */
1210     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
managedProfileUnlock_notUsingWhitelist()1211     public void managedProfileUnlock_notUsingWhitelist() throws RemoteException {
1212         assumeTrue(mHasManagedUserFeature);
1213         final int origMode = getUserTypePackageAllowlistMode();
1214         setUserTypePackageAllowlistMode(USER_TYPE_PACKAGE_ALLOWLIST_MODE_DISABLE);
1215 
1216         try {
1217             while (mRunner.keepRunning()) {
1218                 mRunner.pauseTiming();
1219                 final int userId = createManagedProfile();
1220                 mRunner.resumeTiming();
1221                 Log.i(TAG, "Starting timer");
1222 
1223                 startUserInBackgroundAndWaitForUnlock(userId);
1224 
1225                 mRunner.pauseTiming();
1226                 Log.i(TAG, "Stopping timer");
1227                 removeUser(userId);
1228                 mRunner.resumeTimingForNextIteration();
1229             }
1230         } finally {
1231             setUserTypePackageAllowlistMode(origMode);
1232         }
1233     }
1234 
1235     /** Tests creating a private profile. */
1236     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
createPrivateProfile()1237     public void createPrivateProfile() throws RemoteException {
1238         while (mRunner.keepRunning()) {
1239             Log.i(TAG, "Starting timer");
1240 
1241             final int userId = createPrivateProfileUser();
1242 
1243             mRunner.pauseTiming();
1244             Log.i(TAG, "Stopping timer");
1245             removeUser(userId);
1246             waitCoolDownPeriod();
1247             mRunner.resumeTimingForNextIteration();
1248         }
1249     }
1250 
1251     /**
1252      * Tests creating and starting a newly created private profile. This test waits for the
1253      * {@link Intent.ACTION_USER_STARTED} to be received.
1254      */
1255     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
createAndStartPrivateProfile_realistic()1256     public void createAndStartPrivateProfile_realistic() throws RemoteException {
1257         while (mRunner.keepRunning()) {
1258             Log.i(TAG, "Starting timer");
1259             final int userId = createPrivateProfileUser();
1260 
1261             // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
1262             // ACTION_USER_STARTED.
1263             runThenWaitForBroadcasts(userId, () -> {
1264                 mIam.startUserInBackground(userId);
1265             }, Intent.ACTION_USER_STARTED);
1266 
1267             mRunner.pauseTiming();
1268             Log.i(TAG, "Stopping timer");
1269             removeUser(userId);
1270             waitCoolDownPeriod();
1271             mRunner.resumeTimingForNextIteration();
1272         }
1273     }
1274 
1275     /** Tests for stopping the private profile. */
1276     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
privateProfileStopped()1277     public void privateProfileStopped() throws RemoteException {
1278         while (mRunner.keepRunning()) {
1279             mRunner.pauseTiming();
1280             final int userId = createPrivateProfileUser();
1281             runThenWaitForBroadcasts(userId, () -> {
1282                 startUserInBackgroundAndWaitForUnlock(userId);
1283             }, Intent.ACTION_MEDIA_MOUNTED);
1284 
1285             mRunner.resumeTiming();
1286             Log.i(TAG, "Starting timer");
1287 
1288             stopUser(userId);
1289 
1290             mRunner.pauseTiming();
1291             Log.i(TAG, "Stopping timer");
1292             removeUser(userId);
1293             mRunner.resumeTimingForNextIteration();
1294         }
1295     }
1296 
1297     /**
1298      * Tests unlocking a newly-created private profile using the
1299      * {@link UserManager#requestQuietModeEnabled} api.
1300      */
1301     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
privateProfileUnlock()1302     public void privateProfileUnlock() throws RemoteException {
1303 
1304         while (mRunner.keepRunning()) {
1305             mRunner.pauseTiming();
1306             final int userId = createPrivateProfileUser();
1307             startUserInBackgroundAndWaitForUnlock(userId);
1308             mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
1309             waitCoolDownPeriod();
1310             mRunner.resumeTiming();
1311             Log.i(TAG, "Starting timer");
1312 
1313             mUm.requestQuietModeEnabled(false, UserHandle.of(userId));
1314 
1315             mRunner.pauseTiming();
1316             Log.i(TAG, "Stopping timer");
1317             removeUser(userId);
1318             mRunner.resumeTimingForNextIteration();
1319         }
1320     }
1321 
1322     /**
1323      * Tests unlocking a newly-created private profile using the
1324      * {@link UserManager#requestQuietModeEnabled} api and waiting for the
1325      * {@link Intent.ACTION_PROFILE_AVAILABLE} to be received.
1326      */
1327     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
privateProfileUnlock_realistic()1328     public void privateProfileUnlock_realistic() throws RemoteException {
1329 
1330         while (mRunner.keepRunning()) {
1331             mRunner.pauseTiming();
1332             final int userId = createPrivateProfileUser();
1333             startUserInBackgroundAndWaitForUnlock(userId);
1334             mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
1335             waitCoolDownPeriod();
1336             mRunner.resumeTiming();
1337             Log.i(TAG, "Starting timer");
1338 
1339             runThenWaitForBroadcasts(userId, () -> {
1340                 mUm.requestQuietModeEnabled(false, UserHandle.of(userId));
1341             }, Intent.ACTION_PROFILE_AVAILABLE);
1342 
1343             mRunner.pauseTiming();
1344             Log.i(TAG, "Stopping timer");
1345             removeUser(userId);
1346             mRunner.resumeTimingForNextIteration();
1347         }
1348     }
1349 
1350     /**
1351      * Tests locking a newly-created private profile using the
1352      * {@link UserManager#requestQuietModeEnabled} api.
1353      */
1354     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
privateProfileLock()1355     public void privateProfileLock() throws RemoteException {
1356 
1357         while (mRunner.keepRunning()) {
1358             mRunner.pauseTiming();
1359             final int userId = createPrivateProfileUser();
1360             startUserInBackgroundAndWaitForUnlock(userId);
1361             mRunner.resumeTiming();
1362             Log.i(TAG, "Starting timer");
1363 
1364             mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
1365 
1366             mRunner.pauseTiming();
1367             Log.i(TAG, "Stopping timer");
1368             removeUser(userId);
1369             mRunner.resumeTimingForNextIteration();
1370         }
1371     }
1372 
1373     /**
1374      * Tests locking a newly-created private profile using the
1375      * {@link UserManager#requestQuietModeEnabled} api and waiting for the
1376      * {@link Intent.ACTION_PROFILE_UNAVAILABLE} to be received.
1377      */
1378     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
privateProfileLock_realistic()1379     public void privateProfileLock_realistic() throws RemoteException {
1380 
1381         while (mRunner.keepRunning()) {
1382             mRunner.pauseTiming();
1383             final int userId = createPrivateProfileUser();
1384             startUserInBackgroundAndWaitForUnlock(userId);
1385             mRunner.resumeTiming();
1386             Log.i(TAG, "Starting timer");
1387 
1388             runThenWaitForBroadcasts(userId, () -> {
1389                 mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
1390             }, Intent.ACTION_PROFILE_UNAVAILABLE);
1391 
1392 
1393             mRunner.pauseTiming();
1394             Log.i(TAG, "Stopping timer");
1395             removeUser(userId);
1396             mRunner.resumeTimingForNextIteration();
1397         }
1398     }
1399 
1400     /** Tests removing a newly-created private profile */
1401     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
privateProfileRemove()1402     public void privateProfileRemove() throws RemoteException {
1403         while (mRunner.keepRunning()) {
1404             mRunner.pauseTiming();
1405             final int userId = createPrivateProfileUser();
1406             mRunner.resumeTiming();
1407             Log.i(TAG, "Starting timer");
1408             removeUser(userId);
1409             mRunner.pauseTiming();
1410             Log.i(TAG, "Stopping timer");
1411             mRunner.resumeTimingForNextIteration();
1412         }
1413     }
1414 
1415     /** Tests installing a pre-existing app in a private profile. */
1416     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
privateProfileInstall()1417     public void privateProfileInstall() throws RemoteException {
1418         while (mRunner.keepRunning()) {
1419             mRunner.pauseTiming();
1420             final int userId = createPrivateProfileUser();
1421             startUserInBackgroundAndWaitForUnlock(userId);
1422             mRunner.resumeTiming();
1423             Log.i(TAG, "Starting timer");
1424 
1425             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
1426 
1427             mRunner.pauseTiming();
1428             Log.i(TAG, "Stopping timer");
1429             removeUser(userId);
1430             waitCoolDownPeriod();
1431             mRunner.resumeTimingForNextIteration();
1432         }
1433     }
1434 
1435     /**
1436      * Tests creating a new private profile, starting it, installing an app, and launching that app
1437      * in it.
1438      */
1439     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
privateProfileCreateStartInstallAndLaunchApp()1440     public void privateProfileCreateStartInstallAndLaunchApp() throws RemoteException {
1441         while (mRunner.keepRunning()) {
1442             mRunner.pauseTiming();
1443             WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
1444             mRunner.resumeTiming();
1445             Log.i(TAG, "Starting timer");
1446 
1447             final int userId = createPrivateProfileUser();
1448             startUserInBackgroundAndWaitForUnlock(userId);
1449             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
1450             startApp(userId, DUMMY_PACKAGE_NAME);
1451 
1452             mRunner.pauseTiming();
1453             Log.i(TAG, "Stopping timer");
1454             removeUser(userId);
1455             waitCoolDownPeriod();
1456             mRunner.resumeTimingForNextIteration();
1457         }
1458     }
1459 
1460     /**
1461      * Tests starting & launching an already-installed app in a private profile.
1462      */
1463     @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
privateProfileStartAndLaunchApp()1464     public void privateProfileStartAndLaunchApp() throws RemoteException {
1465         while (mRunner.keepRunning()) {
1466             mRunner.pauseTiming();
1467             final int userId = createPrivateProfileUser();
1468             WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
1469             installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
1470             mRunner.resumeTiming();
1471             Log.i(TAG, "Starting timer");
1472 
1473             startUserInBackgroundAndWaitForUnlock(userId);
1474             startApp(userId, DUMMY_PACKAGE_NAME);
1475 
1476             mRunner.pauseTiming();
1477             Log.i(TAG, "Stopping timer");
1478             removeUser(userId);
1479             waitCoolDownPeriod();
1480             mRunner.resumeTimingForNextIteration();
1481         }
1482     }
1483 
1484     /** Creates a new user, returning its userId. */
createUserNoFlags()1485     private int createUserNoFlags() {
1486         return createUserWithFlags(/* flags= */ 0);
1487     }
1488 
1489     /** Creates a new user with the given flags, returning its userId. */
createUserWithFlags(int flags)1490     private int createUserWithFlags(int flags) {
1491         int userId = mUm.createUser(TEST_USER_NAME, flags).id;
1492         mUsersToRemove.add(userId);
1493         return userId;
1494     }
1495 
1496     /** Creates a managed (work) profile under the current user, returning its userId. */
createManagedProfile()1497     private int createManagedProfile() {
1498         final UserInfo userInfo = mUm.createProfileForUser(TEST_USER_NAME,
1499                 UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, mAm.getCurrentUser());
1500         attestFalse("Creating managed profile failed. Most likely there is "
1501                 + "already a pre-existing profile on the device.", userInfo == null);
1502         mUsersToRemove.add(userInfo.id);
1503         return userInfo.id;
1504     }
1505 
1506     /** Creates a private profile under the current user, returning its userId. */
createPrivateProfileUser()1507     private int createPrivateProfileUser() {
1508         final UserInfo userInfo = mUm.createProfileForUser(TEST_USER_NAME,
1509                 UserManager.USER_TYPE_PROFILE_PRIVATE, /* flags */ 0, mAm.getCurrentUser());
1510         attestFalse(
1511                 "Creating a private profile failed. Most likely there is already a pre-existing "
1512                         + "private profile on the device.",
1513                 userInfo == null);
1514         mUsersToRemove.add(userInfo.id);
1515         return userInfo.id;
1516     }
1517 
1518     /**
1519      * Start user in background and wait for it to unlock by waiting for
1520      * UserState.mUnlockProgress.finish().
1521      * <p> To start in foreground instead, see {@link #switchUser(int)}.
1522      * <p> This should always be used for profiles since profiles cannot be started in foreground.
1523      */
startUserInBackgroundAndWaitForUnlock(int userId)1524     private void startUserInBackgroundAndWaitForUnlock(int userId) {
1525         try {
1526             attestTrue("Failed to start user " + userId + " in background.",
1527                     ShellHelper.runShellCommandWithTimeout("am start-user -w " + userId,
1528                             TIMEOUT_IN_SECOND).startsWith("Success:"));
1529         } catch (TimeoutException e) {
1530             fail("Could not start user " + userId + " in " + TIMEOUT_IN_SECOND + " seconds");
1531         }
1532     }
1533 
1534     /** Starts the given user in the foreground. */
switchUser(int userId)1535     private void switchUser(int userId) throws RemoteException {
1536         boolean success = switchUserNoCheck(userId);
1537         attestTrue("Failed to properly switch to user " + userId, success);
1538     }
1539 
1540     /**
1541      * Starts the given user in the foreground.
1542      * Returns true if successful. Does not fail the test if unsuccessful.
1543      * If lack of success should fail the test, use {@link #switchUser(int)} instead.
1544      */
switchUserNoCheck(int userId)1545     private boolean switchUserNoCheck(int userId) throws RemoteException {
1546         final boolean[] success = {true};
1547         mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(userId, () -> {
1548             mAm.switchUser(userId);
1549         }, () -> success[0] = false);
1550         return success[0];
1551     }
1552 
1553     /**
1554      * Waits for broadcast idle before stopping a user, to prevent timeouts on stop user.
1555      * Stopping a user heavily depends on broadcast queue, and that gets crowded after user creation
1556      * or user switches, which leads to a timeout on stopping user and cause the tests to be flaky.
1557      * Do not call this method while timing is on. i.e. between mRunner.resumeTiming() and
1558      * mRunner.pauseTiming(). Otherwise it would cause the test results to be spiky.
1559      */
stopUserAfterWaitingForBroadcastIdle(int userId)1560     private void stopUserAfterWaitingForBroadcastIdle(int userId)
1561             throws RemoteException {
1562         waitForBroadcastIdle();
1563         stopUser(userId);
1564     }
1565 
stopUser(int userId)1566     private void stopUser(int userId) throws RemoteException {
1567         final CountDownLatch latch = new CountDownLatch(1);
1568         mIam.stopUserWithCallback(userId, new IStopUserCallback.Stub() {
1569             @Override
1570             public void userStopped(int userId) throws RemoteException {
1571                 latch.countDown();
1572             }
1573 
1574             @Override
1575             public void userStopAborted(int userId) throws RemoteException {
1576             }
1577         });
1578         waitForLatch("Failed to properly stop user " + userId, latch);
1579     }
1580 
initializeNewUserAndSwitchBack(boolean stopNewUser)1581     private int initializeNewUserAndSwitchBack(boolean stopNewUser) throws RemoteException {
1582         return initializeNewUserAndSwitchBack(stopNewUser, /* useStaticWallpaper */ false);
1583     }
1584 
1585     /**
1586      * Creates a user and waits for its ACTION_USER_UNLOCKED.
1587      * Then switches to back to the original user and waits for its switchUser() to finish.
1588      *
1589      * @param stopNewUser whether to stop the new user after switching to otherUser.
1590      * @param useStaticWallpaper whether to switch the wallpaper of the default user to a static.
1591      * @return userId of the newly created user.
1592      */
initializeNewUserAndSwitchBack(boolean stopNewUser, boolean useStaticWallpaper)1593     private int initializeNewUserAndSwitchBack(boolean stopNewUser, boolean useStaticWallpaper)
1594             throws RemoteException {
1595         final int origUser = mAm.getCurrentUser();
1596         // First, create and switch to testUser, waiting for its ACTION_USER_UNLOCKED
1597         final int testUser = createUserNoFlags();
1598         runThenWaitForBroadcasts(testUser, () -> {
1599             mAm.switchUser(testUser);
1600         }, Intent.ACTION_USER_UNLOCKED, Intent.ACTION_MEDIA_MOUNTED);
1601 
1602         if (useStaticWallpaper) {
1603             assertTrue(mWm.isWallpaperSupported() && mWm.isSetWallpaperAllowed());
1604             try {
1605                 Bitmap blank = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
1606                 mWm.setBitmap(blank, /* visibleCropHint */ null, /* allowBackup */ true,
1607                         /* which */ FLAG_SYSTEM | FLAG_LOCK, testUser);
1608             } catch (IOException exception) {
1609                 fail("Unable to set static wallpaper.");
1610             }
1611         }
1612 
1613         // Second, switch back to origUser, waiting merely for switchUser() to finish
1614         switchUser(origUser);
1615         attestTrue("Didn't switch back to user, " + origUser, origUser == mAm.getCurrentUser());
1616 
1617         if (stopNewUser) {
1618             stopUserAfterWaitingForBroadcastIdle(testUser);
1619             attestFalse("Failed to stop user " + testUser, mAm.isUserRunning(testUser));
1620         }
1621 
1622         return testUser;
1623     }
1624 
1625     /**
1626      * Installs the given package in the given user.
1627      */
installPreexistingApp(int userId, String packageName)1628     private void installPreexistingApp(int userId, String packageName) throws RemoteException {
1629         final CountDownLatch latch = new CountDownLatch(1);
1630 
1631         final IntentSender sender = new IntentSender((IIntentSender) new IIntentSender.Stub() {
1632             @Override
1633             public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
1634                     IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
1635                 latch.countDown();
1636             }
1637         });
1638 
1639         final IPackageInstaller installer = AppGlobals.getPackageManager().getPackageInstaller();
1640         installer.installExistingPackage(packageName,
1641                 PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
1642                 PackageManager.INSTALL_REASON_UNKNOWN, sender, userId, null);
1643 
1644         waitForLatch("Failed to install app " + packageName + " on user " + userId, latch);
1645     }
1646 
1647     /**
1648      * Launches the given package in the given user.
1649      * Make sure the keyguard has been dismissed prior to calling.
1650      */
startApp(int userId, String packageName)1651     private void startApp(int userId, String packageName) {
1652         final String failMessage = "User " + userId + " failed to start " + packageName;
1653         final String component = InstrumentationRegistry.getContext().getPackageManager()
1654                 .getLaunchIntentForPackage(packageName).getComponent().flattenToShortString();
1655         try {
1656             final String result = ShellHelper.runShellCommandWithTimeout(
1657                     "am start -W -n " + component + " --user " + userId, TIMEOUT_IN_SECOND);
1658             assertTrue(failMessage + ", component=" + component + ", result=" + result,
1659                     result.contains("Status: ok")
1660                     && !result.contains("Warning:")
1661                     && !result.contains("Error:"));
1662         } catch (TimeoutException e) {
1663             fail(failMessage + " in " + TIMEOUT_IN_SECOND + " seconds");
1664         }
1665     }
1666 
1667     private class ProgressWaiter extends IProgressListener.Stub {
1668         private final CountDownLatch mFinishedLatch = new CountDownLatch(1);
1669 
1670         @Override
onStarted(int id, Bundle extras)1671         public void onStarted(int id, Bundle extras) {}
1672 
1673         @Override
onProgress(int id, int progress, Bundle extras)1674         public void onProgress(int id, int progress, Bundle extras) {}
1675 
1676         @Override
onFinished(int id, Bundle extras)1677         public void onFinished(int id, Bundle extras) {
1678             mFinishedLatch.countDown();
1679         }
1680 
waitForFinish(long timeoutSecs)1681         public boolean waitForFinish(long timeoutSecs) {
1682             try {
1683                 return mFinishedLatch.await(timeoutSecs, TimeUnit.SECONDS);
1684             } catch (InterruptedException e) {
1685                 Log.e(TAG, "Thread interrupted unexpectedly.", e);
1686                 return false;
1687             }
1688         }
1689     }
1690 
1691     /**
1692      * Waits TIMEOUT_IN_SECOND for the broadcast to be received, otherwise declares the given error.
1693      * It only works for the broadcasts provided in {@link #mBroadcastWaiter}'s instantiation above.
1694      * @param userId userId associated with the broadcast. It is {@link Intent#EXTRA_USER_HANDLE}
1695      *               or in case that is null, then it is {@link BroadcastReceiver#getSendingUserId}.
1696      * @param runnable function to be run after clearing any possible previously received broadcasts
1697      *                 and before waiting for the new broadcasts. This function should typically do
1698      *                 something to trigger broadcasts to be sent. Like starting or stopping a user.
1699      * @param actions actions of the broadcasts, i.e. {@link Intent#ACTION_USER_STARTED}.
1700      *                If multiple actions are provided, they will be waited in given order.
1701      */
runThenWaitForBroadcasts(int userId, FunctionalUtils.ThrowingRunnable runnable, String... actions)1702     private void runThenWaitForBroadcasts(int userId, FunctionalUtils.ThrowingRunnable runnable,
1703             String... actions) {
1704         final String unreceivedAction =
1705                 mBroadcastWaiter.runThenWaitForBroadcasts(userId, runnable, actions);
1706 
1707         attestTrue("Failed to achieve " + unreceivedAction + " for user " + userId,
1708                 unreceivedAction == null);
1709     }
1710 
1711     /** Waits TIMEOUT_IN_SECOND for the latch to complete, otherwise declares the given error. */
waitForLatch(String errMsg, CountDownLatch latch)1712     private void waitForLatch(String errMsg, CountDownLatch latch) {
1713         boolean success = false;
1714         try {
1715             success = latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
1716         } catch (InterruptedException e) {
1717             Log.e(TAG, "Thread interrupted unexpectedly.", e);
1718         }
1719         attestTrue(errMsg, success);
1720     }
1721 
1722     /** Gets the PACKAGE_ALLOWLIST_MODE_PROP System Property. */
getUserTypePackageAllowlistMode()1723     private int getUserTypePackageAllowlistMode() {
1724         return SystemProperties.getInt(PACKAGE_ALLOWLIST_MODE_PROP,
1725                 USER_TYPE_PACKAGE_ALLOWLIST_MODE_DEVICE_DEFAULT);
1726     }
1727 
1728     /** Sets the PACKAGE_ALLOWLIST_MODE_PROP System Property to the given value. */
setUserTypePackageAllowlistMode(int mode)1729     private void setUserTypePackageAllowlistMode(int mode) {
1730         String result = ShellHelper.runShellCommand(
1731                 String.format("setprop %s %d", PACKAGE_ALLOWLIST_MODE_PROP, mode));
1732         attestFalse("Failed to set sysprop " + PACKAGE_ALLOWLIST_MODE_PROP + ": " + result,
1733                 result != null && result.contains("Failed"));
1734     }
1735 
removeUser(int userId)1736     private void removeUser(int userId) throws RemoteException {
1737         stopUserAfterWaitingForBroadcastIdle(userId);
1738         try {
1739             ShellHelper.runShellCommandWithTimeout("pm remove-user -w " + userId,
1740                     TIMEOUT_IN_SECOND);
1741         } catch (TimeoutException e) {
1742             Log.e(TAG, String.format("Could not remove user %d in %d seconds",
1743                     userId, TIMEOUT_IN_SECOND), e);
1744         }
1745         if (mUm.getUserInfo(userId) != null) {
1746             mUsersToRemove.add(userId);
1747         }
1748     }
1749 
removeAnyPreviousTestUsers()1750     private void removeAnyPreviousTestUsers() {
1751         for (UserInfo user : mUm.getUsers()) {
1752             if (TEST_USER_NAME.equals(user.name)) {
1753                 Log.i(TAG, "Found previous test user " + user.id + ". Removing it.");
1754                 if (mAm.getCurrentUser() == user.id) {
1755                     try {
1756                         switchUserNoCheck(UserHandle.USER_SYSTEM);
1757                     } catch (RemoteException e) {
1758                         Log.e(TAG, "Failed to correctly switch to system user", e);
1759                     }
1760                 }
1761                 mUm.removeUser(user.id);
1762             }
1763         }
1764     }
1765 
1766     /**
1767      * Start the user and stop after that, will repeat numberOfIterations times.
1768      * Make sure the user is started before proceeding with the test.
1769      * @param userId identifier of the user that will be started.
1770      * @param numberOfIterations number of iterations that must be skipped.
1771      */
preStartUser(int userId, int numberOfIterations)1772     private void preStartUser(int userId, int numberOfIterations) throws RemoteException {
1773         for (int i = 0; i < numberOfIterations; i++) {
1774             final ProgressWaiter preWaiter = new ProgressWaiter();
1775 
1776             final boolean preStartComplete = mIam.startUserInBackgroundWithListener(userId,
1777                     preWaiter) && preWaiter.waitForFinish(TIMEOUT_IN_SECOND * 1000);
1778             stopUserAfterWaitingForBroadcastIdle(userId);
1779 
1780             assertTrue("Pre start was not performed for user" + userId, preStartComplete);
1781         }
1782     }
1783 
fail(@onNull String message)1784     private void fail(@NonNull String message) {
1785         Log.e(TAG, "Test failed on iteration #" + mRunner.getIteration() + ": " + message);
1786         mRunner.markAsFailed(new AssertionError(message));
1787     }
1788 
attestTrue(@onNull String message, boolean assertion)1789     private void attestTrue(@NonNull String message, boolean assertion) {
1790         if (!assertion) {
1791             fail(message);
1792         }
1793     }
1794 
attestFalse(@onNull String message, boolean assertion)1795     private void attestFalse(@NonNull String message, boolean assertion) {
1796         attestTrue(message, !assertion);
1797     }
1798 
setSystemProperty(String name, String value)1799     private String setSystemProperty(String name, String value) throws Exception {
1800         final String oldValue = ShellHelper.runShellCommand("getprop " + name);
1801         assertEquals("", ShellHelper.runShellCommand("setprop " + name + " " + value));
1802         return TextUtils.firstNotEmpty(oldValue, "invalid");
1803     }
1804 
waitForBroadcastIdle()1805     private void waitForBroadcastIdle() {
1806         try {
1807             ShellHelper.runShellCommandWithTimeout(
1808                     "am wait-for-broadcast-idle --flush-broadcast-loopers", TIMEOUT_IN_SECOND);
1809         } catch (TimeoutException e) {
1810             Log.e(TAG, "Ending waitForBroadcastIdle because it is taking too long", e);
1811         }
1812     }
1813 
sleep(long ms)1814     private void sleep(long ms) {
1815         try {
1816             Thread.sleep(ms);
1817         } catch (InterruptedException e) {
1818             // Ignore
1819         }
1820     }
1821 
waitCoolDownPeriod()1822     private void waitCoolDownPeriod() {
1823         // Heuristic value based on local tests. Stability increased compared to no waiting.
1824         final int tenSeconds = 1000 * 10;
1825         waitForBroadcastIdle();
1826         sleep(tenSeconds);
1827     }
1828 }
1829