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