133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev/* 233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * Copyright (C) 2016 The Android Open Source Project 333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * 433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * Licensed under the Apache License, Version 2.0 (the "License"); 533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * you may not use this file except in compliance with the License. 633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * You may obtain a copy of the License at 733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * 833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * http://www.apache.org/licenses/LICENSE-2.0 933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * 1033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * Unless required by applicable law or agreed to in writing, software 1133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * distributed under the License is distributed on an "AS IS" BASIS, 1233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * See the License for the specific language governing permissions and 1433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev * limitations under the License. 1533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev */ 1633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev#define LOG_TAG "DefaultVehicleHal_v2_0" 17356c2ced1dd58915ba3997c80a3db56b1a8fdc0eSteven Moreland 1833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev#include <android/log.h> 19356c2ced1dd58915ba3997c80a3db56b1a8fdc0eSteven Moreland#include <android-base/macros.h> 2033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 2133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev#include "EmulatedVehicleHal.h" 22f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan#include "JsonFakeValueGenerator.h" 23f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan#include "LinearFakeValueGenerator.h" 24250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev#include "Obd2SensorStore.h" 2533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 2633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevnamespace android { 2733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevnamespace hardware { 2833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevnamespace automotive { 2933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevnamespace vehicle { 3033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevnamespace V2_0 { 3133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 3233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevnamespace impl { 3333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 34250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsevstatic std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorIntegerSensors, 35250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev size_t numVendorFloatSensors) { 36250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev std::unique_ptr<Obd2SensorStore> sensorStore( 37250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev new Obd2SensorStore(numVendorIntegerSensors, numVendorFloatSensors)); 38250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 39250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS, 40250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev toInt(Obd2FuelSystemStatus::CLOSED_LOOP)); 41250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON, 0); 42250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::IGNITION_MONITORS_SUPPORTED, 43250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev toInt(Obd2IgnitionMonitorKind::SPARK)); 44250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::IGNITION_SPECIFIC_MONITORS, 45250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev Obd2CommonIgnitionMonitors::COMPONENTS_AVAILABLE | 46250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev Obd2CommonIgnitionMonitors::MISFIRE_AVAILABLE | 47250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev Obd2SparkIgnitionMonitors::AC_REFRIGERANT_AVAILABLE | 48250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev Obd2SparkIgnitionMonitors::EVAPORATIVE_SYSTEM_AVAILABLE); 49250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::INTAKE_AIR_TEMPERATURE, 35); 50250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::COMMANDED_SECONDARY_AIR_STATUS, 51250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev toInt(Obd2SecondaryAirStatus::FROM_OUTSIDE_OR_OFF)); 52250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT, 1); 53250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::RUNTIME_SINCE_ENGINE_START, 500); 54250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor( 55250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON, 0); 56250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::WARMUPS_SINCE_CODES_CLEARED, 51); 57250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor( 58250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev DiagnosticIntegerSensorIndex::DISTANCE_TRAVELED_SINCE_CODES_CLEARED, 365); 59250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::ABSOLUTE_BAROMETRIC_PRESSURE, 30); 60250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::CONTROL_MODULE_VOLTAGE, 12); 61250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::AMBIENT_AIR_TEMPERATURE, 18); 62250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::MAX_FUEL_AIR_EQUIVALENCE_RATIO, 1); 63250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setIntegerSensor(DiagnosticIntegerSensorIndex::FUEL_TYPE, 64250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev toInt(Obd2FuelType::GASOLINE)); 65250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD, 0.153); 66250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1, -0.16); 67250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1, -0.16); 68250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK2, -0.16); 69250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK2, -0.16); 70250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::INTAKE_MANIFOLD_ABSOLUTE_PRESSURE, 7.5); 71250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ENGINE_RPM, 1250.); 72250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::VEHICLE_SPEED, 40.); 73250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::TIMING_ADVANCE, 2.5); 74250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::THROTTLE_POSITION, 19.75); 75250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::OXYGEN_SENSOR1_VOLTAGE, 0.265); 76250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::FUEL_TANK_LEVEL_INPUT, 0.824); 77250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::EVAPORATION_SYSTEM_VAPOR_PRESSURE, 78250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev -0.373); 79250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::CATALYST_TEMPERATURE_BANK1_SENSOR1, 80250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 190.); 81250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::RELATIVE_THROTTLE_POSITION, 3.); 82250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ABSOLUTE_THROTTLE_POSITION_B, 0.306); 83250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_D, 0.188); 84250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::ACCELERATOR_PEDAL_POSITION_E, 0.094); 85250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->setFloatSensor(DiagnosticFloatSensorIndex::COMMANDED_THROTTLE_ACTUATOR, 0.024); 86250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 87250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev return sensorStore; 88250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev} 89250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 9033676528f85f29906b5875cfc5d28b4639402afdPavel MaltsevEmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore) 9133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev : mPropStore(propStore), 9233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)), 93f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan mRecurrentTimer( 94f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)), 95f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan mLinearFakeValueGenerator(std::make_unique<LinearFakeValueGenerator>( 96f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1))), 97f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan mJsonFakeValueGenerator(std::make_unique<JsonFakeValueGenerator>( 98f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1))) { 99250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev initStaticConfig(); 10033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev for (size_t i = 0; i < arraysize(kVehicleProperties); i++) { 10133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev mPropStore->registerProperty(kVehicleProperties[i].config); 10233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 10333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 10433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 10533676528f85f29906b5875cfc5d28b4639402afdPavel MaltsevVehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get( 10633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev const VehiclePropValue& requestedPropValue, StatusCode* outStatus) { 107250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev auto propId = requestedPropValue.prop; 108250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev auto& pool = *getValuePool(); 10933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev VehiclePropValuePtr v = nullptr; 11033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 111250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev switch (propId) { 112250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev case OBD2_FREEZE_FRAME: 113250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev v = pool.obtainComplex(); 114250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev *outStatus = fillObd2FreezeFrame(requestedPropValue, v.get()); 115250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev break; 116250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev case OBD2_FREEZE_FRAME_INFO: 117250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev v = pool.obtainComplex(); 118250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev *outStatus = fillObd2DtcInfo(v.get()); 119250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev break; 120250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev default: 121250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev auto internalPropValue = mPropStore->readValueOrNull(requestedPropValue); 122250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev if (internalPropValue != nullptr) { 123250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev v = getValuePool()->obtain(*internalPropValue); 124250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 125250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 126250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev *outStatus = v != nullptr ? StatusCode::OK : StatusCode::INVALID_ARG; 127250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev break; 12833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 12933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 13033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return v; 13133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 13233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 13333676528f85f29906b5875cfc5d28b4639402afdPavel MaltsevStatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) { 1348acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata static constexpr bool shouldUpdateStatus = false; 1358acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata 136794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev if (propValue.prop == kGenerateFakeDataControllingProperty) { 137d84109482013f5d0920f87636861f070f04c7a80Steve Paik StatusCode status = handleGenerateFakeDataRequest(propValue); 138d84109482013f5d0920f87636861f070f04c7a80Steve Paik if (status != StatusCode::OK) { 139d84109482013f5d0920f87636861f070f04c7a80Steve Paik return status; 140d84109482013f5d0920f87636861f070f04c7a80Steve Paik } 141d84109482013f5d0920f87636861f070f04c7a80Steve Paik } else if (mHvacPowerProps.count(propValue.prop)) { 1421ae977d6e87a88e1689d406636982e8296d68175Steve Paik auto hvacPowerOn = mPropStore->readValueOrNull( 1431ae977d6e87a88e1689d406636982e8296d68175Steve Paik toInt(VehicleProperty::HVAC_POWER_ON), 144de2feefd4df44428b6da5abcfe1dc9b49c52f4bfSteve Paik (VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT | 145de2feefd4df44428b6da5abcfe1dc9b49c52f4bfSteve Paik VehicleAreaSeat::ROW_2_LEFT | VehicleAreaSeat::ROW_2_CENTER | 146de2feefd4df44428b6da5abcfe1dc9b49c52f4bfSteve Paik VehicleAreaSeat::ROW_2_RIGHT)); 14733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 14833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (hvacPowerOn && hvacPowerOn->value.int32Values.size() == 1 14933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev && hvacPowerOn->value.int32Values[0] == 0) { 15033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return StatusCode::NOT_AVAILABLE; 15133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 1521b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik } else { 1531b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik // Handle property specific code 1541b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik switch (propValue.prop) { 1551b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik case OBD2_FREEZE_FRAME_CLEAR: 1561b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik return clearObd2FreezeFrames(propValue); 1571b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik case VEHICLE_MAP_SERVICE: 1581b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik // Placeholder for future implementation of VMS property in the default hal. For 1591b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik // now, just returns OK; otherwise, hal clients crash with property not supported. 1601b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik return StatusCode::OK; 16128b9f8be0b849c58e905c4a67358036a1fa82c65Steve Paik case AP_POWER_STATE_REPORT: 1621b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik // This property has different behavior between get/set. When it is set, the value 1631b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik // goes to the vehicle but is NOT updated in the property store back to Android. 1641b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik // Commented out for now, because it may mess up automated testing that use the 1651b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik // emulator interface. 1661b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik // getEmulatorOrDie()->doSetValueFromClient(propValue); 1671b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik return StatusCode::OK; 1681b48bba00e9b4f70659548eadf49489e1d85766eSteve Paik } 16933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 17033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 17174268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata if (propValue.status != VehiclePropertyStatus::AVAILABLE) { 17274268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata // Android side cannot set property status - this value is the 17374268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata // purview of the HAL implementation to reflect the state of 17474268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata // its underlying hardware 17574268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata return StatusCode::INVALID_ARG; 17674268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata } 17774268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata auto currentPropValue = mPropStore->readValueOrNull(propValue); 17874268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata 17974268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata if (currentPropValue == nullptr) { 18074268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata return StatusCode::INVALID_ARG; 18174268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata } 18274268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata if (currentPropValue->status != VehiclePropertyStatus::AVAILABLE) { 18374268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata // do not allow Android side to set() a disabled/error property 18474268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata return StatusCode::NOT_AVAILABLE; 18574268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata } 18674268e6490d6c02a9d247bf7c9a2b12a9a53960fEnrico Granata 1878acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata if (!mPropStore->writeValue(propValue, shouldUpdateStatus)) { 18833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return StatusCode::INVALID_ARG; 18933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 19033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 19133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev getEmulatorOrDie()->doSetValueFromClient(propValue); 19233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 19333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return StatusCode::OK; 19433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 19533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 196ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granatastatic bool isDiagnosticProperty(VehiclePropConfig propConfig) { 197ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata switch (propConfig.prop) { 198ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata case OBD2_LIVE_FRAME: 199ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata case OBD2_FREEZE_FRAME: 200ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata case OBD2_FREEZE_FRAME_CLEAR: 201ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata case OBD2_FREEZE_FRAME_INFO: 202ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata return true; 203ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata } 204ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata return false; 205ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata} 206ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata 20733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev// Parse supported properties list and generate vector of property values to hold current values. 20833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevvoid EmulatedVehicleHal::onCreate() { 2098acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata static constexpr bool shouldUpdateStatus = true; 2108acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata 21133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev for (auto& it : kVehicleProperties) { 21233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev VehiclePropConfig cfg = it.config; 2131ae977d6e87a88e1689d406636982e8296d68175Steve Paik int32_t numAreas = cfg.areaConfigs.size(); 21433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 215ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata if (isDiagnosticProperty(cfg)) { 216ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata // do not write an initial empty value for the diagnostic properties 217ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata // as we will initialize those separately. 218ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata continue; 219ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata } 220ad2baebb3b1c4455d3f7fe3cfd9f91e2a1442c15Enrico Granata 2211ae977d6e87a88e1689d406636982e8296d68175Steve Paik // A global property will have only a single area 22233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (isGlobalProp(cfg.prop)) { 2231ae977d6e87a88e1689d406636982e8296d68175Steve Paik numAreas = 1; 22433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 22533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 2261ae977d6e87a88e1689d406636982e8296d68175Steve Paik for (int i = 0; i < numAreas; i++) { 2271ae977d6e87a88e1689d406636982e8296d68175Steve Paik int32_t curArea; 2281ae977d6e87a88e1689d406636982e8296d68175Steve Paik 2291ae977d6e87a88e1689d406636982e8296d68175Steve Paik if (isGlobalProp(cfg.prop)) { 2301ae977d6e87a88e1689d406636982e8296d68175Steve Paik curArea = 0; 2311ae977d6e87a88e1689d406636982e8296d68175Steve Paik } else { 2321ae977d6e87a88e1689d406636982e8296d68175Steve Paik curArea = cfg.areaConfigs[i].areaId; 2331ae977d6e87a88e1689d406636982e8296d68175Steve Paik } 23433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 23533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev // Create a separate instance for each individual zone 23633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev VehiclePropValue prop = { 23733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev .prop = cfg.prop, 23833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev .areaId = curArea, 23933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev }; 2401ae977d6e87a88e1689d406636982e8296d68175Steve Paik 24133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (it.initialAreaValues.size() > 0) { 24233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev auto valueForAreaIt = it.initialAreaValues.find(curArea); 24333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (valueForAreaIt != it.initialAreaValues.end()) { 24433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev prop.value = valueForAreaIt->second; 24533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } else { 24633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev ALOGW("%s failed to get default value for prop 0x%x area 0x%x", 24733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev __func__, cfg.prop, curArea); 24833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 24933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } else { 25033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev prop.value = it.initialValue; 25133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 2528acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata mPropStore->writeValue(prop, shouldUpdateStatus); 2531ae977d6e87a88e1689d406636982e8296d68175Steve Paik } 25433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 255250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev initObd2LiveFrame(*mPropStore->getConfigOrDie(OBD2_LIVE_FRAME)); 256250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev initObd2FreezeFrame(*mPropStore->getConfigOrDie(OBD2_FREEZE_FRAME)); 25733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 25833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 25933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevstd::vector<VehiclePropConfig> EmulatedVehicleHal::listProperties() { 26033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return mPropStore->getAllConfigs(); 26133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 26233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 26333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevvoid EmulatedVehicleHal::onContinuousPropertyTimer(const std::vector<int32_t>& properties) { 26433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev VehiclePropValuePtr v; 26533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 26633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev auto& pool = *getValuePool(); 26733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 26833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev for (int32_t property : properties) { 26933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (isContinuousProperty(property)) { 27033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev auto internalPropValue = mPropStore->readValueOrNull(property); 27133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (internalPropValue != nullptr) { 27233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev v = pool.obtain(*internalPropValue); 27333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 27433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } else { 27533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev ALOGE("Unexpected onContinuousPropertyTimer for property: 0x%x", property); 27633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 27733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 27833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (v.get()) { 27933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev v->timestamp = elapsedRealtimeNano(); 28033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev doHalEvent(std::move(v)); 28133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 28233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 28333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 28433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 2851ae977d6e87a88e1689d406636982e8296d68175Steve PaikStatusCode EmulatedVehicleHal::subscribe(int32_t property, float sampleRate) { 28633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev ALOGI("%s propId: 0x%x, sampleRate: %f", __func__, property, sampleRate); 28733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 28833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (isContinuousProperty(property)) { 28933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev mRecurrentTimer.registerRecurrentEvent(hertzToNanoseconds(sampleRate), property); 29033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 29133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return StatusCode::OK; 29233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 29333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 29433676528f85f29906b5875cfc5d28b4639402afdPavel MaltsevStatusCode EmulatedVehicleHal::unsubscribe(int32_t property) { 29533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev ALOGI("%s propId: 0x%x", __func__, property); 29633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (isContinuousProperty(property)) { 29733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev mRecurrentTimer.unregisterRecurrentEvent(property); 29833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 29933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return StatusCode::OK; 30033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 30133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 30233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevbool EmulatedVehicleHal::isContinuousProperty(int32_t propId) const { 30333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev const VehiclePropConfig* config = mPropStore->getConfigOrNull(propId); 30433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev if (config == nullptr) { 30533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev ALOGW("Config not found for property: 0x%x", propId); 30633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return false; 30733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 30833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return config->changeMode == VehiclePropertyChangeMode::CONTINUOUS; 30933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 31033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 31133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevbool EmulatedVehicleHal::setPropertyFromVehicle(const VehiclePropValue& propValue) { 3128acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata static constexpr bool shouldUpdateStatus = true; 3138acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata 314d84109482013f5d0920f87636861f070f04c7a80Steve Paik if (propValue.prop == kGenerateFakeDataControllingProperty) { 315d84109482013f5d0920f87636861f070f04c7a80Steve Paik StatusCode status = handleGenerateFakeDataRequest(propValue); 316d84109482013f5d0920f87636861f070f04c7a80Steve Paik if (status != StatusCode::OK) { 317d84109482013f5d0920f87636861f070f04c7a80Steve Paik return false; 318d84109482013f5d0920f87636861f070f04c7a80Steve Paik } 319d84109482013f5d0920f87636861f070f04c7a80Steve Paik } 320d84109482013f5d0920f87636861f070f04c7a80Steve Paik 3218acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata if (mPropStore->writeValue(propValue, shouldUpdateStatus)) { 32233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev doHalEvent(getValuePool()->obtain(propValue)); 32333676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return true; 32433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } else { 32533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return false; 32633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev } 32733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 32833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 32933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsevstd::vector<VehiclePropValue> EmulatedVehicleHal::getAllProperties() const { 33033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev return mPropStore->readAllValues(); 33133676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} 33233676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 333794fc4f9ff910541f78d12621b3291630de14674Pavel MaltsevStatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropValue& request) { 334794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev ALOGI("%s", __func__); 335794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev const auto& v = request.value; 336f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan if (!v.int32Values.size()) { 337f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan ALOGE("%s: expected at least \"command\" field in int32Values", __func__); 338794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev return StatusCode::INVALID_ARG; 339794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev } 340794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev 341794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev FakeDataCommand command = static_cast<FakeDataCommand>(v.int32Values[0]); 342794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev 343794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev switch (command) { 344f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan case FakeDataCommand::StartLinear: { 345f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan ALOGI("%s, FakeDataCommand::StartLinear", __func__); 346f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan return mLinearFakeValueGenerator->start(request); 347794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev } 348f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan case FakeDataCommand::StartJson: { 349f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan ALOGI("%s, FakeDataCommand::StartJson", __func__); 350f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan return mJsonFakeValueGenerator->start(request); 351f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan } 352f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan case FakeDataCommand::StopLinear: { 353f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan ALOGI("%s, FakeDataCommand::StopLinear", __func__); 354f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan return mLinearFakeValueGenerator->stop(request); 355f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan } 356f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan case FakeDataCommand::StopJson: { 357f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan ALOGI("%s, FakeDataCommand::StopJson", __func__); 358f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan return mJsonFakeValueGenerator->stop(request); 359794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev } 360f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev case FakeDataCommand::KeyPress: { 361f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev ALOGI("%s, FakeDataCommand::KeyPress", __func__); 362f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev int32_t keyCode = request.value.int32Values[2]; 363f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev int32_t display = request.value.int32Values[3]; 364f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev doHalEvent( 365f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display)); 366f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev doHalEvent(createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display)); 367f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev break; 368f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev } 369794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev default: { 370794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev ALOGE("%s: unexpected command: %d", __func__, command); 371794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev return StatusCode::INVALID_ARG; 372794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev } 373794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev } 374794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev return StatusCode::OK; 375794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev} 376794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev 377f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel MaltsevVehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createHwInputKeyProp( 378f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay) { 379f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev auto keyEvent = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 3); 380f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev keyEvent->prop = toInt(VehicleProperty::HW_KEY_INPUT); 381f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev keyEvent->areaId = 0; 382f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev keyEvent->timestamp = elapsedRealtimeNano(); 383f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev keyEvent->status = VehiclePropertyStatus::AVAILABLE; 384f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev keyEvent->value.int32Values[0] = toInt(action); 385f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev keyEvent->value.int32Values[1] = keyCode; 386f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev keyEvent->value.int32Values[2] = targetDisplay; 387f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev return keyEvent; 388f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev} 389f0cd5e146a407f8dc88caeb0facf743d641d5bd2Pavel Maltsev 390f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yanvoid EmulatedVehicleHal::onFakeValueGenerated(const VehiclePropValue& value) { 391f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan ALOGD("%s: %s", __func__, toString(value).c_str()); 3928acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata static constexpr bool shouldUpdateStatus = false; 3938acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata 394f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value); 395794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev if (updatedPropValue) { 396794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev updatedPropValue->timestamp = elapsedRealtimeNano(); 39754f2ac6994ffe6a12f54aa1404150af0640c1a60Steve Paik updatedPropValue->status = VehiclePropertyStatus::AVAILABLE; 3988acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus); 399f63c2cad23924ec0f62d534bbe88350c5088d579Chao Yan auto changeMode = mPropStore->getConfigOrDie(value.prop)->changeMode; 400794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev if (VehiclePropertyChangeMode::ON_CHANGE == changeMode) { 401794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev doHalEvent(move(updatedPropValue)); 402794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev } 403794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev } 404794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev} 405794fc4f9ff910541f78d12621b3291630de14674Pavel Maltsev 406250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsevvoid EmulatedVehicleHal::initStaticConfig() { 407250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev for (auto&& it = std::begin(kVehicleProperties); it != std::end(kVehicleProperties); ++it) { 408250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev const auto& cfg = it->config; 409250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev VehiclePropertyStore::TokenFunction tokenFunction = nullptr; 410250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 411250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev switch (cfg.prop) { 412250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev case OBD2_FREEZE_FRAME: { 413250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev tokenFunction = [](const VehiclePropValue& propValue) { 414250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev return propValue.timestamp; 415250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev }; 416250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev break; 417250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 418250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev default: 419250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev break; 420250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 421250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 422250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev mPropStore->registerProperty(cfg, tokenFunction); 423250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 424250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev} 425250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 426250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsevvoid EmulatedVehicleHal::initObd2LiveFrame(const VehiclePropConfig& propConfig) { 4278acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata static constexpr bool shouldUpdateStatus = true; 4288acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata 4291ae977d6e87a88e1689d406636982e8296d68175Steve Paik auto liveObd2Frame = createVehiclePropValue(VehiclePropertyType::MIXED, 0); 430250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]), 431250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev static_cast<size_t>(propConfig.configArray[1])); 432250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->fillPropValue("", liveObd2Frame.get()); 433250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev liveObd2Frame->prop = OBD2_LIVE_FRAME; 434250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 4358acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata mPropStore->writeValue(*liveObd2Frame, shouldUpdateStatus); 436250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev} 437250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 438250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsevvoid EmulatedVehicleHal::initObd2FreezeFrame(const VehiclePropConfig& propConfig) { 4398acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata static constexpr bool shouldUpdateStatus = true; 4408acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata 441250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev auto sensorStore = fillDefaultObd2Frame(static_cast<size_t>(propConfig.configArray[0]), 442250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev static_cast<size_t>(propConfig.configArray[1])); 443250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 444250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev static std::vector<std::string> sampleDtcs = {"P0070", 445250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev "P0102" 446250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev "P0123"}; 447250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev for (auto&& dtc : sampleDtcs) { 4481ae977d6e87a88e1689d406636982e8296d68175Steve Paik auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0); 449250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev sensorStore->fillPropValue(dtc, freezeFrame.get()); 450250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev freezeFrame->prop = OBD2_FREEZE_FRAME; 451250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 4528acfc2246ad4a0d5e76d47c029ee37900f9cc97fEnrico Granata mPropStore->writeValue(*freezeFrame, shouldUpdateStatus); 453250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 454250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev} 455250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 456250139c8b076609e59ab9137fd8a04dc93fa5afePavel MaltsevStatusCode EmulatedVehicleHal::fillObd2FreezeFrame(const VehiclePropValue& requestedPropValue, 457250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev VehiclePropValue* outValue) { 458250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev if (requestedPropValue.value.int64Values.size() != 1) { 459250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev ALOGE("asked for OBD2_FREEZE_FRAME without valid timestamp"); 460250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev return StatusCode::INVALID_ARG; 461250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 462250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev auto timestamp = requestedPropValue.value.int64Values[0]; 463250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev auto freezeFrame = mPropStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp); 464250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev if (freezeFrame == nullptr) { 465250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp"); 466250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev return StatusCode::INVALID_ARG; 467250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 468250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev outValue->prop = OBD2_FREEZE_FRAME; 469250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev outValue->value.int32Values = freezeFrame->value.int32Values; 470250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev outValue->value.floatValues = freezeFrame->value.floatValues; 471250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev outValue->value.bytes = freezeFrame->value.bytes; 472250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev outValue->value.stringValue = freezeFrame->value.stringValue; 473250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev outValue->timestamp = freezeFrame->timestamp; 474250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev return StatusCode::OK; 475250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev} 476250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 477250139c8b076609e59ab9137fd8a04dc93fa5afePavel MaltsevStatusCode EmulatedVehicleHal::clearObd2FreezeFrames(const VehiclePropValue& propValue) { 478250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev if (propValue.value.int64Values.size() == 0) { 479250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev mPropStore->removeValuesForProperty(OBD2_FREEZE_FRAME); 480250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev return StatusCode::OK; 481250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } else { 482250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev for (int64_t timestamp : propValue.value.int64Values) { 483250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev auto freezeFrame = mPropStore->readValueOrNull(OBD2_FREEZE_FRAME, 0, timestamp); 484250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev if (freezeFrame == nullptr) { 485250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev ALOGE("asked for OBD2_FREEZE_FRAME at invalid timestamp"); 486250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev return StatusCode::INVALID_ARG; 487250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 488250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev mPropStore->removeValue(*freezeFrame); 489250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 490250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 491250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev return StatusCode::OK; 492250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev} 493250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 494250139c8b076609e59ab9137fd8a04dc93fa5afePavel MaltsevStatusCode EmulatedVehicleHal::fillObd2DtcInfo(VehiclePropValue* outValue) { 495250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev std::vector<int64_t> timestamps; 496250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev for (const auto& freezeFrame : mPropStore->readValuesForProperty(OBD2_FREEZE_FRAME)) { 497250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev timestamps.push_back(freezeFrame.timestamp); 498250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev } 499250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev outValue->value.int64Values = timestamps; 500250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev outValue->prop = OBD2_FREEZE_FRAME_INFO; 501250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev return StatusCode::OK; 502250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev} 503250139c8b076609e59ab9137fd8a04dc93fa5afePavel Maltsev 50433676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} // impl 50533676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev 50633676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} // namespace V2_0 50733676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} // namespace vehicle 50833676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} // namespace automotive 50933676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} // namespace hardware 51033676528f85f29906b5875cfc5d28b4639402afdPavel Maltsev} // namespace android 511