1 /*
2  * Copyright (C) 2020 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 #include "UserHalHelper.h"
18 
19 #include <gtest/gtest.h>
20 
21 #include <cstdint>
22 
23 #include "gmock/gmock.h"
24 
25 namespace android {
26 namespace hardware {
27 namespace automotive {
28 namespace vehicle {
29 namespace V2_0 {
30 
31 namespace user_hal_helper {
32 
33 namespace {
34 
35 using testing::Eq;
36 using testing::Gt;
37 using testing::IsNull;
38 using testing::NotNull;
39 using testing::Pointee;
40 
41 constexpr int32_t INITIAL_USER_INFO = static_cast<int32_t>(VehicleProperty::INITIAL_USER_INFO);
42 constexpr int32_t SWITCH_USER = static_cast<int32_t>(VehicleProperty::SWITCH_USER);
43 constexpr int32_t CREATE_USER = static_cast<int32_t>(VehicleProperty::CREATE_USER);
44 constexpr int32_t REMOVE_USER = static_cast<int32_t>(VehicleProperty::REMOVE_USER);
45 constexpr int32_t USER_IDENTIFICATION_ASSOCIATION =
46         static_cast<int32_t>(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);
47 
48 constexpr int32_t FIRST_BOOT_AFTER_OTA =
49         static_cast<int32_t>(InitialUserInfoRequestType::FIRST_BOOT_AFTER_OTA);
50 constexpr int32_t LEGACY_ANDROID_SWITCH =
51         static_cast<int32_t>(SwitchUserMessageType::LEGACY_ANDROID_SWITCH);
52 constexpr int32_t VEHICLE_REQUEST = static_cast<int32_t>(SwitchUserMessageType::VEHICLE_REQUEST);
53 
54 constexpr int32_t GUEST_USER = static_cast<int32_t>(UserFlags::GUEST);
55 constexpr int32_t NONE_USER = static_cast<int32_t>(UserFlags::NONE);
56 constexpr int32_t SYSTEM_USER = static_cast<int32_t>(UserFlags::SYSTEM);
57 constexpr int32_t ADMIN_USER = static_cast<int32_t>(UserFlags::ADMIN);
58 constexpr int32_t SYSTEM_ADMIN_USER = static_cast<int32_t>(UserFlags::SYSTEM | UserFlags::ADMIN);
59 // 0x1111 is not a valid UserFlags combination.
60 constexpr int32_t INVALID_USER_FLAG = 0x1111;
61 
62 constexpr int32_t USER_ID_ASSOC_KEY_FOB =
63         static_cast<int32_t>(UserIdentificationAssociationType::KEY_FOB);
64 constexpr int32_t USER_ID_ASSOC_CUSTOM_1 =
65         static_cast<int32_t>(UserIdentificationAssociationType::CUSTOM_1);
66 
67 constexpr int32_t USER_ID_ASSOC_SET_CURRENT_USER =
68         static_cast<int32_t>(UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER);
69 constexpr int32_t USER_ID_ASSOC_UNSET_CURRENT_USER =
70         static_cast<int32_t>(UserIdentificationAssociationSetValue::DISASSOCIATE_CURRENT_USER);
71 
72 constexpr int32_t USER_ID_ASSOC_CURRENT_USER =
73         static_cast<int32_t>(UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER);
74 constexpr int32_t USER_ID_ASSOC_NO_USER =
75         static_cast<int32_t>(UserIdentificationAssociationValue::NOT_ASSOCIATED_ANY_USER);
76 
77 }  // namespace
78 
TEST(UserHalHelperTest,TestToInitialUserInfoRequestSystemUser)79 TEST(UserHalHelperTest, TestToInitialUserInfoRequestSystemUser) {
80     VehiclePropValue propValue{
81             .prop = INITIAL_USER_INFO,
82             .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, SYSTEM_USER,
83                                       10, NONE_USER}},
84     };
85     InitialUserInfoRequest expected{
86             .requestId = 23,
87             .requestType = InitialUserInfoRequestType::FIRST_BOOT_AFTER_OTA,
88             .usersInfo = {{10, UserFlags::NONE},
89                           2,
90                           {{0, UserFlags::SYSTEM}, {10, UserFlags::NONE}}},
91     };
92 
93     auto actual = toInitialUserInfoRequest(propValue);
94 
95     ASSERT_TRUE(actual.ok()) << actual.error().message();
96     EXPECT_THAT(actual.value(), Eq(expected));
97 }
98 
TEST(UserHalHelperTest,TestToInitialUserInfoRequestAdminUser)99 TEST(UserHalHelperTest, TestToInitialUserInfoRequestAdminUser) {
100     VehiclePropValue propValue{
101             .prop = INITIAL_USER_INFO,
102             .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, ADMIN_USER, 10,
103                                       NONE_USER}},
104     };
105     InitialUserInfoRequest expected{
106             .requestId = 23,
107             .requestType = InitialUserInfoRequestType::FIRST_BOOT_AFTER_OTA,
108             .usersInfo = {{10, UserFlags::NONE}, 2, {{0, UserFlags::ADMIN}, {10, UserFlags::NONE}}},
109     };
110 
111     auto actual = toInitialUserInfoRequest(propValue);
112 
113     ASSERT_TRUE(actual.ok()) << actual.error().message();
114     EXPECT_THAT(actual.value(), Eq(expected));
115 }
116 
TEST(UserHalHelperTest,TestToInitialUserInfoRequestUserFlagsBitCombination)117 TEST(UserHalHelperTest, TestToInitialUserInfoRequestUserFlagsBitCombination) {
118     // SYSTEM_ADMIN_USER is two UserFlags combined and is itself not a defined UserFlags enum.
119     VehiclePropValue propValue{
120             .prop = INITIAL_USER_INFO,
121             .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0,
122                                       SYSTEM_ADMIN_USER, 10, NONE_USER}},
123     };
124     InitialUserInfoRequest expected{
125             .requestId = 23,
126             .requestType = InitialUserInfoRequestType::FIRST_BOOT_AFTER_OTA,
127             .usersInfo = {{10, UserFlags::NONE},
128                           2,
129                           {{0, static_cast<UserFlags>(SYSTEM_ADMIN_USER)}, {10, UserFlags::NONE}}},
130     };
131 
132     auto actual = toInitialUserInfoRequest(propValue);
133 
134     ASSERT_TRUE(actual.ok()) << actual.error().message();
135     EXPECT_THAT(actual.value(), Eq(expected));
136 }
137 
TEST(UserHalHelperTest,TestToInitialUserInfoRequestUserInvalidUserFlag)138 TEST(UserHalHelperTest, TestToInitialUserInfoRequestUserInvalidUserFlag) {
139     // 0x1111 is not a valid UserFlags flag combination.
140     VehiclePropValue propValue{
141             .prop = INITIAL_USER_INFO,
142             .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0,
143                                       INVALID_USER_FLAG, 10, NONE_USER}},
144     };
145 
146     auto actual = toInitialUserInfoRequest(propValue);
147 
148     EXPECT_FALSE(actual.ok()) << "No error returned on invalid user flags";
149 }
150 
TEST(UserHalHelperTest,TestFailsToInitialUserInfoRequestWithMismatchingPropType)151 TEST(UserHalHelperTest, TestFailsToInitialUserInfoRequestWithMismatchingPropType) {
152     VehiclePropValue propValue{
153             .prop = INT32_MAX,
154             .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, SYSTEM_USER,
155                                       10, NONE_USER}},
156     };
157 
158     auto actual = toInitialUserInfoRequest(propValue);
159 
160     EXPECT_FALSE(actual.ok()) << "No error returned on mismatching property type";
161 }
162 
TEST(UserHalHelperTest,TestFailsToInitialUserInfoRequestWithInvalidRequestType)163 TEST(UserHalHelperTest, TestFailsToInitialUserInfoRequestWithInvalidRequestType) {
164     VehiclePropValue propValue{
165             .prop = INITIAL_USER_INFO,
166             .value = {.int32Values = {23, INT32_MAX, 10, NONE_USER, 2, 0, SYSTEM_USER, 10,
167                                       NONE_USER}},
168     };
169 
170     auto actual = toInitialUserInfoRequest(propValue);
171 
172     EXPECT_FALSE(actual.ok()) << "No error returned on invalid request type";
173 }
174 
TEST(UserHalHelperTest,TestFailsToInitialUserInfoRequestWithInvalidUserFlag)175 TEST(UserHalHelperTest, TestFailsToInitialUserInfoRequestWithInvalidUserFlag) {
176     VehiclePropValue propValue{
177             .prop = INITIAL_USER_INFO,
178             .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, SYSTEM_USER,
179                                       10, INT32_MAX}},
180     };
181 
182     auto actual = toInitialUserInfoRequest(propValue);
183 
184     EXPECT_FALSE(actual.ok()) << "No error returned on invalid user flags";
185 }
186 
TEST(UserHalHelperTest,TestFailsToInitialUserInfoRequestWithIncompleteUsersInfo)187 TEST(UserHalHelperTest, TestFailsToInitialUserInfoRequestWithIncompleteUsersInfo) {
188     VehiclePropValue propValueMissingSecondUserInfo{
189             .prop = INITIAL_USER_INFO,
190             .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0,
191                                       SYSTEM_USER /*Missing 2nd UserInfo*/}},
192     };
193 
194     auto actual = toInitialUserInfoRequest(propValueMissingSecondUserInfo);
195 
196     EXPECT_FALSE(actual.ok()) << "No error returned on missing second user info";
197 
198     VehiclePropValue propValueMissingUsersInfo{
199             .prop = INITIAL_USER_INFO,
200             .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, /*Missing UsersInfo*/}},
201     };
202 
203     actual = toInitialUserInfoRequest(propValueMissingUsersInfo);
204 
205     EXPECT_FALSE(actual.ok()) << "No error returned on missing users info";
206 }
207 
TEST(UserHalHelperTest,TestToSwitchUserRequest)208 TEST(UserHalHelperTest, TestToSwitchUserRequest) {
209     VehiclePropValue propValue{
210             .prop = SWITCH_USER,
211             .value = {.int32Values = {23, LEGACY_ANDROID_SWITCH, 0, SYSTEM_USER, 10, NONE_USER, 2,
212                                       0, SYSTEM_USER, 10, NONE_USER}},
213     };
214     SwitchUserRequest expected{
215             .requestId = 23,
216             .messageType = SwitchUserMessageType::LEGACY_ANDROID_SWITCH,
217             .targetUser = {0, UserFlags::SYSTEM},
218             .usersInfo = {{10, UserFlags::NONE},
219                           2,
220                           {{0, UserFlags::SYSTEM}, {10, UserFlags::NONE}}},
221     };
222 
223     auto actual = toSwitchUserRequest(propValue);
224 
225     ASSERT_TRUE(actual.ok()) << actual.error().message();
226     EXPECT_THAT(actual.value(), Eq(expected));
227 }
228 
TEST(UserHalHelperTest,TestFailsToSwitchUserRequestWithMismatchingPropType)229 TEST(UserHalHelperTest, TestFailsToSwitchUserRequestWithMismatchingPropType) {
230     VehiclePropValue propValue{
231             .prop = INITIAL_USER_INFO,
232             .value = {.int32Values = {23, LEGACY_ANDROID_SWITCH, 0, SYSTEM_USER, 10, NONE_USER, 2,
233                                       0, SYSTEM_USER, 10, NONE_USER}},
234     };
235 
236     auto actual = toSwitchUserRequest(propValue);
237 
238     EXPECT_FALSE(actual.ok()) << "No error returned on mismatching property type";
239 }
240 
TEST(UserHalHelperTest,TestFailsToSwitchUserRequestWithInvalidMessageType)241 TEST(UserHalHelperTest, TestFailsToSwitchUserRequestWithInvalidMessageType) {
242     VehiclePropValue propValueIncompatibleMessageType{
243             .prop = SWITCH_USER,
244             .value = {.int32Values = {23, VEHICLE_REQUEST, 0, SYSTEM_USER, 10, NONE_USER, 2, 0,
245                                       SYSTEM_USER, 10, NONE_USER}},
246     };
247 
248     auto actual = toSwitchUserRequest(propValueIncompatibleMessageType);
249 
250     EXPECT_FALSE(actual.ok()) << "No error returned on incompatible message type";
251 
252     VehiclePropValue propValueInvalidMessageType{
253             .prop = SWITCH_USER,
254             .value = {.int32Values = {23, INT32_MAX, 0, SYSTEM_USER, 10, NONE_USER, 2, 0,
255                                       SYSTEM_USER, 10, NONE_USER}},
256     };
257 
258     actual = toSwitchUserRequest(propValueInvalidMessageType);
259 
260     EXPECT_FALSE(actual.ok()) << "No error returned on invalid message type";
261 }
262 
TEST(UserHalHelperTest,TestFailsToSwitchUserRequestWithIncompleteUsersInfo)263 TEST(UserHalHelperTest, TestFailsToSwitchUserRequestWithIncompleteUsersInfo) {
264     VehiclePropValue propValueMissingSecondUserInfo{
265             .prop = SWITCH_USER,
266             .value = {.int32Values = {23, LEGACY_ANDROID_SWITCH, 0, SYSTEM_USER, 10, NONE_USER, 2,
267                                       0, SYSTEM_USER,
268                                       /*Missing 2nd UserInfo*/}},
269     };
270 
271     auto actual = toSwitchUserRequest(propValueMissingSecondUserInfo);
272 
273     EXPECT_FALSE(actual.ok()) << "No error returned on missing second user info";
274 
275     VehiclePropValue propValueMissingUsersInfo{
276             .prop = SWITCH_USER,
277             .value = {.int32Values = {23, LEGACY_ANDROID_SWITCH, 0, SYSTEM_USER,
278                                       /*Missing UsersInfo*/}},
279     };
280 
281     actual = toSwitchUserRequest(propValueMissingUsersInfo);
282 
283     EXPECT_FALSE(actual.ok()) << "No error returned on missing users info";
284 
285     VehiclePropValue propValueMissingTargetUser{
286             .prop = SWITCH_USER,
287             .value = {.int32Values = {23, LEGACY_ANDROID_SWITCH, /*Missing target UserInfo*/}},
288     };
289 
290     actual = toSwitchUserRequest(propValueMissingTargetUser);
291 
292     EXPECT_FALSE(actual.ok()) << "No error returned on missing target user info";
293 }
294 
TEST(UserHalHelperTest,TestToCreateUserRequest)295 TEST(UserHalHelperTest, TestToCreateUserRequest) {
296     VehiclePropValue propValue{
297             .prop = CREATE_USER,
298             .value = {.int32Values = {23, 11, GUEST_USER, 10, NONE_USER, 2, 0, SYSTEM_USER, 10,
299                                       NONE_USER},
300                       .stringValue = "Guest11"},
301     };
302     CreateUserRequest expected{
303             .requestId = 23,
304             .newUserInfo = {11, UserFlags::GUEST},
305             .newUserName = "Guest11",
306             .usersInfo = {{10, UserFlags::NONE},
307                           2,
308                           {{0, UserFlags::SYSTEM}, {10, UserFlags::NONE}}},
309     };
310 
311     auto actual = toCreateUserRequest(propValue);
312 
313     ASSERT_TRUE(actual.ok()) << actual.error().message();
314     EXPECT_THAT(actual.value(), Eq(expected));
315 }
316 
TEST(UserHalHelperTest,TestFailsToCreateUserRequestWithMismatchingPropType)317 TEST(UserHalHelperTest, TestFailsToCreateUserRequestWithMismatchingPropType) {
318     VehiclePropValue propValue{
319             .prop = INITIAL_USER_INFO,
320             .value = {.int32Values = {23, 11, GUEST_USER, 10, NONE_USER, 2, 0, SYSTEM_USER, 10,
321                                       NONE_USER},
322                       .stringValue = "Guest11"},
323     };
324 
325     auto actual = toCreateUserRequest(propValue);
326 
327     EXPECT_FALSE(actual.ok()) << "No error returned on mismatching property type";
328 }
329 
TEST(UserHalHelperTest,TestFailsToCreateUserRequestWithIncompleteUsersInfo)330 TEST(UserHalHelperTest, TestFailsToCreateUserRequestWithIncompleteUsersInfo) {
331     VehiclePropValue propValueMissingSecondUserInfo{
332             .prop = CREATE_USER,
333             .value = {.int32Values = {23, 11, GUEST_USER, 10, NONE_USER, 2, 0,
334                                       SYSTEM_USER /*Missing 2nd UserInfo*/},
335                       .stringValue = "Guest11"},
336     };
337 
338     auto actual = toCreateUserRequest(propValueMissingSecondUserInfo);
339 
340     EXPECT_FALSE(actual.ok()) << "No error returned on missing second user info";
341 
342     VehiclePropValue propValueMissingUsersInfo{
343             .prop = CREATE_USER,
344             .value = {.int32Values = {23, 11, GUEST_USER, /*Missing UsersInfo*/},
345                       .stringValue = "Guest11"},
346     };
347 
348     actual = toCreateUserRequest(propValueMissingUsersInfo);
349 
350     EXPECT_FALSE(actual.ok()) << "No error returned on missing users info";
351 
352     VehiclePropValue propValueMissingCreateUserInfo{
353             .prop = CREATE_USER,
354             .value = {.int32Values = {23, /*Missing create UserInfo*/}, .stringValue = "Guest11"},
355     };
356 
357     actual = toCreateUserRequest(propValueMissingCreateUserInfo);
358 
359     EXPECT_FALSE(actual.ok()) << "No error returned on missing create user info";
360 }
361 
TEST(UserHalHelperTest,TestToRemoveUserRequest)362 TEST(UserHalHelperTest, TestToRemoveUserRequest) {
363     VehiclePropValue propValue{
364             .prop = REMOVE_USER,
365             .value = {.int32Values = {23, 10, NONE_USER, 10, NONE_USER, 2, 0, SYSTEM_USER, 10,
366                                       NONE_USER}},
367     };
368     RemoveUserRequest expected{
369             .requestId = 23,
370             .removedUserInfo = {10, UserFlags::NONE},
371             .usersInfo = {{10, UserFlags::NONE},
372                           2,
373                           {{0, UserFlags::SYSTEM}, {10, UserFlags::NONE}}},
374     };
375 
376     auto actual = toRemoveUserRequest(propValue);
377 
378     ASSERT_TRUE(actual.ok()) << actual.error().message();
379     EXPECT_THAT(actual.value(), Eq(expected));
380 }
381 
TEST(UserHalHelperTest,TestFailsToRemoveUserRequestWithMismatchingPropType)382 TEST(UserHalHelperTest, TestFailsToRemoveUserRequestWithMismatchingPropType) {
383     VehiclePropValue propValue{
384             .prop = INITIAL_USER_INFO,
385             .value = {.int32Values = {23, 10, NONE_USER, 10, NONE_USER, 2, 0, SYSTEM_USER, 10,
386                                       NONE_USER}},
387     };
388 
389     auto actual = toRemoveUserRequest(propValue);
390 
391     EXPECT_FALSE(actual.ok()) << "No error returned on mismatching property type";
392 }
393 
TEST(UserHalHelperTest,TestFailsToRemoveUserRequestWithIncompleteUsersInfo)394 TEST(UserHalHelperTest, TestFailsToRemoveUserRequestWithIncompleteUsersInfo) {
395     VehiclePropValue propValueMissingSecondUserInfo{
396             .prop = REMOVE_USER,
397             .value = {.int32Values = {23, 10, NONE_USER, 10, NONE_USER, 2, 0,
398                                       SYSTEM_USER /*Missing 2nd UserInfo*/}},
399     };
400 
401     auto actual = toRemoveUserRequest(propValueMissingSecondUserInfo);
402 
403     EXPECT_FALSE(actual.ok()) << "No error returned on missing second user info";
404 
405     VehiclePropValue propValueMissingUsersInfo{
406             .prop = REMOVE_USER,
407             .value = {.int32Values = {23, 10, NONE_USER, /*Missing UsersInfo*/}},
408     };
409 
410     actual = toRemoveUserRequest(propValueMissingUsersInfo);
411 
412     EXPECT_FALSE(actual.ok()) << "No error returned on missing users info";
413 
414     VehiclePropValue propValueMissingRemoveUserInfo{
415             .prop = REMOVE_USER,
416             .value = {.int32Values = {23, /*Missing remove UserInfo*/}},
417     };
418 
419     actual = toRemoveUserRequest(propValueMissingRemoveUserInfo);
420 
421     EXPECT_FALSE(actual.ok()) << "No error returned on missing remove user info";
422 }
423 
TEST(UserHalHelperTest,TestFailsToUserIdentificationGetRequest)424 TEST(UserHalHelperTest, TestFailsToUserIdentificationGetRequest) {
425     VehiclePropValue propValue{
426             .prop = USER_IDENTIFICATION_ASSOCIATION,
427             .value = {.int32Values = {23, 10, NONE_USER, 2, USER_ID_ASSOC_KEY_FOB,
428                                       USER_ID_ASSOC_CUSTOM_1}},
429     };
430     UserIdentificationGetRequest expected{
431             .requestId = 23,
432             .userInfo = {10, UserFlags::NONE},
433             .numberAssociationTypes = 2,
434             .associationTypes = {UserIdentificationAssociationType::KEY_FOB,
435                                  UserIdentificationAssociationType::CUSTOM_1},
436     };
437 
438     auto actual = toUserIdentificationGetRequest(propValue);
439 
440     ASSERT_TRUE(actual.ok()) << actual.error().message();
441     EXPECT_THAT(actual.value(), Eq(expected));
442 }
443 
TEST(UserHalHelperTest,TestFailsToUserIdentificationGetRequestWithMismatchingPropType)444 TEST(UserHalHelperTest, TestFailsToUserIdentificationGetRequestWithMismatchingPropType) {
445     VehiclePropValue propValue{
446             .prop = INITIAL_USER_INFO,
447             .value = {.int32Values = {23, 10, NONE_USER, 2, USER_ID_ASSOC_KEY_FOB,
448                                       USER_ID_ASSOC_CUSTOM_1}},
449     };
450 
451     auto actual = toUserIdentificationGetRequest(propValue);
452 
453     EXPECT_FALSE(actual.ok()) << "No error returned on mismatching property type";
454 }
455 
TEST(UserHalHelperTest,TestFailsToUserIdentificationGetRequestWithInvalidAssociationTypes)456 TEST(UserHalHelperTest, TestFailsToUserIdentificationGetRequestWithInvalidAssociationTypes) {
457     VehiclePropValue propValue{
458             .prop = USER_IDENTIFICATION_ASSOCIATION,
459             .value = {.int32Values = {23, 10, NONE_USER, 1, INT32_MAX}},
460     };
461 
462     auto actual = toUserIdentificationGetRequest(propValue);
463 
464     EXPECT_FALSE(actual.ok()) << "No error returned on invalid association type";
465 }
466 
TEST(UserHalHelperTest,TestFailsToUserIdentificationGetRequestWithIncompleteAssociationTypes)467 TEST(UserHalHelperTest, TestFailsToUserIdentificationGetRequestWithIncompleteAssociationTypes) {
468     VehiclePropValue propValueMissingSecondAssociationType{
469             .prop = USER_IDENTIFICATION_ASSOCIATION,
470             .value = {.int32Values = {23, 10, NONE_USER, 2,
471                                       USER_ID_ASSOC_KEY_FOB /*Missing 2nd association type*/}},
472     };
473 
474     auto actual = toUserIdentificationGetRequest(propValueMissingSecondAssociationType);
475 
476     EXPECT_FALSE(actual.ok()) << "No error returned on missing second association type";
477 
478     VehiclePropValue propValueMissingNumberAssociationTypes{
479             .prop = USER_IDENTIFICATION_ASSOCIATION,
480             .value = {.int32Values = {23, 10, NONE_USER, /*Missing number association types*/}},
481     };
482 
483     actual = toUserIdentificationGetRequest(propValueMissingNumberAssociationTypes);
484 
485     EXPECT_FALSE(actual.ok()) << "No error returned on missing number association types";
486 }
487 
TEST(UserHalHelperTest,TestFailsToUserIdentificationGetRequestWithMissingUserInfo)488 TEST(UserHalHelperTest, TestFailsToUserIdentificationGetRequestWithMissingUserInfo) {
489     VehiclePropValue propValue{
490             .prop = USER_IDENTIFICATION_ASSOCIATION,
491             .value = {.int32Values = {23, /*Missing user info*/}},
492     };
493 
494     auto actual = toUserIdentificationGetRequest(propValue);
495 
496     EXPECT_FALSE(actual.ok()) << "No error returned on missing UserInfo";
497 }
498 
TEST(UserHalHelperTest,TestToUserIdentificationSetRequest)499 TEST(UserHalHelperTest, TestToUserIdentificationSetRequest) {
500     VehiclePropValue propValue{
501             .prop = USER_IDENTIFICATION_ASSOCIATION,
502             .value = {.int32Values = {23, 10, NONE_USER, 2, USER_ID_ASSOC_KEY_FOB,
503                                       USER_ID_ASSOC_SET_CURRENT_USER, USER_ID_ASSOC_CUSTOM_1,
504                                       USER_ID_ASSOC_UNSET_CURRENT_USER}},
505     };
506     UserIdentificationSetRequest expected{
507             .requestId = 23,
508             .userInfo = {10, UserFlags::NONE},
509             .numberAssociations = 2,
510             .associations = {{UserIdentificationAssociationType::KEY_FOB,
511                               UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER},
512                              {UserIdentificationAssociationType::CUSTOM_1,
513                               UserIdentificationAssociationSetValue::DISASSOCIATE_CURRENT_USER}},
514     };
515 
516     auto actual = toUserIdentificationSetRequest(propValue);
517 
518     ASSERT_TRUE(actual.ok()) << actual.error().message();
519     EXPECT_THAT(actual.value(), Eq(expected));
520 }
521 
TEST(UserHalHelperTest,TestFailsToUserIdentificationSetRequestWithMismatchingPropType)522 TEST(UserHalHelperTest, TestFailsToUserIdentificationSetRequestWithMismatchingPropType) {
523     VehiclePropValue propValue{
524             .prop = INITIAL_USER_INFO,
525             .value = {.int32Values = {23, 10, NONE_USER, 2, USER_ID_ASSOC_KEY_FOB,
526                                       USER_ID_ASSOC_SET_CURRENT_USER, USER_ID_ASSOC_CUSTOM_1,
527                                       USER_ID_ASSOC_UNSET_CURRENT_USER}},
528     };
529 
530     auto actual = toUserIdentificationSetRequest(propValue);
531 
532     EXPECT_FALSE(actual.ok()) << "No error returned on mismatching property type";
533 }
534 
TEST(UserHalHelperTest,TestFailsToUserIdentificationSetRequestWithInvalidAssociations)535 TEST(UserHalHelperTest, TestFailsToUserIdentificationSetRequestWithInvalidAssociations) {
536     VehiclePropValue propValueInvalidAssociationType{
537             .prop = USER_IDENTIFICATION_ASSOCIATION,
538             .value = {.int32Values = {23, 10, NONE_USER, 1, INT32_MAX,
539                                       USER_ID_ASSOC_SET_CURRENT_USER}},
540     };
541 
542     auto actual = toUserIdentificationSetRequest(propValueInvalidAssociationType);
543 
544     EXPECT_FALSE(actual.ok()) << "No error returned on invalid association type";
545 
546     VehiclePropValue propValueInvalidAssociationValue{
547             .prop = USER_IDENTIFICATION_ASSOCIATION,
548             .value = {.int32Values = {23, 10, NONE_USER, USER_ID_ASSOC_KEY_FOB, INT32_MAX}},
549     };
550 
551     actual = toUserIdentificationSetRequest(propValueInvalidAssociationValue);
552 
553     EXPECT_FALSE(actual.ok()) << "No error returned on missing number association types";
554 }
555 
TEST(UserHalHelperTest,TestFailsToUserIdentificationSetRequestWithIncompleteAssociations)556 TEST(UserHalHelperTest, TestFailsToUserIdentificationSetRequestWithIncompleteAssociations) {
557     VehiclePropValue propValueMissingSecondAssociationType{
558             .prop = USER_IDENTIFICATION_ASSOCIATION,
559             .value = {.int32Values = {23, 10, NONE_USER, 2, USER_ID_ASSOC_KEY_FOB,
560                                       USER_ID_ASSOC_SET_CURRENT_USER,
561                                       /*Missing 2nd association*/}},
562     };
563 
564     auto actual = toUserIdentificationSetRequest(propValueMissingSecondAssociationType);
565 
566     EXPECT_FALSE(actual.ok()) << "No error returned on missing second association type";
567 
568     VehiclePropValue propValueMissingNumberAssociationTypes{
569             .prop = USER_IDENTIFICATION_ASSOCIATION,
570             .value = {.int32Values = {23, 10, NONE_USER, /*Missing number associations*/}},
571     };
572 
573     actual = toUserIdentificationSetRequest(propValueMissingNumberAssociationTypes);
574 
575     EXPECT_FALSE(actual.ok()) << "No error returned on missing number association types";
576 }
577 
TEST(UserHalHelperTest,TestFailsToUserIdentificationSetRequestWithMissingUserInfo)578 TEST(UserHalHelperTest, TestFailsToUserIdentificationSetRequestWithMissingUserInfo) {
579     VehiclePropValue propValue{
580             .prop = USER_IDENTIFICATION_ASSOCIATION,
581             .value = {.int32Values = {23, /*Missing user info*/}},
582     };
583 
584     auto actual = toUserIdentificationSetRequest(propValue);
585 
586     EXPECT_FALSE(actual.ok()) << "No error returned on missing UserInfo";
587 }
588 
TEST(UserHalHelperTest,TestSwitchUserRequestToVehiclePropValue)589 TEST(UserHalHelperTest, TestSwitchUserRequestToVehiclePropValue) {
590     SwitchUserRequest request{
591             .requestId = 23,
592             .messageType = SwitchUserMessageType::VEHICLE_REQUEST,
593             .targetUser = {11, UserFlags::GUEST},
594     };
595     VehiclePropValue expected{
596             .prop = SWITCH_USER,
597             .value = {.int32Values = {23,
598                                       static_cast<int32_t>(SwitchUserMessageType::VEHICLE_REQUEST),
599                                       11}},
600     };
601 
602     auto actual = toVehiclePropValue(request);
603 
604     ASSERT_THAT(actual, NotNull());
605     EXPECT_THAT(actual->timestamp, Gt(0));
606     // Don't rely on real timestamp in tests as the expected and actual objects won't have the same
607     // timestamps. Thus remove the timestamps before comparing them.
608     actual->timestamp = 0;
609     EXPECT_THAT(actual, Pointee(Eq(expected)));
610 }
611 
TEST(UserHalHelperTest,TestFailsSwitchUserRequestToVehiclePropValueWithIncompatibleMessageType)612 TEST(UserHalHelperTest, TestFailsSwitchUserRequestToVehiclePropValueWithIncompatibleMessageType) {
613     SwitchUserRequest request{
614             .requestId = 23,
615             .messageType = SwitchUserMessageType::VEHICLE_RESPONSE,
616             .targetUser = {11, UserFlags::GUEST},
617     };
618 
619     auto actual = toVehiclePropValue(request);
620 
621     EXPECT_THAT(actual, IsNull());
622 }
623 
TEST(UserHalHelperTest,TestInitialUserInfoResponseToVehiclePropValue)624 TEST(UserHalHelperTest, TestInitialUserInfoResponseToVehiclePropValue) {
625     InitialUserInfoResponse response{
626             .requestId = 23,
627             .action = InitialUserInfoResponseAction::CREATE,
628             .userToSwitchOrCreate = {11, UserFlags::GUEST},
629             .userLocales = "en-US,pt-BR",
630             .userNameToCreate = "Owner",
631     };
632     VehiclePropValue expected{
633             .prop = INITIAL_USER_INFO,
634             .value = {.int32Values = {23,
635                                       static_cast<int32_t>(InitialUserInfoResponseAction::CREATE),
636                                       11, GUEST_USER},
637                       .stringValue = "en-US,pt-BR||Owner"},
638     };
639 
640     auto actual = toVehiclePropValue(response);
641 
642     ASSERT_THAT(actual, NotNull());
643     EXPECT_THAT(actual->timestamp, Gt(0));
644     actual->timestamp = 0;
645     EXPECT_THAT(actual, Pointee(Eq(expected)));
646 }
647 
TEST(UserHalHelperTest,TestSwitchUserResponseToVehiclePropValue)648 TEST(UserHalHelperTest, TestSwitchUserResponseToVehiclePropValue) {
649     SwitchUserResponse response{
650             .requestId = 23,
651             .messageType = SwitchUserMessageType::VEHICLE_RESPONSE,
652             .status = SwitchUserStatus::FAILURE,
653             .errorMessage = "random error",
654     };
655     VehiclePropValue expected{
656             .prop = SWITCH_USER,
657             .value = {.int32Values = {23,
658                                       static_cast<int32_t>(SwitchUserMessageType::VEHICLE_RESPONSE),
659                                       static_cast<int32_t>(SwitchUserStatus::FAILURE)},
660                       .stringValue = "random error"},
661     };
662 
663     auto actual = toVehiclePropValue(response);
664 
665     ASSERT_THAT(actual, NotNull());
666     EXPECT_THAT(actual->timestamp, Gt(0));
667     actual->timestamp = 0;
668     EXPECT_THAT(actual, Pointee(Eq(expected)));
669 }
670 
TEST(UserHalHelperTest,TestCreateUserResponseToVehiclePropValue)671 TEST(UserHalHelperTest, TestCreateUserResponseToVehiclePropValue) {
672     CreateUserResponse response{
673             .requestId = 23,
674             .status = CreateUserStatus::FAILURE,
675             .errorMessage = "random error",
676     };
677     VehiclePropValue expected{
678             .prop = CREATE_USER,
679             .value = {.int32Values = {23, static_cast<int32_t>(CreateUserStatus::FAILURE)},
680                       .stringValue = "random error"},
681     };
682 
683     auto actual = toVehiclePropValue(response);
684 
685     ASSERT_THAT(actual, NotNull());
686     EXPECT_THAT(actual->timestamp, Gt(0));
687     actual->timestamp = 0;
688     EXPECT_THAT(actual, Pointee(Eq(expected)));
689 }
690 
TEST(UserHalHelperTest,TestUserIdentificationResponseToVehiclePropValue)691 TEST(UserHalHelperTest, TestUserIdentificationResponseToVehiclePropValue) {
692     UserIdentificationResponse response{
693             .requestId = 23,
694             .numberAssociation = 2,
695             .associations = {{UserIdentificationAssociationType::KEY_FOB,
696                               UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER},
697                              {UserIdentificationAssociationType::CUSTOM_1,
698                               UserIdentificationAssociationValue::NOT_ASSOCIATED_ANY_USER}},
699             .errorMessage = "random error",
700     };
701     VehiclePropValue expected{
702             .prop = USER_IDENTIFICATION_ASSOCIATION,
703             .value = {.int32Values = {23, 2, USER_ID_ASSOC_KEY_FOB, USER_ID_ASSOC_CURRENT_USER,
704                                       USER_ID_ASSOC_CUSTOM_1, USER_ID_ASSOC_NO_USER},
705                       .stringValue = "random error"},
706     };
707 
708     auto actual = toVehiclePropValue(response);
709 
710     ASSERT_THAT(actual, NotNull());
711     EXPECT_THAT(actual->timestamp, Gt(0));
712     actual->timestamp = 0;
713     EXPECT_THAT(actual, Pointee(Eq(expected)));
714 }
715 
716 }  // namespace user_hal_helper
717 
718 }  // namespace V2_0
719 }  // namespace vehicle
720 }  // namespace automotive
721 }  // namespace hardware
722 }  // namespace android
723