• 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.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