• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.eq;
28 import static org.mockito.ArgumentMatchers.notNull;
29 import static org.mockito.Mockito.doReturn;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.never;
32 import static org.mockito.Mockito.spy;
33 import static org.mockito.Mockito.times;
34 import static org.mockito.Mockito.verify;
35 import static org.robolectric.Shadows.shadowOf;
36 
37 import android.app.settings.SettingsEnums;
38 import android.content.ComponentName;
39 import android.content.Context;
40 import android.content.Intent;
41 import android.content.SharedPreferences;
42 import android.content.pm.UserInfo;
43 import android.graphics.Bitmap;
44 import android.graphics.drawable.Drawable;
45 import android.os.Bundle;
46 import android.os.UserHandle;
47 import android.os.UserManager;
48 import android.provider.Settings;
49 import android.text.SpannableStringBuilder;
50 import android.view.Menu;
51 import android.view.MenuInflater;
52 import android.view.MenuItem;
53 
54 import androidx.fragment.app.FragmentActivity;
55 import androidx.preference.PreferenceCategory;
56 import androidx.preference.PreferenceManager;
57 import androidx.preference.PreferenceScreen;
58 
59 import com.android.settings.SettingsActivity;
60 import com.android.settings.SubSettings;
61 import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
62 import com.android.settings.testutils.shadow.ShadowUserManager;
63 import com.android.settingslib.RestrictedLockUtils;
64 import com.android.settingslib.RestrictedPreference;
65 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
66 
67 import org.junit.After;
68 import org.junit.Before;
69 import org.junit.Test;
70 import org.junit.runner.RunWith;
71 import org.mockito.AdditionalMatchers;
72 import org.mockito.ArgumentCaptor;
73 import org.mockito.Mock;
74 import org.mockito.MockitoAnnotations;
75 import org.robolectric.RobolectricTestRunner;
76 import org.robolectric.RuntimeEnvironment;
77 import org.robolectric.android.controller.ActivityController;
78 import org.robolectric.annotation.Config;
79 import org.robolectric.shadows.ShadowIntent;
80 import org.robolectric.util.ReflectionHelpers;
81 
82 import java.util.Arrays;
83 import java.util.Collections;
84 import java.util.List;
85 
86 @RunWith(RobolectricTestRunner.class)
87 @Config(shadows = {ShadowUserManager.class, ShadowDevicePolicyManager.class})
88 public class UserSettingsTest {
89 
90     private static final String KEY_USER_GUEST = "user_guest";
91     private static final int ACTIVE_USER_ID = 0;
92     private static final int INACTIVE_ADMIN_USER_ID = 1;
93     private static final int INACTIVE_SECONDARY_USER_ID = 14;
94     private static final int INACTIVE_RESTRICTED_USER_ID = 21;
95     private static final int INACTIVE_GUEST_USER_ID = 23;
96     private static final int MANAGED_USER_ID = 11;
97     private static final String ADMIN_USER_NAME = "Owner";
98     private static final String SECONDARY_USER_NAME = "Tom";
99     private static final String RESTRICTED_USER_NAME = "Bob";
100     private static final String GUEST_USER_NAME = "Guest";
101     private static final String MANAGED_USER_NAME = "Work profile";
102     private int mProvisionedBackupValue;
103 
104     @Mock
105     private Drawable mDefaultIconDrawable;
106     @Mock
107     private PreferenceManager mMockPreferenceManager;
108     @Mock
109     private UserPreference mMePreference;
110     @Mock
111     private RestrictedPreference mAddUserPreference;
112     @Mock
113     private RestrictedPreference mAddGuestPreference;
114     @Mock
115     private UserManager mUserManager;
116     @Mock
117     private MetricsFeatureProvider mMetricsFeatureProvider;
118 
119     private FragmentActivity mActivity;
120     private Context mContext;
121     private UserSettings mFragment;
122     private UserCapabilities mUserCapabilities;
123 
124     @Before
setUp()125     public void setUp() {
126         MockitoAnnotations.initMocks(this);
127         mActivity = spy(ActivityController.of(new FragmentActivity()).get());
128         mContext = spy(RuntimeEnvironment.application);
129         mUserCapabilities = UserCapabilities.create(mContext);
130         mUserCapabilities.mUserSwitcherEnabled = true;
131 
132         mFragment = spy(new UserSettings());
133         ReflectionHelpers.setField(mFragment, "mAddUserWhenLockedPreferenceController",
134                 mock(AddUserWhenLockedPreferenceController.class));
135         ReflectionHelpers.setField(mFragment, "mMultiUserTopIntroPreferenceController",
136                 mock(MultiUserTopIntroPreferenceController.class));
137         ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
138         ReflectionHelpers.setField(mFragment, "mUserCaps", mUserCapabilities);
139         ReflectionHelpers.setField(mFragment, "mDefaultIconDrawable", mDefaultIconDrawable);
140         ReflectionHelpers.setField(mFragment, "mAddingUser", false);
141         ReflectionHelpers.setField(mFragment, "mMetricsFeatureProvider", mMetricsFeatureProvider);
142 
143         doReturn(mUserManager).when(mActivity).getSystemService(UserManager.class);
144 
145         doReturn(mActivity).when(mFragment).getActivity();
146         doReturn(mContext).when(mFragment).getContext();
147         doReturn(mMockPreferenceManager).when(mFragment).getPreferenceManager();
148         doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
149 
150         mProvisionedBackupValue = Settings.Global.getInt(mContext.getContentResolver(),
151                 Settings.Global.DEVICE_PROVISIONED, 0);
152         Settings.Global.putInt(mContext.getContentResolver(),
153                 Settings.Global.DEVICE_PROVISIONED, 1); //default state
154 
155         final SharedPreferences prefs = mock(SharedPreferences.class);
156 
157         doReturn(prefs).when(mMockPreferenceManager).getSharedPreferences();
158         doReturn(mContext).when(mMockPreferenceManager).getContext();
159         doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
160 
161         mFragment.mMePreference = mMePreference;
162         mFragment.mAddUser = mAddUserPreference;
163         mFragment.mAddGuest = mAddGuestPreference;
164         mFragment.mUserListCategory = mock(PreferenceCategory.class);
165     }
166 
167     @After
tearDown()168     public void tearDown() {
169         Settings.Global.putInt(mContext.getContentResolver(),
170                 Settings.Global.DEVICE_PROVISIONED, mProvisionedBackupValue);
171     }
172 
173     @Test
testAssignDefaultPhoto_ContextNull_ReturnFalseAndNotCrash()174     public void testAssignDefaultPhoto_ContextNull_ReturnFalseAndNotCrash() {
175         // Should not crash here
176         assertThat(UserSettings.assignDefaultPhoto(null, ACTIVE_USER_ID)).isFalse();
177     }
178 
179     @Test
testExitGuest_ShouldLogAction()180     public void testExitGuest_ShouldLogAction() {
181         mUserCapabilities.mIsGuest = true;
182         mFragment.exitGuest();
183         verify(mMetricsFeatureProvider).action(any(),
184                 eq(SettingsEnums.ACTION_USER_GUEST_EXIT_CONFIRMED));
185     }
186 
187     @Test
testExitGuestWhenNotGuest_ShouldNotLogAction()188     public void testExitGuestWhenNotGuest_ShouldNotLogAction() {
189         mUserCapabilities.mIsGuest = false;
190         mFragment.exitGuest();
191         verify(mMetricsFeatureProvider, never()).action(any(),
192                 eq(SettingsEnums.ACTION_USER_GUEST_EXIT_CONFIRMED));
193     }
194 
195     @Test
withDisallowRemoveUser_ShouldDisableRemoveUser()196     public void withDisallowRemoveUser_ShouldDisableRemoveUser() {
197         // TODO(b/115781615): Tidy robolectric tests
198         // Arrange
199         final int userId = UserHandle.myUserId();
200         final List<UserManager.EnforcingUser> enforcingUsers = Collections.singletonList(
201                 new UserManager.EnforcingUser(userId,
202                         UserManager.RESTRICTION_SOURCE_DEVICE_OWNER)
203         );
204         ShadowUserManager.getShadow().setUserRestrictionSources(
205                 UserManager.DISALLOW_REMOVE_USER,
206                 UserHandle.of(userId),
207                 enforcingUsers);
208 
209         ShadowDevicePolicyManager.getShadow().setDeviceOwnerComponentOnAnyUser(
210                 new ComponentName("test", "test"));
211 
212         doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability();
213         mUserCapabilities.mIsAdmin = false;
214 
215         Menu menu = mock(Menu.class);
216         MenuItem menuItem = mock(MenuItem.class);
217         final String title = "title";
218 
219         doReturn(title).when(menuItem).getTitle();
220         doReturn(menuItem).when(menu).add(
221                 anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class));
222 
223         // Act
224         mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class));
225 
226         // Assert
227         // Expect that the click will be overridden and the color will be faded
228         // (by RestrictedLockUtilsInternal)
229         verify(menuItem).setOnMenuItemClickListener(notNull());
230         SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title);
231         verify(menuItem).setTitle(AdditionalMatchers.not(eq(defaultTitle)));
232     }
233 
234     @Test
withoutDisallowRemoveUser_ShouldNotDisableRemoveUser()235     public void withoutDisallowRemoveUser_ShouldNotDisableRemoveUser() {
236         // Arrange
237         doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability();
238         mUserCapabilities.mIsAdmin = false;
239 
240         Menu menu = mock(Menu.class);
241         MenuItem menuItem = mock(MenuItem.class);
242         final String title = "title";
243 
244         doReturn(title).when(menuItem).getTitle();
245         doReturn(menuItem).when(menu).add(
246                 anyInt(), eq(Menu.FIRST), anyInt(), any(CharSequence.class));
247 
248         // Act
249         mFragment.onCreateOptionsMenu(menu, mock(MenuInflater.class));
250 
251         // Assert
252         // Expect that a click listener will not be added and the title will not be changed
253         verify(menuItem, never()).setOnMenuItemClickListener(notNull());
254         SpannableStringBuilder defaultTitle = new SpannableStringBuilder(title);
255         verify(menuItem, never()).setTitle(AdditionalMatchers.not(eq(defaultTitle)));
256     }
257 
258     @Test
updateUserList_canAddUserAndSwitchUser_shouldShowAddUser()259     public void updateUserList_canAddUserAndSwitchUser_shouldShowAddUser() {
260         mUserCapabilities.mCanAddUser = true;
261         doReturn(true).when(mUserManager).canAddMoreUsers();
262         doReturn(true).when(mAddUserPreference).isEnabled();
263         doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability();
264 
265         mFragment.updateUserList();
266 
267         verify(mAddUserPreference).setVisible(true);
268         verify(mAddUserPreference).setSummary(null);
269         verify(mAddUserPreference).setEnabled(true);
270         verify(mAddUserPreference).setDisabledByAdmin(null);
271         verify(mAddUserPreference).setSelectable(true);
272     }
273 
274     @Test
updateUserList_canAddGuestAndSwitchUser_shouldShowAddGuest()275     public void updateUserList_canAddGuestAndSwitchUser_shouldShowAddGuest() {
276         mUserCapabilities.mCanAddGuest = true;
277         doReturn(true).when(mUserManager).canAddMoreUsers();
278         doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability();
279 
280         mFragment.updateUserList();
281 
282         verify(mAddGuestPreference).setVisible(true);
283         verify(mAddGuestPreference).setEnabled(true);
284         verify(mAddGuestPreference).setIcon(any(Drawable.class));
285         verify(mAddGuestPreference).setSelectable(true);
286     }
287 
288     @Test
updateUserList_cannotSwitchUser_shouldDisableAddUser()289     public void updateUserList_cannotSwitchUser_shouldDisableAddUser() {
290         mUserCapabilities.mCanAddUser = true;
291         doReturn(true).when(mUserManager).canAddMoreUsers();
292         doReturn(true).when(mAddUserPreference).isEnabled();
293         doReturn(SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED)
294                 .when(mUserManager).getUserSwitchability();
295 
296         mFragment.updateUserList();
297 
298         verify(mAddUserPreference).setVisible(true);
299         verify(mAddUserPreference).setSummary(null);
300         verify(mAddUserPreference).setEnabled(false);
301         verify(mAddUserPreference).setSelectable(true);
302     }
303 
304     @Test
updateUserList_canNotAddMoreUsers_shouldDisableAddUserWithSummary()305     public void updateUserList_canNotAddMoreUsers_shouldDisableAddUserWithSummary() {
306         mUserCapabilities.mCanAddUser = true;
307         doReturn(false).when(mUserManager).canAddMoreUsers();
308         doReturn(false).when(mAddUserPreference).isEnabled();
309         doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability();
310         doReturn(4).when(mFragment).getRealUsersCount();
311 
312         mFragment.updateUserList();
313 
314         verify(mAddUserPreference).setVisible(true);
315         verify(mAddUserPreference).setSummary("You can add up to 4 users");
316         verify(mAddUserPreference).setEnabled(false);
317         verify(mAddUserPreference).setSelectable(true);
318     }
319 
320     @Test
updateUserList_cannotSwitchUser_shouldDisableAddGuest()321     public void updateUserList_cannotSwitchUser_shouldDisableAddGuest() {
322         mUserCapabilities.mCanAddGuest = true;
323         doReturn(true).when(mUserManager).canAddMoreUsers();
324         doReturn(SWITCHABILITY_STATUS_USER_IN_CALL).when(mUserManager).getUserSwitchability();
325 
326         mFragment.updateUserList();
327 
328         verify(mAddGuestPreference).setVisible(true);
329         verify(mAddGuestPreference).setEnabled(false);
330         verify(mAddGuestPreference).setIcon(any(Drawable.class));
331         verify(mAddGuestPreference).setSelectable(true);
332     }
333 
334     @Test
updateUserList_addUserDisallowedByAdmin_shouldShowDisabledAddUser()335     public void updateUserList_addUserDisallowedByAdmin_shouldShowDisabledAddUser() {
336         RestrictedLockUtils.EnforcedAdmin enforcedAdmin = mock(
337                 RestrictedLockUtils.EnforcedAdmin.class);
338         mUserCapabilities.mEnforcedAdmin = enforcedAdmin;
339         mUserCapabilities.mCanAddUser = false;
340         mUserCapabilities.mDisallowAddUser = true;
341         mUserCapabilities.mDisallowAddUserSetByAdmin = true;
342         doReturn(true).when(mAddUserPreference).isEnabled();
343 
344         mFragment.updateUserList();
345 
346         verify(mAddUserPreference).setVisible(true);
347         ArgumentCaptor<RestrictedLockUtils.EnforcedAdmin> captor = ArgumentCaptor.forClass(
348                 RestrictedLockUtils.EnforcedAdmin.class);
349         verify(mAddUserPreference).setDisabledByAdmin(captor.capture());
350         assertThat(captor.getValue()).isEqualTo(enforcedAdmin);
351     }
352 
353     @Test
updateUserList_cannotAddUserButCanSwitchUser_shouldNotShowAddUser()354     public void updateUserList_cannotAddUserButCanSwitchUser_shouldNotShowAddUser() {
355         mUserCapabilities.mCanAddUser = false;
356 
357         mFragment.updateUserList();
358 
359         verify(mAddUserPreference).setVisible(false);
360     }
361 
362     @Test
updateUserList_canNotAddGuest_shouldNotShowAddGuest()363     public void updateUserList_canNotAddGuest_shouldNotShowAddGuest() {
364         mUserCapabilities.mCanAddGuest = false;
365 
366         mFragment.updateUserList();
367 
368         verify(mAddGuestPreference).setVisible(false);
369     }
370 
371     @Test
updateUserList_notProvisionedDevice_shouldNotShowAddUser()372     public void updateUserList_notProvisionedDevice_shouldNotShowAddUser() {
373         Settings.Global.putInt(mContext.getContentResolver(),
374                 Settings.Global.DEVICE_PROVISIONED, 0);
375         mUserCapabilities.mCanAddUser = true;
376 
377         mFragment.updateUserList();
378 
379         verify(mAddUserPreference).setVisible(false);
380     }
381 
382     @Test
updateUserList_notProvisionedDevice_shouldNotShowAddGuest()383     public void updateUserList_notProvisionedDevice_shouldNotShowAddGuest() {
384         Settings.Global.putInt(mContext.getContentResolver(),
385                 Settings.Global.DEVICE_PROVISIONED, 0);
386         mUserCapabilities.mCanAddGuest = true;
387 
388         mFragment.updateUserList();
389 
390         verify(mAddGuestPreference).setVisible(false);
391     }
392 
393     @Test
updateUserList_userSwitcherDisabled_shouldNotShowAddUser()394     public void updateUserList_userSwitcherDisabled_shouldNotShowAddUser() {
395         mUserCapabilities.mCanAddUser = true;
396         mUserCapabilities.mUserSwitcherEnabled = false;
397 
398         mFragment.updateUserList();
399 
400         verify(mAddUserPreference).setVisible(false);
401     }
402 
403     @Test
updateUserList_userSwitcherDisabled_shouldNotShowAddGuest()404     public void updateUserList_userSwitcherDisabled_shouldNotShowAddGuest() {
405         mUserCapabilities.mCanAddGuest = true;
406         mUserCapabilities.mUserSwitcherEnabled = false;
407 
408         mFragment.updateUserList();
409 
410         verify(mAddGuestPreference).setVisible(false);
411     }
412 
413     @Test
updateUserList_shouldAddAdminUserPreference()414     public void updateUserList_shouldAddAdminUserPreference() {
415         givenUsers(getAdminUser(true));
416 
417         mFragment.updateUserList();
418 
419         ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class);
420         verify(mFragment.mUserListCategory).addPreference(captor.capture());
421         UserPreference adminPref = captor.getValue();
422         assertThat(adminPref).isSameInstanceAs(mMePreference);
423     }
424 
425     @Test
updateUserList_existingGuest_shouldAddGuestUserPreference()426     public void updateUserList_existingGuest_shouldAddGuestUserPreference() {
427         givenUsers(getAdminUser(true), getGuest(false));
428 
429         mFragment.updateUserList();
430 
431         ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class);
432         verify(mFragment.mUserListCategory, times(2))
433                 .addPreference(captor.capture());
434         UserPreference guestPref = captor.getAllValues().get(1);
435         assertThat(guestPref.getUserId()).isEqualTo(INACTIVE_GUEST_USER_ID);
436         assertThat(guestPref.getTitle()).isEqualTo("Guest");
437         assertThat(guestPref.getIcon()).isNotNull();
438         assertThat(guestPref.getKey()).isEqualTo(KEY_USER_GUEST);
439         assertThat(guestPref.isEnabled()).isEqualTo(true);
440         assertThat(guestPref.isSelectable()).isEqualTo(true);
441         assertThat(guestPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment);
442     }
443 
444     @Test
updateUserList_existingSecondaryUser_shouldAddSecondaryUserPreference()445     public void updateUserList_existingSecondaryUser_shouldAddSecondaryUserPreference() {
446         givenUsers(getAdminUser(true), getSecondaryUser(false));
447 
448         mFragment.updateUserList();
449 
450         ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class);
451         verify(mFragment.mUserListCategory, times(2))
452                 .addPreference(captor.capture());
453         UserPreference userPref = captor.getAllValues().get(1);
454         assertThat(userPref.getUserId()).isEqualTo(INACTIVE_SECONDARY_USER_ID);
455         assertThat(userPref.getTitle()).isEqualTo(SECONDARY_USER_NAME);
456         assertThat(userPref.getIcon()).isNotNull();
457         assertThat(userPref.getKey()).isEqualTo("id=" + INACTIVE_SECONDARY_USER_ID);
458         assertThat(userPref.isEnabled()).isEqualTo(true);
459         assertThat(userPref.isSelectable()).isEqualTo(true);
460         assertThat(userPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment);
461     }
462 
463     @Test
updateUserList_existingRestrictedUser_shouldAddRestrictedUserPreference()464     public void updateUserList_existingRestrictedUser_shouldAddRestrictedUserPreference() {
465         givenUsers(getAdminUser(true), getRestrictedUser(false));
466 
467         mFragment.updateUserList();
468 
469         ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class);
470         verify(mFragment.mUserListCategory, times(2))
471                 .addPreference(captor.capture());
472         UserPreference userPref = captor.getAllValues().get(1);
473         assertThat(userPref.getUserId()).isEqualTo(INACTIVE_RESTRICTED_USER_ID);
474         assertThat(userPref.getTitle()).isEqualTo(RESTRICTED_USER_NAME);
475         assertThat(userPref.getIcon()).isNotNull();
476         assertThat(userPref.getKey()).isEqualTo("id=" + INACTIVE_RESTRICTED_USER_ID);
477         assertThat(userPref.getSummary()).isEqualTo("Restricted profile");
478         assertThat(userPref.isEnabled()).isEqualTo(true);
479         assertThat(userPref.isSelectable()).isEqualTo(true);
480         assertThat(userPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment);
481     }
482 
483     @Test
updateUserList_existingManagedUser_shouldNotAddUserPreference()484     public void updateUserList_existingManagedUser_shouldNotAddUserPreference() {
485         givenUsers(getAdminUser(true), getManagedUser());
486 
487         mFragment.updateUserList();
488 
489         ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class);
490         verify(mFragment.mUserListCategory).addPreference(captor.capture());
491         List<UserPreference> userPreferences = captor.getAllValues();
492         assertThat(userPreferences.size()).isEqualTo(1);
493         assertThat(userPreferences.get(0).getUserId()).isEqualTo(ACTIVE_USER_ID);
494     }
495 
496     @Test
updateUserList_uninitializedRestrictedUser_shouldAddUserPreference()497     public void updateUserList_uninitializedRestrictedUser_shouldAddUserPreference() {
498         UserInfo restrictedUser = getRestrictedUser(false);
499         removeFlag(restrictedUser, UserInfo.FLAG_INITIALIZED);
500         givenUsers(getAdminUser(true), restrictedUser);
501         doReturn(SWITCHABILITY_STATUS_OK).when(mUserManager).getUserSwitchability();
502         mUserCapabilities.mDisallowSwitchUser = false;
503 
504         mFragment.updateUserList();
505 
506         ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class);
507         verify(mFragment.mUserListCategory, times(2))
508                 .addPreference(captor.capture());
509         UserPreference userPref = captor.getAllValues().get(1);
510         assertThat(userPref.getUserId()).isEqualTo(INACTIVE_RESTRICTED_USER_ID);
511         assertThat(userPref.getTitle()).isEqualTo(RESTRICTED_USER_NAME);
512         assertThat(userPref.getIcon()).isNotNull();
513         assertThat(userPref.getKey()).isEqualTo("id=" + INACTIVE_RESTRICTED_USER_ID);
514         assertThat(userPref.getSummary()).isEqualTo("Not set up - Restricted profile");
515         assertThat(userPref.isEnabled()).isEqualTo(true);
516         assertThat(userPref.isSelectable()).isEqualTo(true);
517         assertThat(userPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment);
518     }
519 
520     @Test
updateUserList_uninitializedUserAndCanNotSwitchUser_shouldDisablePref()521     public void updateUserList_uninitializedUserAndCanNotSwitchUser_shouldDisablePref() {
522         UserInfo uninitializedUser = getSecondaryUser(false);
523         removeFlag(uninitializedUser, UserInfo.FLAG_INITIALIZED);
524         givenUsers(getAdminUser(true), uninitializedUser);
525         doReturn(SWITCHABILITY_STATUS_USER_SWITCH_DISALLOWED)
526                 .when(mUserManager).getUserSwitchability();
527         mUserCapabilities.mDisallowSwitchUser = false;
528 
529         mFragment.updateUserList();
530 
531         ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class);
532         verify(mFragment.mUserListCategory, times(2))
533                 .addPreference(captor.capture());
534         UserPreference userPref = captor.getAllValues().get(1);
535         assertThat(userPref.getUserId()).isEqualTo(INACTIVE_SECONDARY_USER_ID);
536         assertThat(userPref.getTitle()).isEqualTo(SECONDARY_USER_NAME);
537         assertThat(userPref.getIcon()).isNotNull();
538         assertThat(userPref.getKey()).isEqualTo("id=" + INACTIVE_SECONDARY_USER_ID);
539         assertThat(userPref.getSummary()).isEqualTo("Not set up");
540         assertThat(userPref.isEnabled()).isEqualTo(false);
541         assertThat(userPref.isSelectable()).isEqualTo(true);
542         assertThat(userPref.getOnPreferenceClickListener()).isSameInstanceAs(mFragment);
543     }
544 
545     @Test
updateUserList_guestWithoutInitializedFlag_shouldNotSetSummary()546     public void updateUserList_guestWithoutInitializedFlag_shouldNotSetSummary() {
547         UserInfo guest = getGuest(false);
548         removeFlag(guest, UserInfo.FLAG_INITIALIZED);
549         givenUsers(getAdminUser(true), guest);
550 
551         mFragment.updateUserList();
552 
553         ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class);
554         verify(mFragment.mUserListCategory, times(2))
555                 .addPreference(captor.capture());
556         UserPreference userPref = captor.getAllValues().get(1);
557         assertThat(userPref.getUserId()).isEqualTo(INACTIVE_GUEST_USER_ID);
558         assertThat(userPref.getSummary()).isNull();
559     }
560 
561     @Test
updateUserList_activeUserWithoutInitializedFlag_shouldNotSetSummary()562     public void updateUserList_activeUserWithoutInitializedFlag_shouldNotSetSummary() {
563         UserInfo activeUser = getSecondaryUser(true);
564         removeFlag(activeUser, UserInfo.FLAG_INITIALIZED);
565         givenUsers(activeUser);
566 
567         mFragment.updateUserList();
568 
569         ArgumentCaptor<UserPreference> captor = ArgumentCaptor.forClass(UserPreference.class);
570         verify(mFragment.mUserListCategory).addPreference(captor.capture());
571         UserPreference userPref = captor.getValue();
572         assertThat(userPref.getUserId()).isEqualTo(ACTIVE_USER_ID);
573         assertThat(userPref.getSummary()).isNull();
574     }
575 
576     @Test
updateUserList_guestIsAlreadyCreated_shouldNotShowAddGuest()577     public void updateUserList_guestIsAlreadyCreated_shouldNotShowAddGuest() {
578         givenUsers(getAdminUser(true), getGuest(true));
579         mUserCapabilities.mCanAddGuest = true;
580 
581         mFragment.updateUserList();
582 
583         verify(mAddGuestPreference).setVisible(false);
584     }
585 
586     @Test
updateUserList_userIconLoaded_shouldNotLoadIcon()587     public void updateUserList_userIconLoaded_shouldNotLoadIcon() {
588         UserInfo currentUser = getAdminUser(true);
589         currentUser.iconPath = "/data/system/users/0/photo.png";
590         givenUsers(currentUser);
591         mFragment.mUserIcons.put(ACTIVE_USER_ID,
592                 Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888));
593 
594         mFragment.updateUserList();
595 
596         verify(mUserManager, never()).getUserIcon(anyInt());
597         // updateUserList should be called only once
598         verify(mUserManager).getAliveUsers();
599     }
600 
601     @Test
updateUserList_userIconMissing_shouldLoadIcon()602     public void updateUserList_userIconMissing_shouldLoadIcon() {
603         UserInfo currentUser = getAdminUser(true);
604         currentUser.iconPath = "/data/system/users/0/photo.png";
605         givenUsers(currentUser);
606         // create a non-empty sparsearray
607         mFragment.mUserIcons.put(5, Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888));
608         Bitmap userIcon = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888);
609         doReturn(userIcon).when(mUserManager).getUserIcon(ACTIVE_USER_ID);
610 
611         mFragment.updateUserList();
612 
613         verify(mUserManager).getUserIcon(ACTIVE_USER_ID);
614         // updateUserList should be called another time after loading the icons
615         verify(mUserManager, times(2)).getAliveUsers();
616     }
617 
618     @Test
onPreferenceClick_addGuestClicked_createGuestAndOpenDetails()619     public void onPreferenceClick_addGuestClicked_createGuestAndOpenDetails() {
620         UserInfo createdGuest = getGuest(false);
621         removeFlag(createdGuest, UserInfo.FLAG_INITIALIZED);
622         doReturn(createdGuest).when(mUserManager).createGuest(mActivity, "Guest");
623         doReturn(mActivity).when(mFragment).getContext();
624 
625         mFragment.onPreferenceClick(mAddGuestPreference);
626 
627         verify(mUserManager).createGuest(mActivity, "Guest");
628         Intent startedIntent = shadowOf(mActivity).getNextStartedActivity();
629         ShadowIntent shadowIntent = shadowOf(startedIntent);
630         assertThat(shadowIntent.getIntentClass()).isEqualTo(SubSettings.class);
631         assertThat(startedIntent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
632                 .isEqualTo(UserDetailsSettings.class.getName());
633         Bundle arguments = startedIntent.getBundleExtra(
634                 SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
635         assertThat(arguments).isNotNull();
636         assertThat(arguments.getInt(UserDetailsSettings.EXTRA_USER_ID, 0))
637                 .isEqualTo(createdGuest.id);
638         assertThat(arguments.getBoolean(AppRestrictionsFragment.EXTRA_NEW_USER, false))
639                 .isEqualTo(true);
640         verify(mMetricsFeatureProvider).action(any(), eq(SettingsEnums.ACTION_USER_GUEST_ADD));
641     }
642 
643     @Test
getRealUsersCount_onlyAdmin_shouldCount()644     public void getRealUsersCount_onlyAdmin_shouldCount() {
645         givenUsers(getAdminUser(true));
646 
647         int result = mFragment.getRealUsersCount();
648 
649         assertThat(result).isEqualTo(1);
650         verify(mUserManager).getUsers();
651     }
652 
653     @Test
getRealUsersCount_secondaryUser_shouldCount()654     public void getRealUsersCount_secondaryUser_shouldCount() {
655         givenUsers(getAdminUser(true), getSecondaryUser(false));
656 
657         int result = mFragment.getRealUsersCount();
658 
659         assertThat(result).isEqualTo(2);
660         verify(mUserManager).getUsers();
661     }
662 
663     @Test
getRealUsersCount_restrictedUser_shouldCount()664     public void getRealUsersCount_restrictedUser_shouldCount() {
665         givenUsers(getAdminUser(true), getSecondaryUser(false));
666 
667         int result = mFragment.getRealUsersCount();
668 
669         assertThat(result).isEqualTo(2);
670         verify(mUserManager).getUsers();
671     }
672 
673     @Test
getRealUsersCount_guest_shouldNotCount()674     public void getRealUsersCount_guest_shouldNotCount() {
675         givenUsers(getAdminUser(true), getGuest(false));
676 
677         int result = mFragment.getRealUsersCount();
678 
679         assertThat(result).isEqualTo(1);
680         verify(mUserManager).getUsers();
681     }
682 
683     @Test
getRealUsersCount_managedUser_shouldNotCount()684     public void getRealUsersCount_managedUser_shouldNotCount() {
685         givenUsers(getAdminUser(true), getManagedUser());
686 
687         int result = mFragment.getRealUsersCount();
688 
689         assertThat(result).isEqualTo(1);
690         verify(mUserManager).getUsers();
691     }
692 
givenUsers(UserInfo... userInfo)693     private void givenUsers(UserInfo... userInfo) {
694         List<UserInfo> users = Arrays.asList(userInfo);
695         doReturn(users).when(mUserManager).getUsers();
696         doReturn(users).when(mUserManager).getAliveUsers();
697     }
698 
removeFlag(UserInfo userInfo, int flag)699     private static void removeFlag(UserInfo userInfo, int flag) {
700         userInfo.flags &= ~flag;
701     }
702 
getAdminUser(boolean active)703     private static UserInfo getAdminUser(boolean active) {
704         return new UserInfo(active ? ACTIVE_USER_ID : INACTIVE_ADMIN_USER_ID, ADMIN_USER_NAME,
705                 null,
706                 UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN,
707                 UserManager.USER_TYPE_FULL_SYSTEM);
708     }
709 
getSecondaryUser(boolean active)710     private static UserInfo getSecondaryUser(boolean active) {
711         return new UserInfo(active ? ACTIVE_USER_ID : INACTIVE_SECONDARY_USER_ID,
712                 SECONDARY_USER_NAME, null,
713                 UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED,
714                 UserManager.USER_TYPE_FULL_SECONDARY);
715     }
716 
getRestrictedUser(boolean active)717     private static UserInfo getRestrictedUser(boolean active) {
718         return new UserInfo(active ? ACTIVE_USER_ID : INACTIVE_RESTRICTED_USER_ID,
719                 RESTRICTED_USER_NAME, null,
720                 UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_RESTRICTED,
721                 UserManager.USER_TYPE_FULL_RESTRICTED);
722     }
723 
getManagedUser()724     private static UserInfo getManagedUser() {
725         return new UserInfo(MANAGED_USER_ID,
726                 MANAGED_USER_NAME, null,
727                 UserInfo.FLAG_PROFILE | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE,
728                 UserManager.USER_TYPE_PROFILE_MANAGED);
729     }
730 
getGuest(boolean active)731     private static UserInfo getGuest(boolean active) {
732         return new UserInfo(active ? ACTIVE_USER_ID : INACTIVE_GUEST_USER_ID, GUEST_USER_NAME,
733                 null,
734                 UserInfo.FLAG_FULL | UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_GUEST,
735                 UserManager.USER_TYPE_FULL_GUEST);
736     }
737 
738 
739 }
740