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 
17 package com.android.systemui.car.userpicker;
18 
19 import static android.view.Display.INVALID_DISPLAY;
20 
21 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
22 
23 import static com.google.common.truth.Truth.assertThat;
24 
25 import android.content.pm.UserInfo;
26 import android.os.UserManager;
27 import android.testing.AndroidTestingRunner;
28 import android.testing.TestableLooper;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.widget.TextView;
32 
33 import androidx.test.ext.junit.rules.ActivityScenarioRule;
34 import androidx.test.filters.SmallTest;
35 
36 import com.android.systemui.R;
37 import com.android.systemui.car.CarSystemUiTest;
38 import com.android.systemui.car.userswitcher.UserIconProvider;
39 
40 import org.junit.Before;
41 import org.junit.Ignore;
42 import org.junit.Rule;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.Mock;
46 import org.mockito.MockitoAnnotations;
47 
48 import java.util.List;
49 
50 /** Test for the RecyclerView contained in the UserPickerActivity (not a separate class) */
51 @CarSystemUiTest
52 @RunWith(AndroidTestingRunner.class)
53 @TestableLooper.RunWithLooper
54 @SmallTest
55 public class UserPickerRecyclerViewTest extends UserPickerTestCase {
56     @Rule
57     public ActivityScenarioRule<UserPickerRecyclerViewTestActivity> mActivityRule =
58             new ActivityScenarioRule(UserPickerRecyclerViewTestActivity.class);
59 
60     @Mock
61     private UserIconProvider mMockUserIconProvider;
62     @Mock
63     private UserManager mMockUserManager;
64 
65     private UserRecord mDriver;
66     private UserRecord mFront;
67     private UserRecord mRear;
68     private List<UserRecord> mUserList = null;
69 
70     class OnClickListenerCreator extends UserRecord.OnClickListenerCreatorBase {
71         @Override
createOnClickListenerWithUserRecord()72         View.OnClickListener createOnClickListenerWithUserRecord() {
73             return holderView -> {};
74         }
75     }
76 
77     @Before
setUp()78     public void setUp() {
79         MockitoAnnotations.initMocks(this);
80 
81         doReturn(mDriverUserInfo).when(mMockUserManager).getUserInfo(USER_ID_DRIVER);
82         doReturn(mFrontUserInfo).when(mMockUserManager).getUserInfo(USER_ID_FRONT);
83         doReturn(mRearUserInfo).when(mMockUserManager).getUserInfo(USER_ID_REAR);
84         mContext.addMockSystemService(UserManager.class, mMockUserManager);
85         doReturn(FRONT_PASSENGER_DISPLAY_ID).when(mContext).getDisplayId();
86 
87         mDriver = UserRecord.create(mDriverUserInfo, /* mName= */ mDriverUserInfo.name,
88                 /* mIsStartGuestSession= */ false, /* mIsAddUser= */ false,
89                 /* mIsForeground= */ true,
90                 /* mIcon= */ mMockUserIconProvider.getRoundedUserIcon(mDriverUserInfo, mContext),
91                 /* OnClickListenerMaker */ new OnClickListenerCreator(), /* mIsLoggedIn= */ true,
92                 /* mLoggedInDisplay= */ MAIN_DISPLAY_ID,
93                 /* mSeatLocationName= */ USER_NAME_DRIVER, /* mIsStopping= */ false);
94         mFront = UserRecord.create(mFrontUserInfo, /* mName= */ mFrontUserInfo.name,
95                 /* mIsStartGuestSession= */ false, /* mIsAddUser= */ false,
96                 /* mIsForeground= */ false,
97                 /* mIcon= */ mMockUserIconProvider.getRoundedUserIcon(mFrontUserInfo, mContext),
98                 /* OnClickListenerMaker */ new OnClickListenerCreator(), /* mIsLoggedIn= */ true,
99                 /* mLoggedInDisplay= */ FRONT_PASSENGER_DISPLAY_ID,
100                 /* mSeatLocationName= */ USER_NAME_FRONT, /* mIsStopping= */ false);
101         mRear = UserRecord.create(mRearUserInfo, /* mName= */ mRearUserInfo.name,
102                 /* mIsStartGuestSession= */ false, /* mIsAddUser= */ false,
103                 /* mIsForeground= */ false,
104                 /* mIcon= */ mMockUserIconProvider.getRoundedUserIcon(mRearUserInfo, mContext),
105                 /* OnClickListenerMaker */ new OnClickListenerCreator(), /* mIsLoggedIn= */ false,
106                 /* mLoggedInDisplay= */ INVALID_DISPLAY,
107                 /* mSeatLocationName= */ "", /* mIsStopping= */ false);
108     }
109 
updateUsers_refreshView(UserPickerAdapter adapter, List<UserRecord> mUserList)110     void updateUsers_refreshView(UserPickerAdapter adapter, List<UserRecord> mUserList) {
111         adapter.updateUsers(mUserList);
112         adapter.notifyDataSetChanged();
113     }
114 
getPositionOnPrimaryGrid(String name)115     int getPositionOnPrimaryGrid(String name) {
116         if (name == null || mUserList == null) {
117             return -1;
118         } else if (name.equals(mGuestLabel)) {
119             return mUserList.size() - 2;
120         } else if (name.equals(mAddLabel)) {
121             return mUserList.size() - 1;
122         } else {
123             for (int i = 0; i < mUserList.size(); i++) {
124                 if (name.equals(mUserList.get(i).mName)) {
125                     return i;
126                 }
127             }
128             return -1;
129         }
130     }
131 
isHighlightingfromUserPod(ViewGroup vg)132     Boolean isHighlightingfromUserPod(ViewGroup vg) {
133         ViewGroup avatar = (ViewGroup) vg.getChildAt(0);
134         View v = (View) avatar.getChildAt(1);
135         return v.getVisibility() == View.VISIBLE;
136     }
137 
getUserNamefromUserPod(ViewGroup vg)138     String getUserNamefromUserPod(ViewGroup vg) {
139         TextView t = (TextView) vg.getChildAt(1);
140         return t.getText().toString();
141     }
142 
getUserDescfromUserPod(ViewGroup vg)143     String getUserDescfromUserPod(ViewGroup vg) {
144         TextView t = (TextView) vg.getChildAt(2);
145         return t.getText().toString();
146     }
147 
148     @Test
149     @Ignore("b/281125325")
checkUserList_changeUserState_frontUserLoggedIn()150     public void checkUserList_changeUserState_frontUserLoggedIn() {
151         UserRecord mGuest = UserRecord.create(/* mInfo= */ null, /* mName= */ mGuestLabel,
152                 /* mIsStartGuestSession= */ true, /* mIsAddUser= */ false,
153                 /* mIsForeground= */ false,
154                 mMockUserIconProvider.getRoundedGuestDefaultIcon(mContext),
155                 /* OnClickListenerMaker */ new OnClickListenerCreator(), false, INVALID_DISPLAY,
156                 /* mSeatLocationName= */"", /* mIsStopping= */ false);
157         UserRecord mAddUser = UserRecord.create(/* mInfo= */ null, /* mName= */ mAddLabel,
158                 /* mIsStartGuestSession= */ false, /* mIsAddUser= */ true,
159                 /* mIsForeground= */ false,
160                 /* mIcon= */ mContext.getDrawable(R.drawable.car_add_circle_round),
161                 /* OnClickListenerMaker */ new OnClickListenerCreator());
162         mUserList = List.of(mDriver, mFront, mRear, mGuest, mAddUser);
163         mActivityRule.getScenario().onActivity(activity -> {
164             updateUsers_refreshView(activity.mAdapter, mUserList);
165 
166             View userIcon = activity.mUserPickerView.getRecyclerViewChildAt(
167                     getPositionOnPrimaryGrid(USER_NAME_DRIVER));
168             assertThat(getUserDescfromUserPod(((ViewGroup) userIcon)))
169                     .isEqualTo(mContext.getString(R.string.prefix_logged_in_info_for_other_seat,
170                             USER_NAME_DRIVER));
171             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isFalse();
172             userIcon = activity.mUserPickerView.getRecyclerViewChildAt(
173                     getPositionOnPrimaryGrid(USER_NAME_FRONT));
174             assertThat(getUserDescfromUserPod(((ViewGroup) userIcon))).isEqualTo(mLoggedinLabel);
175 
176             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isTrue();
177             userIcon = activity.mUserPickerView
178                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(USER_NAME_REAR));
179             assertThat(getUserDescfromUserPod(((ViewGroup) userIcon))).isEqualTo("");
180             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isFalse();
181             userIcon = activity.mUserPickerView
182                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(mGuestLabel));
183             assertThat(getUserDescfromUserPod(((ViewGroup) userIcon))).isEqualTo("");
184             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isFalse();
185             userIcon = activity.mUserPickerView
186                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(mAddLabel));
187             assertThat(getUserDescfromUserPod(((ViewGroup) userIcon))).isEqualTo("");
188             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isFalse();
189         });
190     }
191 
192     @Test
193     @Ignore("b/281125325")
checkUserList_logoutState_frontUserLoggedOut()194     public void checkUserList_logoutState_frontUserLoggedOut() {
195         mFront = UserRecord.create(mFrontUserInfo, /* mName= */ mFrontUserInfo.name,
196                 /* mIsStartGuestSession= */ false, /* mIsAddUser= */ false,
197                 /* mIsForeground= */ false,
198                 /* mIcon= */ mMockUserIconProvider.getRoundedUserIcon(mFrontUserInfo, mContext),
199                 /* OnClickListenerMaker */ new OnClickListenerCreator(), /* mIsLoggedIn= */ false,
200                 /* mLoggedInDisplay= */ -1,
201                 /* mSeatLocationName= */ "Test", /* mIsStopping= */ false);
202         UserRecord mGuest = UserRecord.create(/* mInfo= */ null, /* mName= */ mGuestLabel,
203                 /* mIsStartGuestSession= */ true, /* mIsAddUser= */ false,
204                 /* mIsForeground= */ false,
205                 mMockUserIconProvider.getRoundedGuestDefaultIcon(mContext),
206                 /* OnClickListenerMaker */ new OnClickListenerCreator(), false, INVALID_DISPLAY,
207                 /* mSeatLocationName= */"", /* mIsStopping= */ false);
208         UserRecord mAddUser = UserRecord.create(/* mInfo= */ null, /* mName= */ mAddLabel,
209                 /* mIsStartGuestSession= */ false, /* mIsAddUser= */ true,
210                 /* mIsForeground= */ false,
211                 /* mIcon= */ mContext.getDrawable(R.drawable.car_add_circle_round),
212                 /* OnClickListenerMaker */ new OnClickListenerCreator());
213         mUserList = List.of(mDriver, mFront, mRear, mGuest, mAddUser);
214         mActivityRule.getScenario().onActivity(activity -> {
215             updateUsers_refreshView(activity.mAdapter, mUserList);
216 
217             View userIcon = activity.mUserPickerView
218                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(USER_NAME_DRIVER));
219             assertThat(getUserDescfromUserPod(((ViewGroup) userIcon)))
220                     .isEqualTo(mContext.getString(R.string.prefix_logged_in_info_for_other_seat,
221                             USER_NAME_DRIVER));
222             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isFalse();
223             userIcon = activity.mUserPickerView
224                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(USER_NAME_FRONT));
225             assertThat(getUserDescfromUserPod(((ViewGroup) userIcon))).isEqualTo("");
226             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isFalse();
227             userIcon = activity.mUserPickerView
228                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(USER_NAME_REAR));
229             assertThat(getUserDescfromUserPod(((ViewGroup) userIcon))).isEqualTo("");
230             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isFalse();
231             userIcon = activity.mUserPickerView
232                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(mGuestLabel));
233             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isFalse();
234             userIcon = activity.mUserPickerView
235                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(mAddLabel));
236             assertThat(isHighlightingfromUserPod(((ViewGroup) userIcon))).isFalse();
237         });
238     }
239 
240     @Test
updateUserList_addUser_increaseUserCount()241     public void updateUserList_addUser_increaseUserCount() {
242         mUserList = List.of(mDriver, mFront, mRear);
243         mActivityRule.getScenario().onActivity(activity -> {
244             updateUsers_refreshView(activity.mAdapter, mUserList);
245             int prevRecordCount = activity.mAdapter.getItemCount();
246 
247             String newUsername = "New";
248             UserInfo newUserInfo = new UserInfo(USER_ID_REAR + 1, newUsername, UserInfo.FLAG_FULL);
249             UserRecord mNew = UserRecord.create(newUserInfo, /* mName= */ newUserInfo.name,
250                     /* mIsStartGuestSession= */ false, /* mIsAddUser= */ false,
251                     /* mIsForeground= */ false,
252                     /* mIcon= */ mMockUserIconProvider.getRoundedUserIcon(newUserInfo, mContext),
253                     /* OnClickListenerMaker */ new OnClickListenerCreator(), /* mIsLoggedIn= */
254                     false,
255                     /* mLoggedInDisplay= */ INVALID_DISPLAY,
256                     /* mSeatLocationName= */ "", /* mIsStopping= */ false);
257             mUserList = List.of(mDriver, mFront, mNew, mRear);
258             updateUsers_refreshView(activity.mAdapter, mUserList);
259 
260             assertThat(activity.mAdapter.getItemCount()).isEqualTo(prevRecordCount + 1);
261             assertThat(getPositionOnPrimaryGrid(newUsername))
262                     .isEqualTo(getPositionOnPrimaryGrid(USER_NAME_FRONT) + 1);
263             assertThat(getPositionOnPrimaryGrid(newUsername))
264                     .isEqualTo(getPositionOnPrimaryGrid(USER_NAME_REAR) - 1);
265         });
266     }
267 
268     @Test
updateUserList_removeUser_decreaseUserCount()269     public void updateUserList_removeUser_decreaseUserCount() {
270         mUserList = List.of(mDriver, mFront, mRear);
271         mActivityRule.getScenario().onActivity(activity -> {
272             updateUsers_refreshView(activity.mAdapter, mUserList);
273             int prevRecordCount = activity.mAdapter.getItemCount();
274 
275             mUserList = List.of(mDriver, mRear);
276             updateUsers_refreshView(activity.mAdapter, mUserList);
277 
278             assertThat(activity.mAdapter.getItemCount()).isEqualTo(prevRecordCount - 1);
279             assertThat(getPositionOnPrimaryGrid(USER_NAME_REAR))
280                     .isEqualTo(getPositionOnPrimaryGrid(USER_NAME_DRIVER) + 1);
281         });
282     }
283 
284     @Test
285     @Ignore("b/281125325")
updateUserList_loginUser_changedRearPassengerDesc()286     public void updateUserList_loginUser_changedRearPassengerDesc() {
287         mUserList = List.of(mDriver, mFront, mRear);
288         mActivityRule.getScenario().onActivity(activity -> {
289             updateUsers_refreshView(activity.mAdapter, mUserList);
290 
291             View RearButton = activity.mUserPickerView.getRecyclerViewChildAt(
292                     getPositionOnPrimaryGrid(USER_NAME_REAR));
293             assertThat(getUserNamefromUserPod(((ViewGroup) RearButton))).isEqualTo(USER_NAME_REAR);
294             assertThat(getUserDescfromUserPod(((ViewGroup) RearButton))).isEqualTo("");
295             mRear = UserRecord.create(mRearUserInfo, /* mName= */ mRearUserInfo.name,
296                     /* mIsStartGuestSession= */ false, /* mIsAddUser= */ false,
297                     /* mIsForeground= */ false,
298                     /* mIcon= */ mMockUserIconProvider.getRoundedUserIcon(mRearUserInfo, mContext),
299                     /* OnClickListenerMaker */ new OnClickListenerCreator(), /* mIsLoggedIn= */
300                     true,
301                     /* mLoggedInDisplay= */ REAR_PASSENGER_DISPLAY_ID,
302                     /* mSeatLocationName= */ USER_NAME_REAR, /* mIsStopping= */ false);
303             mUserList = List.of(mDriver, mFront, mRear);
304             updateUsers_refreshView(activity.mAdapter, mUserList);
305 
306             RearButton = activity.mUserPickerView.getRecyclerViewChildAt(
307                     getPositionOnPrimaryGrid(USER_NAME_REAR));
308             assertThat(getUserDescfromUserPod(((ViewGroup) RearButton)))
309                     .isEqualTo(mContext.getString(R.string.prefix_logged_in_info_for_other_seat,
310                             USER_NAME_REAR));
311         });
312     }
313 
314     @Test
315     @Ignore("b/281125325")
updateUserList_logoutUser_changedRearPassengerDesc()316     public void updateUserList_logoutUser_changedRearPassengerDesc() {
317         mRear = UserRecord.create(mRearUserInfo, /* mName= */ mRearUserInfo.name,
318                 /* mIsStartGuestSession= */ false, /* mIsAddUser= */ false,
319                 /* mIsForeground= */ false,
320                 /* mIcon= */ mMockUserIconProvider.getRoundedUserIcon(mRearUserInfo, mContext),
321                 /* OnClickListenerMaker */ new OnClickListenerCreator(), /* mIsLoggedIn= */ true,
322                 /* mLoggedInDisplay= */ REAR_PASSENGER_DISPLAY_ID,
323                 /* mSeatLocationName= */ USER_NAME_REAR, /* mIsStopping= */ false);
324         mUserList = List.of(mDriver, mFront, mRear);
325         mActivityRule.getScenario().onActivity(activity -> {
326             updateUsers_refreshView(activity.mAdapter, mUserList);
327 
328             View rearPassengerUserIcon = activity.mUserPickerView
329                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(USER_NAME_REAR));
330             assertThat(getUserDescfromUserPod(((ViewGroup) rearPassengerUserIcon)))
331                     .isEqualTo(mContext.getString(R.string.prefix_logged_in_info_for_other_seat,
332                             USER_NAME_REAR));
333             mRear = UserRecord.create(mRearUserInfo, /* mName= */ mRearUserInfo.name,
334                     /* mIsStartGuestSession= */ false, /* mIsAddUser= */ false,
335                     /* mIsForeground= */ false,
336                     /* mIcon= */ mMockUserIconProvider.getRoundedUserIcon(mRearUserInfo, mContext),
337                     /* OnClickListenerMaker */ new OnClickListenerCreator(), /* mIsLoggedIn= */
338                     false,
339                     /* mLoggedInDisplay= */ INVALID_DISPLAY,
340                     /* mSeatLocationName= */ "", /* mIsStopping= */ false);
341             mUserList = List.of(mDriver, mFront, mRear);
342             updateUsers_refreshView(activity.mAdapter, mUserList);
343 
344             rearPassengerUserIcon = activity.mUserPickerView
345                     .getRecyclerViewChildAt(getPositionOnPrimaryGrid(USER_NAME_REAR));
346             assertThat(getUserDescfromUserPod(((ViewGroup) rearPassengerUserIcon))).isEqualTo("");
347         });
348     }
349 
350     @Test
351     @Ignore("b/281125325")
updateUserList_changeName_changedUserName()352     public void updateUserList_changeName_changedUserName() {
353         String changeName = "Test";
354         mUserList = List.of(mDriver, mFront, mRear);
355         mActivityRule.getScenario().onActivity(activity -> {
356             updateUsers_refreshView(activity.mAdapter, mUserList);
357             View rearPassengerUserIcon = activity.mUserPickerView
358                     .getRecyclerViewChildAt(mUserList.size() - 1);
359             assertThat(getUserNamefromUserPod(((ViewGroup) rearPassengerUserIcon)))
360                     .isEqualTo(USER_NAME_REAR);
361 
362             mRearUserInfo.name = changeName;
363             mRear = UserRecord.create(mRearUserInfo, /* mName= */ mRearUserInfo.name,
364                     /* mIsStartGuestSession= */ false, /* mIsAddUser= */ false,
365                     /* mIsForeground= */ false,
366                     /* mIcon= */ mMockUserIconProvider.getRoundedUserIcon(mRearUserInfo, mContext),
367                     /* OnClickListenerMaker */ new OnClickListenerCreator(), /* mIsLoggedIn= */
368                     false,
369                     /* mLoggedInDisplay= */ INVALID_DISPLAY,
370                     /* mSeatLocationName= */ "", /* mIsStopping= */ false);
371             mUserList = List.of(mDriver, mFront, mRear);
372             updateUsers_refreshView(activity.mAdapter, mUserList);
373 
374             rearPassengerUserIcon = activity.mUserPickerView
375                     .getRecyclerViewChildAt(mUserList.size() - 1);
376             assertThat(getUserNamefromUserPod(((ViewGroup) rearPassengerUserIcon)))
377                     .isEqualTo(changeName);
378         });
379     }
380 }
381