• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 package com.android.systemui.car.userpicker;
17 
18 import static android.car.CarOccupantZoneManager.INVALID_USER_ID;
19 import static android.view.Display.INVALID_DISPLAY;
20 
21 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
22 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
23 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
24 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
26 
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.ArgumentMatchers.anyBoolean;
29 import static org.mockito.ArgumentMatchers.anyInt;
30 import static org.mockito.ArgumentMatchers.anyString;
31 import static org.mockito.ArgumentMatchers.eq;
32 import static org.mockito.Mockito.after;
33 
34 import android.app.ActivityManager;
35 import android.car.test.mocks.AndroidMockitoHelper;
36 import android.car.user.UserCreationResult;
37 import android.content.pm.UserInfo;
38 import android.testing.AndroidTestingRunner;
39 import android.testing.TestableLooper;
40 import android.view.View;
41 
42 import androidx.test.filters.SmallTest;
43 
44 import com.android.systemui.R;
45 import com.android.systemui.car.CarSystemUiTest;
46 import com.android.systemui.car.userpicker.UserPickerController.Callbacks;
47 import com.android.systemui.car.userswitcher.UserIconProvider;
48 import com.android.systemui.settings.DisplayTracker;
49 
50 import com.google.android.material.snackbar.Snackbar;
51 
52 import org.junit.After;
53 import org.junit.Before;
54 import org.junit.Test;
55 import org.junit.runner.RunWith;
56 import org.mockito.Mock;
57 import org.mockito.MockitoSession;
58 import org.mockito.quality.Strictness;
59 
60 import java.util.ArrayList;
61 import java.util.List;
62 
63 @CarSystemUiTest
64 @RunWith(AndroidTestingRunner.class)
65 @TestableLooper.RunWithLooper
66 @SmallTest
67 public class UserPickerControllerTest extends UserPickerTestCase {
68     private UserPickerController mUserPickerController;
69     private SnackbarManager mSnackbarManager;
70     private UserPickerSharedState mUserPickerSharedState;
71 
72     @Mock
73     private DialogManager mMockDialogManager;
74     @Mock
75     private CarServiceMediator mMockCarServiceMediator;
76     @Mock
77     private UserEventManager mMockUserEventManager;
78     @Mock
79     private DisplayTracker mMockDisplayTracker;
80     @Mock
81     private Callbacks mMockCallbacks;
82     @Mock
83     private UserCreationResult mCreateResult;
84 
85     private List<UserInfo> mAliveUsers = new ArrayList<UserInfo>();
86     private List<UserRecord> mUserRecords = null;
87     private MockitoSession mMockingSession;
88 
89     @Before
setUp()90     public void setUp() {
91         mMockingSession = mockitoSession()
92                 .initMocks(this)
93                 .spyStatic(ActivityManager.class)
94                 .spyStatic(Snackbar.class)
95                 .strictness(Strictness.WARN)
96                 .startMocking();
97 
98         mAliveUsers.clear();
99         doReturn(mAliveUsers).when(mMockUserEventManager).getAliveUsers();
100         doReturn(mDriverUserInfo).when(mMockUserEventManager).getCurrentForegroundUserInfo();
101     }
102 
103     @After
tearDown()104     public void tearDown() {
105         if (mMockingSession != null) {
106             mMockingSession.finishMocking();
107         }
108     }
109 
displaySetup(boolean isLogoutState, int displayId)110     void displaySetup(boolean isLogoutState, int displayId) {
111         mAliveUsers.add(mDriverUserInfo);
112         doReturn(true).when(mMockUserEventManager).isUserRunning(USER_ID_DRIVER);
113         doReturn(MAIN_DISPLAY_ID).when(mMockCarServiceMediator).getDisplayIdForUser(USER_ID_DRIVER);
114         doReturn(USER_ID_DRIVER).when(mMockCarServiceMediator).getUserForDisplay(MAIN_DISPLAY_ID);
115 
116         mAliveUsers.add(mFrontUserInfo);
117         if (isLogoutState) {
118             doReturn(INVALID_DISPLAY).when(mMockCarServiceMediator)
119                     .getDisplayIdForUser(USER_ID_FRONT);
120             doReturn(INVALID_USER_ID).when(mMockCarServiceMediator)
121                     .getUserForDisplay(FRONT_PASSENGER_DISPLAY_ID);
122         } else {
123             doReturn(true).when(mMockUserEventManager).isUserRunning(USER_ID_FRONT);
124             doReturn(FRONT_PASSENGER_DISPLAY_ID).when(mMockCarServiceMediator)
125                     .getDisplayIdForUser(USER_ID_FRONT);
126             doReturn(USER_ID_FRONT).when(mMockCarServiceMediator)
127                     .getUserForDisplay(FRONT_PASSENGER_DISPLAY_ID);
128         }
129 
130         mAliveUsers.add(mRearUserInfo);
131         doReturn(INVALID_DISPLAY).when(mMockCarServiceMediator).getDisplayIdForUser(USER_ID_REAR);
132         doReturn(INVALID_USER_ID).when(mMockCarServiceMediator)
133                 .getUserForDisplay(REAR_PASSENGER_DISPLAY_ID);
134 
135         doReturn(displayId).when(mContext).getDisplayId();
136         doReturn(MAIN_DISPLAY_ID).when(mMockDisplayTracker).getDefaultDisplayId();
137 
138         mSnackbarManager = new SnackbarManager();
139         mUserPickerSharedState = new UserPickerSharedState();
140         View rootView = mInflater.inflate(R.layout.test_empty_layout, null);
141         mSnackbarManager.setRootView(rootView, R.id.test_empty_layout_frame);
142 
143         mUserPickerController = new UserPickerController(mContext, mMockUserEventManager,
144                 mMockCarServiceMediator, mMockDialogManager, mSnackbarManager,
145                 mMockDisplayTracker, mUserPickerSharedState, mock(UserIconProvider.class));
146         mUserPickerController.init(mMockCallbacks, displayId);
147         mUserPickerController.onConfigurationChanged();
148         AndroidMockitoHelper.mockAmGetCurrentUser(USER_ID_DRIVER);
149         mUserPickerController.updateUsers();
150         mUserRecords = mUserPickerController.createUserRecords();
151     }
152 
getUserRecord(String name)153     UserRecord getUserRecord(String name) {
154         if (name != null) {
155             for (int i = 0; i < mUserRecords.size(); i++) {
156                 if (name.equals(mUserRecords.get(i).mName)) {
157                     return mUserRecords.get(i);
158                 }
159             }
160         }
161         return null;
162     }
163 
164     @Test
loginItself_changeUserState_finishUserPicker()165     public void loginItself_changeUserState_finishUserPicker() {
166         displaySetup(/* isLogoutState= */ false, /* displayId= */ FRONT_PASSENGER_DISPLAY_ID);
167 
168         mUserPickerController.handleUserSelected(getUserRecord(USER_NAME_FRONT));
169 
170         verify(mMockUserEventManager, after(IDLE_TIMEOUT).never())
171                 .startUserForDisplay(anyInt(), anyInt(), anyInt(), anyBoolean());
172         verify(mMockCallbacks, after(IDLE_TIMEOUT)).onFinishRequested();
173     }
174 
175     @Test
checkSnackbar_loginDriverUser_showSnackbar()176     public void checkSnackbar_loginDriverUser_showSnackbar() {
177         Snackbar snackbar = mock(Snackbar.class);
178         doReturn(snackbar).when(() -> Snackbar.make(any(View.class), any(String.class), anyInt()));
179         displaySetup(/* isLogoutState= */ false, /* displayId= */ FRONT_PASSENGER_DISPLAY_ID);
180         spyOn(mSnackbarManager);
181 
182         mUserPickerController.handleUserSelected(getUserRecord(USER_NAME_DRIVER));
183 
184         verify(mMockUserEventManager, after(IDLE_TIMEOUT).never())
185                 .startUserForDisplay(anyInt(), anyInt(), anyInt(), anyBoolean());
186         verify(mSnackbarManager, after(IDLE_TIMEOUT)).showSnackbar(anyString());
187     }
188 
189     @Test
checkSwitchUser_changeUserState_switchUser()190     public void checkSwitchUser_changeUserState_switchUser() {
191         displaySetup(/* isLogoutState= */ false, /* displayId= */ MAIN_DISPLAY_ID);
192 
193         mUserPickerController.handleUserSelected((getUserRecord(USER_NAME_REAR)));
194 
195         verify(mMockUserEventManager, after(IDLE_TIMEOUT).never()).createNewUser();
196         verify(mMockUserEventManager, after(IDLE_TIMEOUT))
197                 .startUserForDisplay(anyInt(), eq(USER_ID_REAR), anyInt(), anyBoolean());
198     }
199 
200     @Test
checkChangeUser_changeUserState_changeUser()201     public void checkChangeUser_changeUserState_changeUser() {
202         doReturn(true).when(mMockUserEventManager).stopUserUnchecked(anyInt(), anyInt());
203         displaySetup(/* isLogoutState= */ false, /* displayId= */ FRONT_PASSENGER_DISPLAY_ID);
204 
205         mUserPickerController.handleUserSelected(getUserRecord(USER_NAME_REAR));
206 
207         verify(mMockUserEventManager, after(IDLE_TIMEOUT).atLeastOnce())
208                 .stopUserUnchecked(USER_ID_FRONT, FRONT_PASSENGER_DISPLAY_ID);
209         verify(mMockUserEventManager, after(IDLE_TIMEOUT))
210                 .startUserForDisplay(anyInt(), eq(USER_ID_REAR), anyInt(), anyBoolean());
211     }
212 
213     @Test
checkLoginUser_logoutState_startUser()214     public void checkLoginUser_logoutState_startUser() {
215         doReturn(true).when(mMockUserEventManager).stopUserUnchecked(anyInt(), anyInt());
216         displaySetup(/* isLogoutState= */ true, /* displayId= */ FRONT_PASSENGER_DISPLAY_ID);
217 
218         mUserPickerController.handleUserSelected(getUserRecord(USER_NAME_REAR));
219 
220         verify(mMockUserEventManager, after(IDLE_TIMEOUT).never())
221                 .stopUserUnchecked(anyInt(), anyInt());
222         verify(mMockUserEventManager, after(IDLE_TIMEOUT))
223                 .startUserForDisplay(anyInt(), eq(USER_ID_REAR), anyInt(), anyBoolean());
224     }
225 
226     @Test
checkCreateGuest_pressGuestIcon_createdGuestUser()227     public void checkCreateGuest_pressGuestIcon_createdGuestUser() {
228         UserInfo guestInfo = new UserInfo(USER_ID_GUEST, "G", UserInfo.FLAG_GUEST);
229         doReturn(true).when(mCreateResult).isSuccess();
230         doReturn(mCreateResult).when(mMockUserEventManager).createGuest();
231         doReturn(guestInfo.getUserHandle()).when(mCreateResult).getUser();
232         doReturn(guestInfo).when(mMockUserEventManager).getUserInfo(USER_ID_GUEST);
233         doReturn(true).when(mMockUserEventManager).stopUserUnchecked(anyInt(), anyInt());
234         displaySetup(/* isLogoutState= */ false, /* displayId= */ FRONT_PASSENGER_DISPLAY_ID);
235 
236         mUserPickerController.handleUserSelected(getUserRecord(mGuestLabel));
237 
238         verify(mMockUserEventManager, after(IDLE_TIMEOUT)).createGuest();
239         verify(mMockUserEventManager, after(IDLE_TIMEOUT).atLeastOnce())
240                 .stopUserUnchecked(USER_ID_FRONT, FRONT_PASSENGER_DISPLAY_ID);
241         verify(mMockUserEventManager, after(IDLE_TIMEOUT))
242                 .startUserForDisplay(anyInt(), eq(USER_ID_GUEST), anyInt(), anyBoolean());
243     }
244 
245     @Test
checkAddNewUser_pressAddUserIcon_createdUser()246     public void checkAddNewUser_pressAddUserIcon_createdUser() {
247         UserInfo newUserInfo = new UserInfo(USER_ID_REAR + 1, "New", UserInfo.FLAG_FULL);
248         doReturn(true).when(mCreateResult).isSuccess();
249         doReturn(mCreateResult).when(mMockUserEventManager).createNewUser();
250         doReturn(true).when(mMockUserEventManager).stopUserUnchecked(anyInt(), anyInt());
251         doReturn(newUserInfo.getUserHandle()).when(mCreateResult).getUser();
252         doReturn(newUserInfo).when(mMockUserEventManager)
253                 .getUserInfo(newUserInfo.getUserHandle().getIdentifier());
254         displaySetup(/* isLogoutState= */ false, /* displayId= */ FRONT_PASSENGER_DISPLAY_ID);
255 
256         mUserPickerController.startAddNewUser();
257 
258         verify(mMockUserEventManager, after(IDLE_TIMEOUT)).createNewUser();
259         verify(mMockUserEventManager, after(IDLE_TIMEOUT).atLeastOnce())
260                 .stopUserUnchecked(USER_ID_FRONT, FRONT_PASSENGER_DISPLAY_ID);
261         verify(mMockUserEventManager, after(IDLE_TIMEOUT))
262                 .startUserForDisplay(anyInt(), eq(USER_ID_REAR + 1), anyInt(), anyBoolean());
263     }
264 
265     @Test
checkDestroyController_callOnDestroy_destroyAll()266     public void checkDestroyController_callOnDestroy_destroyAll() {
267         displaySetup(/* isLogoutState= */ false, /* displayId= */ FRONT_PASSENGER_DISPLAY_ID);
268         spyOn(mUserPickerSharedState);
269 
270         mUserPickerController.onDestroy();
271 
272         verify(mUserPickerSharedState).resetUserLoginStarted(eq(FRONT_PASSENGER_DISPLAY_ID));
273         verify(mMockUserEventManager)
274                 .unregisterOnUpdateUsersListener(eq(FRONT_PASSENGER_DISPLAY_ID));
275     }
276 }
277