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