aboutsummaryrefslogtreecommitdiff
path: root/tests/carservice_unit_test/src/com/android/car
diff options
context:
space:
mode:
authorBill Yi <byi@google.com>2018-11-28 18:35:00 -0800
committerBill Yi <byi@google.com>2018-11-28 18:35:00 -0800
commit0f8320f6b95736ea4b703764a7d11a8a6ca13674 (patch)
treed7b300e81f05e45345ada1ffcaf39b2512dd8f6f /tests/carservice_unit_test/src/com/android/car
parentf02b56678700a4035d0ad8882f7d20371bb96ee2 (diff)
parent911e6566751a60c29eada6ad0679694bed11be4f (diff)
downloadCar-pie-platform-release.tar.gz
Merge pi-qpr1-release PQ1A.181105.017.A1 to pi-platform-releasepie-platform-releasepie-cuttlefish-testing
Change-Id: Ibafbc25e1d704d7e84a168b32d35a165dd41e06f
Diffstat (limited to 'tests/carservice_unit_test/src/com/android/car')
-rw-r--r--tests/carservice_unit_test/src/com/android/car/CarLocationServiceTest.java52
-rw-r--r--tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java655
-rw-r--r--tests/carservice_unit_test/src/com/android/car/user/CarUserServiceTest.java136
3 files changed, 698 insertions, 145 deletions
diff --git a/tests/carservice_unit_test/src/com/android/car/CarLocationServiceTest.java b/tests/carservice_unit_test/src/com/android/car/CarLocationServiceTest.java
index 8ac7d9b1db..b071e9947d 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarLocationServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarLocationServiceTest.java
@@ -31,6 +31,7 @@ import android.car.hardware.CarSensorEvent;
import android.car.hardware.CarSensorManager;
import android.car.hardware.property.CarPropertyEvent;
import android.car.hardware.property.ICarPropertyEventListener;
+import android.car.user.CarUserManagerHelper;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -72,7 +73,9 @@ import java.util.stream.Collectors;
* The following mocks are used:
* 1. {@link Context} provides files and a mocked {@link LocationManager}.
* 2. {@link LocationManager} provides dummy {@link Location}s.
- * 3. {@link CarSensorService} registers a handler for sensor events and sends ignition-off events.
+ * 3. {@link CarPropertyService} registers a listener for ignition state events.
+ * 3. {@link CarPowerManagementService} registers a handler for power events.
+ * 4. {@link CarUserManagerHelper} tells whether or not the system user is headless.
*/
@RunWith(AndroidJUnit4.class)
public class CarLocationServiceTest {
@@ -85,6 +88,7 @@ public class CarLocationServiceTest {
@Mock private LocationManager mMockLocationManager;
@Mock private CarPropertyService mMockCarPropertyService;
@Mock private CarPowerManagementService mMockCarPowerManagementService;
+ @Mock private CarUserManagerHelper mMockCarUserManagerHelper;
/**
* Initialize all of the objects with the @Mock annotation.
@@ -95,7 +99,7 @@ public class CarLocationServiceTest {
mContext = InstrumentationRegistry.getTargetContext();
mLatch = new CountDownLatch(1);
mCarLocationService = new CarLocationService(mMockContext, mMockCarPowerManagementService,
- mMockCarPropertyService) {
+ mMockCarPropertyService, mMockCarUserManagerHelper) {
@Override
void asyncOperation(Runnable operation) {
super.asyncOperation(() -> {
@@ -143,12 +147,13 @@ public class CarLocationServiceTest {
mCarLocationService);
verify(mMockContext).registerReceiver(eq(mCarLocationService), argument.capture());
IntentFilter intentFilter = argument.getValue();
- assertEquals(3, intentFilter.countActions());
+ assertEquals(4, intentFilter.countActions());
String[] actions = {intentFilter.getAction(0), intentFilter.getAction(1),
- intentFilter.getAction(2)};
+ intentFilter.getAction(2), intentFilter.getAction(3)};
assertTrue(ArrayUtils.contains(actions, Intent.ACTION_LOCKED_BOOT_COMPLETED));
assertTrue(ArrayUtils.contains(actions, LocationManager.MODE_CHANGED_ACTION));
assertTrue(ArrayUtils.contains(actions, LocationManager.GPS_ENABLED_CHANGE_ACTION));
+ assertTrue(ArrayUtils.contains(actions, Intent.ACTION_USER_SWITCHED));
verify(mMockCarPropertyService).registerListener(
eq(CarSensorManager.SENSOR_TYPE_IGNITION_STATE), eq(0.0f), any());
}
@@ -166,10 +171,11 @@ public class CarLocationServiceTest {
/**
* Test that the {@link CarLocationService} parses a location from a JSON serialization and then
- * injects it into the {@link LocationManager} upon boot complete.
+ * injects it into the {@link LocationManager} upon boot complete if the system user is not
+ * headless.
*/
@Test
- public void testLoadsLocation() throws IOException, InterruptedException {
+ public void testLoadsLocationOnLockedBootComplete() throws IOException, InterruptedException {
long currentTime = System.currentTimeMillis();
long elapsedTime = SystemClock.elapsedRealtimeNanos();
long pastTime = currentTime - 60000;
@@ -181,6 +187,7 @@ public class CarLocationServiceTest {
when(mMockLocationManager.injectLocation(argument.capture())).thenReturn(true);
when(mMockContext.getFileStreamPath("location_cache.json"))
.thenReturn(mContext.getFileStreamPath(TEST_FILENAME));
+ when(mMockCarUserManagerHelper.isHeadlessSystemUser()).thenReturn(false);
mCarLocationService.onReceive(mMockContext,
new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
@@ -196,6 +203,39 @@ public class CarLocationServiceTest {
}
/**
+ * Test that the {@link CarLocationService} parses a location from a JSON seialization and then
+ * injects it into the {@link LocationManager} upon user switch if the system user is headless.
+ */
+ @Test
+ public void testLoadsLocationWithHeadlessSystemUser() throws IOException, InterruptedException {
+ long currentTime = System.currentTimeMillis();
+ long elapsedTime = SystemClock.elapsedRealtimeNanos();
+ long pastTime = currentTime - 60000;
+ writeCacheFile("{\"provider\": \"gps\", \"latitude\": 16.7666, \"longitude\": 3.0026,"
+ + "\"accuracy\":12.3, \"captureTime\": " + pastTime + "}");
+ ArgumentCaptor<Location> argument = ArgumentCaptor.forClass(Location.class);
+ when(mMockContext.getSystemService(Context.LOCATION_SERVICE))
+ .thenReturn(mMockLocationManager);
+ when(mMockLocationManager.injectLocation(argument.capture())).thenReturn(true);
+ when(mMockContext.getFileStreamPath("location_cache.json"))
+ .thenReturn(mContext.getFileStreamPath(TEST_FILENAME));
+ when(mMockCarUserManagerHelper.isHeadlessSystemUser()).thenReturn(true);
+
+ Intent userSwitchedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
+ userSwitchedIntent.putExtra(Intent.EXTRA_USER_HANDLE, 11);
+ mCarLocationService.onReceive(mMockContext, userSwitchedIntent);
+ mLatch.await();
+
+ Location location = argument.getValue();
+ assertEquals("gps", location.getProvider());
+ assertEquals(16.7666, location.getLatitude());
+ assertEquals(3.0026, location.getLongitude());
+ assertEquals(12.3f, location.getAccuracy());
+ assertTrue(location.getTime() >= currentTime);
+ assertTrue(location.getElapsedRealtimeNanos() >= elapsedTime);
+ }
+
+ /**
* Test that the {@link CarLocationService} does not inject a location if there is no location
* cache file.
*/
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 44cc0d6ae5..7f53da5655 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarUserManagerHelperTest.java
@@ -18,8 +18,12 @@ package com.android.car;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.app.ActivityManager;
import android.car.user.CarUserManagerHelper;
@@ -30,11 +34,13 @@ import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.os.Handler;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Before;
@@ -42,6 +48,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
@@ -54,10 +61,11 @@ import java.util.List;
* The following mocks are used:
* 1. {@link Context} provides system services and resources.
* 2. {@link UserManager} provides dummy users and user info.
- * 3. {@link ActivityManager} provides dummy current process user.
+ * 3. {@link ActivityManager} to verify user switch is invoked.
* 4. {@link CarUserManagerHelper.OnUsersUpdateListener} registers a listener for user updates.
*/
@RunWith(AndroidJUnit4.class)
+@SmallTest
public class CarUserManagerHelperTest {
@Mock
private Context mContext;
@@ -68,25 +76,37 @@ public class CarUserManagerHelperTest {
@Mock
private CarUserManagerHelper.OnUsersUpdateListener mTestListener;
- private CarUserManagerHelper mHelper;
+ private CarUserManagerHelper mCarUserManagerHelper;
private UserInfo mCurrentProcessUser;
private UserInfo mSystemUser;
private String mGuestUserName = "testGuest";
private String mTestUserName = "testUser";
+ private int mForegroundUserId;
+ private UserInfo mForegroundUser;
@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.
+ // We cannot rely on foreground_id != system_id, they could be the same user.
+ mForegroundUserId = ActivityManager.getCurrentUser();
+ mForegroundUser = createUserInfoForId(mForegroundUserId);
+
+ // Restore the non-headless state before every test. Individual tests can set the property
+ // to true to test the headless system user scenario.
+ SystemProperties.set("android.car.systemuser.headless", "false");
}
@Test
@@ -94,10 +114,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.
@@ -108,92 +128,67 @@ public class CarUserManagerHelperTest {
UserInfo otherUser2 = createUserInfoForId(11);
UserInfo otherUser3 = createUserInfoForId(12);
- List<UserInfo> testUsers = new ArrayList<>();
- testUsers.add(mSystemUser);
- testUsers.add(otherUser1);
- testUsers.add(otherUser2);
- testUsers.add(otherUser3);
+ mockGetUsers(mSystemUser, otherUser1, otherUser2, otherUser3);
- when(mUserManager.getUsers(true)).thenReturn(testUsers);
-
- // Should return 3 users that don't have SYSTEM USER id.
- assertThat(mHelper.getAllUsers()).hasSize(3);
- assertThat(mHelper.getAllUsers())
- .containsExactly(otherUser1, otherUser2, otherUser3);
+ assertThat(mCarUserManagerHelper.getAllUsers())
+ .containsExactly(otherUser1, otherUser2, otherUser3);
}
@Test
- public void testHeadlessUser0GetAllUsersWithActiveForegroundUser_NotReturnSystemUser() {
- SystemProperties.set("android.car.systemuser.headless", "true");
- mCurrentProcessUser = createUserInfoForId(10);
-
- UserInfo otherUser1 = createUserInfoForId(11);
- UserInfo otherUser2 = createUserInfoForId(12);
- UserInfo otherUser3 = createUserInfoForId(13);
+ public void testGetAllSwitchableUsers() {
+ // Create two non-foreground users.
+ UserInfo user1 = createUserInfoForId(mForegroundUserId + 1);
+ UserInfo user2 = createUserInfoForId(mForegroundUserId + 2);
- List<UserInfo> testUsers = new ArrayList<>();
- testUsers.add(mSystemUser);
- testUsers.add(mCurrentProcessUser);
- testUsers.add(otherUser1);
- testUsers.add(otherUser2);
- testUsers.add(otherUser3);
+ mockGetUsers(mForegroundUser, user1, user2);
- when(mUserManager.getUsers(true)).thenReturn(testUsers);
+ // Should return all non-foreground users.
+ assertThat(mCarUserManagerHelper.getAllSwitchableUsers()).containsExactly(user1, user2);
+ }
- assertThat(mHelper.getAllUsers().size()).isEqualTo(4);
- assertThat(mHelper.getAllUsers())
- .containsExactly(mCurrentProcessUser, otherUser1, otherUser2, otherUser3);
+ @Test
+ public void testGetAllPersistentUsers() {
+ // Create two non-ephemeral users.
+ UserInfo user1 = createUserInfoForId(mForegroundUserId);
+ UserInfo user2 = createUserInfoForId(mForegroundUserId + 1);
+ // Create two ephemeral users.
+ UserInfo user3 = new UserInfo(
+ /* id= */mForegroundUserId + 2, /* name = */ "user3", UserInfo.FLAG_EPHEMERAL);
+ UserInfo user4 = new UserInfo(
+ /* id= */mForegroundUserId + 3, /* name = */ "user4", UserInfo.FLAG_EPHEMERAL);
+
+ mockGetUsers(user1, user2, user3, user4);
+
+ // Should return all non-ephemeral users.
+ assertThat(mCarUserManagerHelper.getAllPersistentUsers()).containsExactly(user1, user2);
}
@Test
- public void testGetAllSwitchableUsers() {
- UserInfo user1 = createUserInfoForId(10);
+ public void testGetAllAdminUsers() {
+ // Create two admin, and two non-admin users.
+ UserInfo user1 = new UserInfo(/* id= */ 10, /* name = */ "user10", UserInfo.FLAG_ADMIN);
UserInfo user2 = createUserInfoForId(11);
UserInfo user3 = createUserInfoForId(12);
+ UserInfo user4 = new UserInfo(/* id= */ 13, /* name = */ "user13", UserInfo.FLAG_ADMIN);
- List<UserInfo> testUsers = new ArrayList<>();
- testUsers.add(mSystemUser);
- testUsers.add(user1);
- testUsers.add(user2);
- testUsers.add(user3);
-
- when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers));
-
- // Should return all 3 non-system users.
- assertThat(mHelper.getAllUsers().size())
- .isEqualTo(3);
+ mockGetUsers(user1, user2, user3, user4);
- when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(user1);
- // Should return user 10, 11 and 12.
- assertThat(mHelper.getAllSwitchableUsers().size())
- .isEqualTo(3);
- assertThat(mHelper.getAllSwitchableUsers()).contains(user1);
- assertThat(mHelper.getAllSwitchableUsers()).contains(user2);
- assertThat(mHelper.getAllSwitchableUsers()).contains(user3);
+ // Should return only admin users.
+ assertThat(mCarUserManagerHelper.getAllAdminUsers()).containsExactly(user1, user4);
}
- // Get all users for headless user 0 model should exclude system user by default.
@Test
- public void testHeadlessUser0GetAllSwitchableUsers() {
- SystemProperties.set("android.car.systemuser.headless", "true");
+ public void testGetAllUsersExceptGuests() {
+ // Create two users and a guest user.
UserInfo user1 = createUserInfoForId(10);
- UserInfo user2 = createUserInfoForId(11);
- UserInfo user3 = createUserInfoForId(12);
-
- List<UserInfo> testUsers = new ArrayList<>();
- testUsers.add(mSystemUser);
- testUsers.add(user1);
- testUsers.add(user2);
- testUsers.add(user3);
+ UserInfo user2 = createUserInfoForId(12);
+ UserInfo user3 = new UserInfo(/* id= */ 13, /* name = */ "user13", UserInfo.FLAG_GUEST);
- when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers));
+ mockGetUsers(user1, user2, user3);
- // Should return all 3 non-system users.
- assertThat(mHelper.getAllUsers()).hasSize(3);
-
- when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(user1);
- // Should return user 10, 11 and 12.
- assertThat(mHelper.getAllSwitchableUsers()).containsExactly(user1, user2, user3);
+ // Should not return guests.
+ assertThat(mCarUserManagerHelper.getAllUsersExceptGuests())
+ .containsExactly(user1, user2);
}
@Test
@@ -202,127 +197,304 @@ 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();
+
+ doReturn(true).when(mUserManager).isDemoUser();
- when(mUserManager.isDemoUser()).thenReturn(true);
- assertThat(mHelper.canCurrentProcessModifyAccounts()).isFalse();
+ 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);
+
+ assertThat(mCarUserManagerHelper.canCurrentProcessModifyAccounts()).isFalse();
+ }
+
+ @Test
+ public void testGetMaxSupportedUsers() {
+ SystemProperties.set("fw.max_users", "11");
+
+ assertThat(mCarUserManagerHelper.getMaxSupportedUsers()).isEqualTo(11);
+
+ // In headless user 0 model, we want to exclude the system user.
+ SystemProperties.set("android.car.systemuser.headless", "true");
+ assertThat(mCarUserManagerHelper.getMaxSupportedUsers()).isEqualTo(10);
+ }
+
+ @Test
+ public void testGetMaxSupportedRealUsers() {
+ SystemProperties.set("fw.max_users", "7");
+
+ // Create three managed profiles, and two normal users.
+ UserInfo user1 = createUserInfoForId(10);
+ UserInfo user2 =
+ new UserInfo(/* id= */ 11, /* name = */ "user11", UserInfo.FLAG_MANAGED_PROFILE);
+ UserInfo user3 =
+ new UserInfo(/* id= */ 12, /* name = */ "user12", UserInfo.FLAG_MANAGED_PROFILE);
+ UserInfo user4 = createUserInfoForId(13);
+ UserInfo user5 =
+ new UserInfo(/* id= */ 14, /* name = */ "user14", UserInfo.FLAG_MANAGED_PROFILE);
+
+ mockGetUsers(user1, user2, user3, user4, user5);
+
+ // Max users - # managed profiles.
+ assertThat(mCarUserManagerHelper.getMaxSupportedRealUsers()).isEqualTo(4);
+ }
+
+ @Test
+ public void testIsUserLimitReached() {
+ UserInfo user1 = createUserInfoForId(10);
+ UserInfo user2 =
+ new UserInfo(/* id= */ 11, /* name = */ "user11", UserInfo.FLAG_MANAGED_PROFILE);
+ UserInfo user3 =
+ new UserInfo(/* id= */ 12, /* name = */ "user12", UserInfo.FLAG_MANAGED_PROFILE);
+ UserInfo user4 = createUserInfoForId(13);
- when(mUserManager.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS))
- .thenReturn(true);
- assertThat(mHelper.canCurrentProcessModifyAccounts()).isFalse();
+ mockGetUsers(user1, user2, user3, user4);
+
+ SystemProperties.set("fw.max_users", "5");
+ assertThat(mCarUserManagerHelper.isUserLimitReached()).isFalse();
+
+ SystemProperties.set("fw.max_users", "4");
+ assertThat(mCarUserManagerHelper.isUserLimitReached()).isTrue();
+ }
+
+ @Test
+ public void testHeadlessSystemUser_IsUserLimitReached() {
+ SystemProperties.set("android.car.systemuser.headless", "true");
+ UserInfo user1 = createUserInfoForId(10);
+ UserInfo user2 =
+ new UserInfo(/* id= */ 11, /* name = */ "user11", UserInfo.FLAG_MANAGED_PROFILE);
+ UserInfo user3 =
+ new UserInfo(/* id= */ 12, /* name = */ "user12", UserInfo.FLAG_MANAGED_PROFILE);
+ UserInfo user4 = createUserInfoForId(13);
+
+ mockGetUsers(mSystemUser, user1, user2, user3, user4);
+
+ SystemProperties.set("fw.max_users", "6");
+ assertThat(mCarUserManagerHelper.isUserLimitReached()).isFalse();
+
+ SystemProperties.set("fw.max_users", "5");
+ assertThat(mCarUserManagerHelper.isUserLimitReached()).isTrue();
+ }
+
+ @Test
+ public void testIsUserLimitReachedIgnoresGuests() {
+ SystemProperties.set("fw.max_users", "5");
+
+ UserInfo user1 = createUserInfoForId(10);
+ UserInfo user2 =
+ new UserInfo(/* id= */ 11, /* name = */ "user11", UserInfo.FLAG_MANAGED_PROFILE);
+ UserInfo user3 =
+ new UserInfo(/* id= */ 12, /* name = */ "user12", UserInfo.FLAG_MANAGED_PROFILE);
+ UserInfo user4 = createUserInfoForId(13);
+ UserInfo user5 = new UserInfo(/* id= */ 14, /* name = */ "user14", UserInfo.FLAG_GUEST);
+ UserInfo user6 = createUserInfoForId(15);
+
+ mockGetUsers(user1, user2, user3, user4);
+ assertThat(mCarUserManagerHelper.isUserLimitReached()).isFalse();
+
+ // Add guest user. Verify it doesn't affect the limit.
+ mockGetUsers(user1, user2, user3, user4, user5);
+ assertThat(mCarUserManagerHelper.isUserLimitReached()).isFalse();
+
+ // Add normal user. Limit is reached
+ mockGetUsers(user1, user2, user3, user4, user5, user6);
+ assertThat(mCarUserManagerHelper.isUserLimitReached()).isTrue();
}
@Test
public void testCreateNewAdminUser() {
+ // Make sure current user is admin, since only admins can create other admins.
+ 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
+ public void testAdminsCanCreateAdmins() {
+ String newAdminName = "Test new admin";
+ UserInfo expectedAdmin = new UserInfo();
+ expectedAdmin.name = newAdminName;
+ doReturn(expectedAdmin).when(mUserManager).createUser(newAdminName, UserInfo.FLAG_ADMIN);
+
+ // Admins can create other admins.
+ doReturn(true).when(mUserManager).isAdminUser();
+ UserInfo actualAdmin = mCarUserManagerHelper.createNewAdminUser(newAdminName);
+ assertThat(actualAdmin).isEqualTo(expectedAdmin);
+ }
+
+ @Test
+ public void testNonAdminsCanNotCreateAdmins() {
+ String newAdminName = "Test new admin";
+ UserInfo expectedAdmin = new UserInfo();
+ expectedAdmin.name = newAdminName;
+ doReturn(expectedAdmin).when(mUserManager).createUser(newAdminName, UserInfo.FLAG_ADMIN);
+
+ // Test that non-admins cannot create new admins.
+ doReturn(false).when(mUserManager).isAdminUser(); // Current user non-admin.
+ assertThat(mCarUserManagerHelper.createNewAdminUser(newAdminName)).isNull();
+ }
+
+ @Test
+ public void testSystemUserCanCreateAdmins() {
+ String newAdminName = "Test new admin";
+ UserInfo expectedAdmin = new UserInfo();
+ expectedAdmin.name = newAdminName;
+
+ doReturn(expectedAdmin).when(mUserManager).createUser(newAdminName, UserInfo.FLAG_ADMIN);
+
+ // System user can create admins.
+ 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(mCarUserManagerHelper.removeUser(mSystemUser, mGuestUserName)).isFalse();
+ }
+
+ @Test
+ public void testAdminsCanRemoveOtherUsers() {
+ int idToRemove = mCurrentProcessUser.id + 2;
+ UserInfo userToRemove = createUserInfoForId(idToRemove);
+
+ doReturn(true).when(mUserManager).removeUser(idToRemove);
+
+ // If Admin is removing non-current, non-system user, simply calls removeUser.
+ doReturn(true).when(mUserManager).isAdminUser();
+ assertThat(mCarUserManagerHelper.removeUser(userToRemove, mGuestUserName)).isTrue();
+ verify(mUserManager).removeUser(idToRemove);
+ }
+
+ @Test
+ public void testNonAdminsCanNotRemoveOtherUsers() {
+ UserInfo otherUser = createUserInfoForId(mCurrentProcessUser.id + 2);
+
+ // Make current user non-admin.
+ doReturn(false).when(mUserManager).isAdminUser();
+
+ // Mock so that removeUser always pretends it's successful.
+ doReturn(true).when(mUserManager).removeUser(anyInt());
+
+ // If Non-Admin is trying to remove someone other than themselves, they should fail.
+ assertThat(mCarUserManagerHelper.removeUser(otherUser, mGuestUserName)).isFalse();
+ verify(mUserManager, never()).removeUser(otherUser.id);
}
@Test
- public void testRemoveUser() {
+ public void testRemoveLastActiveUser() {
// Cannot remove system user.
- assertThat(mHelper.removeUser(mSystemUser, mGuestUserName)).isFalse();
+ assertThat(mCarUserManagerHelper.removeUser(mSystemUser, mGuestUserName)).isFalse();
- // Removing non-current, non-system user, simply calls removeUser.
- UserInfo userToRemove = createUserInfoForId(mCurrentProcessUser.id + 2);
+ UserInfo adminInfo = new UserInfo(/* id= */10, "admin", UserInfo.FLAG_ADMIN);
+ mockGetUsers(adminInfo);
- mHelper.removeUser(userToRemove, mGuestUserName);
- verify(mUserManager).removeUser(mCurrentProcessUser.id + 2);
+ 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);
}
@@ -331,13 +503,107 @@ 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() {
+ doReturn(true).when(mUserManager).isAdminUser();
+ assertThat(mCarUserManagerHelper.isCurrentProcessAdminUser()).isTrue();
+
+ doReturn(false).when(mUserManager).isAdminUser();
+ assertThat(mCarUserManagerHelper.isCurrentProcessAdminUser()).isFalse();
+ }
+
+ @Test
+ public void testAssignAdminPrivileges() {
+ int userId = 30;
+ UserInfo testInfo = createUserInfoForId(userId);
+
+ // Test that non-admins cannot assign admin privileges.
+ doReturn(false).when(mUserManager).isAdminUser(); // Current user non-admin.
+ mCarUserManagerHelper.assignAdminPrivileges(testInfo);
+ verify(mUserManager, never()).setUserAdmin(userId);
+
+ // Admins can assign admin privileges.
+ doReturn(true).when(mUserManager).isAdminUser();
+ mCarUserManagerHelper.assignAdminPrivileges(testInfo);
+ verify(mUserManager).setUserAdmin(userId);
+ }
+
+ @Test
+ public void testSetUserRestriction() {
+ int userId = 20;
+ UserInfo testInfo = createUserInfoForId(userId);
+
+ mCarUserManagerHelper.setUserRestriction(
+ testInfo, UserManager.DISALLOW_ADD_USER, /* enable= */ true);
+ verify(mUserManager).setUserRestriction(
+ UserManager.DISALLOW_ADD_USER, true, UserHandle.of(userId));
+
+ mCarUserManagerHelper.setUserRestriction(
+ testInfo, UserManager.DISALLOW_REMOVE_USER, /* enable= */ false);
+ verify(mUserManager).setUserRestriction(
+ UserManager.DISALLOW_REMOVE_USER, false, UserHandle.of(userId));
+ }
+
+ @Test
+ public void testDefaultNonAdminRestrictions() {
+ String testUserName = "Test User";
+ int userId = 20;
+ UserInfo newNonAdmin = createUserInfoForId(userId);
+
+ doReturn(newNonAdmin).when(mUserManager).createUser(testUserName, /* flags= */ 0);
+
+ mCarUserManagerHelper.createNewNonAdminUser(testUserName);
+
+ verify(mUserManager).setUserRestriction(
+ UserManager.DISALLOW_FACTORY_RESET, /* enable= */ true, UserHandle.of(userId));
+ verify(mUserManager).setUserRestriction(
+ UserManager.DISALLOW_SMS, /* enable= */ false, UserHandle.of(userId));
+ verify(mUserManager).setUserRestriction(
+ UserManager.DISALLOW_OUTGOING_CALLS, /* enable= */ false, UserHandle.of(userId));
+ }
+
+ @Test
+ public void testDefaultGuestRestrictions() {
+ int guestRestrictionsExpectedCount = 7;
+
+ ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
+ mCarUserManagerHelper.initDefaultGuestRestrictions();
+
+ verify(mUserManager).setDefaultGuestRestrictions(bundleCaptor.capture());
+ Bundle guestRestrictions = bundleCaptor.getValue();
+
+ assertThat(guestRestrictions.keySet()).hasSize(guestRestrictionsExpectedCount);
+ assertThat(guestRestrictions.getBoolean(UserManager.DISALLOW_FACTORY_RESET)).isTrue();
+ assertThat(guestRestrictions.getBoolean(UserManager.DISALLOW_REMOVE_USER)).isTrue();
+ assertThat(guestRestrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS)).isTrue();
+ assertThat(guestRestrictions.getBoolean(UserManager.DISALLOW_OUTGOING_CALLS)).isTrue();
+ assertThat(guestRestrictions.getBoolean(UserManager.DISALLOW_SMS)).isTrue();
+ assertThat(guestRestrictions.getBoolean(UserManager.DISALLOW_INSTALL_APPS)).isTrue();
+ assertThat(guestRestrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS)).isTrue();
+ }
+
+ @Test
+ public void testAssigningAdminPrivilegesRemovesNonAdminRestrictions() {
+ int testUserId = 30;
+ boolean restrictionEnabled = false;
+ UserInfo testInfo = createUserInfoForId(testUserId);
+
+ // Only admins can assign privileges.
+ doReturn(true).when(mUserManager).isAdminUser();
+
+ mCarUserManagerHelper.assignAdminPrivileges(testInfo);
+
+ verify(mUserManager).setUserRestriction(
+ UserManager.DISALLOW_FACTORY_RESET, restrictionEnabled, UserHandle.of(testUserId));
+ }
+
+ @Test
public void testRegisterUserChangeReceiver() {
- mHelper.registerOnUsersUpdateListener(mTestListener);
+ mCarUserManagerHelper.registerOnUsersUpdateListener(mTestListener);
ArgumentCaptor<BroadcastReceiver> receiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
@@ -375,13 +641,148 @@ public class CarUserManagerHelperTest {
assertThat(handlerCaptor.getValue()).isNull();
// Unregister the receiver.
- mHelper.unregisterOnUsersUpdateListener();
+ mCarUserManagerHelper.unregisterOnUsersUpdateListener(mTestListener);
verify(mContext).unregisterReceiver(receiverCaptor.getValue());
}
+ @Test
+ public void testMultipleRegistrationsOfSameListener() {
+ CarUserManagerHelper.OnUsersUpdateListener listener =
+ Mockito.mock(CarUserManagerHelper.OnUsersUpdateListener.class);
+
+ ArgumentCaptor<BroadcastReceiver> receiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+
+ mCarUserManagerHelper.registerOnUsersUpdateListener(listener);
+ mCarUserManagerHelper.registerOnUsersUpdateListener(listener);
+ // Even for multiple registrations of the same listener, broadcast receiver registered once.
+ verify(mContext, times(1))
+ .registerReceiverAsUser(receiverCaptor.capture(), any(), any(), any(), any());
+
+ // Verify that calling the receiver calls the listener.
+ receiverCaptor.getValue().onReceive(mContext, new Intent());
+ verify(listener).onUsersUpdate();
+
+ // Verify that a single removal unregisters the listener.
+ mCarUserManagerHelper.unregisterOnUsersUpdateListener(listener);
+ verify(mContext).unregisterReceiver(any());
+ }
+
+ @Test
+ public void testMultipleUnregistrationsOfTheSameListener() {
+ CarUserManagerHelper.OnUsersUpdateListener listener =
+ Mockito.mock(CarUserManagerHelper.OnUsersUpdateListener.class);
+ mCarUserManagerHelper.registerOnUsersUpdateListener(listener);
+
+ // Verify that a multiple unregistrations cause only one unregister for broadcast receiver.
+ mCarUserManagerHelper.unregisterOnUsersUpdateListener(listener);
+ mCarUserManagerHelper.unregisterOnUsersUpdateListener(listener);
+ mCarUserManagerHelper.unregisterOnUsersUpdateListener(listener);
+ verify(mContext, times(1)).unregisterReceiver(any());
+ }
+
+ @Test
+ public void testUnregisterReceiverCalledAfterAllListenersUnregister() {
+ CarUserManagerHelper.OnUsersUpdateListener listener1 =
+ Mockito.mock(CarUserManagerHelper.OnUsersUpdateListener.class);
+ CarUserManagerHelper.OnUsersUpdateListener listener2 =
+ Mockito.mock(CarUserManagerHelper.OnUsersUpdateListener.class);
+
+ mCarUserManagerHelper.registerOnUsersUpdateListener(listener1);
+ mCarUserManagerHelper.registerOnUsersUpdateListener(listener2);
+
+ mCarUserManagerHelper.unregisterOnUsersUpdateListener(listener1);
+ verify(mContext, never()).unregisterReceiver(any());
+
+ mCarUserManagerHelper.unregisterOnUsersUpdateListener(listener2);
+ verify(mContext, times(1)).unregisterReceiver(any());
+ }
+
+ @Test
+ public void testRegisteringMultipleListeners() {
+ CarUserManagerHelper.OnUsersUpdateListener listener1 =
+ Mockito.mock(CarUserManagerHelper.OnUsersUpdateListener.class);
+ CarUserManagerHelper.OnUsersUpdateListener listener2 =
+ Mockito.mock(CarUserManagerHelper.OnUsersUpdateListener.class);
+ ArgumentCaptor<BroadcastReceiver> receiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+
+ mCarUserManagerHelper.registerOnUsersUpdateListener(listener1);
+ mCarUserManagerHelper.registerOnUsersUpdateListener(listener2);
+ verify(mContext, times(1))
+ .registerReceiverAsUser(receiverCaptor.capture(), any(), any(), any(), any());
+
+ // Verify that calling the receiver calls both listeners.
+ receiverCaptor.getValue().onReceive(mContext, new Intent());
+ verify(listener1).onUsersUpdate();
+ verify(listener2).onUsersUpdate();
+ }
+
+ @Test
+ public void testUnregisteringListenerStopsUpdatesForListener() {
+ CarUserManagerHelper.OnUsersUpdateListener listener1 =
+ Mockito.mock(CarUserManagerHelper.OnUsersUpdateListener.class);
+ CarUserManagerHelper.OnUsersUpdateListener listener2 =
+ Mockito.mock(CarUserManagerHelper.OnUsersUpdateListener.class);
+ ArgumentCaptor<BroadcastReceiver> receiverCaptor =
+ ArgumentCaptor.forClass(BroadcastReceiver.class);
+
+ mCarUserManagerHelper.registerOnUsersUpdateListener(listener1);
+ mCarUserManagerHelper.registerOnUsersUpdateListener(listener2);
+ verify(mContext, times(1))
+ .registerReceiverAsUser(receiverCaptor.capture(), any(), any(), any(), any());
+
+ // Unregister listener2
+ mCarUserManagerHelper.unregisterOnUsersUpdateListener(listener2);
+
+ // Verify that calling the receiver calls only one listener.
+ receiverCaptor.getValue().onReceive(mContext, new Intent());
+ verify(listener1).onUsersUpdate();
+ verify(listener2, never()).onUsersUpdate();
+ }
+
+ @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);
+
+ mCarUserManagerHelper.setLastActiveUser(
+ lastActiveUserId, /* skipGlobalSettings= */ true);
+ mockGetUsers(mSystemUser, otherUser1, otherUser2, otherUser3);
+
+ 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);
+
+ mCarUserManagerHelper.setLastActiveUser(
+ lastActiveUserId, /* skipGlobalSettings= */ true);
+ mockGetUsers(mSystemUser, otherUser1, otherUser2);
+
+ assertThat(mCarUserManagerHelper.getInitialUser()).isEqualTo(lastActiveUserId - 2);
+ }
+
private UserInfo createUserInfoForId(int id) {
UserInfo userInfo = new UserInfo();
userInfo.id = id;
return userInfo;
}
+
+ private void mockGetUsers(UserInfo... users) {
+ List<UserInfo> testUsers = new ArrayList<>();
+ for (UserInfo user: users) {
+ testUsers.add(user);
+ }
+ doReturn(testUsers).when(mUserManager).getUsers(true);
+ }
}
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 faa7bd0965..48d447bc0f 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
@@ -21,18 +21,17 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.car.user.CarUserManagerHelper;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
+import android.location.LocationManager;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.support.test.runner.AndroidJUnit4;
-import java.util.ArrayList;
-import java.util.List;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -40,6 +39,9 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* This class contains unit tests for the {@link CarUserService}.
*
@@ -60,17 +62,23 @@ public class CarUserServiceTest {
private Context mApplicationContext;
@Mock
+ private LocationManager mLocationManager;
+
+ @Mock
private CarUserManagerHelper mCarUserManagerHelper;
/**
* Initialize all of the objects with the @Mock annotation.
*/
@Before
- public void setUp() throws Exception {
+ public void setUpMocks() throws Exception {
MockitoAnnotations.initMocks(this);
- when(mMockContext.getApplicationContext()).thenReturn(mApplicationContext);
+ doReturn(mApplicationContext).when(mMockContext).getApplicationContext();
+ doReturn(mLocationManager).when(mMockContext).getSystemService(Context.LOCATION_SERVICE);
mCarUserService = new CarUserService(mMockContext, mCarUserManagerHelper);
+
+ doReturn(new ArrayList<>()).when(mCarUserManagerHelper).getAllUsers();
}
/**
@@ -83,9 +91,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);
}
/**
@@ -102,20 +111,123 @@ public class CarUserServiceTest {
*/
@Test
public void testStartsSecondaryAdminUserOnFirstRun() {
+ UserInfo admin = mockAdmin(/* adminId= */ 10);
+
+ mCarUserService.onReceive(mMockContext,
+ new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
+
+ verify(mCarUserManagerHelper).createNewAdminUser(CarUserService.OWNER_NAME);
+ verify(mCarUserManagerHelper).switchToUser(admin);
+ }
+
+ /**
+ * Test that the {@link CarUserService} disable modify account for user 0 upon first run.
+ */
+ @Test
+ public void testDisableModifyAccountsForSystemUserOnFirstRun() {
+ // Mock system user.
+ UserInfo systemUser = new UserInfo();
+ systemUser.id = UserHandle.USER_SYSTEM;
+ doReturn(systemUser).when(mCarUserManagerHelper).getSystemUserInfo();
+
+ mockAdmin(10);
+
+ mCarUserService.onReceive(mMockContext,
+ new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
+
+ verify(mCarUserManagerHelper)
+ .setUserRestriction(systemUser, UserManager.DISALLOW_MODIFY_ACCOUNTS, true);
+ }
+
+ /**
+ * Test that the {@link CarUserService} disable location service for user 0 upon first run.
+ */
+ @Test
+ public void testDisableLocationForSystemUserOnFirstRun() {
+ mockAdmin(/* adminId= */ 10);
+
+ mCarUserService.onReceive(mMockContext,
+ new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
+
+ verify(mLocationManager).setLocationEnabledForUser(
+ /* enabled= */ false, UserHandle.of(UserHandle.USER_SYSTEM));
+ }
+
+ /**
+ * Test that the {@link CarUserService} updates last active user to the first admin user
+ * on first run.
+ */
+ @Test
+ public void testUpdateLastActiveUserOnFirstRun() {
+ UserInfo admin = mockAdmin(/* adminId= */ 10);
+
+ mCarUserService.onReceive(mMockContext,
+ new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
+
+ verify(mCarUserManagerHelper)
+ .setLastActiveUser(admin.id, /* skipGlobalSetting= */ false);
+ }
+
+ /**
+ * 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(users).when(mCarUserManagerHelper.getAllUsers());
- doReturn(admin).when(mCarUserManagerHelper).createNewAdminUser(CarUserService.OWNER_NAME);
- doReturn(true).when(mCarUserManagerHelper).switchToUser(admin);
+ doReturn(secUserId).when(mCarUserManagerHelper).getInitialUser();
mCarUserService.onReceive(mMockContext,
new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
- verify(mCarUserManagerHelper).createNewAdminUser(CarUserService.OWNER_NAME);
- verify(mCarUserManagerHelper).switchToUser(admin);
+ verify(mCarUserManagerHelper).switchToUserId(secUserId);
+ }
+
+ /**
+ * Test that the {@link CarUserService} updates last active user on user switch intent.
+ */
+ @Test
+ public void testLastActiveUserUpdatedOnUserSwitch() {
+ int lastActiveUserId = 11;
+
+ Intent intent = new Intent(Intent.ACTION_USER_SWITCHED);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, lastActiveUserId);
+
+ doReturn(true).when(mCarUserManagerHelper).isPersistentUser(lastActiveUserId);
+
+ mCarUserService.onReceive(mMockContext, intent);
+
+ verify(mCarUserManagerHelper).setLastActiveUser(
+ lastActiveUserId, /* skipGlobalSetting= */ false);
+ }
+
+ /**
+ * Test that the {@link CarUserService} sets default guest restrictions on first boot.
+ */
+ @Test
+ public void testInitializeGuestRestrictionsOnFirstRun() {
+ mockAdmin(/* adminId= */ 10);
+
+ mCarUserService.onReceive(mMockContext,
+ new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED));
+
+ verify(mCarUserManagerHelper).initDefaultGuestRestrictions();
+ }
+
+ private UserInfo mockAdmin(int adminId) {
+ UserInfo admin = new UserInfo(adminId, CarUserService.OWNER_NAME, UserInfo.FLAG_ADMIN);
+ doReturn(admin).when(mCarUserManagerHelper).createNewAdminUser(CarUserService.OWNER_NAME);
+ return admin;
}
}