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