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