Home | History | Annotate | Download | only in car
      1 /*
      2  * Copyright (C) 2018 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.car;
     18 
     19 import static com.google.common.truth.Truth.assertThat;
     20 
     21 import static org.mockito.Mockito.verify;
     22 import static org.mockito.Mockito.when;
     23 
     24 import android.app.ActivityManager;
     25 import android.car.user.CarUserManagerHelper;
     26 import android.content.BroadcastReceiver;
     27 import android.content.Context;
     28 import android.content.Intent;
     29 import android.content.IntentFilter;
     30 import android.content.pm.UserInfo;
     31 import android.graphics.Bitmap;
     32 import android.graphics.drawable.Drawable;
     33 import android.os.Handler;
     34 import android.os.SystemProperties;
     35 import android.os.UserHandle;
     36 import android.os.UserManager;
     37 import android.support.test.InstrumentationRegistry;
     38 import android.support.test.runner.AndroidJUnit4;
     39 
     40 import org.junit.Before;
     41 import org.junit.Test;
     42 import org.junit.runner.RunWith;
     43 import org.mockito.ArgumentCaptor;
     44 import org.mockito.Mock;
     45 import org.mockito.MockitoAnnotations;
     46 
     47 import java.util.ArrayList;
     48 import java.util.List;
     49 
     50 /**
     51  * This class contains unit tests for the {@link CarUserManagerHelper}.
     52  * It tests that {@link CarUserManagerHelper} does the right thing for user management flows.
     53  *
     54  * The following mocks are used:
     55  * 1. {@link Context} provides system services and resources.
     56  * 2. {@link UserManager} provides dummy users and user info.
     57  * 3. {@link ActivityManager} provides dummy current process user.
     58  * 4. {@link CarUserManagerHelper.OnUsersUpdateListener} registers a listener for user updates.
     59  */
     60 @RunWith(AndroidJUnit4.class)
     61 public class CarUserManagerHelperTest {
     62     @Mock
     63     private Context mContext;
     64     @Mock
     65     private UserManager mUserManager;
     66     @Mock
     67     private ActivityManager mActivityManager;
     68     @Mock
     69     private CarUserManagerHelper.OnUsersUpdateListener mTestListener;
     70 
     71     private CarUserManagerHelper mHelper;
     72     private UserInfo mCurrentProcessUser;
     73     private UserInfo mSystemUser;
     74     private String mGuestUserName = "testGuest";
     75     private String mTestUserName = "testUser";
     76 
     77     @Before
     78     public void setUpMocksAndVariables() throws Exception {
     79         MockitoAnnotations.initMocks(this);
     80         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
     81         when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager);
     82         when(mContext.getResources())
     83             .thenReturn(InstrumentationRegistry.getTargetContext().getResources());
     84         when(mContext.getApplicationContext()).thenReturn(mContext);
     85         mHelper = new CarUserManagerHelper(mContext);
     86 
     87         mCurrentProcessUser = createUserInfoForId(UserHandle.myUserId());
     88         mSystemUser = createUserInfoForId(UserHandle.USER_SYSTEM);
     89         when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(mCurrentProcessUser);
     90     }
     91 
     92     @Test
     93     public void checkIsSystemUser() {
     94         UserInfo testInfo = new UserInfo();
     95 
     96         testInfo.id = UserHandle.USER_SYSTEM;
     97         assertThat(mHelper.isSystemUser(testInfo)).isTrue();
     98 
     99         testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
    100         assertThat(mHelper.isSystemUser(testInfo)).isFalse();
    101     }
    102 
    103     // System user will not be returned when calling get all users.
    104     @Test
    105     public void testHeadlessUser0GetAllUsers_NotReturnSystemUser() {
    106         SystemProperties.set("android.car.systemuser.headless", "true");
    107         UserInfo otherUser1 = createUserInfoForId(10);
    108         UserInfo otherUser2 = createUserInfoForId(11);
    109         UserInfo otherUser3 = createUserInfoForId(12);
    110 
    111         List<UserInfo> testUsers = new ArrayList<>();
    112         testUsers.add(mSystemUser);
    113         testUsers.add(otherUser1);
    114         testUsers.add(otherUser2);
    115         testUsers.add(otherUser3);
    116 
    117         when(mUserManager.getUsers(true)).thenReturn(testUsers);
    118 
    119         // Should return 3 users that don't have SYSTEM USER id.
    120         assertThat(mHelper.getAllUsers()).hasSize(3);
    121         assertThat(mHelper.getAllUsers())
    122             .containsExactly(otherUser1, otherUser2, otherUser3);
    123     }
    124 
    125     @Test
    126     public void testHeadlessUser0GetAllUsersWithActiveForegroundUser_NotReturnSystemUser() {
    127         SystemProperties.set("android.car.systemuser.headless", "true");
    128         mCurrentProcessUser = createUserInfoForId(10);
    129 
    130         UserInfo otherUser1 = createUserInfoForId(11);
    131         UserInfo otherUser2 = createUserInfoForId(12);
    132         UserInfo otherUser3 = createUserInfoForId(13);
    133 
    134         List<UserInfo> testUsers = new ArrayList<>();
    135         testUsers.add(mSystemUser);
    136         testUsers.add(mCurrentProcessUser);
    137         testUsers.add(otherUser1);
    138         testUsers.add(otherUser2);
    139         testUsers.add(otherUser3);
    140 
    141         when(mUserManager.getUsers(true)).thenReturn(testUsers);
    142 
    143         assertThat(mHelper.getAllUsers().size()).isEqualTo(4);
    144         assertThat(mHelper.getAllUsers())
    145             .containsExactly(mCurrentProcessUser, otherUser1, otherUser2, otherUser3);
    146     }
    147 
    148     @Test
    149     public void testGetAllSwitchableUsers() {
    150         UserInfo user1 = createUserInfoForId(10);
    151         UserInfo user2 = createUserInfoForId(11);
    152         UserInfo user3 = createUserInfoForId(12);
    153 
    154         List<UserInfo> testUsers = new ArrayList<>();
    155         testUsers.add(mSystemUser);
    156         testUsers.add(user1);
    157         testUsers.add(user2);
    158         testUsers.add(user3);
    159 
    160         when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers));
    161 
    162         // Should return all 3 non-system users.
    163         assertThat(mHelper.getAllUsers().size())
    164                 .isEqualTo(3);
    165 
    166         when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(user1);
    167         // Should return user 10, 11 and 12.
    168         assertThat(mHelper.getAllSwitchableUsers().size())
    169                 .isEqualTo(3);
    170         assertThat(mHelper.getAllSwitchableUsers()).contains(user1);
    171         assertThat(mHelper.getAllSwitchableUsers()).contains(user2);
    172         assertThat(mHelper.getAllSwitchableUsers()).contains(user3);
    173     }
    174 
    175     // Get all users for headless user 0 model should exclude system user by default.
    176     @Test
    177     public void testHeadlessUser0GetAllSwitchableUsers() {
    178         SystemProperties.set("android.car.systemuser.headless", "true");
    179         UserInfo user1 = createUserInfoForId(10);
    180         UserInfo user2 = createUserInfoForId(11);
    181         UserInfo user3 = createUserInfoForId(12);
    182 
    183         List<UserInfo> testUsers = new ArrayList<>();
    184         testUsers.add(mSystemUser);
    185         testUsers.add(user1);
    186         testUsers.add(user2);
    187         testUsers.add(user3);
    188 
    189         when(mUserManager.getUsers(true)).thenReturn(new ArrayList<>(testUsers));
    190 
    191         // Should return all 3 non-system users.
    192         assertThat(mHelper.getAllUsers()).hasSize(3);
    193 
    194         when(mUserManager.getUserInfo(UserHandle.myUserId())).thenReturn(user1);
    195         // Should return user 10, 11 and 12.
    196         assertThat(mHelper.getAllSwitchableUsers()).containsExactly(user1, user2, user3);
    197     }
    198 
    199     @Test
    200     public void testUserCanBeRemoved() {
    201         UserInfo testInfo = new UserInfo();
    202 
    203         // System user cannot be removed.
    204         testInfo.id = UserHandle.USER_SYSTEM;
    205         assertThat(mHelper.canUserBeRemoved(testInfo)).isFalse();
    206 
    207         testInfo.id = UserHandle.USER_SYSTEM + 2; // Make it different than system id.
    208         assertThat(mHelper.canUserBeRemoved(testInfo)).isTrue();
    209     }
    210 
    211     @Test
    212     public void testCurrentProcessCanAddUsers() {
    213         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(false);
    214         assertThat(mHelper.canCurrentProcessAddUsers()).isTrue();
    215 
    216         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_USER)).thenReturn(true);
    217         assertThat(mHelper.canCurrentProcessAddUsers()).isFalse();
    218     }
    219 
    220     @Test
    221     public void testCurrentProcessCanRemoveUsers() {
    222         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(false);
    223         assertThat(mHelper.canCurrentProcessRemoveUsers()).isTrue();
    224 
    225         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_REMOVE_USER)).thenReturn(true);
    226         assertThat(mHelper.canCurrentProcessRemoveUsers()).isFalse();
    227     }
    228 
    229     @Test
    230     public void testCurrentProcessCanSwitchUsers() {
    231         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(false);
    232         assertThat(mHelper.canCurrentProcessSwitchUsers()).isTrue();
    233 
    234         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_USER_SWITCH)).thenReturn(true);
    235         assertThat(mHelper.canCurrentProcessSwitchUsers()).isFalse();
    236     }
    237 
    238     @Test
    239     public void testCurrentGuestProcessCannotModifyAccounts() {
    240         assertThat(mHelper.canCurrentProcessModifyAccounts()).isTrue();
    241 
    242         when(mUserManager.isGuestUser()).thenReturn(true);
    243         assertThat(mHelper.canCurrentProcessModifyAccounts()).isFalse();
    244     }
    245 
    246     @Test
    247     public void testCurrentDemoProcessCannotModifyAccounts() {
    248         assertThat(mHelper.canCurrentProcessModifyAccounts()).isTrue();
    249 
    250         when(mUserManager.isDemoUser()).thenReturn(true);
    251         assertThat(mHelper.canCurrentProcessModifyAccounts()).isFalse();
    252     }
    253 
    254     @Test
    255     public void testCurrentDisallowModifyAccountsProcessIsEnforced() {
    256         assertThat(mHelper.canCurrentProcessModifyAccounts()).isTrue();
    257 
    258         when(mUserManager.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS))
    259             .thenReturn(true);
    260         assertThat(mHelper.canCurrentProcessModifyAccounts()).isFalse();
    261     }
    262 
    263     @Test
    264     public void testCreateNewAdminUser() {
    265         // Verify createUser on UserManager gets called.
    266         mHelper.createNewAdminUser(mTestUserName);
    267         verify(mUserManager).createUser(mTestUserName, UserInfo.FLAG_ADMIN);
    268 
    269         when(mUserManager.createUser(mTestUserName, UserInfo.FLAG_ADMIN)).thenReturn(null);
    270         assertThat(mHelper.createNewAdminUser(mTestUserName)).isNull();
    271 
    272         UserInfo newUser = new UserInfo();
    273         newUser.name = mTestUserName;
    274         when(mUserManager.createUser(mTestUserName, UserInfo.FLAG_ADMIN)).thenReturn(newUser);
    275         assertThat(mHelper.createNewAdminUser(mTestUserName)).isEqualTo(newUser);
    276     }
    277 
    278     @Test
    279     public void testCreateNewNonAdminUser() {
    280         // Verify createUser on UserManager gets called.
    281         mHelper.createNewNonAdminUser(mTestUserName);
    282         verify(mUserManager).createUser(mTestUserName, 0);
    283 
    284         when(mUserManager.createUser(mTestUserName, 0)).thenReturn(null);
    285         assertThat(mHelper.createNewNonAdminUser(mTestUserName)).isNull();
    286 
    287         UserInfo newUser = new UserInfo();
    288         newUser.name = mTestUserName;
    289         when(mUserManager.createUser(mTestUserName, 0)).thenReturn(newUser);
    290         assertThat(mHelper.createNewNonAdminUser(mTestUserName)).isEqualTo(newUser);
    291     }
    292 
    293     @Test
    294     public void testRemoveUser() {
    295         // Cannot remove system user.
    296         assertThat(mHelper.removeUser(mSystemUser, mGuestUserName)).isFalse();
    297 
    298         // Removing non-current, non-system user, simply calls removeUser.
    299         UserInfo userToRemove = createUserInfoForId(mCurrentProcessUser.id + 2);
    300 
    301         mHelper.removeUser(userToRemove, mGuestUserName);
    302         verify(mUserManager).removeUser(mCurrentProcessUser.id + 2);
    303     }
    304 
    305     @Test
    306     public void testSwitchToGuest() {
    307         mHelper.startNewGuestSession(mGuestUserName);
    308         verify(mUserManager).createGuest(mContext, mGuestUserName);
    309 
    310         UserInfo guestInfo = new UserInfo(21, mGuestUserName, UserInfo.FLAG_GUEST);
    311         when(mUserManager.createGuest(mContext, mGuestUserName)).thenReturn(guestInfo);
    312         mHelper.startNewGuestSession(mGuestUserName);
    313         verify(mActivityManager).switchUser(21);
    314     }
    315 
    316     @Test
    317     public void testGetUserIcon() {
    318         mHelper.getUserIcon(mCurrentProcessUser);
    319         verify(mUserManager).getUserIcon(mCurrentProcessUser.id);
    320     }
    321 
    322     @Test
    323     public void testScaleUserIcon() {
    324         Bitmap fakeIcon = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
    325         Drawable scaledIcon = mHelper.scaleUserIcon(fakeIcon, 300);
    326         assertThat(scaledIcon.getIntrinsicWidth()).isEqualTo(300);
    327         assertThat(scaledIcon.getIntrinsicHeight()).isEqualTo(300);
    328     }
    329 
    330     @Test
    331     public void testSetUserName() {
    332         UserInfo testInfo = createUserInfoForId(mCurrentProcessUser.id + 3);
    333         String newName = "New Test Name";
    334         mHelper.setUserName(testInfo, newName);
    335         verify(mUserManager).setUserName(mCurrentProcessUser.id + 3, newName);
    336     }
    337 
    338     @Test
    339     public void testRegisterUserChangeReceiver() {
    340         mHelper.registerOnUsersUpdateListener(mTestListener);
    341 
    342         ArgumentCaptor<BroadcastReceiver> receiverCaptor =
    343                 ArgumentCaptor.forClass(BroadcastReceiver.class);
    344         ArgumentCaptor<UserHandle> handleCaptor = ArgumentCaptor.forClass(UserHandle.class);
    345         ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(IntentFilter.class);
    346         ArgumentCaptor<String> permissionCaptor = ArgumentCaptor.forClass(String.class);
    347         ArgumentCaptor<Handler> handlerCaptor = ArgumentCaptor.forClass(Handler.class);
    348 
    349         verify(mContext).registerReceiverAsUser(
    350                 receiverCaptor.capture(),
    351                 handleCaptor.capture(),
    352                 filterCaptor.capture(),
    353                 permissionCaptor.capture(),
    354                 handlerCaptor.capture());
    355 
    356         // Verify we're listening to Intents from ALL users.
    357         assertThat(handleCaptor.getValue()).isEqualTo(UserHandle.ALL);
    358 
    359         // Verify the presence of each intent in the filter.
    360         // Verify the exact number of filters. Every time a new intent is added, this test should
    361         // get updated.
    362         assertThat(filterCaptor.getValue().countActions()).isEqualTo(6);
    363         assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_REMOVED)).isTrue();
    364         assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_ADDED)).isTrue();
    365         assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_INFO_CHANGED)).isTrue();
    366         assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_SWITCHED)).isTrue();
    367         assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_STOPPED)).isTrue();
    368         assertThat(filterCaptor.getValue().hasAction(Intent.ACTION_USER_UNLOCKED)).isTrue();
    369 
    370         // Verify that calling the receiver calls the listener.
    371         receiverCaptor.getValue().onReceive(mContext, new Intent());
    372         verify(mTestListener).onUsersUpdate();
    373 
    374         assertThat(permissionCaptor.getValue()).isNull();
    375         assertThat(handlerCaptor.getValue()).isNull();
    376 
    377         // Unregister the receiver.
    378         mHelper.unregisterOnUsersUpdateListener();
    379         verify(mContext).unregisterReceiver(receiverCaptor.getValue());
    380     }
    381 
    382     private UserInfo createUserInfoForId(int id) {
    383         UserInfo userInfo = new UserInfo();
    384         userInfo.id = id;
    385         return userInfo;
    386     }
    387 }
    388