1 /*
2  * Copyright (C) 2022 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 <JsonConfigLoader.h>
18 
19 #include <AccessForVehicleProperty.h>
20 #include <ChangeModeForVehicleProperty.h>
21 #include <PropertyUtils.h>
22 
23 #ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
24 #include <android/hardware/automotive/vehicle/TestVendorProperty.h>
25 #endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
26 
27 #include <android-base/strings.h>
28 #include <fstream>
29 
30 namespace android {
31 namespace hardware {
32 namespace automotive {
33 namespace vehicle {
34 
35 namespace jsonconfigloader_impl {
36 
37 using ::aidl::android::hardware::automotive::vehicle::AccessForVehicleProperty;
38 using ::aidl::android::hardware::automotive::vehicle::AutomaticEmergencyBrakingState;
39 using ::aidl::android::hardware::automotive::vehicle::BlindSpotWarningState;
40 using ::aidl::android::hardware::automotive::vehicle::CameraServiceState;
41 using ::aidl::android::hardware::automotive::vehicle::ChangeModeForVehicleProperty;
42 using ::aidl::android::hardware::automotive::vehicle::CrossTrafficMonitoringWarningState;
43 using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
44 using ::aidl::android::hardware::automotive::vehicle::CruiseControlState;
45 using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
46 using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
47 using ::aidl::android::hardware::automotive::vehicle::DriverDistractionWarning;
48 using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionState;
49 using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionWarning;
50 using ::aidl::android::hardware::automotive::vehicle::ElectronicStabilityControlState;
51 using ::aidl::android::hardware::automotive::vehicle::EmergencyLaneKeepAssistState;
52 using ::aidl::android::hardware::automotive::vehicle::ErrorState;
53 using ::aidl::android::hardware::automotive::vehicle::EvConnectorType;
54 using ::aidl::android::hardware::automotive::vehicle::EvsServiceState;
55 using ::aidl::android::hardware::automotive::vehicle::EvsServiceType;
56 using ::aidl::android::hardware::automotive::vehicle::ForwardCollisionWarningState;
57 using ::aidl::android::hardware::automotive::vehicle::FuelType;
58 using ::aidl::android::hardware::automotive::vehicle::GsrComplianceRequirementType;
59 using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionDriverState;
60 using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionWarning;
61 using ::aidl::android::hardware::automotive::vehicle::ImpactSensorLocation;
62 using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistCommand;
63 using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistState;
64 using ::aidl::android::hardware::automotive::vehicle::LaneDepartureWarningState;
65 using ::aidl::android::hardware::automotive::vehicle::LaneKeepAssistState;
66 using ::aidl::android::hardware::automotive::vehicle::LocationCharacterization;
67 using ::aidl::android::hardware::automotive::vehicle::LowSpeedAutomaticEmergencyBrakingState;
68 using ::aidl::android::hardware::automotive::vehicle::LowSpeedCollisionWarningState;
69 using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
70 using ::aidl::android::hardware::automotive::vehicle::VehicleAirbagLocation;
71 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerBootupReason;
72 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
73 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
74 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
75 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
76 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
77 using ::aidl::android::hardware::automotive::vehicle::VehicleAutonomousState;
78 using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
79 using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
80 using ::aidl::android::hardware::automotive::vehicle::VehicleIgnitionState;
81 using ::aidl::android::hardware::automotive::vehicle::VehicleOilLevel;
82 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
83 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
84 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
85 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
86 using ::aidl::android::hardware::automotive::vehicle::VehicleSeatOccupancyState;
87 using ::aidl::android::hardware::automotive::vehicle::VehicleSizeClass;
88 using ::aidl::android::hardware::automotive::vehicle::VehicleTurnSignal;
89 using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
90 using ::aidl::android::hardware::automotive::vehicle::VehicleVendorPermission;
91 using ::aidl::android::hardware::automotive::vehicle::WindshieldWipersState;
92 using ::aidl::android::hardware::automotive::vehicle::WindshieldWipersSwitch;
93 
94 using ::android::base::Error;
95 using ::android::base::Result;
96 
97 // Defines a map from constant names to constant values, the values defined here corresponds to
98 // the "Constants::XXXX" used in JSON config file.
99 const std::unordered_map<std::string, int> CONSTANTS_BY_NAME = {
100         {"DOOR_1_RIGHT", DOOR_1_RIGHT},
101         {"DOOR_1_LEFT", DOOR_1_LEFT},
102         {"DOOR_2_RIGHT", DOOR_2_RIGHT},
103         {"DOOR_2_LEFT", DOOR_2_LEFT},
104         {"DOOR_REAR", DOOR_REAR},
105         {"HVAC_ALL", HVAC_ALL},
106         {"HVAC_LEFT", HVAC_LEFT},
107         {"HVAC_RIGHT", HVAC_RIGHT},
108         {"HVAC_FRONT_ROW", HVAC_FRONT_ROW},
109         {"HVAC_REAR_ROW", HVAC_REAR_ROW},
110         {"WINDOW_1_LEFT", WINDOW_1_LEFT},
111         {"WINDOW_1_RIGHT", WINDOW_1_RIGHT},
112         {"WINDOW_2_LEFT", WINDOW_2_LEFT},
113         {"WINDOW_2_RIGHT", WINDOW_2_RIGHT},
114         {"WINDOW_ROOF_TOP_1", WINDOW_ROOF_TOP_1},
115         {"WINDOW_1_RIGHT_2_LEFT_2_RIGHT", WINDOW_1_RIGHT | WINDOW_2_LEFT | WINDOW_2_RIGHT},
116         {"SEAT_1_LEFT", SEAT_1_LEFT},
117         {"SEAT_1_RIGHT", SEAT_1_RIGHT},
118         {"SEAT_2_LEFT", SEAT_2_LEFT},
119         {"SEAT_2_RIGHT", SEAT_2_RIGHT},
120         {"SEAT_2_CENTER", SEAT_2_CENTER},
121         {"SEAT_2_LEFT_2_RIGHT_2_CENTER", SEAT_2_LEFT | SEAT_2_RIGHT | SEAT_2_CENTER},
122         {"WHEEL_REAR_RIGHT", WHEEL_REAR_RIGHT},
123         {"WHEEL_REAR_LEFT", WHEEL_REAR_LEFT},
124         {"WHEEL_FRONT_RIGHT", WHEEL_FRONT_RIGHT},
125         {"WHEEL_FRONT_LEFT", WHEEL_FRONT_LEFT},
126         {"CHARGE_PORT_FRONT_LEFT", CHARGE_PORT_FRONT_LEFT},
127         {"CHARGE_PORT_REAR_LEFT", CHARGE_PORT_REAR_LEFT},
128         {"FAN_DIRECTION_UNKNOWN", toInt(VehicleHvacFanDirection::UNKNOWN)},
129         {"FAN_DIRECTION_FLOOR", FAN_DIRECTION_FLOOR},
130         {"FAN_DIRECTION_FACE", FAN_DIRECTION_FACE},
131         {"FAN_DIRECTION_DEFROST", FAN_DIRECTION_DEFROST},
132         {"FAN_DIRECTION_FACE_FLOOR", FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR},
133         {"FAN_DIRECTION_FACE_DEFROST", FAN_DIRECTION_FACE | FAN_DIRECTION_DEFROST},
134         {"FAN_DIRECTION_FLOOR_DEFROST", FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST},
135         {"FAN_DIRECTION_FLOOR_DEFROST_FACE",
136          FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST | FAN_DIRECTION_FACE},
137         {"FUEL_DOOR_REAR_LEFT", FUEL_DOOR_REAR_LEFT},
138         {"LIGHT_STATE_ON", LIGHT_STATE_ON},
139         {"LIGHT_STATE_OFF", LIGHT_STATE_OFF},
140         {"LIGHT_SWITCH_OFF", LIGHT_SWITCH_OFF},
141         {"LIGHT_SWITCH_ON", LIGHT_SWITCH_ON},
142         {"LIGHT_SWITCH_AUTO", LIGHT_SWITCH_AUTO},
143         {"EV_STOPPING_MODE_CREEP", EV_STOPPING_MODE_CREEP},
144         {"EV_STOPPING_MODE_ROLL", EV_STOPPING_MODE_ROLL},
145         {"EV_STOPPING_MODE_HOLD", EV_STOPPING_MODE_HOLD},
146         {"MIRROR_DRIVER_LEFT_RIGHT",
147          toInt(VehicleAreaMirror::DRIVER_LEFT) | toInt(VehicleAreaMirror::DRIVER_RIGHT)},
148 };
149 
150 // A class to parse constant values for type T where T is defined as an enum in NDK AIDL backend.
151 template <class T>
152 class ConstantParser final : public ConstantParserInterface {
153   public:
ConstantParser()154     ConstantParser() {
155         for (const T& v : ndk::enum_range<T>()) {
156             std::string name = aidl::android::hardware::automotive::vehicle::toString(v);
157             // We use the same constant for both VehicleUnit::GALLON and VehicleUnit::US_GALLON,
158             // which caused toString() not work properly for US_GALLON. So we explicitly add the
159             // map here.
160             if (name == "GALLON") {
161                 mValueByName["US_GALLON"] = toInt(v);
162             }
163             mValueByName[name] = toInt(v);
164         }
165     }
166 
167     ~ConstantParser() = default;
168 
parseValue(const std::string & name) const169     Result<int> parseValue(const std::string& name) const override {
170         auto it = mValueByName.find(name);
171         if (it == mValueByName.end()) {
172             return Error() << "Constant name: " << name << " is not defined";
173         }
174         return it->second;
175     }
176 
177   private:
178     std::unordered_map<std::string, int> mValueByName;
179 };
180 
181 #ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
182 // A class to parse constant values for type T where T is defined as an enum in CPP AIDL backend.
183 template <class T>
184 class CppConstantParser final : public ConstantParserInterface {
185   public:
CppConstantParser()186     CppConstantParser() {
187         for (const T& v : android::enum_range<T>()) {
188             std::string name = android::hardware::automotive::vehicle::toString(v);
189             mValueByName[name] = toInt(v);
190         }
191     }
192 
193     ~CppConstantParser() = default;
194 
parseValue(const std::string & name) const195     Result<int> parseValue(const std::string& name) const override {
196         auto it = mValueByName.find(name);
197         if (it == mValueByName.end()) {
198             return Error() << "Constant name: " << name << " is not defined";
199         }
200         return it->second;
201     }
202 
203   private:
204     std::unordered_map<std::string, int> mValueByName;
205 };
206 #endif
207 
208 // A class to parse constant values defined in CONSTANTS_BY_NAME map.
209 class LocalVariableParser final : public ConstantParserInterface {
210   public:
211     ~LocalVariableParser() = default;
212 
parseValue(const std::string & name) const213     Result<int> parseValue(const std::string& name) const override {
214         auto constantsIt = CONSTANTS_BY_NAME.find(name);
215         if (constantsIt == CONSTANTS_BY_NAME.end()) {
216             return Error() << "Constant variable name: " << name << " is not defined";
217         }
218         return constantsIt->second;
219     }
220 };
221 
JsonValueParser()222 JsonValueParser::JsonValueParser() {
223     mConstantParsersByType["VehiclePropertyAccess"] =
224             std::make_unique<ConstantParser<VehiclePropertyAccess>>();
225     mConstantParsersByType["VehiclePropertyChangeMode"] =
226             std::make_unique<ConstantParser<VehiclePropertyChangeMode>>();
227     mConstantParsersByType["LocationCharacterization"] =
228             std::make_unique<ConstantParser<LocationCharacterization>>();
229     mConstantParsersByType["VehicleGear"] = std::make_unique<ConstantParser<VehicleGear>>();
230     mConstantParsersByType["VehicleAreaWindow"] =
231             std::make_unique<ConstantParser<VehicleAreaWindow>>();
232     mConstantParsersByType["VehicleAreaMirror"] =
233             std::make_unique<ConstantParser<VehicleAreaMirror>>();
234     mConstantParsersByType["VehicleOilLevel"] = std::make_unique<ConstantParser<VehicleOilLevel>>();
235     mConstantParsersByType["VehicleUnit"] = std::make_unique<ConstantParser<VehicleUnit>>();
236     mConstantParsersByType["VehicleSeatOccupancyState"] =
237             std::make_unique<ConstantParser<VehicleSeatOccupancyState>>();
238     mConstantParsersByType["VehicleHvacFanDirection"] =
239             std::make_unique<ConstantParser<VehicleHvacFanDirection>>();
240     mConstantParsersByType["VehicleApPowerStateReport"] =
241             std::make_unique<ConstantParser<VehicleApPowerStateReport>>();
242     mConstantParsersByType["VehicleTurnSignal"] =
243             std::make_unique<ConstantParser<VehicleTurnSignal>>();
244     mConstantParsersByType["VehicleVendorPermission"] =
245             std::make_unique<ConstantParser<VehicleVendorPermission>>();
246     mConstantParsersByType["EvsServiceType"] = std::make_unique<ConstantParser<EvsServiceType>>();
247     mConstantParsersByType["EvsServiceState"] = std::make_unique<ConstantParser<EvsServiceState>>();
248     mConstantParsersByType["EvConnectorType"] = std::make_unique<ConstantParser<EvConnectorType>>();
249     mConstantParsersByType["VehicleProperty"] = std::make_unique<ConstantParser<VehicleProperty>>();
250     mConstantParsersByType["GsrComplianceRequirementType"] =
251             std::make_unique<ConstantParser<GsrComplianceRequirementType>>();
252     mConstantParsersByType["VehicleIgnitionState"] =
253             std::make_unique<ConstantParser<VehicleIgnitionState>>();
254     mConstantParsersByType["FuelType"] = std::make_unique<ConstantParser<FuelType>>();
255     mConstantParsersByType["WindshieldWipersState"] =
256             std::make_unique<ConstantParser<WindshieldWipersState>>();
257     mConstantParsersByType["WindshieldWipersSwitch"] =
258             std::make_unique<ConstantParser<WindshieldWipersSwitch>>();
259     mConstantParsersByType["VehicleAutonomousState"] =
260             std::make_unique<ConstantParser<VehicleAutonomousState>>();
261     mConstantParsersByType["VehicleAirbagLocation"] =
262             std::make_unique<ConstantParser<VehicleAirbagLocation>>();
263     mConstantParsersByType["ImpactSensorLocation"] =
264             std::make_unique<ConstantParser<ImpactSensorLocation>>();
265     mConstantParsersByType["VehicleSizeClass"] =
266             std::make_unique<ConstantParser<VehicleSizeClass>>();
267     mConstantParsersByType["EmergencyLaneKeepAssistState"] =
268             std::make_unique<ConstantParser<EmergencyLaneKeepAssistState>>();
269     mConstantParsersByType["CameraServiceState"] =
270             std::make_unique<ConstantParser<CameraServiceState>>();
271     mConstantParsersByType["CruiseControlType"] =
272             std::make_unique<ConstantParser<CruiseControlType>>();
273     mConstantParsersByType["CruiseControlState"] =
274             std::make_unique<ConstantParser<CruiseControlState>>();
275     mConstantParsersByType["CruiseControlCommand"] =
276             std::make_unique<ConstantParser<CruiseControlCommand>>();
277     mConstantParsersByType["HandsOnDetectionDriverState"] =
278             std::make_unique<ConstantParser<HandsOnDetectionDriverState>>();
279     mConstantParsersByType["HandsOnDetectionWarning"] =
280             std::make_unique<ConstantParser<HandsOnDetectionWarning>>();
281     mConstantParsersByType["DriverDrowsinessAttentionState"] =
282             std::make_unique<ConstantParser<DriverDrowsinessAttentionState>>();
283     mConstantParsersByType["DriverDrowsinessAttentionWarning"] =
284             std::make_unique<ConstantParser<DriverDrowsinessAttentionWarning>>();
285     mConstantParsersByType["DriverDistractionState"] =
286             std::make_unique<ConstantParser<DriverDistractionState>>();
287     mConstantParsersByType["DriverDistractionWarning"] =
288             std::make_unique<ConstantParser<DriverDistractionWarning>>();
289     mConstantParsersByType["ErrorState"] = std::make_unique<ConstantParser<ErrorState>>();
290     mConstantParsersByType["AutomaticEmergencyBrakingState"] =
291             std::make_unique<ConstantParser<AutomaticEmergencyBrakingState>>();
292     mConstantParsersByType["ForwardCollisionWarningState"] =
293             std::make_unique<ConstantParser<ForwardCollisionWarningState>>();
294     mConstantParsersByType["BlindSpotWarningState"] =
295             std::make_unique<ConstantParser<BlindSpotWarningState>>();
296     mConstantParsersByType["LaneDepartureWarningState"] =
297             std::make_unique<ConstantParser<LaneDepartureWarningState>>();
298     mConstantParsersByType["LaneKeepAssistState"] =
299             std::make_unique<ConstantParser<LaneKeepAssistState>>();
300     mConstantParsersByType["LaneCenteringAssistCommand"] =
301             std::make_unique<ConstantParser<LaneCenteringAssistCommand>>();
302     mConstantParsersByType["LaneCenteringAssistState"] =
303             std::make_unique<ConstantParser<LaneCenteringAssistState>>();
304     mConstantParsersByType["LowSpeedCollisionWarningState"] =
305             std::make_unique<ConstantParser<LowSpeedCollisionWarningState>>();
306     mConstantParsersByType["ElectronicStabilityControlState"] =
307             std::make_unique<ConstantParser<ElectronicStabilityControlState>>();
308     mConstantParsersByType["CrossTrafficMonitoringWarningState"] =
309             std::make_unique<ConstantParser<CrossTrafficMonitoringWarningState>>();
310     mConstantParsersByType["LowSpeedAutomaticEmergencyBrakingState"] =
311             std::make_unique<ConstantParser<LowSpeedAutomaticEmergencyBrakingState>>();
312     mConstantParsersByType["VehicleApPowerBootupReason"] =
313             std::make_unique<ConstantParser<VehicleApPowerBootupReason>>();
314     mConstantParsersByType["Constants"] = std::make_unique<LocalVariableParser>();
315 #ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
316     mConstantParsersByType["TestVendorProperty"] =
317             std::make_unique<CppConstantParser<TestVendorProperty>>();
318 #endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
319 }
320 
321 template <>
convertValueToType(const std::string & fieldName,const Json::Value & value)322 Result<bool> JsonValueParser::convertValueToType<bool>(const std::string& fieldName,
323                                                        const Json::Value& value) {
324     if (!value.isBool()) {
325         return Error() << "The value: " << value << " for field: " << fieldName
326                        << " is not in correct type, expect bool";
327     }
328     return value.asBool();
329 }
330 
331 template <>
convertValueToType(const std::string & fieldName,const Json::Value & value)332 Result<int32_t> JsonValueParser::convertValueToType<int32_t>(const std::string& fieldName,
333                                                              const Json::Value& value) {
334     if (!value.isInt()) {
335         return Error() << "The value: " << value << " for field: " << fieldName
336                        << " is not in correct type, expect int";
337     }
338     return static_cast<int32_t>(value.asInt());
339 }
340 
341 template <>
convertValueToType(const std::string & fieldName,const Json::Value & value)342 Result<float> JsonValueParser::convertValueToType<float>(const std::string& fieldName,
343                                                          const Json::Value& value) {
344     // isFloat value does not exist, so we use isDouble here.
345     if (!value.isDouble()) {
346         return Error() << "The value: " << value << " for field: " << fieldName
347                        << " is not in correct type, expect float";
348     }
349     return value.asFloat();
350 }
351 
352 template <>
convertValueToType(const std::string & fieldName,const Json::Value & value)353 Result<int64_t> JsonValueParser::convertValueToType<int64_t>(const std::string& fieldName,
354                                                              const Json::Value& value) {
355     if (!value.isInt64()) {
356         return Error() << "The value: " << value << " for field: " << fieldName
357                        << " is not in correct type, expect int64";
358     }
359     return static_cast<int64_t>(value.asInt64());
360 }
361 
362 template <>
convertValueToType(const std::string & fieldName,const Json::Value & value)363 Result<std::string> JsonValueParser::convertValueToType<std::string>(const std::string& fieldName,
364                                                                      const Json::Value& value) {
365     if (!value.isString()) {
366         return Error() << "The value: " << value << " for field: " << fieldName
367                        << " is not in correct type, expect string";
368     }
369     return value.asString();
370 }
371 
parseStringValue(const std::string & fieldName,const Json::Value & value) const372 Result<std::string> JsonValueParser::parseStringValue(const std::string& fieldName,
373                                                       const Json::Value& value) const {
374     return convertValueToType<std::string>(fieldName, value);
375 }
376 
377 template <class T>
parseValue(const std::string & fieldName,const Json::Value & value) const378 Result<T> JsonValueParser::parseValue(const std::string& fieldName,
379                                       const Json::Value& value) const {
380     if (!value.isString()) {
381         return convertValueToType<T>(fieldName, value);
382     }
383     auto maybeTypeAndValue = maybeGetTypeAndValueName(value.asString());
384     if (!maybeTypeAndValue.has_value()) {
385         return Error() << "Invalid constant value: " << value << " for field: " << fieldName;
386     }
387     auto constantParseResult = parseConstantValue(maybeTypeAndValue.value());
388     if (!constantParseResult.ok()) {
389         return constantParseResult.error();
390     }
391     int constantValue = constantParseResult.value();
392     return static_cast<T>(constantValue);
393 }
394 
395 template <>
parseValue(const std::string & fieldName,const Json::Value & value) const396 Result<std::string> JsonValueParser::parseValue<std::string>(const std::string& fieldName,
397                                                              const Json::Value& value) const {
398     return parseStringValue(fieldName, value);
399 }
400 
401 template <class T>
parseArray(const std::string & fieldName,const Json::Value & value) const402 Result<std::vector<T>> JsonValueParser::parseArray(const std::string& fieldName,
403                                                    const Json::Value& value) const {
404     if (!value.isArray()) {
405         return Error() << "The value: " << value << " for field: " << fieldName
406                        << " is not in correct type, expect array";
407     }
408     std::vector<T> parsedValues;
409     for (unsigned int i = 0; i < value.size(); i++) {
410         auto result = parseValue<T>(fieldName, value[i]);
411         if (!result.ok()) {
412             return result.error();
413         }
414         parsedValues.push_back(result.value());
415     }
416     return std::move(parsedValues);
417 }
418 
maybeGetTypeAndValueName(const std::string & jsonFieldValue) const419 std::optional<std::pair<std::string, std::string>> JsonValueParser::maybeGetTypeAndValueName(
420         const std::string& jsonFieldValue) const {
421     size_t pos = jsonFieldValue.find(DELIMITER);
422     if (pos == std::string::npos) {
423         return {};
424     }
425     std::string type = jsonFieldValue.substr(0, pos);
426     std::string valueName = jsonFieldValue.substr(pos + DELIMITER.length(), std::string::npos);
427     if (type != "Constants" && mConstantParsersByType.find(type) == mConstantParsersByType.end()) {
428         return {};
429     }
430     return std::make_pair(type, valueName);
431 }
432 
parseConstantValue(const std::pair<std::string,std::string> & typeValueName) const433 Result<int> JsonValueParser::parseConstantValue(
434         const std::pair<std::string, std::string>& typeValueName) const {
435     const std::string& type = typeValueName.first;
436     const std::string& valueName = typeValueName.second;
437     auto it = mConstantParsersByType.find(type);
438     if (it == mConstantParsersByType.end()) {
439         return Error() << "Unrecognized type: " << type;
440     }
441     auto result = it->second->parseValue(valueName);
442     if (!result.ok()) {
443         return Error() << type << "::" << valueName << " undefined";
444     }
445     return result;
446 }
447 
448 template <class T>
tryParseJsonValueToVariable(const Json::Value & parentJsonNode,const std::string & fieldName,bool fieldIsOptional,T * outPtr,std::vector<std::string> * errors)449 bool JsonConfigParser::tryParseJsonValueToVariable(const Json::Value& parentJsonNode,
450                                                    const std::string& fieldName,
451                                                    bool fieldIsOptional, T* outPtr,
452                                                    std::vector<std::string>* errors) {
453     if (!parentJsonNode.isObject()) {
454         errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
455         return false;
456     }
457     if (!parentJsonNode.isMember(fieldName)) {
458         if (!fieldIsOptional) {
459             errors->push_back("Missing required field: " + fieldName +
460                               " in node: " + parentJsonNode.toStyledString());
461             return false;
462         }
463         return true;
464     }
465     auto result = mValueParser.parseValue<T>(fieldName, parentJsonNode[fieldName]);
466     if (!result.ok()) {
467         errors->push_back(result.error().message());
468         return false;
469     }
470     *outPtr = std::move(result.value());
471     return true;
472 }
473 
474 template <class T>
tryParseJsonArrayToVariable(const Json::Value & parentJsonNode,const std::string & fieldName,bool fieldIsOptional,std::vector<T> * outPtr,std::vector<std::string> * errors)475 bool JsonConfigParser::tryParseJsonArrayToVariable(const Json::Value& parentJsonNode,
476                                                    const std::string& fieldName,
477                                                    bool fieldIsOptional, std::vector<T>* outPtr,
478                                                    std::vector<std::string>* errors) {
479     if (!parentJsonNode.isObject()) {
480         errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
481         return false;
482     }
483     if (!parentJsonNode.isMember(fieldName)) {
484         if (!fieldIsOptional) {
485             errors->push_back("Missing required field: " + fieldName +
486                               " in node: " + parentJsonNode.toStyledString());
487             return false;
488         }
489         return true;
490     }
491     auto result = mValueParser.parseArray<T>(fieldName, parentJsonNode[fieldName]);
492     if (!result.ok()) {
493         errors->push_back(result.error().message());
494         return false;
495     }
496     *outPtr = std::move(result.value());
497     return true;
498 }
499 
500 template <class T>
parseAccessChangeMode(const Json::Value & parentJsonNode,const std::string & fieldName,const std::string & propStr,const T * defaultAccessChangeModeValuePtr,T * outPtr,std::vector<std::string> * errors)501 void JsonConfigParser::parseAccessChangeMode(const Json::Value& parentJsonNode,
502                                              const std::string& fieldName,
503                                              const std::string& propStr,
504                                              const T* defaultAccessChangeModeValuePtr, T* outPtr,
505                                              std::vector<std::string>* errors) {
506     if (!parentJsonNode.isObject()) {
507         errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
508         return;
509     }
510     if (parentJsonNode.isMember(fieldName)) {
511         auto result = mValueParser.parseValue<int32_t>(fieldName, parentJsonNode[fieldName]);
512         if (!result.ok()) {
513             errors->push_back(result.error().message());
514             return;
515         }
516         *outPtr = static_cast<T>(result.value());
517         return;
518     }
519     if (defaultAccessChangeModeValuePtr == NULL) {
520         errors->push_back("No " + fieldName + " specified for property: " + propStr);
521         return;
522     }
523     *outPtr = *defaultAccessChangeModeValuePtr;
524     return;
525 }
526 
parsePropValues(const Json::Value & parentJsonNode,const std::string & fieldName,RawPropValues * outPtr,std::vector<std::string> * errors)527 bool JsonConfigParser::parsePropValues(const Json::Value& parentJsonNode,
528                                        const std::string& fieldName, RawPropValues* outPtr,
529                                        std::vector<std::string>* errors) {
530     if (!parentJsonNode.isObject()) {
531         errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
532         return false;
533     }
534     if (!parentJsonNode.isMember(fieldName)) {
535         return false;
536     }
537     const Json::Value& jsonValue = parentJsonNode[fieldName];
538     bool success = true;
539     success &= tryParseJsonArrayToVariable(jsonValue, "int32Values",
540                                            /*optional=*/true, &(outPtr->int32Values), errors);
541     success &= tryParseJsonArrayToVariable(jsonValue, "floatValues",
542                                            /*optional=*/true, &(outPtr->floatValues), errors);
543     success &= tryParseJsonArrayToVariable(jsonValue, "int64Values",
544                                            /*optional=*/true, &(outPtr->int64Values), errors);
545     // We don't support "byteValues" yet.
546     success &= tryParseJsonValueToVariable(jsonValue, "stringValue",
547                                            /*optional=*/true, &(outPtr->stringValue), errors);
548     return success;
549 }
550 
parseAreas(const Json::Value & parentJsonNode,const std::string & fieldName,ConfigDeclaration * config,std::vector<std::string> * errors)551 void JsonConfigParser::parseAreas(const Json::Value& parentJsonNode, const std::string& fieldName,
552                                   ConfigDeclaration* config, std::vector<std::string>* errors) {
553     if (!parentJsonNode.isObject()) {
554         errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
555         return;
556     }
557     if (!parentJsonNode.isMember(fieldName)) {
558         return;
559     }
560     std::string propStr = parentJsonNode["property"].toStyledString();
561     const Json::Value& jsonValue = parentJsonNode[fieldName];
562 
563     if (!jsonValue.isArray()) {
564         errors->push_back("Field: " + fieldName + " is not an array");
565         return;
566     }
567     for (unsigned int i = 0; i < jsonValue.size(); i++) {
568         int32_t areaId;
569         const Json::Value& jsonAreaConfig = jsonValue[i];
570         if (!tryParseJsonValueToVariable(jsonAreaConfig, "areaId",
571                                          /*optional=*/false, &areaId, errors)) {
572             continue;
573         }
574         VehicleAreaConfig areaConfig = {};
575         areaConfig.areaId = areaId;
576         parseAccessChangeMode(jsonAreaConfig, "access", propStr, &(config->config.access),
577                               &areaConfig.access, errors);
578         tryParseJsonValueToVariable(jsonAreaConfig, "minInt32Value", /*optional=*/true,
579                                     &areaConfig.minInt32Value, errors);
580         tryParseJsonValueToVariable(jsonAreaConfig, "maxInt32Value", /*optional=*/true,
581                                     &areaConfig.maxInt32Value, errors);
582         tryParseJsonValueToVariable(jsonAreaConfig, "minInt64Value", /*optional=*/true,
583                                     &areaConfig.minInt64Value, errors);
584         tryParseJsonValueToVariable(jsonAreaConfig, "maxInt64Value", /*optional=*/true,
585                                     &areaConfig.maxInt64Value, errors);
586         tryParseJsonValueToVariable(jsonAreaConfig, "minFloatValue", /*optional=*/true,
587                                     &areaConfig.minFloatValue, errors);
588         tryParseJsonValueToVariable(jsonAreaConfig, "maxFloatValue", /*optional=*/true,
589                                     &areaConfig.maxFloatValue, errors);
590 
591         // By default we support variable update rate for all properties except it is explicitly
592         // disabled.
593         areaConfig.supportVariableUpdateRate = true;
594         tryParseJsonValueToVariable(jsonAreaConfig, "supportVariableUpdateRate", /*optional=*/true,
595                                     &areaConfig.supportVariableUpdateRate, errors);
596 
597         std::vector<int64_t> supportedEnumValues;
598         tryParseJsonArrayToVariable(jsonAreaConfig, "supportedEnumValues", /*optional=*/true,
599                                     &supportedEnumValues, errors);
600         if (!supportedEnumValues.empty()) {
601             areaConfig.supportedEnumValues = std::move(supportedEnumValues);
602         }
603         config->config.areaConfigs.push_back(std::move(areaConfig));
604 
605         RawPropValues areaValue = {};
606         if (parsePropValues(jsonAreaConfig, "defaultValue", &areaValue, errors)) {
607             config->initialAreaValues[areaId] = std::move(areaValue);
608         }
609     }
610 }
611 
parseEachProperty(const Json::Value & propJsonValue,std::vector<std::string> * errors)612 std::optional<ConfigDeclaration> JsonConfigParser::parseEachProperty(
613         const Json::Value& propJsonValue, std::vector<std::string>* errors) {
614     size_t initialErrorCount = errors->size();
615     ConfigDeclaration configDecl = {};
616     int32_t propId;
617 
618     if (!tryParseJsonValueToVariable(propJsonValue, "property", /*optional=*/false, &propId,
619                                      errors)) {
620         return std::nullopt;
621     }
622 
623     configDecl.config.prop = propId;
624     std::string propStr = propJsonValue["property"].toStyledString();
625     VehiclePropertyAccess* defaultAccessMode = NULL;
626     auto itAccess = AccessForVehicleProperty.find(static_cast<VehicleProperty>(propId));
627     if (itAccess != AccessForVehicleProperty.end()) {
628         defaultAccessMode = &itAccess->second;
629     }
630     VehiclePropertyChangeMode* defaultChangeMode = NULL;
631     auto itChangeMode = ChangeModeForVehicleProperty.find(static_cast<VehicleProperty>(propId));
632     if (itChangeMode != ChangeModeForVehicleProperty.end()) {
633         defaultChangeMode = &itChangeMode->second;
634     }
635     parseAccessChangeMode(propJsonValue, "access", propStr, defaultAccessMode,
636                           &configDecl.config.access, errors);
637 
638     parseAccessChangeMode(propJsonValue, "changeMode", propStr, defaultChangeMode,
639                           &configDecl.config.changeMode, errors);
640 
641     tryParseJsonValueToVariable(propJsonValue, "configString", /*optional=*/true,
642                                 &configDecl.config.configString, errors);
643 
644     tryParseJsonArrayToVariable(propJsonValue, "configArray", /*optional=*/true,
645                                 &configDecl.config.configArray, errors);
646 
647     parsePropValues(propJsonValue, "defaultValue", &configDecl.initialValue, errors);
648 
649     tryParseJsonValueToVariable(propJsonValue, "minSampleRate", /*optional=*/true,
650                                 &configDecl.config.minSampleRate, errors);
651 
652     tryParseJsonValueToVariable(propJsonValue, "maxSampleRate", /*optional=*/true,
653                                 &configDecl.config.maxSampleRate, errors);
654 
655     parseAreas(propJsonValue, "areas", &configDecl, errors);
656 
657     // If there is no area config, by default we allow variable update rate, so we have to add
658     // a global area config.
659     if (configDecl.config.areaConfigs.size() == 0) {
660         VehicleAreaConfig areaConfig = {
661                 .areaId = 0,
662                 .access = configDecl.config.access,
663                 .supportVariableUpdateRate = true,
664         };
665         configDecl.config.areaConfigs.push_back(std::move(areaConfig));
666     }
667 
668     if (errors->size() != initialErrorCount) {
669         return std::nullopt;
670     }
671 
672     return configDecl;
673 }
674 
parseJsonConfig(std::istream & is)675 Result<std::unordered_map<int32_t, ConfigDeclaration>> JsonConfigParser::parseJsonConfig(
676         std::istream& is) {
677     Json::CharReaderBuilder builder;
678     Json::Value root;
679     std::unordered_map<int32_t, ConfigDeclaration> configsByPropId;
680     std::string errs;
681     if (!Json::parseFromStream(builder, is, &root, &errs)) {
682         return Error() << "Failed to parse property config file as JSON, error: " << errs;
683     }
684     if (!root.isObject()) {
685         return Error() << "root element must be an object";
686     }
687     if (!root.isMember("properties") || !root["properties"].isArray()) {
688         return Error() << "Missing 'properties' field in root or the field is not an array";
689     }
690     Json::Value properties = root["properties"];
691     std::vector<std::string> errors;
692     for (unsigned int i = 0; i < properties.size(); i++) {
693         if (auto maybeConfig = parseEachProperty(properties[i], &errors); maybeConfig.has_value()) {
694             configsByPropId[maybeConfig.value().config.prop] = std::move(maybeConfig.value());
695         }
696     }
697     if (!errors.empty()) {
698         return Error() << android::base::Join(errors, '\n');
699     }
700     return configsByPropId;
701 }
702 
703 }  // namespace jsonconfigloader_impl
704 
JsonConfigLoader()705 JsonConfigLoader::JsonConfigLoader() {
706     mParser = std::make_unique<jsonconfigloader_impl::JsonConfigParser>();
707 }
708 
709 android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>>
loadPropConfig(std::istream & is)710 JsonConfigLoader::loadPropConfig(std::istream& is) {
711     return mParser->parseJsonConfig(is);
712 }
713 
714 android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>>
loadPropConfig(const std::string & configPath)715 JsonConfigLoader::loadPropConfig(const std::string& configPath) {
716     std::ifstream ifs(configPath.c_str());
717     if (!ifs) {
718         return android::base::Error() << "couldn't open " << configPath << " for parsing.";
719     }
720 
721     return loadPropConfig(ifs);
722 }
723 
724 }  // namespace vehicle
725 }  // namespace automotive
726 }  // namespace hardware
727 }  // namespace android
728