Merge "UserLifecycleTests - give proper errors on fail"

This commit is contained in:
TreeHugger Robot
2020-06-24 10:05:26 +00:00
committed by Android (Google) Code Review

View File

@@ -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();
switchLatch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
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);
}
}