Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d4d7d15 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "UserLifecycleTests - give proper errors on fail"

parents 4cd7d533 b995a6b2
Loading
Loading
Loading
Loading
+78 −56
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.IProgressListener;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
@@ -153,7 +154,7 @@ public class UserLifecycleTests {
    }

    @Test
    public void createAndStartUser() throws Exception {
    public void createAndStartUser() throws RemoteException {
        while (mRunner.keepRunning()) {
            final int userId = createUserNoFlags();

@@ -162,7 +163,7 @@ public class UserLifecycleTests {
            // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
            // ACTION_USER_STARTED.
            mIam.startUserInBackground(userId);
            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
            waitForLatch("Failed to achieve ACTION_USER_STARTED for user " + userId, latch);

            mRunner.pauseTiming();
            removeUser(userId);
@@ -174,7 +175,7 @@ public class UserLifecycleTests {
     * Measures the time until ACTION_USER_STARTED is received.
     */
    @Test
    public void startUser() throws Exception {
    public void startUser() throws RemoteException {
        while (mRunner.keepRunning()) {
            mRunner.pauseTiming();
            final int userId = createUserNoFlags();
@@ -183,7 +184,7 @@ public class UserLifecycleTests {
            mRunner.resumeTiming();

            mIam.startUserInBackground(userId);
            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
            waitForLatch("Failed to achieve ACTION_USER_STARTED for user " + userId, latch);

            mRunner.pauseTiming();
            removeUser(userId);
@@ -195,7 +196,7 @@ public class UserLifecycleTests {
     * Measures the time until unlock listener is triggered and user is unlocked.
     */
    @Test
    public void startAndUnlockUser() throws Exception {
    public void startAndUnlockUser() {
        while (mRunner.keepRunning()) {
            mRunner.pauseTiming();
            final int userId = createUserNoFlags();
@@ -210,10 +211,8 @@ public class UserLifecycleTests {
        }
    }



    @Test
    public void switchUser() throws Exception {
    public void switchUser() throws RemoteException {
        while (mRunner.keepRunning()) {
            mRunner.pauseTiming();
            final int startUser = mAm.getCurrentUser();
@@ -223,7 +222,7 @@ public class UserLifecycleTests {
            switchUser(userId);

            mRunner.pauseTiming();
            switchUser(startUser);
            switchUserNoCheck(startUser);
            removeUser(userId);
            mRunner.resumeTiming();
        }
@@ -231,7 +230,7 @@ public class UserLifecycleTests {

    /** Tests switching to an already-created, but no-longer-running, user. */
    @Test
    public void switchUser_stopped() throws Exception {
    public void switchUser_stopped() throws RemoteException {
        while (mRunner.keepRunning()) {
            mRunner.pauseTiming();
            final int startUser = mAm.getCurrentUser();
@@ -241,11 +240,11 @@ public class UserLifecycleTests {
            mRunner.resumeTiming();

            mAm.switchUser(testUser);
            boolean success = latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
            waitForLatch("Failed to achieve 2nd ACTION_USER_UNLOCKED for user " + testUser, latch);


            mRunner.pauseTiming();
            attestTrue("Failed to achieve 2nd ACTION_USER_UNLOCKED for user " + testUser, success);
            switchUser(startUser);
            switchUserNoCheck(startUser);
            removeUser(testUser);
            mRunner.resumeTiming();
        }
@@ -253,7 +252,7 @@ public class UserLifecycleTests {

    /** Tests switching to an already-created already-running non-owner user. */
    @Test
    public void switchUser_running() throws Exception {
    public void switchUser_running() throws RemoteException {
        while (mRunner.keepRunning()) {
            mRunner.pauseTiming();
            final int startUser = mAm.getCurrentUser();
@@ -263,22 +262,21 @@ public class UserLifecycleTests {
            switchUser(testUser);

            mRunner.pauseTiming();
            attestTrue("Failed to switch to user " + testUser, mAm.isUserRunning(testUser));
            switchUser(startUser);
            switchUserNoCheck(startUser);
            removeUser(testUser);
            mRunner.resumeTiming();
        }
    }

    @Test
    public void stopUser() throws Exception {
    public void stopUser() throws RemoteException {
        while (mRunner.keepRunning()) {
            mRunner.pauseTiming();
            final int userId = createUserNoFlags();
            final CountDownLatch latch = new CountDownLatch(1);
            registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userId);
            mIam.startUserInBackground(userId);
            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
            waitForLatch("Failed to achieve ACTION_USER_STARTED for user " + userId, latch);
            mRunner.resumeTiming();

            stopUser(userId, false);
@@ -290,7 +288,7 @@ public class UserLifecycleTests {
    }

    @Test
    public void lockedBootCompleted() throws Exception {
    public void lockedBootCompleted() throws RemoteException {
        while (mRunner.keepRunning()) {
            mRunner.pauseTiming();
            final int startUser = mAm.getCurrentUser();
@@ -300,17 +298,17 @@ public class UserLifecycleTests {
            mRunner.resumeTiming();

            mAm.switchUser(userId);
            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
            waitForLatch("Failed to achieve onLockedBootComplete for user " + userId, latch);

            mRunner.pauseTiming();
            switchUser(startUser);
            switchUserNoCheck(startUser);
            removeUser(userId);
            mRunner.resumeTiming();
        }
    }

    @Test
    public void ephemeralUserStopped() throws Exception {
    public void ephemeralUserStopped() throws RemoteException {
        while (mRunner.keepRunning()) {
            mRunner.pauseTiming();
            final int startUser = mAm.getCurrentUser();
@@ -331,10 +329,14 @@ public class UserLifecycleTests {
            mRunner.resumeTiming();

            mAm.switchUser(startUser);
            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
            waitForLatch("Failed to achieve ACTION_USER_STOPPED for user " + userId, latch);

            mRunner.pauseTiming();
            try {
                switchLatch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                Log.e(TAG, "Thread interrupted unexpectedly while waiting for switch.", e);
            }
            removeUser(userId);
            mRunner.resumeTiming();
        }
@@ -342,7 +344,7 @@ public class UserLifecycleTests {

    /** Tests creating a new profile. */
    @Test
    public void managedProfileCreate() throws Exception {
    public void managedProfileCreate() {
        assumeTrue(mHasManagedUserFeature);

        while (mRunner.keepRunning()) {
@@ -357,7 +359,7 @@ public class UserLifecycleTests {

    /** Tests starting (unlocking) a newly-created profile. */
    @Test
    public void managedProfileUnlock() throws Exception {
    public void managedProfileUnlock() {
        assumeTrue(mHasManagedUserFeature);

        while (mRunner.keepRunning()) {
@@ -375,7 +377,7 @@ public class UserLifecycleTests {

    /** Tests starting (unlocking) an already-created, but no-longer-running, profile. */
    @Test
    public void managedProfileUnlock_stopped() throws Exception {
    public void managedProfileUnlock_stopped() throws RemoteException {
        assumeTrue(mHasManagedUserFeature);

        while (mRunner.keepRunning()) {
@@ -398,7 +400,7 @@ public class UserLifecycleTests {
     * Tests starting (unlocking) and launching an already-installed app in a newly-created profile.
     */
    @Test
    public void managedProfileUnlockAndLaunchApp() throws Exception {
    public void managedProfileUnlockAndLaunchApp() throws RemoteException {
        assumeTrue(mHasManagedUserFeature);

        while (mRunner.keepRunning()) {
@@ -424,7 +426,7 @@ public class UserLifecycleTests {
     * {@link #managedProfileUnlock_stopped}}.
     */
    @Test
    public void managedProfileUnlockAndLaunchApp_stopped() throws Exception {
    public void managedProfileUnlockAndLaunchApp_stopped() throws RemoteException {
        assumeTrue(mHasManagedUserFeature);

        while (mRunner.keepRunning()) {
@@ -435,7 +437,7 @@ public class UserLifecycleTests {
            startUserInBackgroundAndWaitForUnlock(userId);
            startApp(userId, DUMMY_PACKAGE_NAME);
            stopUser(userId, true);
            TimeUnit.SECONDS.sleep(1); // Brief cool-down before re-starting profile.
            SystemClock.sleep(1_000); // 1 second cool-down before re-starting profile.
            mRunner.resumeTiming();

            startUserInBackgroundAndWaitForUnlock(userId);
@@ -449,7 +451,7 @@ public class UserLifecycleTests {

    /** Tests installing a pre-existing app in a newly-created profile. */
    @Test
    public void managedProfileInstall() throws Exception {
    public void managedProfileInstall() throws RemoteException {
        assumeTrue(mHasManagedUserFeature);

        while (mRunner.keepRunning()) {
@@ -470,7 +472,7 @@ public class UserLifecycleTests {
     * and launching that app in it.
     */
    @Test
    public void managedProfileCreateUnlockInstallAndLaunchApp() throws Exception {
    public void managedProfileCreateUnlockInstallAndLaunchApp() throws RemoteException {
        assumeTrue(mHasManagedUserFeature);

        while (mRunner.keepRunning()) {
@@ -491,7 +493,7 @@ public class UserLifecycleTests {

    /** Tests stopping a profile. */
    @Test
    public void managedProfileStopped() throws Exception {
    public void managedProfileStopped() throws RemoteException {
        assumeTrue(mHasManagedUserFeature);

        while (mRunner.keepRunning()) {
@@ -511,7 +513,7 @@ public class UserLifecycleTests {
    // TODO: This is just a POC. Do this properly and add more.
    /** Tests starting (unlocking) a newly-created profile using the user-type-pkg-whitelist. */
    @Test
    public void managedProfileUnlock_usingWhitelist() throws Exception {
    public void managedProfileUnlock_usingWhitelist() {
        assumeTrue(mHasManagedUserFeature);
        final int origMode = getUserTypePackageWhitelistMode();
        setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE
@@ -535,7 +537,7 @@ public class UserLifecycleTests {
    }
    /** Tests starting (unlocking) a newly-created profile NOT using the user-type-pkg-whitelist. */
    @Test
    public void managedProfileUnlock_notUsingWhitelist() throws Exception {
    public void managedProfileUnlock_notUsingWhitelist() {
        assumeTrue(mHasManagedUserFeature);
        final int origMode = getUserTypePackageWhitelistMode();
        setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE);
@@ -573,10 +575,8 @@ public class UserLifecycleTests {
    private int createManagedProfile() {
        final UserInfo userInfo = mUm.createProfileForUser(TEST_USER_NAME,
                UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, mAm.getCurrentUser());
        if (userInfo == null) {
            throw new IllegalStateException("Creating managed profile failed. Most likely there is "
                    + "already a pre-existing profile on the device.");
        }
        attestFalse("Creating managed profile failed. Most likely there is "
                + "already a pre-existing profile on the device.", userInfo == null);
        mUsersToRemove.add(userInfo.id);
        return userInfo.id;
    }
@@ -589,24 +589,40 @@ public class UserLifecycleTests {
     */
    private void startUserInBackgroundAndWaitForUnlock(int userId) {
        final ProgressWaiter waiter = new ProgressWaiter();
        boolean success = false;
        try {
            mIam.startUserInBackgroundWithListener(userId, waiter);
            boolean success = waiter.waitForFinish(TIMEOUT_IN_SECOND);
            attestTrue("Failed to start user " + userId + " in background.", success);
            success = waiter.waitForFinish(TIMEOUT_IN_SECOND);
        } catch (RemoteException e) {
            Log.e(TAG, "startUserInBackgroundAndWaitForUnlock failed", e);
        }
        attestTrue("Failed to start user " + userId + " in background.", success);
    }

    /** Starts the given user in the foreground. */
    private void switchUser(int userId) throws Exception {
    private void switchUser(int userId) throws RemoteException {
        boolean success = switchUserNoCheck(userId);
        attestTrue("Failed to properly switch to user " + userId, success);
    }

    /**
     * Starts the given user in the foreground.
     * Returns true if successful. Does not fail the test if unsuccessful.
     * If lack of success should fail the test, use {@link #switchUser(int)} instead.
     */
    private boolean switchUserNoCheck(int userId) throws RemoteException {
        final CountDownLatch latch = new CountDownLatch(1);
        registerUserSwitchObserver(latch, null, userId);
        mAm.switchUser(userId);
        latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
        try {
            return latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Log.e(TAG, "Thread interrupted unexpectedly.", e);
            return false;
        }
    }

    private void stopUser(int userId, boolean force) throws Exception {
    private void stopUser(int userId, boolean force) throws RemoteException {
        final CountDownLatch latch = new CountDownLatch(1);
        mIam.stopUser(userId, force /* force */, new IStopUserCallback.Stub() {
            @Override
@@ -618,7 +634,7 @@ public class UserLifecycleTests {
            public void userStopAborted(int userId) throws RemoteException {
            }
        });
        latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
        waitForLatch("Failed to properly stop user " + userId, latch);
    }

    /**
@@ -628,15 +644,14 @@ public class UserLifecycleTests {
     * @param stopNewUser whether to stop the new user after switching to otherUser.
     * @return userId of the newly created user.
     */
    private int initializeNewUserAndSwitchBack(boolean stopNewUser) throws Exception {
    private int initializeNewUserAndSwitchBack(boolean stopNewUser) throws RemoteException {
        final int origUser = mAm.getCurrentUser();
        // First, create and switch to testUser, waiting for its ACTION_USER_UNLOCKED
        final int testUser = createUserNoFlags();
        final CountDownLatch latch1 = new CountDownLatch(1);
        registerBroadcastReceiver(Intent.ACTION_USER_UNLOCKED, latch1, testUser);
        mAm.switchUser(testUser);
        attestTrue("Failed to achieve initial ACTION_USER_UNLOCKED for user " + testUser,
                latch1.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS));
        waitForLatch("Failed to achieve initial ACTION_USER_UNLOCKED for user " + testUser, latch1);

        // Second, switch back to origUser, waiting merely for switchUser() to finish
        switchUser(origUser);
@@ -669,11 +684,7 @@ public class UserLifecycleTests {
                PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
                PackageManager.INSTALL_REASON_UNKNOWN, sender, userId, null);

        try {
            latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Log.e(TAG, "Thread interrupted unexpectedly.", e);
        }
        waitForLatch("Failed to install app " + packageName + " on user " + userId, latch);
    }

    /**
@@ -691,7 +702,7 @@ public class UserLifecycleTests {
    }

    private void registerUserSwitchObserver(final CountDownLatch switchLatch,
            final CountDownLatch bootCompleteLatch, final int userId) throws Exception {
            final CountDownLatch bootCompleteLatch, final int userId) throws RemoteException {
        ActivityManager.getService().registerUserSwitchObserver(
                new UserSwitchObserver() {
                    @Override
@@ -747,6 +758,17 @@ public class UserLifecycleTests {
        }
    }

    /** Waits TIMEOUT_IN_SECOND for the latch to complete, otherwise declares the given error. */
    private void waitForLatch(String errMsg, CountDownLatch latch) {
        boolean success = false;
        try {
            success = latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Log.e(TAG, "Thread interrupted unexpectedly.", e);
        }
        attestTrue(errMsg, success);
    }

    /** Gets the PACKAGE_WHITELIST_MODE_PROP System Property. */
    private int getUserTypePackageWhitelistMode() {
        return SystemProperties.getInt(PACKAGE_WHITELIST_MODE_PROP,
@@ -786,8 +808,8 @@ public class UserLifecycleTests {
                Log.i(TAG, "Found previous test user " + user.id + ". Removing it.");
                if (mAm.getCurrentUser() == user.id) {
                    try {
                        switchUser(UserHandle.USER_SYSTEM);
                    } catch (Exception e) {
                        switchUserNoCheck(UserHandle.USER_SYSTEM);
                    } catch (RemoteException e) {
                        Log.e(TAG, "Failed to correctly switch to system user", e);
                    }
                }