xref: /aosp_15_r20/hardware/interfaces/automotive/vehicle/2.0/utils/UserHalHelper.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "UserHalHelper"
17*4d7e907cSAndroid Build Coastguard Worker 
18*4d7e907cSAndroid Build Coastguard Worker #include "UserHalHelper.h"
19*4d7e907cSAndroid Build Coastguard Worker 
20*4d7e907cSAndroid Build Coastguard Worker #include <log/log.h>
21*4d7e907cSAndroid Build Coastguard Worker #include <utils/SystemClock.h>
22*4d7e907cSAndroid Build Coastguard Worker 
23*4d7e907cSAndroid Build Coastguard Worker namespace android {
24*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
25*4d7e907cSAndroid Build Coastguard Worker namespace automotive {
26*4d7e907cSAndroid Build Coastguard Worker namespace vehicle {
27*4d7e907cSAndroid Build Coastguard Worker namespace V2_0 {
28*4d7e907cSAndroid Build Coastguard Worker 
29*4d7e907cSAndroid Build Coastguard Worker namespace user_hal_helper {
30*4d7e907cSAndroid Build Coastguard Worker namespace {
31*4d7e907cSAndroid Build Coastguard Worker 
32*4d7e907cSAndroid Build Coastguard Worker using android::base::Error;
33*4d7e907cSAndroid Build Coastguard Worker using android::base::Result;
34*4d7e907cSAndroid Build Coastguard Worker 
35*4d7e907cSAndroid Build Coastguard Worker static constexpr const char* kSeparator = "||";
36*4d7e907cSAndroid Build Coastguard Worker static const size_t kNumFieldsPerUserInfo = 2;
37*4d7e907cSAndroid Build Coastguard Worker static const size_t kNumFieldsPerSetAssociation = 2;
38*4d7e907cSAndroid Build Coastguard Worker 
verifyPropValue(const VehiclePropValue & propValue,VehicleProperty vehicleProperty,size_t minInt32Values)39*4d7e907cSAndroid Build Coastguard Worker Result<void> verifyPropValue(const VehiclePropValue& propValue, VehicleProperty vehicleProperty,
40*4d7e907cSAndroid Build Coastguard Worker                              size_t minInt32Values) {
41*4d7e907cSAndroid Build Coastguard Worker     auto prop = verifyAndCast<VehicleProperty>(propValue.prop);
42*4d7e907cSAndroid Build Coastguard Worker     if (!prop.ok()) {
43*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Invalid vehicle property: " << prop.error();
44*4d7e907cSAndroid Build Coastguard Worker     }
45*4d7e907cSAndroid Build Coastguard Worker     if (*prop != vehicleProperty) {
46*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Mismatching " << toString(vehicleProperty) << " request, received "
47*4d7e907cSAndroid Build Coastguard Worker                        << toString(*prop) << " property";
48*4d7e907cSAndroid Build Coastguard Worker     }
49*4d7e907cSAndroid Build Coastguard Worker     if (propValue.value.int32Values.size() < minInt32Values) {
50*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Int32Values must have at least " << minInt32Values
51*4d7e907cSAndroid Build Coastguard Worker                        << " values, received " << propValue.value.int32Values.size();
52*4d7e907cSAndroid Build Coastguard Worker     }
53*4d7e907cSAndroid Build Coastguard Worker     return {};
54*4d7e907cSAndroid Build Coastguard Worker }
55*4d7e907cSAndroid Build Coastguard Worker 
parseUserInfo(const hidl_vec<int32_t> & int32Values,size_t startPos,UserInfo * userInfo)56*4d7e907cSAndroid Build Coastguard Worker Result<void> parseUserInfo(const hidl_vec<int32_t>& int32Values, size_t startPos,
57*4d7e907cSAndroid Build Coastguard Worker                            UserInfo* userInfo) {
58*4d7e907cSAndroid Build Coastguard Worker     if (int32Values.size() < startPos + kNumFieldsPerUserInfo) {
59*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Int32Values must have at least " << startPos + 2 << " values, received "
60*4d7e907cSAndroid Build Coastguard Worker                        << int32Values.size();
61*4d7e907cSAndroid Build Coastguard Worker     }
62*4d7e907cSAndroid Build Coastguard Worker     userInfo->userId = int32Values[startPos];
63*4d7e907cSAndroid Build Coastguard Worker     int32_t intUserFlags = int32Values[startPos + 1];
64*4d7e907cSAndroid Build Coastguard Worker     int32_t expectedUserFlags = 0;
65*4d7e907cSAndroid Build Coastguard Worker     for (const auto& v : hidl_enum_range<UserFlags>()) {
66*4d7e907cSAndroid Build Coastguard Worker         int32_t intEnumUserFlag = static_cast<int32_t>(v);
67*4d7e907cSAndroid Build Coastguard Worker         if ((intUserFlags & intEnumUserFlag) != 0) {
68*4d7e907cSAndroid Build Coastguard Worker             expectedUserFlags |= intEnumUserFlag;
69*4d7e907cSAndroid Build Coastguard Worker         }
70*4d7e907cSAndroid Build Coastguard Worker     }
71*4d7e907cSAndroid Build Coastguard Worker     if (intUserFlags != expectedUserFlags) {
72*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Invalid user flags: " << intUserFlags << ", must be '|' of UserFlags";
73*4d7e907cSAndroid Build Coastguard Worker     }
74*4d7e907cSAndroid Build Coastguard Worker     // intUserFlags is actually not a valid UserFlags enum, instead, it is a 'bit or' of possible
75*4d7e907cSAndroid Build Coastguard Worker     // multiple UserFlags. However, because the HAL interface was defined incorrectly, we have to
76*4d7e907cSAndroid Build Coastguard Worker     // cast it to UserFlags here, which is defined behavior because the underlying type for
77*4d7e907cSAndroid Build Coastguard Worker     // UserFlags is int32_t and our intUserFlags is within the range of int32_t.
78*4d7e907cSAndroid Build Coastguard Worker     userInfo->flags = static_cast<UserFlags>(intUserFlags);
79*4d7e907cSAndroid Build Coastguard Worker     return {};
80*4d7e907cSAndroid Build Coastguard Worker }
81*4d7e907cSAndroid Build Coastguard Worker 
parseUsersInfo(const hidl_vec<int32_t> & int32Values,size_t startPos,UsersInfo * usersInfo)82*4d7e907cSAndroid Build Coastguard Worker Result<void> parseUsersInfo(const hidl_vec<int32_t>& int32Values, size_t startPos,
83*4d7e907cSAndroid Build Coastguard Worker                             UsersInfo* usersInfo) {
84*4d7e907cSAndroid Build Coastguard Worker     if (int32Values.size() < startPos + 3) {
85*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Int32Values must have at least " << startPos + 3 << " values, received "
86*4d7e907cSAndroid Build Coastguard Worker                        << int32Values.size();
87*4d7e907cSAndroid Build Coastguard Worker     }
88*4d7e907cSAndroid Build Coastguard Worker     auto ret = parseUserInfo(int32Values, startPos, &usersInfo->currentUser);
89*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
90*4d7e907cSAndroid Build Coastguard Worker         return ret;
91*4d7e907cSAndroid Build Coastguard Worker     }
92*4d7e907cSAndroid Build Coastguard Worker     usersInfo->numberUsers = int32Values[startPos + 2];
93*4d7e907cSAndroid Build Coastguard Worker     usersInfo->existingUsers.resize(usersInfo->numberUsers);
94*4d7e907cSAndroid Build Coastguard Worker     for (size_t i = 0; i < static_cast<size_t>(usersInfo->numberUsers); ++i) {
95*4d7e907cSAndroid Build Coastguard Worker         ret = parseUserInfo(int32Values, startPos + 3 + (kNumFieldsPerUserInfo * i),
96*4d7e907cSAndroid Build Coastguard Worker                             &usersInfo->existingUsers[i]);
97*4d7e907cSAndroid Build Coastguard Worker         if (!ret.ok()) {
98*4d7e907cSAndroid Build Coastguard Worker             return Error() << "Failed to parse existing user '" << i << "' info: " << ret.error();
99*4d7e907cSAndroid Build Coastguard Worker         }
100*4d7e907cSAndroid Build Coastguard Worker     }
101*4d7e907cSAndroid Build Coastguard Worker     return {};
102*4d7e907cSAndroid Build Coastguard Worker }
103*4d7e907cSAndroid Build Coastguard Worker 
parseUserAssociationTypes(const hidl_vec<int32_t> & int32Values,size_t startPos,size_t numberAssociationTypes,hidl_vec<UserIdentificationAssociationType> * associationTypes)104*4d7e907cSAndroid Build Coastguard Worker Result<void> parseUserAssociationTypes(
105*4d7e907cSAndroid Build Coastguard Worker         const hidl_vec<int32_t>& int32Values, size_t startPos, size_t numberAssociationTypes,
106*4d7e907cSAndroid Build Coastguard Worker         hidl_vec<UserIdentificationAssociationType>* associationTypes) {
107*4d7e907cSAndroid Build Coastguard Worker     size_t minInt32Values = startPos + numberAssociationTypes;
108*4d7e907cSAndroid Build Coastguard Worker     if (int32Values.size() < minInt32Values) {
109*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Int32Values must have at least " << minInt32Values
110*4d7e907cSAndroid Build Coastguard Worker                        << " values, received " << int32Values.size();
111*4d7e907cSAndroid Build Coastguard Worker     }
112*4d7e907cSAndroid Build Coastguard Worker     associationTypes->resize(numberAssociationTypes);
113*4d7e907cSAndroid Build Coastguard Worker     for (size_t i = 0; i < static_cast<size_t>(numberAssociationTypes); ++i) {
114*4d7e907cSAndroid Build Coastguard Worker         size_t pos = startPos + i;
115*4d7e907cSAndroid Build Coastguard Worker         auto type = verifyAndCast<UserIdentificationAssociationType>(int32Values[pos]);
116*4d7e907cSAndroid Build Coastguard Worker         if (!type.ok()) {
117*4d7e907cSAndroid Build Coastguard Worker             return Error() << "Invalid association type in query '" << i << "': " << type.error();
118*4d7e907cSAndroid Build Coastguard Worker         }
119*4d7e907cSAndroid Build Coastguard Worker         (*associationTypes)[i] = *type;
120*4d7e907cSAndroid Build Coastguard Worker     }
121*4d7e907cSAndroid Build Coastguard Worker     return {};
122*4d7e907cSAndroid Build Coastguard Worker }
123*4d7e907cSAndroid Build Coastguard Worker 
parseUserAssociations(const hidl_vec<int32_t> & int32Values,size_t startPos,size_t numberAssociations,hidl_vec<UserIdentificationSetAssociation> * associations)124*4d7e907cSAndroid Build Coastguard Worker Result<void> parseUserAssociations(const hidl_vec<int32_t>& int32Values, size_t startPos,
125*4d7e907cSAndroid Build Coastguard Worker                                    size_t numberAssociations,
126*4d7e907cSAndroid Build Coastguard Worker                                    hidl_vec<UserIdentificationSetAssociation>* associations) {
127*4d7e907cSAndroid Build Coastguard Worker     size_t minInt32Values = startPos + (numberAssociations * kNumFieldsPerSetAssociation);
128*4d7e907cSAndroid Build Coastguard Worker     if (int32Values.size() < minInt32Values) {
129*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Int32Values must have at least " << minInt32Values
130*4d7e907cSAndroid Build Coastguard Worker                        << " values, received " << int32Values.size();
131*4d7e907cSAndroid Build Coastguard Worker     }
132*4d7e907cSAndroid Build Coastguard Worker     associations->resize(numberAssociations);
133*4d7e907cSAndroid Build Coastguard Worker     for (size_t i = 0; i < static_cast<size_t>(numberAssociations); ++i) {
134*4d7e907cSAndroid Build Coastguard Worker         size_t pos = startPos + (kNumFieldsPerSetAssociation * i);
135*4d7e907cSAndroid Build Coastguard Worker         auto type = verifyAndCast<UserIdentificationAssociationType>(int32Values[pos]);
136*4d7e907cSAndroid Build Coastguard Worker         if (!type.ok()) {
137*4d7e907cSAndroid Build Coastguard Worker             return Error() << "Invalid association type in request '" << i << "': " << type.error();
138*4d7e907cSAndroid Build Coastguard Worker         }
139*4d7e907cSAndroid Build Coastguard Worker         (*associations)[i].type = *type;
140*4d7e907cSAndroid Build Coastguard Worker         auto value = verifyAndCast<UserIdentificationAssociationSetValue>(int32Values[pos + 1]);
141*4d7e907cSAndroid Build Coastguard Worker         if (!value.ok()) {
142*4d7e907cSAndroid Build Coastguard Worker             return Error() << "Invalid association set value in request '" << i
143*4d7e907cSAndroid Build Coastguard Worker                            << "': " << value.error();
144*4d7e907cSAndroid Build Coastguard Worker         }
145*4d7e907cSAndroid Build Coastguard Worker         (*associations)[i].value = *value;
146*4d7e907cSAndroid Build Coastguard Worker     }
147*4d7e907cSAndroid Build Coastguard Worker     return {};
148*4d7e907cSAndroid Build Coastguard Worker }
149*4d7e907cSAndroid Build Coastguard Worker 
150*4d7e907cSAndroid Build Coastguard Worker }  // namespace
151*4d7e907cSAndroid Build Coastguard Worker 
152*4d7e907cSAndroid Build Coastguard Worker template <typename T>
verifyAndCast(int32_t value)153*4d7e907cSAndroid Build Coastguard Worker Result<T> verifyAndCast(int32_t value) {
154*4d7e907cSAndroid Build Coastguard Worker     T castValue = static_cast<T>(value);
155*4d7e907cSAndroid Build Coastguard Worker     for (const auto& v : hidl_enum_range<T>()) {
156*4d7e907cSAndroid Build Coastguard Worker         if (castValue == v) {
157*4d7e907cSAndroid Build Coastguard Worker             return castValue;
158*4d7e907cSAndroid Build Coastguard Worker         }
159*4d7e907cSAndroid Build Coastguard Worker     }
160*4d7e907cSAndroid Build Coastguard Worker     return Error() << "Value " << value << " not in enum values";
161*4d7e907cSAndroid Build Coastguard Worker }
162*4d7e907cSAndroid Build Coastguard Worker 
toInitialUserInfoRequest(const VehiclePropValue & propValue)163*4d7e907cSAndroid Build Coastguard Worker Result<InitialUserInfoRequest> toInitialUserInfoRequest(const VehiclePropValue& propValue) {
164*4d7e907cSAndroid Build Coastguard Worker     auto ret = verifyPropValue(propValue, VehicleProperty::INITIAL_USER_INFO, 2);
165*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
166*4d7e907cSAndroid Build Coastguard Worker         return ret.error();
167*4d7e907cSAndroid Build Coastguard Worker     }
168*4d7e907cSAndroid Build Coastguard Worker     InitialUserInfoRequest request;
169*4d7e907cSAndroid Build Coastguard Worker     request.requestId = propValue.value.int32Values[0];
170*4d7e907cSAndroid Build Coastguard Worker     auto requestType = verifyAndCast<InitialUserInfoRequestType>(propValue.value.int32Values[1]);
171*4d7e907cSAndroid Build Coastguard Worker     if (!requestType.ok()) {
172*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Invalid InitialUserInfoRequestType: " << requestType.error();
173*4d7e907cSAndroid Build Coastguard Worker     }
174*4d7e907cSAndroid Build Coastguard Worker     request.requestType = *requestType;
175*4d7e907cSAndroid Build Coastguard Worker     ret = parseUsersInfo(propValue.value.int32Values, 2, &request.usersInfo);
176*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
177*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse users info: " << ret.error();
178*4d7e907cSAndroid Build Coastguard Worker     }
179*4d7e907cSAndroid Build Coastguard Worker     return request;
180*4d7e907cSAndroid Build Coastguard Worker }
181*4d7e907cSAndroid Build Coastguard Worker 
toSwitchUserRequest(const VehiclePropValue & propValue)182*4d7e907cSAndroid Build Coastguard Worker Result<SwitchUserRequest> toSwitchUserRequest(const VehiclePropValue& propValue) {
183*4d7e907cSAndroid Build Coastguard Worker     auto ret = verifyPropValue(propValue, VehicleProperty::SWITCH_USER, 2);
184*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
185*4d7e907cSAndroid Build Coastguard Worker         return ret.error();
186*4d7e907cSAndroid Build Coastguard Worker     }
187*4d7e907cSAndroid Build Coastguard Worker     SwitchUserRequest request;
188*4d7e907cSAndroid Build Coastguard Worker     auto messageType = verifyAndCast<SwitchUserMessageType>(propValue.value.int32Values[1]);
189*4d7e907cSAndroid Build Coastguard Worker     if (!messageType.ok()) {
190*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Invalid SwitchUserMessageType: " << messageType.error();
191*4d7e907cSAndroid Build Coastguard Worker     }
192*4d7e907cSAndroid Build Coastguard Worker     if (*messageType != SwitchUserMessageType::LEGACY_ANDROID_SWITCH &&
193*4d7e907cSAndroid Build Coastguard Worker         *messageType != SwitchUserMessageType::ANDROID_SWITCH &&
194*4d7e907cSAndroid Build Coastguard Worker         *messageType != SwitchUserMessageType::ANDROID_POST_SWITCH) {
195*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Invalid " << toString(*messageType)
196*4d7e907cSAndroid Build Coastguard Worker                        << " message type from Android System";
197*4d7e907cSAndroid Build Coastguard Worker     }
198*4d7e907cSAndroid Build Coastguard Worker     request.requestId = propValue.value.int32Values[0];
199*4d7e907cSAndroid Build Coastguard Worker     request.messageType = *messageType;
200*4d7e907cSAndroid Build Coastguard Worker     ret = parseUserInfo(propValue.value.int32Values, 2, &request.targetUser);
201*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
202*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse target user info: " << ret.error();
203*4d7e907cSAndroid Build Coastguard Worker     }
204*4d7e907cSAndroid Build Coastguard Worker     ret = parseUsersInfo(propValue.value.int32Values, 4, &request.usersInfo);
205*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
206*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse users info: " << ret.error();
207*4d7e907cSAndroid Build Coastguard Worker     }
208*4d7e907cSAndroid Build Coastguard Worker     return request;
209*4d7e907cSAndroid Build Coastguard Worker }
210*4d7e907cSAndroid Build Coastguard Worker 
toCreateUserRequest(const VehiclePropValue & propValue)211*4d7e907cSAndroid Build Coastguard Worker Result<CreateUserRequest> toCreateUserRequest(const VehiclePropValue& propValue) {
212*4d7e907cSAndroid Build Coastguard Worker     auto ret = verifyPropValue(propValue, VehicleProperty::CREATE_USER, 1);
213*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
214*4d7e907cSAndroid Build Coastguard Worker         return ret.error();
215*4d7e907cSAndroid Build Coastguard Worker     }
216*4d7e907cSAndroid Build Coastguard Worker     CreateUserRequest request;
217*4d7e907cSAndroid Build Coastguard Worker     request.requestId = propValue.value.int32Values[0];
218*4d7e907cSAndroid Build Coastguard Worker     ret = parseUserInfo(propValue.value.int32Values, 1, &request.newUserInfo);
219*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
220*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse new user info: " << ret.error();
221*4d7e907cSAndroid Build Coastguard Worker     }
222*4d7e907cSAndroid Build Coastguard Worker     request.newUserName = propValue.value.stringValue;
223*4d7e907cSAndroid Build Coastguard Worker     ret = parseUsersInfo(propValue.value.int32Values, 3, &request.usersInfo);
224*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
225*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse users info: " << ret.error();
226*4d7e907cSAndroid Build Coastguard Worker     }
227*4d7e907cSAndroid Build Coastguard Worker     return request;
228*4d7e907cSAndroid Build Coastguard Worker }
229*4d7e907cSAndroid Build Coastguard Worker 
toRemoveUserRequest(const VehiclePropValue & propValue)230*4d7e907cSAndroid Build Coastguard Worker Result<RemoveUserRequest> toRemoveUserRequest(const VehiclePropValue& propValue) {
231*4d7e907cSAndroid Build Coastguard Worker     auto ret = verifyPropValue(propValue, VehicleProperty::REMOVE_USER, 1);
232*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
233*4d7e907cSAndroid Build Coastguard Worker         return ret.error();
234*4d7e907cSAndroid Build Coastguard Worker     }
235*4d7e907cSAndroid Build Coastguard Worker     RemoveUserRequest request;
236*4d7e907cSAndroid Build Coastguard Worker     request.requestId = propValue.value.int32Values[0];
237*4d7e907cSAndroid Build Coastguard Worker     ret = parseUserInfo(propValue.value.int32Values, 1, &request.removedUserInfo);
238*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
239*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse removed user info: " << ret.error();
240*4d7e907cSAndroid Build Coastguard Worker     }
241*4d7e907cSAndroid Build Coastguard Worker     ret = parseUsersInfo(propValue.value.int32Values, 3, &request.usersInfo);
242*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
243*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse users info: " << ret.error();
244*4d7e907cSAndroid Build Coastguard Worker     }
245*4d7e907cSAndroid Build Coastguard Worker     return request;
246*4d7e907cSAndroid Build Coastguard Worker }
247*4d7e907cSAndroid Build Coastguard Worker 
toUserIdentificationGetRequest(const VehiclePropValue & propValue)248*4d7e907cSAndroid Build Coastguard Worker Result<UserIdentificationGetRequest> toUserIdentificationGetRequest(
249*4d7e907cSAndroid Build Coastguard Worker         const VehiclePropValue& propValue) {
250*4d7e907cSAndroid Build Coastguard Worker     auto ret = verifyPropValue(propValue, VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, 4);
251*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
252*4d7e907cSAndroid Build Coastguard Worker         return ret.error();
253*4d7e907cSAndroid Build Coastguard Worker     }
254*4d7e907cSAndroid Build Coastguard Worker     UserIdentificationGetRequest request;
255*4d7e907cSAndroid Build Coastguard Worker     request.requestId = propValue.value.int32Values[0];
256*4d7e907cSAndroid Build Coastguard Worker     ret = parseUserInfo(propValue.value.int32Values, 1, &request.userInfo);
257*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
258*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse user info: " << ret.error();
259*4d7e907cSAndroid Build Coastguard Worker     }
260*4d7e907cSAndroid Build Coastguard Worker     request.numberAssociationTypes = propValue.value.int32Values[3];
261*4d7e907cSAndroid Build Coastguard Worker     ret = parseUserAssociationTypes(propValue.value.int32Values, 4, request.numberAssociationTypes,
262*4d7e907cSAndroid Build Coastguard Worker                                     &request.associationTypes);
263*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
264*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse UserIdentificationAssociationType: " << ret.error();
265*4d7e907cSAndroid Build Coastguard Worker     }
266*4d7e907cSAndroid Build Coastguard Worker     return request;
267*4d7e907cSAndroid Build Coastguard Worker }
268*4d7e907cSAndroid Build Coastguard Worker 
toUserIdentificationSetRequest(const VehiclePropValue & propValue)269*4d7e907cSAndroid Build Coastguard Worker Result<UserIdentificationSetRequest> toUserIdentificationSetRequest(
270*4d7e907cSAndroid Build Coastguard Worker         const VehiclePropValue& propValue) {
271*4d7e907cSAndroid Build Coastguard Worker     auto ret = verifyPropValue(propValue, VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, 4);
272*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
273*4d7e907cSAndroid Build Coastguard Worker         return ret.error();
274*4d7e907cSAndroid Build Coastguard Worker     }
275*4d7e907cSAndroid Build Coastguard Worker     UserIdentificationSetRequest request;
276*4d7e907cSAndroid Build Coastguard Worker     request.requestId = propValue.value.int32Values[0];
277*4d7e907cSAndroid Build Coastguard Worker     ret = parseUserInfo(propValue.value.int32Values, 1, &request.userInfo);
278*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
279*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse user info: " << ret.error();
280*4d7e907cSAndroid Build Coastguard Worker     }
281*4d7e907cSAndroid Build Coastguard Worker     request.numberAssociations = propValue.value.int32Values[3];
282*4d7e907cSAndroid Build Coastguard Worker     ret = parseUserAssociations(propValue.value.int32Values, 4, request.numberAssociations,
283*4d7e907cSAndroid Build Coastguard Worker                                 &request.associations);
284*4d7e907cSAndroid Build Coastguard Worker     if (!ret.ok()) {
285*4d7e907cSAndroid Build Coastguard Worker         return Error() << "Failed to parse UserIdentificationSetAssociation: " << ret.error();
286*4d7e907cSAndroid Build Coastguard Worker     }
287*4d7e907cSAndroid Build Coastguard Worker     return request;
288*4d7e907cSAndroid Build Coastguard Worker }
289*4d7e907cSAndroid Build Coastguard Worker 
toVehiclePropValue(const SwitchUserRequest & request)290*4d7e907cSAndroid Build Coastguard Worker std::unique_ptr<VehiclePropValue> toVehiclePropValue(const SwitchUserRequest& request) {
291*4d7e907cSAndroid Build Coastguard Worker     if (request.messageType != SwitchUserMessageType::VEHICLE_REQUEST) {
292*4d7e907cSAndroid Build Coastguard Worker         ALOGE("Invalid %s message type %s from HAL", toString(VehicleProperty::SWITCH_USER).c_str(),
293*4d7e907cSAndroid Build Coastguard Worker               toString(request.messageType).c_str());
294*4d7e907cSAndroid Build Coastguard Worker         return nullptr;
295*4d7e907cSAndroid Build Coastguard Worker     }
296*4d7e907cSAndroid Build Coastguard Worker     auto propValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue());
297*4d7e907cSAndroid Build Coastguard Worker     propValue->prop = static_cast<int32_t>(VehicleProperty::SWITCH_USER);
298*4d7e907cSAndroid Build Coastguard Worker     propValue->timestamp = elapsedRealtimeNano();
299*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values.resize(3);
300*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[0] = static_cast<int32_t>(request.requestId);
301*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[1] = static_cast<int32_t>(request.messageType);
302*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[2] = static_cast<int32_t>(request.targetUser.userId);
303*4d7e907cSAndroid Build Coastguard Worker     return propValue;
304*4d7e907cSAndroid Build Coastguard Worker }
305*4d7e907cSAndroid Build Coastguard Worker 
toVehiclePropValue(const InitialUserInfoResponse & response)306*4d7e907cSAndroid Build Coastguard Worker std::unique_ptr<VehiclePropValue> toVehiclePropValue(const InitialUserInfoResponse& response) {
307*4d7e907cSAndroid Build Coastguard Worker     auto propValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue());
308*4d7e907cSAndroid Build Coastguard Worker     propValue->prop = static_cast<int32_t>(VehicleProperty::INITIAL_USER_INFO);
309*4d7e907cSAndroid Build Coastguard Worker     propValue->timestamp = elapsedRealtimeNano();
310*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values.resize(4);
311*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[0] = static_cast<int32_t>(response.requestId);
312*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[1] = static_cast<int32_t>(response.action);
313*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[2] = static_cast<int32_t>(response.userToSwitchOrCreate.userId);
314*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[3] = static_cast<int32_t>(response.userToSwitchOrCreate.flags);
315*4d7e907cSAndroid Build Coastguard Worker     propValue->value.stringValue = std::string(response.userLocales) + std::string(kSeparator) +
316*4d7e907cSAndroid Build Coastguard Worker                                    std::string(response.userNameToCreate);
317*4d7e907cSAndroid Build Coastguard Worker     return propValue;
318*4d7e907cSAndroid Build Coastguard Worker }
319*4d7e907cSAndroid Build Coastguard Worker 
toVehiclePropValue(const SwitchUserResponse & response)320*4d7e907cSAndroid Build Coastguard Worker std::unique_ptr<VehiclePropValue> toVehiclePropValue(const SwitchUserResponse& response) {
321*4d7e907cSAndroid Build Coastguard Worker     auto propValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue());
322*4d7e907cSAndroid Build Coastguard Worker     propValue->prop = static_cast<int32_t>(VehicleProperty::SWITCH_USER);
323*4d7e907cSAndroid Build Coastguard Worker     propValue->timestamp = elapsedRealtimeNano();
324*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values.resize(3);
325*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[0] = static_cast<int32_t>(response.requestId);
326*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[1] = static_cast<int32_t>(response.messageType);
327*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[2] = static_cast<int32_t>(response.status);
328*4d7e907cSAndroid Build Coastguard Worker     if (response.status == SwitchUserStatus::FAILURE) {
329*4d7e907cSAndroid Build Coastguard Worker         propValue->value.stringValue = response.errorMessage;
330*4d7e907cSAndroid Build Coastguard Worker     }
331*4d7e907cSAndroid Build Coastguard Worker     return propValue;
332*4d7e907cSAndroid Build Coastguard Worker }
333*4d7e907cSAndroid Build Coastguard Worker 
toVehiclePropValue(const CreateUserResponse & response)334*4d7e907cSAndroid Build Coastguard Worker std::unique_ptr<VehiclePropValue> toVehiclePropValue(const CreateUserResponse& response) {
335*4d7e907cSAndroid Build Coastguard Worker     auto propValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue());
336*4d7e907cSAndroid Build Coastguard Worker     propValue->prop = static_cast<int32_t>(VehicleProperty::CREATE_USER);
337*4d7e907cSAndroid Build Coastguard Worker     propValue->timestamp = elapsedRealtimeNano();
338*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values.resize(2);
339*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[0] = static_cast<int32_t>(response.requestId);
340*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[1] = static_cast<int32_t>(response.status);
341*4d7e907cSAndroid Build Coastguard Worker     if (response.status == CreateUserStatus::FAILURE) {
342*4d7e907cSAndroid Build Coastguard Worker         propValue->value.stringValue = response.errorMessage;
343*4d7e907cSAndroid Build Coastguard Worker     }
344*4d7e907cSAndroid Build Coastguard Worker     return propValue;
345*4d7e907cSAndroid Build Coastguard Worker }
346*4d7e907cSAndroid Build Coastguard Worker 
toVehiclePropValue(const UserIdentificationResponse & response)347*4d7e907cSAndroid Build Coastguard Worker std::unique_ptr<VehiclePropValue> toVehiclePropValue(const UserIdentificationResponse& response) {
348*4d7e907cSAndroid Build Coastguard Worker     auto propValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue());
349*4d7e907cSAndroid Build Coastguard Worker     propValue->prop = static_cast<int32_t>(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION);
350*4d7e907cSAndroid Build Coastguard Worker     propValue->timestamp = elapsedRealtimeNano();
351*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values.resize(2 + (response.numberAssociation * 2));
352*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[0] = static_cast<int32_t>(response.requestId);
353*4d7e907cSAndroid Build Coastguard Worker     propValue->value.int32Values[1] = static_cast<int32_t>(response.numberAssociation);
354*4d7e907cSAndroid Build Coastguard Worker     for (size_t i = 0; i < static_cast<size_t>(response.numberAssociation); ++i) {
355*4d7e907cSAndroid Build Coastguard Worker         size_t int32ValuesPos = 2 + (2 * i);
356*4d7e907cSAndroid Build Coastguard Worker         propValue->value.int32Values[int32ValuesPos] =
357*4d7e907cSAndroid Build Coastguard Worker                 static_cast<int32_t>(response.associations[i].type);
358*4d7e907cSAndroid Build Coastguard Worker         propValue->value.int32Values[int32ValuesPos + 1] =
359*4d7e907cSAndroid Build Coastguard Worker                 static_cast<int32_t>(response.associations[i].value);
360*4d7e907cSAndroid Build Coastguard Worker     }
361*4d7e907cSAndroid Build Coastguard Worker     if (!response.errorMessage.empty()) {
362*4d7e907cSAndroid Build Coastguard Worker         propValue->value.stringValue = response.errorMessage;
363*4d7e907cSAndroid Build Coastguard Worker     }
364*4d7e907cSAndroid Build Coastguard Worker     return propValue;
365*4d7e907cSAndroid Build Coastguard Worker }
366*4d7e907cSAndroid Build Coastguard Worker 
367*4d7e907cSAndroid Build Coastguard Worker }  // namespace user_hal_helper
368*4d7e907cSAndroid Build Coastguard Worker 
369*4d7e907cSAndroid Build Coastguard Worker }  // namespace V2_0
370*4d7e907cSAndroid Build Coastguard Worker }  // namespace vehicle
371*4d7e907cSAndroid Build Coastguard Worker }  // namespace automotive
372*4d7e907cSAndroid Build Coastguard Worker }  // namespace hardware
373*4d7e907cSAndroid Build Coastguard Worker }  // namespace android
374