1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.users; 18 19 import static android.os.UserManager.SWITCHABILITY_STATUS_OK; 20 import static android.os.UserManager.SWITCHABILITY_STATUS_USER_IN_CALL; 21 import static android.os.UserManager.SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.mockito.ArgumentMatchers.any; 26 import static org.mockito.ArgumentMatchers.anyInt; 27 import static org.mockito.ArgumentMatchers.anyString; 28 import static org.mockito.ArgumentMatchers.eq; 29 import static org.mockito.ArgumentMatchers.notNull; 30 import static org.mockito.Mockito.doNothing; 31 import static org.mockito.Mockito.doReturn; 32 import static org.mockito.Mockito.mock; 33 import static org.mockito.Mockito.never; 34 import static org.mockito.Mockito.spy; 35 import static org.mockito.Mockito.times; 36 import static org.mockito.Mockito.verify; 37 import static org.robolectric.Shadows.shadowOf; 38 39 import android.app.settings.SettingsEnums; 40 import android.content.ComponentName; 41 import android.content.Context; 42 import android.content.Intent; 43 import android.content.SharedPreferences; 44 import android.content.pm.PackageManager; 45 import android.content.pm.ResolveInfo; 46 import android.content.pm.UserInfo; 47 import android.graphics.Bitmap; 48 import android.graphics.drawable.Drawable; 49 import android.os.Bundle; 50 import android.os.Looper; 51 import android.os.UserHandle; 52 import android.os.UserManager; 53 import android.provider.Settings; 54 import android.text.SpannableStringBuilder; 55 import android.view.Menu; 56 import android.view.MenuInflater; 57 import android.view.MenuItem; 58 59 import androidx.fragment.app.FragmentActivity; 60 import androidx.preference.Preference; 61 import androidx.preference.PreferenceCategory; 62 import androidx.preference.PreferenceManager; 63 import androidx.preference.PreferenceScreen; 64 65 import com.android.settings.SettingsActivity; 66 import com.android.settings.SubSettings; 67 import com.android.settings.testutils.shadow.SettingsShadowResources; 68 import com.android.settings.testutils.shadow.ShadowDevicePolicyManager; 69 import com.android.settings.testutils.shadow.ShadowUserManager; 70 import com.android.settingslib.RestrictedLockUtils; 71 import com.android.settingslib.RestrictedPreference; 72 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 73 import com.android.settingslib.search.SearchIndexableRaw; 74 75 import org.junit.After; 76 import org.junit.Before; 77 import org.junit.Ignore; 78 import org.junit.Test; 79 import org.junit.runner.RunWith; 80 import org.mockito.AdditionalMatchers; 81 import org.mockito.ArgumentCaptor; 82 import org.mockito.Mock; 83 import org.mockito.MockitoAnnotations; 84 import org.robolectric.RobolectricTestRunner; 85 import org.robolectric.RuntimeEnvironment; 86 import org.robolectric.android.controller.ActivityController; 87 import org.robolectric.annotation.Config; 88 import org.robolectric.shadows.ShadowIntent; 89 import org.robolectric.util.ReflectionHelpers; 90 91 import java.util.ArrayList; 92 import java.util.Arrays; 93 import java.util.Collections; 94 import java.util.List; 95 96 @RunWith(RobolectricTestRunner.class) 97 @Config(shadows = { 98 ShadowUserManager.class, 99 ShadowDevicePolicyManager.class, 100 SettingsShadowResources.class, 101 com.android.settings.testutils.shadow.ShadowFragment.class, 102 }) 103 public class UserSettingsTest { 104 105 private static final String KEY_USER_GUEST = "user_guest"; 106 private static final String KEY_ALLOW_MULTIPLE_USERS = "allow_multiple_users"; 107 private static final String KEY_USER_SETTINGS_SCREEN = "user_settings_screen"; 108 private static final int ACTIVE_USER_ID = 0; 109 private static final int INACTIVE_ADMIN_USER_ID = 1; 110 private static final int INACTIVE_SECONDARY_USER_ID = 14; 111 private static final int INACTIVE_RESTRICTED_USER_ID = 21; 112 private static final int INACTIVE_GUEST_USER_ID = 23; 113 private static final int MANAGED_USER_ID = 11; 114 private static final String ADMIN_USER_NAME = "Owner"; 115 private static final String SECONDARY_USER_NAME = "Tom"; 116 private static final String RESTRICTED_USER_NAME = "Bob"; 117 private static final String GUEST_USER_NAME = "Guest"; 118 private static final String MANAGED_USER_NAME = "Work profile"; 119 private int mProvisionedBackupValue; 120 121 @Mock 122 private Drawable mDefaultIconDrawable; 123 @Mock 124 private PreferenceManager mMockPreferenceManager; 125 @Mock 126 private UserPreference mMePreference; 127 @Mock 128 private RestrictedPreference mAddUserPreference; 129 @Mock 130 private RestrictedPreference mAddSupervisedUserPreference; 131 @Mock 132 private RestrictedPreference mAddGuestPreference; 133 @Mock 134 private UserManager mUserManager; 135 @Mock 136 private PackageManager mPackageManager; 137 @Mock 138 private MetricsFeatureProvider mMetricsFeatureProvider; 139 140 private FragmentActivity mActivity; 141 private Context mContext; 142 private UserSettings mFragment; 143 private UserCapabilities mUserCapabilities; 144 145 @Before setUp()146 public void setUp() { 147 MockitoAnnotations.initMocks(this); 148 mActivity = spy(ActivityController.of(new FragmentActivity()).get()); 149 mContext = spy(RuntimeEnvironment.application); 150 mUserCapabilities = UserCapabilities.create(mContext); 151 mUserCapabilities.mUserSwitcherEnabled = true; 152 153 mFragment = spy(new UserSettings()); 154 ReflectionHelpers.setField(mFragment, "mAddUserWhenLockedPreferenceController", 155 mock(AddUserWhenLockedPreferenceController.class)); 156 ReflectionHelpers.setField(mFragment, "mGuestTelephonyPreferenceController", 157 mock(GuestTelephonyPreferenceController.class)); 158 ReflectionHelpers.setField(mFragment, "mMultiUserTopIntroPreferenceController", 159 mock(MultiUserTopIntroPreferenceController.class)); 160 ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager); 161 ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities); 162 ReflectionHelpers.setField(mFragment, "mDefaultIconDrawable", mDefaultIconDrawable); 163 ReflectionHelpers.setField(mFragment, "mAddingUser", false); 164 ReflectionHelpers.setField(mFragment, "mMetricsFeatureProvider", mMetricsFeatureProvider); 165 ReflectionHelpers.setField(mFragment, "mRemoveGuestOnExitPreferenceController", 166 mock(RemoveGuestOnExitPreferenceController.class)); 167 168 doReturn(mUserManager).when(mActivity).getSystemService(UserManager.class); 169 doReturn(mPackageManager).when(mActivity).getPackageManager(); 170 171 doReturn(mActivity).when(mFragment).getActivity(); 172 doReturn(mContext).when(mFragment).getContext(); 173 doReturn(mMockPreferenceManager).when(mFragment).getPreferenceManager(); 174 doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); 175 doReturn(mPackageManager).when(mContext).getPackageManager(); 176 177 mProvisionedBackupValue = Settings.Global.getInt(mContext.getContentResolver(), 178 Settings.Global.DEVICE_PROVISIONED, 0); 179 Settings.Global.putInt(mContext.getContentResolver(), 180 Settings.Global.DEVICE_PROVISIONED, 1); //default state 181 182 final SharedPreferences prefs = mock(SharedPreferences.class); 183 184 doReturn(prefs).when(mMockPreferenceManager).getSharedPreferences(); 185 doReturn(mContext).when(mMockPreferenceManager).getContext(); 186 doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen(); 187 doReturn(ACTIVE_USER_ID).when(mContext).getUserId(); 188 189 mFragment.mMePreference = mMePreference; 190 mFragment.mAddUser = mAddUserPreference; 191 mFragment.mAddSupervisedUser = mAddSupervisedUserPreference; 192 mFragment.mAddGuest = mAddGuestPreference; 193 mFragment.mUserListCategory = mock(PreferenceCategory.class); 194 mFragment.mGuestUserCategory = mock(PreferenceCategory.class); 195 mFragment.mGuestCategory = mock(PreferenceCategory.class); 196 mFragment.mGuestResetPreference = mock(Preference.class); 197 mFragment.mGuestExitPreference = mock(Preference.class); 198 } 199 200 @After tearDown()201 public void tearDown() { 202 Settings.Global.putInt(mContext.getContentResolver(), 203 Settings.Global.DEVICE_PROVISIONED, mProvisionedBackupValue); 204 SettingsShadowResources.reset(); 205 } 206 207 @Test testAssignDefaultPhoto_ContextNull_ReturnFalseAndNotCrash()208 public void testAssignDefaultPhoto_ContextNull_ReturnFalseAndNotCrash() { 209 // Should not crash here 210 assertThat(UserSettings.assignDefaultPhoto(null, ACTIVE_USER_ID)).isFalse(); 211 } 212 213 @Test testGetRawDataToIndex_returnAllIndexablePreferences()214 public void testGetRawDataToIndex_returnAllIndexablePreferences() { 215 String[] expectedKeys = {KEY_ALLOW_MULTIPLE_USERS, KEY_USER_SETTINGS_SCREEN}; 216 List<String> keysResultList = new ArrayList<>(); 217 ShadowUserManager.getShadow().setSupportsMultipleUsers(true); 218 List<SearchIndexableRaw> rawData = 219 UserSettings.SEARCH_INDEX_DATA_PROVIDER.getRawDataToIndex(mContext, true); 220 221 for (SearchIndexableRaw rawDataItem : rawData) { 222 keysResultList.add(rawDataItem.key); 223 } 224 225 assertThat(keysResultList).containsExactly(expectedKeys); 226 } 227 228 @Test testAssignDefaultPhoto_hasDefaultUserIconSize()229 public void testAssignDefaultPhoto_hasDefaultUserIconSize() { 230 doReturn(mUserManager).when(mContext).getSystemService(Context.USER_SERVICE); 231 int size = 100; 232 try { 233 SettingsShadowResources.overrideResource( 234 com.android.internal.R.dimen.user_icon_size, 235 size); 236 assertThat(UserSettings.assignDefaultPhoto(mContext, ACTIVE_USER_ID)).isTrue(); 237 238 int pxSize = mContext.getResources() 239 .getDimensionPixelSize(com.android.internal.R.dimen.user_icon_size); 240 241 ArgumentCaptor<Bitmap> captor = ArgumentCaptor.forClass(Bitmap.class); 242 verify(mUserManager).setUserIcon(eq(ACTIVE_USER_ID), captor.capture()); 243 Bitmap bitmap = captor.getValue(); 244 assertThat(bitmap.getWidth()).isEqualTo(pxSize); 245 assertThat(bitmap.getHeight()).isEqualTo(pxSize); 246 } finally { 247 SettingsShadowResources.reset(); 248 } 249 } 250 251 @Test testExitGuest_ShouldLogAction()252 public void testExitGuest_ShouldLogAction() { 253 mUserCapabilities.mIsGuest = true; 254 mFragment.clearAndExitGuest(); 255 verify(mMetricsFeatureProvider).action(any(), 256 eq(SettingsEnums.ACTION_USER_GUEST_EXIT_CONFIRMED)); 257 } 258 259 @Test testExitGuestWhenNotGuest_ShouldNotLogAction()260 public void testExitGuestWhenNotGuest_ShouldNotLogAction() { 261 mUserCapabilities.mIsGuest = false; 262 mFragment.clearAndExitGuest(); 263 verify(mMetricsFeatureProvider, never()).action(any(), 264 eq(SettingsEnums.ACTION_USER_GUEST_EXIT_CONFIRMED)); 265 } 266 267 @Test withDisallowRemoveUser_ShouldDisableRemoveUser()268 public void withDisallowRemoveUser_ShouldDisableRemoveUser() { 269 // TODO(b/115781615): Tidy robolectric tests 270 // Arrange 271 final int userId = UserHandle.myUserId(); 272 final List<UserManager.EnforcingUser> enforcingUsers = Collections.singletonList( 273 new UserManager.EnforcingUser(userId, 274 UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) 275 ); 276 ShadowUserManager.getShadow().setUserRestrictionSources( 277 UserManager.DISALLOW_REMOVE_USER, 278 UserHandle.of(userId), 279 enforcingUsers); 280 281 ShadowDevicePolicyManager.getShadow().setDeviceOwnerComponentOnAnyUser( 282 new ComponentName("test", "test")); 283 284 doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability(); 285 mUserCapabilities.mIsAdmin = false; 286 287 Menu menu = mock(Menu.class); 288 MenuItem menuItem = mock(MenuItem.class); 289 final String title = "title"; 290 291 doReturn(title).when(menuItem).getTitle(); 292 doReturn(menuItem).when(menu).add( 293 anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class)); 294 295 // Act 296 mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class)); 297 298 // Assert 299 // Expect that the click will be overridden and the color will be faded 300 // (by RestrictedLockUtilsInternal) 301 verify(menuItem).setOnMenuItemClickListener(notNull()); 302 SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title); 303 verify(menuItem).setTitle(AdditionalMatchers.not(eq(defaultTitle))); 304 } 305 306 @Test withoutDisallowRemoveUser_ShouldNotDisableRemoveUser()307 public void withoutDisallowRemoveUser_ShouldNotDisableRemoveUser() { 308 // Arrange 309 doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability(); 310 mUserCapabilities.mIsAdmin = false; 311 312 Menu menu = mock(Menu.class); 313 MenuItem menuItem = mock(MenuItem.class); 314 final String title = "title"; 315 316 doReturn(title).when(menuItem).getTitle(); 317 doReturn(menuItem).when(menu).add( 318 anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class)); 319 320 // Act 321 mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class)); 322 323 // Assert 324 // Expect that a click listener will not be added and the title will not be changed 325 verify(menuItem, never()).setOnMenuItemClickListener(notNull()); 326 SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title); 327 verify(menuItem, never()).setTitle(AdditionalMatchers.not(eq(defaultTitle))); 328 } 329 330 @Test updateUserList_canAddUserAndSwitchUser_shouldShowAddUser()331 public void updateUserList_canAddUserAndSwitchUser_shouldShowAddUser() { 332 mUserCapabilities.mCanAddUser = true; 333 doReturn(true) 334 .when(mUserManager).canAddMoreUsers(eq(UserManager.USER_TYPE_FULL_SECONDARY)); 335 doReturn(true).when(mAddUserPreference).isEnabled(); 336 doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability(); 337 338 mFragment.updateUserList(); 339 340 verify(mAddUserPreference).setVisible(true); 341 verify(mAddUserPreference).setSummary(null); 342 verify(mAddUserPreference).setEnabled(true); 343 verify(mAddUserPreference).setDisabledByAdmin(null); 344 verify(mAddUserPreference).setSelectable(true); 345 } 346 347 @Test updateUserList_canAddGuestAndSwitchUser_shouldShowAddGuest()348 public void updateUserList_canAddGuestAndSwitchUser_shouldShowAddGuest() { 349 mUserCapabilities.mCanAddGuest = true; 350 doReturn(true) 351 .when(mUserManager).canAddMoreUsers(eq(UserManager.USER_TYPE_FULL_GUEST)); 352 doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability(); 353 354 mFragment.updateUserList(); 355 356 verify(mAddGuestPreference).setVisible(true); 357 verify(mAddGuestPreference).setEnabled(true); 358 verify(mAddGuestPreference).setSelectable(true); 359 } 360 361 @Test updateUserList_cannotSwitchUser_shouldDisableAddUser()362 public void updateUserList_cannotSwitchUser_shouldDisableAddUser() { 363 mUserCapabilities.mCanAddUser = true; 364 doReturn(true).when(mUserManager).canAddMoreUsers(anyString()); 365 doReturn(true).when(mAddUserPreference).isEnabled(); 366 doReturn(SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED) 367 .when(mUserManager).getUserSwitchability(); 368 369 mFragment.updateUserList(); 370 371 verify(mAddUserPreference).setVisible(true); 372 verify(mAddUserPreference).setSummary(null); 373 verify(mAddUserPreference).setEnabled(false); 374 verify(mAddUserPreference).setSelectable(true); 375 } 376 377 @Test updateUserList_canNotAddMoreUsers_shouldDisableAddUserWithSummary()378 public void updateUserList_canNotAddMoreUsers_shouldDisableAddUserWithSummary() { 379 mUserCapabilities.mCanAddUser = true; 380 doReturn(false).when(mUserManager).canAddMoreUsers(anyString()); 381 doReturn(false).when(mAddUserPreference).isEnabled(); 382 doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability(); 383 doReturn(4).when(mFragment).getRealUsersCount(); 384 385 mFragment.updateUserList(); 386 387 verify(mAddUserPreference).setVisible(true); 388 verify(mAddUserPreference).setSummary( 389 "You can\u2019t add any more users. Remove a user to add a new one."); 390 verify(mAddUserPreference).setEnabled(false); 391 verify(mAddUserPreference).setSelectable(true); 392 } 393 394 @Test updateUserList_cannotSwitchUser_shouldDisableAddGuest()395 public void updateUserList_cannotSwitchUser_shouldDisableAddGuest() { 396 mUserCapabilities.mCanAddGuest = true; 397 doReturn(true) 398 .when(mUserManager).canAddMoreUsers(eq(UserManager.USER_TYPE_FULL_GUEST)); 399 doReturn(SWITCHABILITY_STATUS_USER_IN_CALL).when(mUserManager).getUserSwitchability(); 400 401 mFragment.updateUserList(); 402 403 verify(mAddGuestPreference).setVisible(true); 404 verify(mAddGuestPreference).setEnabled(false); 405 verify(mAddGuestPreference).setSelectable(true); 406 } 407 408 @Test updateUserList_addUserDisallowedByAdmin_shouldNotShowAddUser()409 public void updateUserList_addUserDisallowedByAdmin_shouldNotShowAddUser() { 410 RestrictedLockUtils.EnforcedAdmin enforcedAdmin = mock( 411 RestrictedLockUtils.EnforcedAdmin.class); 412 mUserCapabilities.mEnforcedAdmin = enforcedAdmin; 413 mUserCapabilities.mCanAddUser = false; 414 mUserCapabilities.mDisallowAddUser = true; 415 mUserCapabilities.mDisallowAddUserSetByAdmin = true; 416 doReturn(true).when(mAddUserPreference).isEnabled(); 417 418 mFragment.updateUserList(); 419 420 verify(mAddUserPreference).setVisible(false); 421 } 422 423 @Test updateUserList_cannotAddUserButCanSwitchUser_shouldNotShowAddUser()424 public void updateUserList_cannotAddUserButCanSwitchUser_shouldNotShowAddUser() { 425 mUserCapabilities.mCanAddUser = false; 426 427 mFragment.updateUserList(); 428 429 verify(mAddUserPreference).setVisible(false); 430 } 431 432 @Test updateUserList_canNotAddGuest_shouldNotShowAddGuest()433 public void updateUserList_canNotAddGuest_shouldNotShowAddGuest() { 434 mUserCapabilities.mCanAddGuest = false; 435 436 mFragment.updateUserList(); 437 438 verify(mAddGuestPreference).setVisible(false); 439 } 440 441 @Test updateUserList_notProvisionedDevice_shouldNotShowAddUser()442 public void updateUserList_notProvisionedDevice_shouldNotShowAddUser() { 443 Settings.Global.putInt(mContext.getContentResolver(), 444 Settings.Global.DEVICE_PROVISIONED, 0); 445 mUserCapabilities.mCanAddUser = true; 446 447 mFragment.updateUserList(); 448 449 verify(mAddUserPreference).setVisible(false); 450 } 451 452 @Test updateUserList_notProvisionedDevice_shouldNotShowAddGuest()453 public void updateUserList_notProvisionedDevice_shouldNotShowAddGuest() { 454 Settings.Global.putInt(mContext.getContentResolver(), 455 Settings.Global.DEVICE_PROVISIONED, 0); 456 mUserCapabilities.mCanAddGuest = true; 457 458 mFragment.updateUserList(); 459 460 verify(mAddGuestPreference).setVisible(false); 461 } 462 463 @Test updateUserList_userSwitcherDisabled_shouldNotShowAddUser()464 public void updateUserList_userSwitcherDisabled_shouldNotShowAddUser() { 465 givenUsers(getAdminUser(true)); 466 mUserCapabilities.mCanAddUser = true; 467 mUserCapabilities.mUserSwitcherEnabled = false; 468 469 mFragment.updateUserList(); 470 471 verify(mAddUserPreference).setVisible(false); 472 } 473 474 @Test updateUserList_userSwitcherDisabled_shouldNotShowAddGuest()475 public void updateUserList_userSwitcherDisabled_shouldNotShowAddGuest() { 476 givenUsers(getAdminUser(true)); 477 mUserCapabilities.mCanAddGuest = true; 478 mUserCapabilities.mUserSwitcherEnabled = false; 479 480 mFragment.updateUserList(); 481 482 verify(mAddGuestPreference).setVisible(false); 483 } 484 485 @Test updateUserList_shouldAddAdminUserPreference()486 public void updateUserList_shouldAddAdminUserPreference() { 487 givenUsers(getAdminUser(true)); 488 489 mFragment.updateUserList(); 490 491 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 492 verify(mFragment.mUserListCategory).addPreference(captor.capture()); 493 UserPreference adminPref = captor.getValue(); 494 assertThat(adminPref).isSameInstanceAs(mMePreference); 495 } 496 497 @Test updateUserList_existingGuest_shouldAddGuestUserPreference()498 public void updateUserList_existingGuest_shouldAddGuestUserPreference() { 499 givenUsers(getAdminUser(true), getGuest(false)); 500 501 mFragment.updateUserList(); 502 503 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 504 verify(mFragment.mGuestUserCategory, times(1)) 505 .addPreference(captor.capture()); 506 UserPreference guestPref = captor.getAllValues().get(0); 507 assertThat(guestPref.getUserId()).isEqualTo(INACTIVE_GUEST_USER_ID); 508 assertThat(guestPref.getTitle()).isEqualTo("Guest"); 509 assertThat(guestPref.getIcon()).isNotNull(); 510 assertThat(guestPref.getKey()).isEqualTo(KEY_USER_GUEST); 511 assertThat(guestPref.isEnabled()).isEqualTo(true); 512 assertThat(guestPref.isSelectable()).isEqualTo(true); 513 assertThat(guestPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment); 514 } 515 516 @Test updateUserList_existingSecondaryUser_shouldAddSecondaryUserPreference()517 public void updateUserList_existingSecondaryUser_shouldAddSecondaryUserPreference() { 518 givenUsers(getAdminUser(true), getSecondaryUser(false)); 519 520 mFragment.updateUserList(); 521 522 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 523 verify(mFragment.mUserListCategory, times(2)) 524 .addPreference(captor.capture()); 525 UserPreference userPref = captor.getAllValues().get(1); 526 assertThat(userPref.getUserId()).isEqualTo(INACTIVE_SECONDARY_USER_ID); 527 assertThat(userPref.getTitle()).isEqualTo(SECONDARY_USER_NAME); 528 assertThat(userPref.getIcon()).isNotNull(); 529 assertThat(userPref.getKey()).isEqualTo("id=" + INACTIVE_SECONDARY_USER_ID); 530 assertThat(userPref.isEnabled()).isEqualTo(true); 531 assertThat(userPref.isSelectable()).isEqualTo(true); 532 assertThat(userPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment); 533 } 534 535 @Test updateUserList_existingSecondaryUser_shouldAddOnlyCurrUser_MultiUserIsDisabled()536 public void updateUserList_existingSecondaryUser_shouldAddOnlyCurrUser_MultiUserIsDisabled() { 537 givenUsers(getAdminUser(true), getSecondaryUser(false)); 538 mUserCapabilities.mUserSwitcherEnabled = false; 539 540 mFragment.updateUserList(); 541 542 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 543 verify(mFragment.mUserListCategory, times(1)) 544 .addPreference(captor.capture()); 545 546 List<UserPreference> userPrefs = captor.getAllValues(); 547 assertThat(userPrefs.size()).isEqualTo(1); 548 assertThat(userPrefs.get(0)).isSameInstanceAs(mMePreference); 549 } 550 551 @Test updateUserList_existingSecondaryUser_shouldAddSecondaryUser_MultiUserIsEnabled()552 public void updateUserList_existingSecondaryUser_shouldAddSecondaryUser_MultiUserIsEnabled() { 553 givenUsers(getAdminUser(true), getSecondaryUser(false)); 554 555 mFragment.updateUserList(); 556 557 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 558 verify(mFragment.mUserListCategory, times(2)) 559 .addPreference(captor.capture()); 560 561 List<UserPreference> userPrefs = captor.getAllValues(); 562 UserPreference adminPref = userPrefs.get(0); 563 UserPreference secondaryPref = userPrefs.get(1); 564 565 assertThat(userPrefs.size()).isEqualTo(2); 566 assertThat(adminPref).isSameInstanceAs(mMePreference); 567 assertThat(secondaryPref.getUserId()).isEqualTo(INACTIVE_SECONDARY_USER_ID); 568 assertThat(secondaryPref.getTitle()).isEqualTo(SECONDARY_USER_NAME); 569 assertThat(secondaryPref.getIcon()).isNotNull(); 570 assertThat(secondaryPref.getKey()).isEqualTo("id=" + INACTIVE_SECONDARY_USER_ID); 571 assertThat(secondaryPref.isEnabled()).isEqualTo(true); 572 assertThat(secondaryPref.isSelectable()).isEqualTo(true); 573 assertThat(secondaryPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment); 574 } 575 576 @Test updateUserList_existingRestrictedUser_shouldAddRestrictedUserPreference()577 public void updateUserList_existingRestrictedUser_shouldAddRestrictedUserPreference() { 578 givenUsers(getAdminUser(true), getRestrictedUser(false)); 579 580 mFragment.updateUserList(); 581 582 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 583 verify(mFragment.mUserListCategory, times(2)) 584 .addPreference(captor.capture()); 585 UserPreference userPref = captor.getAllValues().get(1); 586 assertThat(userPref.getUserId()).isEqualTo(INACTIVE_RESTRICTED_USER_ID); 587 assertThat(userPref.getTitle()).isEqualTo(RESTRICTED_USER_NAME); 588 assertThat(userPref.getIcon()).isNotNull(); 589 assertThat(userPref.getKey()).isEqualTo("id=" + INACTIVE_RESTRICTED_USER_ID); 590 assertThat(userPref.getSummary()).isEqualTo("Restricted profile"); 591 assertThat(userPref.isEnabled()).isEqualTo(true); 592 assertThat(userPref.isSelectable()).isEqualTo(true); 593 assertThat(userPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment); 594 } 595 596 @Test updateUserList_existingManagedUser_shouldNotAddUserPreference()597 public void updateUserList_existingManagedUser_shouldNotAddUserPreference() { 598 givenUsers(getAdminUser(true), getManagedUser()); 599 600 mFragment.updateUserList(); 601 602 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 603 verify(mFragment.mUserListCategory).addPreference(captor.capture()); 604 List<UserPreference> userPreferences = captor.getAllValues(); 605 assertThat(userPreferences.size()).isEqualTo(1); 606 assertThat(userPreferences.get(0).getUserId()).isEqualTo(ACTIVE_USER_ID); 607 } 608 609 @Test updateUserList_uninitializedRestrictedUser_shouldAddUserPreference()610 public void updateUserList_uninitializedRestrictedUser_shouldAddUserPreference() { 611 UserInfo restrictedUser = getRestrictedUser(false); 612 removeFlag(restrictedUser, UserInfo.FLAG_INITIALIZED); 613 givenUsers(getAdminUser(true), restrictedUser); 614 doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability(); 615 mUserCapabilities.mDisallowSwitchUser = false; 616 617 mFragment.updateUserList(); 618 619 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 620 verify(mFragment.mUserListCategory, times(2)) 621 .addPreference(captor.capture()); 622 UserPreference userPref = captor.getAllValues().get(1); 623 assertThat(userPref.getUserId()).isEqualTo(INACTIVE_RESTRICTED_USER_ID); 624 assertThat(userPref.getTitle()).isEqualTo(RESTRICTED_USER_NAME); 625 assertThat(userPref.getIcon()).isNotNull(); 626 assertThat(userPref.getKey()).isEqualTo("id=" + INACTIVE_RESTRICTED_USER_ID); 627 assertThat(userPref.getSummary()).isEqualTo("Not set up - Restricted profile"); 628 assertThat(userPref.isEnabled()).isEqualTo(true); 629 assertThat(userPref.isSelectable()).isEqualTo(true); 630 assertThat(userPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment); 631 } 632 633 @Test updateUserList_uninitializedUserAndCanNotSwitchUser_shouldDisablePref()634 public void updateUserList_uninitializedUserAndCanNotSwitchUser_shouldDisablePref() { 635 UserInfo uninitializedUser = getSecondaryUser(false); 636 removeFlag(uninitializedUser, UserInfo.FLAG_INITIALIZED); 637 givenUsers(getAdminUser(true), uninitializedUser); 638 doReturn(SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED) 639 .when(mUserManager).getUserSwitchability(); 640 mUserCapabilities.mDisallowSwitchUser = false; 641 642 mFragment.updateUserList(); 643 644 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 645 verify(mFragment.mUserListCategory, times(2)) 646 .addPreference(captor.capture()); 647 UserPreference userPref = captor.getAllValues().get(1); 648 assertThat(userPref.getUserId()).isEqualTo(INACTIVE_SECONDARY_USER_ID); 649 assertThat(userPref.getTitle()).isEqualTo(SECONDARY_USER_NAME); 650 assertThat(userPref.getIcon()).isNotNull(); 651 assertThat(userPref.getKey()).isEqualTo("id=" + INACTIVE_SECONDARY_USER_ID); 652 assertThat(userPref.getSummary()).isEqualTo("Not set up"); 653 assertThat(userPref.isEnabled()).isEqualTo(false); 654 assertThat(userPref.isSelectable()).isEqualTo(true); 655 assertThat(userPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment); 656 } 657 658 @Test updateUserList_guestWithoutInitializedFlag_shouldNotSetSummary()659 public void updateUserList_guestWithoutInitializedFlag_shouldNotSetSummary() { 660 UserInfo guest = getGuest(false); 661 removeFlag(guest, UserInfo.FLAG_INITIALIZED); 662 givenUsers(getAdminUser(true), guest); 663 664 mFragment.updateUserList(); 665 666 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 667 verify(mFragment.mGuestUserCategory, times(1)) 668 .addPreference(captor.capture()); 669 UserPreference userPref = captor.getAllValues().get(0); 670 assertThat(userPref.getUserId()).isEqualTo(INACTIVE_GUEST_USER_ID); 671 assertThat(userPref.getSummary()).isNull(); 672 } 673 674 @Test updateUserList_activeUserWithoutInitializedFlag_shouldNotSetSummary()675 public void updateUserList_activeUserWithoutInitializedFlag_shouldNotSetSummary() { 676 UserInfo activeUser = getSecondaryUser(true); 677 removeFlag(activeUser, UserInfo.FLAG_INITIALIZED); 678 givenUsers(activeUser); 679 680 mFragment.updateUserList(); 681 682 ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class); 683 verify(mFragment.mUserListCategory).addPreference(captor.capture()); 684 UserPreference userPref = captor.getValue(); 685 assertThat(userPref.getUserId()).isEqualTo(ACTIVE_USER_ID); 686 assertThat(userPref.getSummary()).isNull(); 687 } 688 689 @Test updateUserList_guestIsAlreadyCreated_shouldNotShowAddGuest()690 public void updateUserList_guestIsAlreadyCreated_shouldNotShowAddGuest() { 691 givenUsers(getAdminUser(true), getGuest(true)); 692 mUserCapabilities.mCanAddGuest = true; 693 694 mFragment.updateUserList(); 695 696 verify(mAddGuestPreference).setVisible(false); 697 } 698 699 @Test updateUserList_userIconLoaded_shouldNotLoadIcon()700 public void updateUserList_userIconLoaded_shouldNotLoadIcon() { 701 UserInfo currentUser = getAdminUser(true); 702 currentUser.iconPath = "/data/system/users/0/photo.png"; 703 givenUsers(currentUser); 704 mFragment.mUserIcons.put(ACTIVE_USER_ID, 705 Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888)); 706 707 mFragment.updateUserList(); 708 709 verify(mUserManager, never()).getUserIcon(anyInt()); 710 // updateUserList should be called only once 711 verify(mUserManager).getAliveUsers(); 712 } 713 714 @Ignore 715 @Test updateUserList_userIconMissing_shouldLoadIcon()716 public void updateUserList_userIconMissing_shouldLoadIcon() { 717 UserInfo currentUser = getAdminUser(true); 718 currentUser.iconPath = "/data/system/users/0/photo.png"; 719 givenUsers(currentUser); 720 // create a non-empty sparsearray 721 mFragment.mUserIcons.put(5, Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888)); 722 Bitmap userIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888); 723 doReturn(userIcon).when(mUserManager).getUserIcon(ACTIVE_USER_ID); 724 725 mFragment.updateUserList(); 726 shadowOf(Looper.getMainLooper()).idle(); 727 728 verify(mUserManager).getUserIcon(ACTIVE_USER_ID); 729 // updateUserList should be called another time after loading the icons 730 verify(mUserManager, times(2)).getAliveUsers(); 731 } 732 733 @Test onPreferenceClick_addGuestClicked_createGuestAndOpenDetails()734 public void onPreferenceClick_addGuestClicked_createGuestAndOpenDetails() { 735 UserInfo createdGuest = getGuest(false); 736 removeFlag(createdGuest, UserInfo.FLAG_INITIALIZED); 737 doReturn(createdGuest).when(mUserManager).createGuest(mActivity); 738 doReturn(mActivity).when(mFragment).getContext(); 739 740 mFragment.onPreferenceClick(mAddGuestPreference); 741 742 verify(mUserManager).createGuest(mActivity); 743 Intent startedIntent = shadowOf(mActivity).getNextStartedActivity(); 744 ShadowIntent shadowIntent = shadowOf(startedIntent); 745 assertThat(shadowIntent.getIntentClass()).isEqualTo(SubSettings.class); 746 assertThat(startedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)) 747 .isEqualTo(UserDetailsSettings.class.getName()); 748 Bundle arguments = startedIntent.getBundleExtra( 749 SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS); 750 assertThat(arguments).isNotNull(); 751 assertThat(arguments.getInt(UserDetailsSettings.EXTRA_USER_ID, 0)) 752 .isEqualTo(createdGuest.id); 753 assertThat(arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false)) 754 .isEqualTo(true); 755 verify(mMetricsFeatureProvider).action(any(), eq(SettingsEnums.ACTION_USER_GUEST_ADD)); 756 } 757 758 @Test onPreferenceClick_addSupervisedUserClicked_startIntentWithAction()759 public void onPreferenceClick_addSupervisedUserClicked_startIntentWithAction() { 760 final String intentPackage = "testPackage"; 761 final String intentAction = UserManager.ACTION_CREATE_SUPERVISED_USER; 762 final int intentFlags = Intent.FLAG_ACTIVITY_NEW_TASK; 763 final int metricsAction = SettingsEnums.ACTION_USER_SUPERVISED_ADD; 764 try { 765 setConfigSupervisedUserCreationPackage(intentPackage); 766 doReturn(new ResolveInfo()).when(mPackageManager).resolveActivity(any(), anyInt()); 767 doNothing().when(mFragment).startActivity(any()); 768 769 mFragment.onPreferenceClick(mAddSupervisedUserPreference); 770 771 final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); 772 verify(mFragment).startActivity(captor.capture()); 773 assertThat(captor.getValue().getPackage()).isEqualTo(intentPackage); 774 assertThat(captor.getValue().getAction()).isEqualTo(intentAction); 775 assertThat(captor.getValue().getFlags() & intentFlags).isGreaterThan(0); 776 777 verify(mMetricsFeatureProvider).action(any(), eq(metricsAction)); 778 } finally { 779 SettingsShadowResources.reset(); 780 } 781 } 782 783 @Test getRealUsersCount_onlyAdmin_shouldCount()784 public void getRealUsersCount_onlyAdmin_shouldCount() { 785 givenUsers(getAdminUser(true)); 786 787 int result = mFragment.getRealUsersCount(); 788 789 assertThat(result).isEqualTo(1); 790 verify(mUserManager).getUsers(); 791 } 792 793 @Test getRealUsersCount_secondaryUser_shouldCount()794 public void getRealUsersCount_secondaryUser_shouldCount() { 795 givenUsers(getAdminUser(true), getSecondaryUser(false)); 796 797 int result = mFragment.getRealUsersCount(); 798 799 assertThat(result).isEqualTo(2); 800 verify(mUserManager).getUsers(); 801 } 802 803 @Test getRealUsersCount_restrictedUser_shouldCount()804 public void getRealUsersCount_restrictedUser_shouldCount() { 805 givenUsers(getAdminUser(true), getSecondaryUser(false)); 806 807 int result = mFragment.getRealUsersCount(); 808 809 assertThat(result).isEqualTo(2); 810 verify(mUserManager).getUsers(); 811 } 812 813 @Test getRealUsersCount_guest_shouldNotCount()814 public void getRealUsersCount_guest_shouldNotCount() { 815 givenUsers(getAdminUser(true), getGuest(false)); 816 817 int result = mFragment.getRealUsersCount(); 818 819 assertThat(result).isEqualTo(1); 820 verify(mUserManager).getUsers(); 821 } 822 823 @Test getRealUsersCount_managedUser_shouldNotCount()824 public void getRealUsersCount_managedUser_shouldNotCount() { 825 givenUsers(getAdminUser(true), getManagedUser()); 826 827 int result = mFragment.getRealUsersCount(); 828 829 assertThat(result).isEqualTo(1); 830 verify(mUserManager).getUsers(); 831 } 832 setConfigSupervisedUserCreationPackage(String value)833 private void setConfigSupervisedUserCreationPackage(String value) { 834 SettingsShadowResources.overrideResource( 835 com.android.internal.R.string.config_supervisedUserCreationPackage, 836 value 837 ); 838 mFragment.setConfigSupervisedUserCreationPackage(); 839 mUserCapabilities.mCanAddUser = true; 840 mFragment.updateUserList(); 841 } 842 843 @Test addSupervisedUserOption_resourceIsDefined_shouldBeDisplayed()844 public void addSupervisedUserOption_resourceIsDefined_shouldBeDisplayed() { 845 try { 846 setConfigSupervisedUserCreationPackage("test"); 847 verify(mAddSupervisedUserPreference).setVisible(true); 848 } finally { 849 SettingsShadowResources.reset(); 850 } 851 } 852 853 @Test addSupervisedUserOption_resourceIsNotDefined_shouldBeHidden()854 public void addSupervisedUserOption_resourceIsNotDefined_shouldBeHidden() { 855 try { 856 setConfigSupervisedUserCreationPackage(""); 857 verify(mAddSupervisedUserPreference).setVisible(false); 858 } finally { 859 SettingsShadowResources.reset(); 860 } 861 } 862 givenUsers(UserInfo... userInfo)863 private void givenUsers(UserInfo... userInfo) { 864 List<UserInfo> users = Arrays.asList(userInfo); 865 doReturn(users).when(mUserManager).getUsers(); 866 doReturn(users).when(mUserManager).getAliveUsers(); 867 users.forEach(user -> 868 doReturn(user).when(mUserManager).getUserInfo(user.id)); 869 } 870 removeFlag(UserInfo userInfo, int flag)871 private static void removeFlag(UserInfo userInfo, int flag) { 872 userInfo.flags &= ~flag; 873 } 874 getAdminUser(boolean active)875 private static UserInfo getAdminUser(boolean active) { 876 return new UserInfo(active ? ACTIVE_USER_ID : INACTIVE_ADMIN_USER_ID, ADMIN_USER_NAME, 877 null, 878 UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN, 879 UserManager.USER_TYPE_FULL_SYSTEM); 880 } 881 getSecondaryUser(boolean active)882 private static UserInfo getSecondaryUser(boolean active) { 883 return new UserInfo(active ? ACTIVE_USER_ID : INACTIVE_SECONDARY_USER_ID, 884 SECONDARY_USER_NAME, null, 885 UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED, 886 UserManager.USER_TYPE_FULL_SECONDARY); 887 } 888 getRestrictedUser(boolean active)889 private static UserInfo getRestrictedUser(boolean active) { 890 return new UserInfo(active ? ACTIVE_USER_ID : INACTIVE_RESTRICTED_USER_ID, 891 RESTRICTED_USER_NAME, null, 892 UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_RESTRICTED, 893 UserManager.USER_TYPE_FULL_RESTRICTED); 894 } 895 getManagedUser()896 private static UserInfo getManagedUser() { 897 return new UserInfo(MANAGED_USER_ID, 898 MANAGED_USER_NAME, null, 899 UserInfo.FLAG_PROFILE | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE, 900 UserManager.USER_TYPE_PROFILE_MANAGED); 901 } 902 getGuest(boolean active)903 private static UserInfo getGuest(boolean active) { 904 return new UserInfo(active ? ACTIVE_USER_ID : INACTIVE_GUEST_USER_ID, GUEST_USER_NAME, 905 null, 906 UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_GUEST, 907 UserManager.USER_TYPE_FULL_GUEST); 908 } 909 910 911 } 912