aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYing Zheng <yizheng@google.com>2018-06-19 16:01:05 -0700
committerYing Zheng <yizheng@google.com>2018-06-20 16:42:07 -0700
commitf4339b8cb132a3b6635f4516eb7f65cf8e074fe7 (patch)
treea0b8c826ec1b60d6a2cc0ff791e71dc9f78f7258
parentd812d4c1ac4590e98d41c01fab14f654ea0b3657 (diff)
downloadCar-f4339b8cb132a3b6635f4516eb7f65cf8e074fe7.tar.gz
Complete the logic around last active user, including:
- Update CarSettings last active user when user switched. - Boot into the last active user if valid, or boot into the smallest user id. - Not allow deleting the last admin user, so we have a user 10+ to boot into. Test: Unit test Bug: 110156344,110425490,110425354 Change-Id: I3e85805bf469bd17709973936e8c3285c8f44207
-rw-r--r--car-lib/src/android/car/user/CarUserManagerHelper.java110
-rw-r--r--service/src/com/android/car/user/CarUserService.java16
-rw-r--r--tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java267
-rw-r--r--tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java46
4 files changed, 329 insertions, 110 deletions
diff --git a/car-lib/src/android/car/user/CarUserManagerHelper.java b/car-lib/src/android/car/user/CarUserManagerHelper.java
index 9aafdff4d1..41053536d3 100644
--- a/car-lib/src/android/car/user/CarUserManagerHelper.java
+++ b/car-lib/src/android/car/user/CarUserManagerHelper.java
@@ -34,6 +34,7 @@ import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.UserIcons;
import com.google.android.collect.Sets;
@@ -65,6 +66,7 @@ public class CarUserManagerHelper {
private final Context mContext;
private final UserManager mUserManager;
private final ActivityManager mActivityManager;
+ private int mLastActiveUser = UserHandle.USER_SYSTEM;
private Bitmap mDefaultGuestUserIcon;
private OnUsersUpdateListener mUpdateListener;
private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
@@ -107,7 +109,9 @@ public class CarUserManagerHelper {
* Set default boot into user.
*
* @param userId default user id to boot into.
+ * @deprecated Setting default user is obsolete
*/
+ @Deprecated
public void setDefaultBootUser(int userId) {
Settings.Global.putInt(
mContext.getContentResolver(),
@@ -118,17 +122,23 @@ public class CarUserManagerHelper {
* Set last active user.
*
* @param userId last active user id.
+ * @param skipGlobalSetting whether to skip set the global settings value.
*/
- public void setLastActiveUser(int userId) {
- Settings.Global.putInt(
- mContext.getContentResolver(), CarSettings.Global.LAST_ACTIVE_USER_ID, userId);
+ public void setLastActiveUser(int userId, boolean skipGlobalSetting) {
+ mLastActiveUser = userId;
+ if (!skipGlobalSetting) {
+ Settings.Global.putInt(
+ mContext.getContentResolver(), CarSettings.Global.LAST_ACTIVE_USER_ID, userId);
+ }
}
/**
* Get user id for the default boot into user.
*
* @return user id of the default boot into user
+ * @deprecated Use {@link #getLastActiveUser()} instead.
*/
+ @Deprecated
public int getDefaultBootUser() {
// Make user 10 the original default boot user.
return Settings.Global.getInt(
@@ -139,13 +149,46 @@ public class CarUserManagerHelper {
/**
* Get user id for the last active user.
*
- * @return user id of the last active user
+ * @return user id of the last active user.
*/
public int getLastActiveUser() {
- // Make user 10 the original default last active user.
+ if (mLastActiveUser != UserHandle.USER_SYSTEM) {
+ return mLastActiveUser;
+ }
return Settings.Global.getInt(
mContext.getContentResolver(), CarSettings.Global.LAST_ACTIVE_USER_ID,
- /* default user id= */ 10);
+ /* default user id= */ UserHandle.USER_SYSTEM);
+ }
+
+ /**
+ * Get user id for the initial user to boot into.
+ *
+ * <p>If failed to retrieve the id stored in global settings or the retrieved id does not
+ * exist on device, then return the user with smallest user id.
+ *
+ * @return user id of the last active user or the smallest user id on the device.
+ */
+ public int getInitialUser() {
+ int lastActiveUserId = getLastActiveUser();
+
+ boolean isUserExist = false;
+ List<UserInfo> allUsers = getAllPersistentUsers();
+ int smallestUserId = Integer.MAX_VALUE;
+ for (UserInfo user : allUsers) {
+ if (user.id == lastActiveUserId) {
+ isUserExist = true;
+ }
+ smallestUserId = Math.min(user.id, smallestUserId);
+ }
+
+ // If the last active user is system user or the user id doesn't exist on device,
+ // return the smallest id or all users.
+ if (lastActiveUserId == UserHandle.USER_SYSTEM || !isUserExist) {
+ Log.e(TAG, "Can't get last active user id or the user no longer exist.");
+ lastActiveUserId = smallestUserId;
+ }
+
+ return lastActiveUserId;
}
/**
@@ -237,6 +280,41 @@ public class CarUserManagerHelper {
}
/**
+ * Gets all the users that are non-ephemeral and can be brought to the foreground on the system.
+ *
+ * @return List of {@code UserInfo} for non-ephemeral users that associated with a real person.
+ */
+ public List<UserInfo> getAllPersistentUsers() {
+ List<UserInfo> users = getAllUsers();
+ for (Iterator<UserInfo> iterator = users.iterator(); iterator.hasNext(); ) {
+ UserInfo userInfo = iterator.next();
+ if (userInfo.isEphemeral()) {
+ // Remove user that is not admin.
+ iterator.remove();
+ }
+ }
+ return users;
+ }
+
+ /**
+ * Gets all the users that can be brought to the foreground on the system that have admin roles.
+ *
+ * @return List of {@code UserInfo} for admin users that associated with a real person.
+ */
+ public List<UserInfo> getAllAdminUsers() {
+ List<UserInfo> users = getAllUsers();
+
+ for (Iterator<UserInfo> iterator = users.iterator(); iterator.hasNext(); ) {
+ UserInfo userInfo = iterator.next();
+ if (!userInfo.isAdmin()) {
+ // Remove user that is not admin.
+ iterator.remove();
+ }
+ }
+ return users;
+ }
+
+ /**
* Get all the users except the one with userId passed in.
*
* @param userId of the user not to be returned.
@@ -291,12 +369,25 @@ public class CarUserManagerHelper {
*
* @param userInfo User to check against system user.
* @return {@code true} if is default user, {@code false} otherwise.
+ *
+ * @deprecated Default user is obsolete
*/
+ @Deprecated
public boolean isDefaultUser(UserInfo userInfo) {
return userInfo.id == getDefaultBootUser();
}
/**
+ * Checks whether the user is last active user.
+ *
+ * @param userInfo User to check against last active user.
+ * @return {@code true} if is last active user, {@code false} otherwise.
+ */
+ public boolean isLastActiveUser(UserInfo userInfo) {
+ return userInfo.id == getLastActiveUser();
+ }
+
+ /**
* Checks whether passed in user is the foreground user.
*
* @param userInfo User to check.
@@ -544,10 +635,9 @@ public class CarUserManagerHelper {
return false;
}
- // Not allow to delete the default user for now. Since default user is the one to
- // boot into.
- if (isHeadlessSystemUser() && isDefaultUser(userInfo)) {
- Log.w(TAG, "User " + userInfo.id + " is the default user, could not be removed.");
+ // Not allow to delete the last admin user on the device for now.
+ if (userInfo.isAdmin() && getAllAdminUsers().size() <= 1) {
+ Log.w(TAG, "User " + userInfo.id + " is the last admin user on device.");
return false;
}
diff --git a/service/src/com/android/car/user/CarUserService.java b/service/src/com/android/car/user/CarUserService.java
index a66621085b..46c762c41d 100644
--- a/service/src/com/android/car/user/CarUserService.java
+++ b/service/src/com/android/car/user/CarUserService.java
@@ -36,7 +36,7 @@ import java.io.PrintWriter;
*
* <ol>
* <li> Creates a secondary admin user on first run.
- * <li> Log in to a default user.
+ * <li> Log in to the last active user.
* <ol/>
*/
public class CarUserService extends BroadcastReceiver implements CarServiceBase {
@@ -63,6 +63,7 @@ public class CarUserService extends BroadcastReceiver implements CarServiceBase
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_LOCKED_BOOT_COMPLETED);
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(this, filter);
}
@@ -95,8 +96,19 @@ public class CarUserService extends BroadcastReceiver implements CarServiceBase
// On very first boot, create an admin user and switch to that user.
UserInfo admin = mCarUserManagerHelper.createNewAdminUser(OWNER_NAME);
mCarUserManagerHelper.switchToUser(admin);
+ mCarUserManagerHelper.setLastActiveUser(
+ admin.id, /* skipGlobalSettings= */ false);
} else {
- mCarUserManagerHelper.switchToUserId(mCarUserManagerHelper.getDefaultBootUser());
+ mCarUserManagerHelper.switchToUserId(mCarUserManagerHelper.getInitialUser());
+ }
+ }
+ if (intent.getAction() == Intent.ACTION_USER_SWITCHED) {
+ UserInfo foregroundUser = mCarUserManagerHelper.getCurrentForegroundUserInfo();
+ // Update last active user if foreground user is not ephemeral.
+ if (!foregroundUser.isEphemeral() && !foregroundUser.isGuest()) {
+ mCarUserManagerHelper.setLastActiveUser(
+ mCarUserManagerHelper.getCurrentForegroundUserId(),
+ /* skipGlobalSettings= */ false);
}
}
}
diff --git a/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java b/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java
index 3c97ca19cc..ca6e027843 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java
@@ -19,9 +19,9 @@ package com.android.car;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.car.user.CarUserManagerHelper;
@@ -40,6 +40,10 @@ import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -47,10 +51,6 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
/**
* This class contains unit tests for the {@link CarUserManagerHelper}.
* It tests that {@link CarUserManagerHelper} does the right thing for user management flows.
@@ -73,7 +73,7 @@ public class CarUserManagerHelperTest {
@Mock
private CarUserManagerHelper.OnUsersUpdateListener mTestListener;
- private CarUserManagerHelper mHelper;
+ private CarUserManagerHelper mCarUserManagerHelper;
private UserInfo mCurrentProcessUser;
private UserInfo mSystemUser;
private String mGuestUserName = "testGuest";
@@ -84,16 +84,16 @@ public class CarUserManagerHelperTest {
@Before
public void setUpMocksAndVariables() throws Exception {
MockitoAnnotations.initMocks(this);
- when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
- when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager);
- when(mContext.getResources())
- .thenReturn(InstrumentationRegistry.getTargetContext().getResources());
- when(mContext.getApplicationContext()).thenReturn(mContext);
- mHelper = new CarUserManagerHelper(mContext);
+ doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE);
+ doReturn(mActivityManager).when(mContext).getSystemService(Context.ACTIVITY_SERVICE);
+ doReturn(InstrumentationRegistry.getTargetContext().getResources())
+ .when(mContext).getResources();
+ doReturn(mContext).when(mContext).getApplicationContext();
+ mCarUserManagerHelper = new CarUserManagerHelper(mContext);
mCurrentProcessUser = createUserInfoForId(UserHandle.myUserId());
mSystemUser = createUserInfoForId(UserHandle.USER_SYSTEM);
- when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(mCurrentProcessUser);
+ doReturn(mCurrentProcessUser).when(mUserManager).getUserInfo(UserHandle.myUserId());
// Get the ID of the foreground user running this test.
// We cannot mock the foreground user since getCurrentUser is static.
@@ -111,10 +111,10 @@ public class CarUserManagerHelperTest {
UserInfo testInfo = new UserInfo();
testInfo.id = UserHandle.USER_SYSTEM;
- assertThat(mHelper.isSystemUser(testInfo)).isTrue();
+ assertThat(mCarUserManagerHelper.isSystemUser(testInfo)).isTrue();
testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
- assertThat(mHelper.isSystemUser(testInfo)).isFalse();
+ assertThat(mCarUserManagerHelper.isSystemUser(testInfo)).isFalse();
}
// System user will not be returned when calling get all users.
@@ -131,10 +131,10 @@ public class CarUserManagerHelperTest {
testUsers.add(otherUser2);
testUsers.add(otherUser3);
- when(mUserManager.getUsers(true)).thenReturn(testUsers);
+ doReturn(testUsers).when(mUserManager).getUsers(true);
- assertThat(mHelper.getAllUsers()).hasSize(3);
- assertThat(mHelper.getAllUsers())
+ assertThat(mCarUserManagerHelper.getAllUsers()).hasSize(3);
+ assertThat(mCarUserManagerHelper.getAllUsers())
.containsExactly(otherUser1, otherUser2, otherUser3);
}
@@ -146,14 +146,14 @@ public class CarUserManagerHelperTest {
List<UserInfo> testUsers = Arrays.asList(mForegroundUser, user1, user2);
- when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers));
+ doReturn(new ArrayList<>(testUsers)).when(mUserManager).getUsers(true);
// Should return all 3 users.
- assertThat(mHelper.getAllUsers()).hasSize(3);
+ assertThat(mCarUserManagerHelper.getAllUsers()).hasSize(3);
// Should return all non-foreground users.
- assertThat(mHelper.getAllSwitchableUsers()).hasSize(2);
- assertThat(mHelper.getAllSwitchableUsers()).containsExactly(user1, user2);
+ assertThat(mCarUserManagerHelper.getAllSwitchableUsers()).hasSize(2);
+ assertThat(mCarUserManagerHelper.getAllSwitchableUsers()).containsExactly(user1, user2);
}
@Test
@@ -162,80 +162,89 @@ public class CarUserManagerHelperTest {
// System user cannot be removed.
testInfo.id = UserHandle.USER_SYSTEM;
- assertThat(mHelper.canUserBeRemoved(testInfo)).isFalse();
+ assertThat(mCarUserManagerHelper.canUserBeRemoved(testInfo)).isFalse();
testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
- assertThat(mHelper.canUserBeRemoved(testInfo)).isTrue();
+ assertThat(mCarUserManagerHelper.canUserBeRemoved(testInfo)).isTrue();
}
@Test
public void testCurrentProcessCanAddUsers() {
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(false);
- assertThat(mHelper.canCurrentProcessAddUsers()).isTrue();
+ doReturn(false).when(mUserManager)
+ .hasUserRestriction(UserManager.DISALLOW_ADD_USER);
+ assertThat(mCarUserManagerHelper.canCurrentProcessAddUsers()).isTrue();
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(true);
- assertThat(mHelper.canCurrentProcessAddUsers()).isFalse();
+ doReturn(true).when(mUserManager)
+ .hasUserRestriction(UserManager.DISALLOW_ADD_USER);
+ assertThat(mCarUserManagerHelper.canCurrentProcessAddUsers()).isFalse();
}
@Test
public void testCurrentProcessCanRemoveUsers() {
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(false);
- assertThat(mHelper.canCurrentProcessRemoveUsers()).isTrue();
+ doReturn(false).when(mUserManager)
+ .hasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
+ assertThat(mCarUserManagerHelper.canCurrentProcessRemoveUsers()).isTrue();
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(true);
- assertThat(mHelper.canCurrentProcessRemoveUsers()).isFalse();
+ doReturn(true).when(mUserManager)
+ .hasUserRestriction(UserManager.DISALLOW_REMOVE_USER);
+ assertThat(mCarUserManagerHelper.canCurrentProcessRemoveUsers()).isFalse();
}
@Test
public void testCurrentProcessCanSwitchUsers() {
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false);
- assertThat(mHelper.canCurrentProcessSwitchUsers()).isTrue();
+ doReturn(false).when(mUserManager)
+ .hasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
+ assertThat(mCarUserManagerHelper.canCurrentProcessSwitchUsers()).isTrue();
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true);
- assertThat(mHelper.canCurrentProcessSwitchUsers()).isFalse();
+ doReturn(true).when(mUserManager)
+ .hasUserRestriction(UserManager.DISALLOW_USER_SWITCH);
+ assertThat(mCarUserManagerHelper.canCurrentProcessSwitchUsers()).isFalse();
}
@Test
public void testCurrentGuestProcessCannotModifyAccounts() {
- assertThat(mHelper.canCurrentProcessModifyAccounts()).isTrue();
+ assertThat(mCarUserManagerHelper.canCurrentProcessModifyAccounts()).isTrue();
+
+ doReturn(true).when(mUserManager).isGuestUser();
- when(mUserManager.isGuestUser()).thenReturn(true);
- assertThat(mHelper.canCurrentProcessModifyAccounts()).isFalse();
+ assertThat(mCarUserManagerHelper.canCurrentProcessModifyAccounts()).isFalse();
}
@Test
public void testCurrentDemoProcessCannotModifyAccounts() {
- assertThat(mHelper.canCurrentProcessModifyAccounts()).isTrue();
+ assertThat(mCarUserManagerHelper.canCurrentProcessModifyAccounts()).isTrue();
- when(mUserManager.isDemoUser()).thenReturn(true);
- assertThat(mHelper.canCurrentProcessModifyAccounts()).isFalse();
+ doReturn(true).when(mUserManager).isDemoUser();
+
+ assertThat(mCarUserManagerHelper.canCurrentProcessModifyAccounts()).isFalse();
}
@Test
public void testCurrentDisallowModifyAccountsProcessIsEnforced() {
- assertThat(mHelper.canCurrentProcessModifyAccounts()).isTrue();
+ assertThat(mCarUserManagerHelper.canCurrentProcessModifyAccounts()).isTrue();
+
+ doReturn(true).when(mUserManager)
+ .hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS);
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS))
- .thenReturn(true);
- assertThat(mHelper.canCurrentProcessModifyAccounts()).isFalse();
+ assertThat(mCarUserManagerHelper.canCurrentProcessModifyAccounts()).isFalse();
}
@Test
public void testCreateNewAdminUser() {
// Make sure current user is admin, since only admins can create other admins.
- when(mUserManager.isAdminUser()).thenReturn(true);
+ doReturn(true).when(mUserManager).isAdminUser();
// Verify createUser on UserManager gets called.
- mHelper.createNewAdminUser(mTestUserName);
+ mCarUserManagerHelper.createNewAdminUser(mTestUserName);
verify(mUserManager).createUser(mTestUserName, UserInfo.FLAG_ADMIN);
- when(mUserManager.createUser(mTestUserName, UserInfo.FLAG_ADMIN)).thenReturn(null);
- assertThat(mHelper.createNewAdminUser(mTestUserName)).isNull();
+ doReturn(null).when(mUserManager).createUser(mTestUserName, UserInfo.FLAG_ADMIN);
+ assertThat(mCarUserManagerHelper.createNewAdminUser(mTestUserName)).isNull();
UserInfo newUser = new UserInfo();
newUser.name = mTestUserName;
- when(mUserManager.createUser(mTestUserName, UserInfo.FLAG_ADMIN)).thenReturn(newUser);
- assertThat(mHelper.createNewAdminUser(mTestUserName)).isEqualTo(newUser);
+ doReturn(newUser).when(mUserManager).createUser(mTestUserName, UserInfo.FLAG_ADMIN);
+ assertThat(mCarUserManagerHelper.createNewAdminUser(mTestUserName)).isEqualTo(newUser);
}
@Test
@@ -243,11 +252,11 @@ public class CarUserManagerHelperTest {
String newAdminName = "Test new admin";
UserInfo expectedAdmin = new UserInfo();
expectedAdmin.name = newAdminName;
- when(mUserManager.createUser(newAdminName, UserInfo.FLAG_ADMIN)).thenReturn(expectedAdmin);
+ doReturn(expectedAdmin).when(mUserManager).createUser(newAdminName, UserInfo.FLAG_ADMIN);
// Admins can create other admins.
- when(mUserManager.isAdminUser()).thenReturn(true);
- UserInfo actualAdmin = mHelper.createNewAdminUser(newAdminName);
+ doReturn(true).when(mUserManager).isAdminUser();
+ UserInfo actualAdmin = mCarUserManagerHelper.createNewAdminUser(newAdminName);
assertThat(actualAdmin).isEqualTo(expectedAdmin);
}
@@ -256,11 +265,11 @@ public class CarUserManagerHelperTest {
String newAdminName = "Test new admin";
UserInfo expectedAdmin = new UserInfo();
expectedAdmin.name = newAdminName;
- when(mUserManager.createUser(newAdminName, UserInfo.FLAG_ADMIN)).thenReturn(expectedAdmin);
+ doReturn(expectedAdmin).when(mUserManager).createUser(newAdminName, UserInfo.FLAG_ADMIN);
// Test that non-admins cannot create new admins.
- when(mUserManager.isAdminUser()).thenReturn(false); // Current user non-admin.
- assertThat(mHelper.createNewAdminUser(newAdminName)).isNull();
+ doReturn(false).when(mUserManager).isAdminUser(); // Current user non-admin.
+ assertThat(mCarUserManagerHelper.createNewAdminUser(newAdminName)).isNull();
}
@Test
@@ -268,82 +277,99 @@ public class CarUserManagerHelperTest {
String newAdminName = "Test new admin";
UserInfo expectedAdmin = new UserInfo();
expectedAdmin.name = newAdminName;
- when(mUserManager.createUser(newAdminName, UserInfo.FLAG_ADMIN)).thenReturn(expectedAdmin);
+
+ doReturn(expectedAdmin).when(mUserManager).createUser(newAdminName, UserInfo.FLAG_ADMIN);
// System user can create admins.
- when(mUserManager.isSystemUser()).thenReturn(true);
- UserInfo actualAdmin = mHelper.createNewAdminUser(newAdminName);
+ doReturn(true).when(mUserManager).isSystemUser();
+ UserInfo actualAdmin = mCarUserManagerHelper.createNewAdminUser(newAdminName);
assertThat(actualAdmin).isEqualTo(expectedAdmin);
}
@Test
public void testCreateNewNonAdminUser() {
// Verify createUser on UserManager gets called.
- mHelper.createNewNonAdminUser(mTestUserName);
+ mCarUserManagerHelper.createNewNonAdminUser(mTestUserName);
verify(mUserManager).createUser(mTestUserName, 0);
- when(mUserManager.createUser(mTestUserName, 0)).thenReturn(null);
- assertThat(mHelper.createNewNonAdminUser(mTestUserName)).isNull();
+ doReturn(null).when(mUserManager).createUser(mTestUserName, 0);
+ assertThat(mCarUserManagerHelper.createNewNonAdminUser(mTestUserName)).isNull();
UserInfo newUser = new UserInfo();
newUser.name = mTestUserName;
- when(mUserManager.createUser(mTestUserName, 0)).thenReturn(newUser);
- assertThat(mHelper.createNewNonAdminUser(mTestUserName)).isEqualTo(newUser);
+ doReturn(newUser).when(mUserManager).createUser(mTestUserName, 0);
+ assertThat(mCarUserManagerHelper.createNewNonAdminUser(mTestUserName)).isEqualTo(newUser);
}
@Test
public void testCannotRemoveSystemUser() {
- assertThat(mHelper.removeUser(mSystemUser, mGuestUserName)).isFalse();
+ assertThat(mCarUserManagerHelper.removeUser(mSystemUser, mGuestUserName)).isFalse();
}
@Test
public void testAdminsCanRemoveOtherUsers() {
int idToRemove = mCurrentProcessUser.id + 2;
UserInfo userToRemove = createUserInfoForId(idToRemove);
- when(mUserManager.removeUser(idToRemove)).thenReturn(true);
+
+ doReturn(true).when(mUserManager).removeUser(idToRemove);
// If Admin is removing non-current, non-system user, simply calls removeUser.
- when(mUserManager.isAdminUser()).thenReturn(true);
- assertThat(mHelper.removeUser(userToRemove, mGuestUserName)).isTrue();
+ doReturn(true).when(mUserManager).isAdminUser();
+ assertThat(mCarUserManagerHelper.removeUser(userToRemove, mGuestUserName)).isTrue();
verify(mUserManager).removeUser(idToRemove);
}
@Test
- public void testNonAdminsCanOnlyRemoveThemselves() {
+ public void testNonAdminsCanNotRemoveOtherUsers() {
UserInfo otherUser = createUserInfoForId(mCurrentProcessUser.id + 2);
// Make current user non-admin.
- when(mUserManager.isAdminUser()).thenReturn(false);
+ doReturn(false).when(mUserManager).isAdminUser();
// Mock so that removeUser always pretends it's successful.
- when(mUserManager.removeUser(anyInt())).thenReturn(true);
+ doReturn(true).when(mUserManager).removeUser(anyInt());
// If Non-Admin is trying to remove someone other than themselves, they should fail.
- assertThat(mHelper.removeUser(otherUser, mGuestUserName)).isFalse();
+ assertThat(mCarUserManagerHelper.removeUser(otherUser, mGuestUserName)).isFalse();
verify(mUserManager, never()).removeUser(otherUser.id);
}
@Test
+ public void testRemoveLastActiveUser() {
+ // Cannot remove system user.
+ assertThat(mCarUserManagerHelper.removeUser(mSystemUser, mGuestUserName)).isFalse();
+
+ UserInfo adminInfo = new UserInfo(/* id= */10, "admin", UserInfo.FLAG_ADMIN);
+ List<UserInfo> users = new ArrayList<UserInfo>();
+ users.add(adminInfo);
+
+ doReturn(users).when(mUserManager).getUsers(true);
+
+ assertThat(mCarUserManagerHelper.removeUser(adminInfo, mGuestUserName))
+ .isEqualTo(false);
+ }
+
+ @Test
public void testSwitchToGuest() {
- mHelper.startNewGuestSession(mGuestUserName);
+ mCarUserManagerHelper.startNewGuestSession(mGuestUserName);
verify(mUserManager).createGuest(mContext, mGuestUserName);
- UserInfo guestInfo = new UserInfo(21, mGuestUserName, UserInfo.FLAG_GUEST);
- when(mUserManager.createGuest(mContext, mGuestUserName)).thenReturn(guestInfo);
- mHelper.startNewGuestSession(mGuestUserName);
+ UserInfo guestInfo = new UserInfo(/* id= */21, mGuestUserName, UserInfo.FLAG_GUEST);
+ doReturn(guestInfo).when(mUserManager).createGuest(mContext, mGuestUserName);
+ mCarUserManagerHelper.startNewGuestSession(mGuestUserName);
verify(mActivityManager).switchUser(21);
}
@Test
public void testGetUserIcon() {
- mHelper.getUserIcon(mCurrentProcessUser);
+ mCarUserManagerHelper.getUserIcon(mCurrentProcessUser);
verify(mUserManager).getUserIcon(mCurrentProcessUser.id);
}
@Test
public void testScaleUserIcon() {
Bitmap fakeIcon = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
- Drawable scaledIcon = mHelper.scaleUserIcon(fakeIcon, 300);
+ Drawable scaledIcon = mCarUserManagerHelper.scaleUserIcon(fakeIcon, 300);
assertThat(scaledIcon.getIntrinsicWidth()).isEqualTo(300);
assertThat(scaledIcon.getIntrinsicHeight()).isEqualTo(300);
}
@@ -352,17 +378,17 @@ public class CarUserManagerHelperTest {
public void testSetUserName() {
UserInfo testInfo = createUserInfoForId(mCurrentProcessUser.id + 3);
String newName = "New Test Name";
- mHelper.setUserName(testInfo, newName);
+ mCarUserManagerHelper.setUserName(testInfo, newName);
verify(mUserManager).setUserName(mCurrentProcessUser.id + 3, newName);
}
@Test
public void testIsCurrentProcessSystemUser() {
- when(mUserManager.isAdminUser()).thenReturn(true);
- assertThat(mHelper.isCurrentProcessAdminUser()).isTrue();
+ doReturn(true).when(mUserManager).isAdminUser();
+ assertThat(mCarUserManagerHelper.isCurrentProcessAdminUser()).isTrue();
- when(mUserManager.isAdminUser()).thenReturn(false);
- assertThat(mHelper.isCurrentProcessAdminUser()).isFalse();
+ doReturn(false).when(mUserManager).isAdminUser();
+ assertThat(mCarUserManagerHelper.isCurrentProcessAdminUser()).isFalse();
}
@Test
@@ -371,13 +397,13 @@ public class CarUserManagerHelperTest {
UserInfo testInfo = createUserInfoForId(userId);
// Test that non-admins cannot assign admin privileges.
- when(mUserManager.isAdminUser()).thenReturn(false); // Current user non-admin.
- mHelper.assignAdminPrivileges(testInfo);
+ doReturn(false).when(mUserManager).isAdminUser(); // Current user non-admin.
+ mCarUserManagerHelper.assignAdminPrivileges(testInfo);
verify(mUserManager, never()).setUserAdmin(userId);
// Admins can assign admin privileges.
- when(mUserManager.isAdminUser()).thenReturn(true);
- mHelper.assignAdminPrivileges(testInfo);
+ doReturn(true).when(mUserManager).isAdminUser();
+ mCarUserManagerHelper.assignAdminPrivileges(testInfo);
verify(mUserManager).setUserAdmin(userId);
}
@@ -386,11 +412,13 @@ public class CarUserManagerHelperTest {
int userId = 20;
UserInfo testInfo = createUserInfoForId(userId);
- mHelper.setUserRestriction(testInfo, UserManager.DISALLOW_ADD_USER, /* enable= */ true);
+ mCarUserManagerHelper.setUserRestriction(
+ testInfo, UserManager.DISALLOW_ADD_USER, /* enable= */ true);
verify(mUserManager).setUserRestriction(
UserManager.DISALLOW_ADD_USER, true, UserHandle.of(userId));
- mHelper.setUserRestriction(testInfo, UserManager.DISALLOW_REMOVE_USER, /* enable= */ false);
+ mCarUserManagerHelper.setUserRestriction(
+ testInfo, UserManager.DISALLOW_REMOVE_USER, /* enable= */ false);
verify(mUserManager).setUserRestriction(
UserManager.DISALLOW_REMOVE_USER, false, UserHandle.of(userId));
}
@@ -400,9 +428,10 @@ public class CarUserManagerHelperTest {
String testUserName = "Test User";
int userId = 20;
UserInfo newNonAdmin = createUserInfoForId(userId);
- when(mUserManager.createUser(testUserName, /* flags= */ 0)).thenReturn(newNonAdmin);
- mHelper.createNewNonAdminUser(testUserName);
+ doReturn(newNonAdmin).when(mUserManager).createUser(testUserName, /* flags= */ 0);
+
+ mCarUserManagerHelper.createNewNonAdminUser(testUserName);
verify(mUserManager).setUserRestriction(
UserManager.DISALLOW_FACTORY_RESET, /* enable= */ true, UserHandle.of(userId));
@@ -417,9 +446,11 @@ public class CarUserManagerHelperTest {
int testUserId = 30;
boolean restrictionEnabled = false;
UserInfo testInfo = createUserInfoForId(testUserId);
- when(mUserManager.isAdminUser()).thenReturn(true); // Only admins can assign privileges.
- mHelper.assignAdminPrivileges(testInfo);
+ // Only admins can assign privileges.
+ doReturn(true).when(mUserManager).isAdminUser();
+
+ mCarUserManagerHelper.assignAdminPrivileges(testInfo);
verify(mUserManager).setUserRestriction(
UserManager.DISALLOW_FACTORY_RESET, restrictionEnabled, UserHandle.of(testUserId));
@@ -427,7 +458,7 @@ public class CarUserManagerHelperTest {
@Test
public void testRegisterUserChangeReceiver() {
- mHelper.registerOnUsersUpdateListener(mTestListener);
+ mCarUserManagerHelper.registerOnUsersUpdateListener(mTestListener);
ArgumentCaptor<BroadcastReceiver> receiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@@ -465,10 +496,52 @@ public class CarUserManagerHelperTest {
assertThat(handlerCaptor.getValue()).isNull();
// Unregister the receiver.
- mHelper.unregisterOnUsersUpdateListener();
+ mCarUserManagerHelper.unregisterOnUsersUpdateListener();
verify(mContext).unregisterReceiver(receiverCaptor.getValue());
}
+ @Test
+ public void testGetInitialUserWithValidLastActiveUser() {
+ SystemProperties.set("android.car.systemuser.headless", "true");
+ int lastActiveUserId = 12;
+
+ UserInfo otherUser1 = createUserInfoForId(lastActiveUserId - 2);
+ UserInfo otherUser2 = createUserInfoForId(lastActiveUserId - 1);
+ UserInfo otherUser3 = createUserInfoForId(lastActiveUserId);
+
+ List<UserInfo> testUsers = new ArrayList<>();
+ testUsers.add(mSystemUser);
+ testUsers.add(otherUser1);
+ testUsers.add(otherUser2);
+ testUsers.add(otherUser3);
+
+ mCarUserManagerHelper.setLastActiveUser(
+ lastActiveUserId, /* skipGlobalSettings= */ true);
+ doReturn(testUsers).when(mUserManager).getUsers(true);
+
+ assertThat(mCarUserManagerHelper.getInitialUser()).isEqualTo(lastActiveUserId);
+ }
+
+ @Test
+ public void testGetInitialUserWithNonExistLastActiveUser() {
+ SystemProperties.set("android.car.systemuser.headless", "true");
+ int lastActiveUserId = 12;
+
+ UserInfo otherUser1 = createUserInfoForId(lastActiveUserId - 2);
+ UserInfo otherUser2 = createUserInfoForId(lastActiveUserId - 1);
+
+ List<UserInfo> testUsers = new ArrayList<>();
+ testUsers.add(mSystemUser);
+ testUsers.add(otherUser1);
+ testUsers.add(otherUser2);
+
+ mCarUserManagerHelper.setLastActiveUser(
+ lastActiveUserId, /* skipGlobalSettings= */ true);
+ doReturn(testUsers).when(mUserManager).getUsers(true);
+
+ assertThat(mCarUserManagerHelper.getInitialUser()).isEqualTo(lastActiveUserId - 2);
+ }
+
private UserInfo createUserInfoForId(int id) {
UserInfo userInfo = new UserInfo();
userInfo.id = id;
diff --git a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
index 20cb060f28..a6b48bf8f1 100644
--- a/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java
@@ -84,9 +84,10 @@ public class CarUserServiceTest {
mCarUserService.init();
verify(mMockContext).registerReceiver(eq(mCarUserService), argument.capture());
IntentFilter intentFilter = argument.getValue();
- assertThat(intentFilter.countActions()).isEqualTo(1);
+ assertThat(intentFilter.countActions()).isEqualTo(2);
assertThat(intentFilter.getAction(0)).isEqualTo(Intent.ACTION_LOCKED_BOOT_COMPLETED);
+ assertThat(intentFilter.getAction(1)).isEqualTo(Intent.ACTION_USER_SWITCHED);
}
/**
@@ -139,4 +140,47 @@ public class CarUserServiceTest {
verify(mCarUserManagerHelper).
setUserRestriction(user0, UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
}
+
+ /**
+ * Test that the {@link CarUserService} starts up the last active user on reboot.
+ */
+ @Test
+ public void testStartsLastActiveUserOnReboot() {
+ List<UserInfo> users = new ArrayList<>();
+
+ int adminUserId = 10;
+ UserInfo admin = new UserInfo(adminUserId, CarUserService.OWNER_NAME, UserInfo.FLAG_ADMIN);
+
+ int secUserId = 11;
+ UserInfo secUser =
+ new UserInfo(secUserId, CarUserService.OWNER_NAME, UserInfo.FLAG_ADMIN);
+
+ users.add(admin);
+ users.add(secUser);
+
+ doReturn(users).when(mCarUserManagerHelper).getAllUsers();
+ doReturn(secUserId).when(mCarUserManagerHelper).getLastActiveUser();
+
+ mCarUserService.onReceive(mMockContext,
+ new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
+
+ verify(mCarUserManagerHelper).switchToUserId(secUserId);
+ }
+
+ /**
+ * Test that the {@link CarUserService} updates last active user on user switch intent.
+ */
+ @Test
+ public void testLastActiveUserUpdatedOnUserSwitch() {
+ int lastActiveUserId = 11;
+
+ doReturn(false).when(mCarUserManagerHelper).isForegroundUserGuest();
+ doReturn(lastActiveUserId).when(mCarUserManagerHelper).getCurrentForegroundUserId();
+
+ mCarUserService.onReceive(mMockContext,
+ new Intent(Intent.ACTION_USER_SWITCHED));
+
+ verify(mCarUserManagerHelper).setLastActiveUser(
+ lastActiveUserId, /* skipGlobalSetting= */ false);
+ }
}