diff options
5 files changed, 499 insertions, 172 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java index c4ca339b39be..7d63be4fd5fe 100644 --- a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java +++ b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java @@ -41,6 +41,7 @@ public final class UserManagerHelper { private static final String TAG = "UserManagerHelper"; private final Context mContext; private final UserManager mUserManager; + private final ActivityManager mActivityManager; private OnUsersUpdateListener mUpdateListener; private final BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() { @Override @@ -52,6 +53,7 @@ public final class UserManagerHelper { public UserManagerHelper(Context context) { mContext = context; mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); + mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); } /** @@ -72,30 +74,64 @@ public final class UserManagerHelper { } /** - * Gets {@link UserInfo} for the current user. + * Gets UserInfo for the foreground user. * - * @return {@link UserInfo} for the current user. + * Concept of foreground user is relevant for the multi-user deployment. Foreground user + * corresponds to the currently "logged in" user. + * + * @return {@link UserInfo} for the foreground user. + */ + public UserInfo getForegroundUserInfo() { + return mUserManager.getUserInfo(getForegroundUserId()); + } + + /** + * @return Id of the foreground user. */ - public UserInfo getCurrentUserInfo() { - return mUserManager.getUserInfo(UserHandle.myUserId()); + public int getForegroundUserId() { + return mActivityManager.getCurrentUser(); } /** - * Gets all the other users on the system that are not the current user. + * Gets UserInfo for the user running the caller process. + * + * Differentiation between foreground user and current process user is relevant for multi-user + * deployments. * - * @return List of {@code UserInfo} for each user that is not the current user. + * Some multi-user aware components (like SystemUI) might run as a singleton - one component + * for all users. Current process user is then always the same for that component, even when + * the foreground user changes. + * + * @return {@link UserInfo} for the user running the current process. */ - public List<UserInfo> getAllUsersExcludesCurrentUser() { - List<UserInfo> others = getAllUsers(); + public UserInfo getCurrentProcessUserInfo() { + return mUserManager.getUserInfo(getCurrentProcessUserId()); + } - for (Iterator<UserInfo> iterator = others.iterator(); iterator.hasNext(); ) { - UserInfo userInfo = iterator.next(); - if (userInfo.id == UserHandle.myUserId()) { - // Remove current user from the list. - iterator.remove(); - } - } - return others; + /** + * @return Id for the user running the current process. + */ + public int getCurrentProcessUserId() { + return UserHandle.myUserId(); + } + + /** + * Gets all the other users on the system that are not the user running the current process. + * + * @return List of {@code UserInfo} for each user that is not the user running the process. + */ + public List<UserInfo> getAllUsersExcludesCurrentProcessUser() { + return getAllUsersExceptUser(getCurrentProcessUserId()); + } + + /** + * Gets all the existing users on the system that are not the currently running as the + * foreground user. + * + * @return List of {@code UserInfo} for each user that is not the foreground user. + */ + public List<UserInfo> getAllUsersExcludesForegroundUser() { + return getAllUsersExceptUser(getForegroundUserId()); } /** @@ -104,12 +140,22 @@ public final class UserManagerHelper { * @return List of {@code UserInfo} for each user that is not the system user. */ public List<UserInfo> getAllUsersExcludesSystemUser() { + return getAllUsersExceptUser(UserHandle.USER_SYSTEM); + } + + /** + * Get all the users except the one with userId passed in. + * + * @param userId of the user not to be returned. + * @return All users other than user with userId. + */ + public List<UserInfo> getAllUsersExceptUser(int userId) { List<UserInfo> others = getAllUsers(); for (Iterator<UserInfo> iterator = others.iterator(); iterator.hasNext(); ) { UserInfo userInfo = iterator.next(); - if (userIsSystemUser(userInfo)) { - // Remove system user from the list. + if (userInfo.id == userId) { + // Remove user with userId from the list. iterator.remove(); } } @@ -146,78 +192,115 @@ public final class UserManagerHelper { } /** - * Checks whether passed in user is the user that's currently logged in. + * Checks whether passed in user is the foreground user. + * + * @param userInfo User to check. + * @return {@code true} if foreground user, {@code false} otherwise. + */ + public boolean userIsForegroundUser(UserInfo userInfo) { + return getForegroundUserId() == userInfo.id; + } + + /** + * Checks whether passed in user is the user that's running the current process. * * @param userInfo User to check. - * @return {@code true} if current user, {@code false} otherwise. + * @return {@code true} if user running the process, {@code false} otherwise. + */ + public boolean userIsRunningCurrentProcess(UserInfo userInfo) { + return getCurrentProcessUserId() == userInfo.id; + } + + // Foreground user information accessors. + + /** + * Checks if the foreground user is a guest user. */ - public boolean userIsCurrentUser(UserInfo userInfo) { - return getCurrentUserInfo().id == userInfo.id; + public boolean foregroundUserIsGuestUser() { + return getForegroundUserInfo().isGuest(); } - // Current user information accessors + /** + * Return whether the foreground user has a restriction. + * + * @param restriction Restriction to check. Should be a UserManager.* restriction. + * @return Whether that restriction exists for the foreground user. + */ + public boolean foregroundUserHasUserRestriction(String restriction) { + return mUserManager.hasUserRestriction(restriction, getForegroundUserInfo().getUserHandle()); + } + + /** + * Checks if the foreground user can add new users. + */ + public boolean foregroundUserCanAddUsers() { + return !foregroundUserHasUserRestriction(UserManager.DISALLOW_ADD_USER); + } + + // Current process user information accessors /** - * Checks if the current user is a demo user. + * Checks if the calling app is running in a demo user. */ - public boolean isDemoUser() { + public boolean currentProcessRunningAsDemoUser() { return mUserManager.isDemoUser(); } /** - * Checks if the current user is a guest user. + * Checks if the calling app is running as a guest user. */ - public boolean isGuestUser() { + public boolean currentProcessRunningAsGuestUser() { return mUserManager.isGuestUser(); } /** - * Checks if the current user is the system user (User 0). + * Checks whether this process is running under the system user. */ - public boolean isSystemUser() { + public boolean currentProcessRunningAsSystemUser() { return mUserManager.isSystemUser(); } - // Current user restriction accessors + // Current process user restriction accessors /** - * Return whether the current user has a restriction. + * Return whether the user running the current process has a restriction. * * @param restriction Restriction to check. Should be a UserManager.* restriction. - * @return Whether that restriction exists for the current user. + * @return Whether that restriction exists for the user running the process. */ - public boolean hasUserRestriction(String restriction) { + public boolean currentProcessHasUserRestriction(String restriction) { return mUserManager.hasUserRestriction(restriction); } /** - * Checks if the current user can add new users. + * Checks if the user running the current process can add new users. */ - public boolean canAddUsers() { - return !hasUserRestriction(UserManager.DISALLOW_ADD_USER); + public boolean currentProcessCanAddUsers() { + return !currentProcessHasUserRestriction(UserManager.DISALLOW_ADD_USER); } /** - * Checks if the current user can remove users. + * Checks if the user running the current process can remove users. */ - public boolean canRemoveUsers() { - return !hasUserRestriction(UserManager.DISALLOW_REMOVE_USER); + public boolean currentProcessCanRemoveUsers() { + return !currentProcessHasUserRestriction(UserManager.DISALLOW_REMOVE_USER); } /** - * Checks if the current user is allowed to switch to another user. + * Checks if the user running the current process is allowed to switch to another user. */ - public boolean canSwitchUsers() { - return !hasUserRestriction(UserManager.DISALLOW_USER_SWITCH); + public boolean currentProcessCanSwitchUsers() { + return !currentProcessHasUserRestriction(UserManager.DISALLOW_USER_SWITCH); } /** - * Checks if the current user can modify accounts. Demo and Guest users cannot modify accounts - * even if the DISALLOW_MODIFY_ACCOUNTS restriction is not applied. + * Checks if the current process user can modify accounts. Demo and Guest users cannot modify + * accounts even if the DISALLOW_MODIFY_ACCOUNTS restriction is not applied. */ - public boolean canModifyAccounts() { - return !hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS) && !isDemoUser() - && !isGuestUser(); + public boolean currentProcessCanModifyAccounts() { + return !currentProcessHasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS) + && !currentProcessRunningAsDemoUser() + && !currentProcessRunningAsGuestUser(); } // User actions @@ -242,8 +325,8 @@ public final class UserManagerHelper { /** * Tries to remove the user that's passed in. System user cannot be removed. - * If the user to be removed is current user, it switches to the system user first, and then - * removes the user. + * If the user to be removed is user currently running the process, + * it switches to the system user first, and then removes the user. * * @param userInfo User to be removed * @return {@code true} if user is successfully removed, {@code false} otherwise. @@ -254,7 +337,7 @@ public final class UserManagerHelper { return false; } - if (userInfo.id == getCurrentUserInfo().id) { + if (userInfo.id == getCurrentProcessUserId()) { switchToUserId(UserHandle.USER_SYSTEM); } @@ -267,7 +350,7 @@ public final class UserManagerHelper { * @param userInfo User to switch to. */ public void switchToUser(UserInfo userInfo) { - if (userInfo.id == getCurrentUserInfo().id) { + if (userInfo.id == getForegroundUserId()) { return; } @@ -276,15 +359,6 @@ public final class UserManagerHelper { return; } - if (UserManager.isGuestUserEphemeral()) { - // If switching from guest, we want to bring up the guest exit dialog instead of - // switching - UserInfo currUserInfo = getCurrentUserInfo(); - if (currUserInfo != null && currUserInfo.isGuest()) { - return; - } - } - switchToUserId(userInfo.id); } @@ -366,9 +440,7 @@ public final class UserManagerHelper { private void switchToUserId(int id) { try { - final ActivityManager am = (ActivityManager) - mContext.getSystemService(Context.ACTIVITY_SERVICE); - am.switchUser(id); + mActivityManager.switchUser(id); } catch (Exception e) { Log.e(TAG, "Couldn't switch user.", e); } @@ -389,4 +461,3 @@ public final class UserManagerHelper { void onUsersUpdate(); } } - diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java index 3f1fcbb2966b..c4159acc0c52 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/UserManagerHelperTest.java @@ -58,7 +58,7 @@ public class UserManagerHelperTest { private UserManagerHelper.OnUsersUpdateListener mTestListener; private UserManagerHelper mHelper; - private UserInfo mCurrentUser; + private UserInfo mCurrentProcessUser; private UserInfo mSystemUser; @Before @@ -70,13 +70,13 @@ public class UserManagerHelperTest { .thenReturn(InstrumentationRegistry.getTargetContext().getResources()); mHelper = new UserManagerHelper(mContext); - mCurrentUser = createUserInfoForId(UserHandle.myUserId()); + mCurrentProcessUser = createUserInfoForId(UserHandle.myUserId()); mSystemUser = createUserInfoForId(UserHandle.USER_SYSTEM); - when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(mCurrentUser); + when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(mCurrentProcessUser); } @Test - public void testUserIsSystemUser() { + public void userIsSystemUser() { UserInfo testInfo = new UserInfo(); testInfo.id = UserHandle.USER_SYSTEM; @@ -87,57 +87,55 @@ public class UserManagerHelperTest { } @Test - public void testGetAllUsersExcludesCurrentUser() { - int currentUser = UserHandle.myUserId(); - - UserInfo otherUser1 = createUserInfoForId(currentUser + 1); - UserInfo otherUser2 = createUserInfoForId(currentUser - 1); - UserInfo otherUser3 = createUserInfoForId(currentUser + 2); + public void getAllUsersExcludesSystemUser() { + UserInfo otherUser1 = createUserInfoForId(10); + UserInfo otherUser2 = createUserInfoForId(11); + UserInfo otherUser3 = createUserInfoForId(12); List<UserInfo> testUsers = new ArrayList<>(); testUsers.add(otherUser1); testUsers.add(otherUser2); - testUsers.add(mCurrentUser); + testUsers.add(mSystemUser); testUsers.add(otherUser3); when(mUserManager.getUsers(true)).thenReturn(testUsers); - // Should return 3 users that don't have currentUser id. - assertThat(mHelper.getAllUsersExcludesCurrentUser().size()).isEqualTo(3); - // Should not contain current user. - assertThat(mHelper.getAllUsersExcludesCurrentUser()).doesNotContain(mCurrentUser); - // Should contain non-current users. - assertThat(mHelper.getAllUsersExcludesCurrentUser()).contains(otherUser1); - assertThat(mHelper.getAllUsersExcludesCurrentUser()).contains(otherUser2); - assertThat(mHelper.getAllUsersExcludesCurrentUser()).contains(otherUser3); + // Should return 3 users that don't have SYSTEM USER id. + assertThat(mHelper.getAllUsersExcludesSystemUser()).hasSize(3); + assertThat(mHelper.getAllUsersExcludesSystemUser()) + .containsExactly(otherUser1, otherUser2, otherUser3); } @Test - public void testGetAllUsersExcludesSystemUser() { - UserInfo otherUser1 = createUserInfoForId(10); - UserInfo otherUser2 = createUserInfoForId(11); - UserInfo otherUser3 = createUserInfoForId(12); + public void getAllUsersExceptUser() { + UserInfo user1 = createUserInfoForId(10); + UserInfo user2 = createUserInfoForId(10); + UserInfo user3 = createUserInfoForId(12); List<UserInfo> testUsers = new ArrayList<>(); - testUsers.add(otherUser1); - testUsers.add(otherUser2); - testUsers.add(mSystemUser); - testUsers.add(otherUser3); + testUsers.add(user1); + testUsers.add(user2); + testUsers.add(user3); - when(mUserManager.getUsers(true)).thenReturn(testUsers); + when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers)); - // Should return 3 users that don't have SYSTEM USER id. - assertThat(mHelper.getAllUsersExcludesSystemUser().size()).isEqualTo(3); - // Should not contain system user. - assertThat(mHelper.getAllUsersExcludesSystemUser()).doesNotContain(mSystemUser); - // Should contain non-system users. - assertThat(mHelper.getAllUsersExcludesSystemUser()).contains(otherUser1); - assertThat(mHelper.getAllUsersExcludesSystemUser()).contains(otherUser2); - assertThat(mHelper.getAllUsersExcludesSystemUser()).contains(otherUser3); + // Should return all 3 users. + assertThat(mHelper.getAllUsersExceptUser(9).size()).isEqualTo(3); + + // Should return only user 12. + assertThat(mHelper.getAllUsersExceptUser(10).size()).isEqualTo(1); + assertThat(mHelper.getAllUsersExceptUser(10)).contains(user3); + + when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers)); + + // Should drop user 12. + assertThat(mHelper.getAllUsersExceptUser(12).size()).isEqualTo(2); + assertThat(mHelper.getAllUsersExceptUser(12)).contains(user1); + assertThat(mHelper.getAllUsersExceptUser(12)).contains(user2); } @Test - public void testGetAllUsers() { + public void getAllUsers() { int currentUser = UserHandle.myUserId(); UserInfo otherUser1 = createUserInfoForId(currentUser + 1); @@ -147,21 +145,18 @@ public class UserManagerHelperTest { List<UserInfo> testUsers = new ArrayList<>(); testUsers.add(otherUser1); testUsers.add(otherUser2); - testUsers.add(mCurrentUser); + testUsers.add(mCurrentProcessUser); testUsers.add(otherUser3); when(mUserManager.getUsers(true)).thenReturn(testUsers); - // Should return 3 users that don't have currentUser id. assertThat(mHelper.getAllUsers().size()).isEqualTo(4); - assertThat(mHelper.getAllUsers()).contains(mCurrentUser); - assertThat(mHelper.getAllUsers()).contains(otherUser1); - assertThat(mHelper.getAllUsers()).contains(otherUser2); - assertThat(mHelper.getAllUsers()).contains(otherUser3); + assertThat(mHelper.getAllUsers()) + .containsExactly(mCurrentProcessUser, otherUser1, otherUser2, otherUser3); } @Test - public void testUserCanBeRemoved() { + public void userCanBeRemoved() { UserInfo testInfo = new UserInfo(); // System user cannot be removed. @@ -173,71 +168,59 @@ public class UserManagerHelperTest { } @Test - public void testUserIsCurrentUser() { - UserInfo testInfo = new UserInfo(); - - // System user cannot be removed. - testInfo.id = UserHandle.myUserId(); - assertThat(mHelper.userIsCurrentUser(testInfo)).isTrue(); - - testInfo.id = UserHandle.myUserId() + 2; - assertThat(mHelper.userIsCurrentUser(testInfo)).isFalse(); - } - - @Test - public void testCanAddUsers() { + public void currentProcessCanAddUsers() { when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(false); - assertThat(mHelper.canAddUsers()).isTrue(); + assertThat(mHelper.currentProcessCanAddUsers()).isTrue(); when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(true); - assertThat(mHelper.canAddUsers()).isFalse(); + assertThat(mHelper.currentProcessCanAddUsers()).isFalse(); } @Test - public void testCanRemoveUsers() { + public void currentProcessCanRemoveUsers() { when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(false); - assertThat(mHelper.canRemoveUsers()).isTrue(); + assertThat(mHelper.currentProcessCanRemoveUsers()).isTrue(); when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(true); - assertThat(mHelper.canRemoveUsers()).isFalse(); + assertThat(mHelper.currentProcessCanRemoveUsers()).isFalse(); } @Test - public void testCanSwitchUsers() { + public void currentProcessCanSwitchUsers() { when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false); - assertThat(mHelper.canSwitchUsers()).isTrue(); + assertThat(mHelper.currentProcessCanSwitchUsers()).isTrue(); when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true); - assertThat(mHelper.canSwitchUsers()).isFalse(); + assertThat(mHelper.currentProcessCanSwitchUsers()).isFalse(); } @Test - public void testGuestCannotModifyAccounts() { - assertThat(mHelper.canModifyAccounts()).isTrue(); + public void currentProcessRunningAsGuestCannotModifyAccounts() { + assertThat(mHelper.currentProcessCanModifyAccounts()).isTrue(); when(mUserManager.isGuestUser()).thenReturn(true); - assertThat(mHelper.canModifyAccounts()).isFalse(); + assertThat(mHelper.currentProcessCanModifyAccounts()).isFalse(); } @Test - public void testDemoUserCannotModifyAccounts() { - assertThat(mHelper.canModifyAccounts()).isTrue(); + public void currentProcessRunningAsDemoUserCannotModifyAccounts() { + assertThat(mHelper.currentProcessCanModifyAccounts()).isTrue(); when(mUserManager.isDemoUser()).thenReturn(true); - assertThat(mHelper.canModifyAccounts()).isFalse(); + assertThat(mHelper.currentProcessCanModifyAccounts()).isFalse(); } @Test - public void testUserWithDisallowModifyAccountsRestrictionCannotModifyAccounts() { - assertThat(mHelper.canModifyAccounts()).isTrue(); + public void currentProcessWithDisallowModifyAccountsRestrictionCannotModifyAccounts() { + assertThat(mHelper.currentProcessCanModifyAccounts()).isTrue(); when(mUserManager.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) .thenReturn(true); - assertThat(mHelper.canModifyAccounts()).isFalse(); + assertThat(mHelper.currentProcessCanModifyAccounts()).isFalse(); } @Test - public void testCreateNewUser() { + public void createNewUser() { // Verify createUser on UserManager gets called. mHelper.createNewUser("Test User"); verify(mUserManager).createUser("Test User", 0); @@ -252,52 +235,36 @@ public class UserManagerHelperTest { } @Test - public void testRemoveUser() { + public void removeUser() { // Cannot remove system user. assertThat(mHelper.removeUser(mSystemUser)).isFalse(); // Removing non-current, non-system user, simply calls removeUser. - UserInfo userToRemove = createUserInfoForId(mCurrentUser.id + 2); - mHelper.removeUser(userToRemove); - verify(mUserManager).removeUser(mCurrentUser.id + 2); - } + UserInfo userToRemove = createUserInfoForId(mCurrentProcessUser.id + 2); - @Test - public void testSwitchToUser() { - // Switching to current user doesn't do anything. - mHelper.switchToUser(mCurrentUser); - verify(mActivityManager, never()).switchUser(mCurrentUser.id); - - // Switching to Guest calls createGuest. - UserInfo guestInfo = new UserInfo(mCurrentUser.id + 1, "Test Guest", UserInfo.FLAG_GUEST); - mHelper.switchToUser(guestInfo); - verify(mUserManager).createGuest(mContext, "Test Guest"); - - // Switching to non-current, non-guest user, simply calls switchUser. - UserInfo userToSwitchTo = new UserInfo(mCurrentUser.id + 5, "Test User", 0); - mHelper.switchToUser(userToSwitchTo); - verify(mActivityManager).switchUser(mCurrentUser.id + 5); + mHelper.removeUser(userToRemove); + verify(mUserManager).removeUser(mCurrentProcessUser.id + 2); } @Test - public void testSwitchToGuest() { + public void switchToGuest() { mHelper.switchToGuest("Test Guest"); verify(mUserManager).createGuest(mContext, "Test Guest"); - UserInfo guestInfo = new UserInfo(mCurrentUser.id + 2, "Test Guest", UserInfo.FLAG_GUEST); + UserInfo guestInfo = new UserInfo(21, "Test Guest", UserInfo.FLAG_GUEST); when(mUserManager.createGuest(mContext, "Test Guest")).thenReturn(guestInfo); mHelper.switchToGuest("Test Guest"); - verify(mActivityManager).switchUser(mCurrentUser.id + 2); + verify(mActivityManager).switchUser(21); } @Test - public void testGetUserIcon() { - mHelper.getUserIcon(mCurrentUser); - verify(mUserManager).getUserIcon(mCurrentUser.id); + public void getUserIcon() { + mHelper.getUserIcon(mCurrentProcessUser); + verify(mUserManager).getUserIcon(mCurrentProcessUser.id); } @Test - public void testScaleUserIcon() { + public void scaleUserIcon() { Bitmap fakeIcon = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); Drawable scaledIcon = mHelper.scaleUserIcon(fakeIcon, 300); assertThat(scaledIcon.getIntrinsicWidth()).isEqualTo(300); @@ -305,14 +272,14 @@ public class UserManagerHelperTest { } @Test - public void testSetUserName() { - UserInfo testInfo = createUserInfoForId(mCurrentUser.id + 3); + public void setUserName() { + UserInfo testInfo = createUserInfoForId(mCurrentProcessUser.id + 3); mHelper.setUserName(testInfo, "New Test Name"); - verify(mUserManager).setUserName(mCurrentUser.id + 3, "New Test Name"); + verify(mUserManager).setUserName(mCurrentProcessUser.id + 3, "New Test Name"); } @Test - public void testRegisterUserChangeReceiver() { + public void registerUserChangeReceiver() { mHelper.registerOnUsersUpdateListener(mTestListener); ArgumentCaptor<BroadcastReceiver> receiverCaptor = diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowActivityManager.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowActivityManager.java new file mode 100644 index 000000000000..4a8ef1e5d17c --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowActivityManager.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.testutils.shadow; + +import android.app.ActivityManager; + +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.annotation.Resetter; +import org.robolectric.shadow.api.Shadow; + +@Implements(ActivityManager.class) +public class ShadowActivityManager { + private static int sCurrentUserId = 0; + private int mUserSwitchedTo = -1; + + @Resetter + public void reset() { + sCurrentUserId = 0; + mUserSwitchedTo = 0; + } + + @Implementation + public static int getCurrentUser() { + return sCurrentUserId; + } + + @Implementation + public boolean switchUser(int userId) { + mUserSwitchedTo = userId; + return true; + } + + public boolean getSwitchUserCalled() { + return mUserSwitchedTo != -1; + } + + public int getUserSwitchedTo() { + return mUserSwitchedTo; + } + + public static void setCurrentUser(int userId) { + sCurrentUserId = userId; + } + + public static ShadowActivityManager getShadow() { + return (ShadowActivityManager) Shadow.extract( + RuntimeEnvironment.application.getSystemService(ActivityManager.class)); + } +} diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java new file mode 100644 index 000000000000..f2ea3a4a3d87 --- /dev/null +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/UserManagerHelperRoboTest.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settingslib.users; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.ActivityManager; + +import android.content.Context; +import android.content.pm.UserInfo; +import android.os.UserHandle; +import android.os.UserManager; + +import com.android.settingslib.testutils.shadow.ShadowActivityManager; +import com.android.settingslib.SettingsLibRobolectricTestRunner; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.annotation.Resetter; + +import java.util.ArrayList; +import java.util.List; + +@RunWith(SettingsLibRobolectricTestRunner.class) +@Config(shadows = { ShadowActivityManager.class, UserManagerHelperRoboTest.ShadowUserHandle.class}) +public class UserManagerHelperRoboTest { + @Mock + private Context mContext; + @Mock + private UserManager mUserManager; + + private UserManagerHelper mHelper; + + @Before + public void setUpMocksAndUserManagerHelper() { + MockitoAnnotations.initMocks(this); + when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); + when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn( + RuntimeEnvironment.application.getSystemService(ActivityManager.class)); + mHelper = new UserManagerHelper(mContext); + } + + @After + public void tearDown() { + ShadowActivityManager.getShadow().reset(); + } + + @Test + public void getForegroundUserId() { + ShadowActivityManager.setCurrentUser(15); + assertThat(mHelper.getForegroundUserId()).isEqualTo(15); + } + + @Test + public void getForegroundUserInfo() { + ShadowActivityManager.setCurrentUser(17); + when(mUserManager.getUserInfo(ShadowActivityManager.getCurrentUser())) + .thenReturn(createUserInfoForId(ShadowActivityManager.getCurrentUser())); + assertThat(mHelper.getForegroundUserInfo().id).isEqualTo(17); + } + + @Test + public void getCurrentProcessUserId() { + ShadowUserHandle.setUid(11); + assertThat(mHelper.getCurrentProcessUserId()).isEqualTo(11); + } + + @Test + public void getCurrentProcessUserInfo() { + ShadowUserHandle.setUid(12); + when(mUserManager.getUserInfo(UserHandle.myUserId())) + .thenReturn(createUserInfoForId(UserHandle.myUserId())); + assertThat(mHelper.getCurrentProcessUserInfo().id).isEqualTo(12); + } + + @Test + public void getAllUsersExcludesCurrentProcessUser() { + ShadowUserHandle.setUid(12); + UserInfo currentProcessUser = createUserInfoForId(12); + + UserInfo otherUser1 = createUserInfoForId(13); + UserInfo otherUser2 = createUserInfoForId(11); + UserInfo otherUser3 = createUserInfoForId(14); + + List<UserInfo> testUsers = new ArrayList<>(); + testUsers.add(otherUser1); + testUsers.add(otherUser2); + testUsers.add(currentProcessUser); + testUsers.add(otherUser3); + + when(mUserManager.getUsers(true)).thenReturn(testUsers); + + // Should return 3 users that don't have currentProcessUser id. + assertThat(mHelper.getAllUsersExcludesCurrentProcessUser()).hasSize(3); + assertThat(mHelper.getAllUsersExcludesCurrentProcessUser()) + .containsExactly(otherUser1, otherUser2, otherUser3); + } + + @Test + public void getAllUsersExcludesForegroundUser() { + ShadowActivityManager.setCurrentUser(17); + UserInfo foregroundUser = createUserInfoForId(17); + + UserInfo otherUser1 = createUserInfoForId(11); + UserInfo otherUser2 = createUserInfoForId(18); + UserInfo otherUser3 = createUserInfoForId(16); + + List<UserInfo> testUsers = new ArrayList<>(); + testUsers.add(otherUser1); + testUsers.add(otherUser2); + testUsers.add(foregroundUser); + testUsers.add(otherUser3); + + when(mUserManager.getUsers(true)).thenReturn(testUsers); + + // Should return 3 users that don't have foregroundUser id. + assertThat(mHelper.getAllUsersExcludesForegroundUser()).hasSize(3); + assertThat(mHelper.getAllUsersExcludesForegroundUser()) + .containsExactly(otherUser1, otherUser2, otherUser3); + } + + @Test + public void userIsForegroundUser() { + ShadowActivityManager.setCurrentUser(10); + assertThat(mHelper.userIsForegroundUser(createUserInfoForId(10))).isTrue(); + assertThat(mHelper.userIsForegroundUser(createUserInfoForId(11))).isFalse(); + + ShadowActivityManager.setCurrentUser(11); + assertThat(mHelper.userIsForegroundUser(createUserInfoForId(11))).isTrue(); + } + + @Test + public void userIsRunningCurrentProcess() { + ShadowUserHandle.setUid(10); + assertThat(mHelper.userIsRunningCurrentProcess(createUserInfoForId(10))).isTrue(); + assertThat(mHelper.userIsRunningCurrentProcess(createUserInfoForId(11))).isFalse(); + + ShadowUserHandle.setUid(11); + assertThat(mHelper.userIsRunningCurrentProcess(createUserInfoForId(11))).isTrue(); + } + + @Test + public void removingCurrentProcessUserSwitchesToSystemUser() { + // Set currentProcess user to be user 10. + ShadowUserHandle.setUid(10); + + // Removing a currentProcess user, calls "switch" to system user + mHelper.removeUser(createUserInfoForId(10)); + assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isTrue(); + assertThat(ShadowActivityManager.getShadow().getUserSwitchedTo()).isEqualTo(0); + + verify(mUserManager).removeUser(10); + } + + @Test + public void switchToUser() { + ShadowActivityManager.setCurrentUser(20); + + // Switching to foreground user doesn't do anything. + mHelper.switchToUser(createUserInfoForId(20)); + assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isFalse(); + + // Switching to Guest calls createGuest. + UserInfo guestInfo = new UserInfo(21, "Test Guest", UserInfo.FLAG_GUEST); + mHelper.switchToUser(guestInfo); + verify(mUserManager).createGuest(mContext, "Test Guest"); + + // Switching to non-current, non-guest user, simply calls switchUser. + UserInfo userToSwitchTo = new UserInfo(22, "Test User", 0); + mHelper.switchToUser(userToSwitchTo); + assertThat(ShadowActivityManager.getShadow().getSwitchUserCalled()).isTrue(); + assertThat(ShadowActivityManager.getShadow().getUserSwitchedTo()).isEqualTo(22); + } + + private UserInfo createUserInfoForId(int id) { + UserInfo userInfo = new UserInfo(); + userInfo.id = id; + return userInfo; + } + + @Implements(UserHandle.class) + public static class ShadowUserHandle { + private static int sUid = 0; // SYSTEM by default + + public static void setUid(int uid) { + sUid = uid; + } + + @Implementation + public static int myUserId() { + return sUid; + } + + @Resetter + public static void reset() { + sUid = 0; + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java index e09a36030cd7..9c9d3eefedb1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java @@ -109,12 +109,12 @@ public class UserGridRecyclerView extends RecyclerView implements } // Add guest user record if the current user is not a guest - if (!mUserManagerHelper.isGuestUser()) { + if (!mUserManagerHelper.foregroundUserIsGuestUser()) { userRecords.add(addGuestUserRecord()); } // Add add user record if the current user can add users - if (mUserManagerHelper.canAddUsers()) { + if (mUserManagerHelper.foregroundUserCanAddUsers()) { userRecords.add(addUserRecord()); } |