Loading automotive/vehicle/2.0/default/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,8 @@ cc_library_static { "impl/vhal_v2_0/VehicleEmulator.cpp", "impl/vhal_v2_0/PipeComm.cpp", "impl/vhal_v2_0/SocketComm.cpp", "impl/vhal_v2_0/LinearFakeValueGenerator.cpp", "impl/vhal_v2_0/JsonFakeValueGenerator.cpp", ], local_include_dirs: ["common/include/vhal_v2_0"], export_include_dirs: ["impl"], Loading @@ -71,6 +73,7 @@ cc_library_static { "libprotobuf-cpp-lite", ], static_libs: [ "libjsoncpp", "libqemu_pipe", "android.hardware.automotive.vehicle@2.0-libproto-native", ], Loading Loading @@ -107,6 +110,7 @@ cc_binary { "android.hardware.automotive.vehicle@2.0-manager-lib", "android.hardware.automotive.vehicle@2.0-default-impl-lib", "android.hardware.automotive.vehicle@2.0-libproto-native", "libjsoncpp", "libqemu_pipe", ], } automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +45 −17 Original line number Diff line number Diff line Loading @@ -42,38 +42,66 @@ constexpr int WHEEL_TICK = (int)VehicleProperty::WHEEL_TICK; constexpr int ALL_WHEELS = (int)(Wheel::LEFT_FRONT | Wheel::RIGHT_FRONT | Wheel::LEFT_REAR | Wheel::RIGHT_REAR); /* * This property is used for test purpose to generate fake events. * * It has the following format: * * int32Values[0] - command (see FakeDataCommand below for possible values) * int32Values[1] - VehicleProperty to which command applies /** * This property is used for test purpose to generate fake events. Here is the test package that * is referencing this property definition: packages/services/Car/tests/vehiclehal_test */ const int32_t kGenerateFakeDataControllingProperty = 0x0666 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; /** * FakeDataCommand enum defines the supported command type for kGenerateFakeDataControllingProperty. * All those commands can be send independently with each other. And each will override the one sent * previously. * * The controlling property has the following format: * * int32Values[0] - command enum defined in FakeDataCommand * * The format of the arguments is defined for each command type as below: */ enum class FakeDataCommand : int32_t { /** Stops generating of fake data that was triggered by Start command */ Stop = 0, /** * Starts fake data generation. Caller must provide additional data: * Starts linear fake data generation. Caller must provide additional data: * int32Values[1] - VehicleProperty to which command applies * int64Values[0] - periodic interval in nanoseconds * floatValues[0] - initial value * floatValues[1] - dispersion defines min and max range relative to initial value * floatValues[1] - dispersion defines the min/max value relative to initial value, where * max = initial_value + dispersion, min = initial_value - dispersion. * Dispersion should be non-negative, otherwise the behavior is undefined. * floatValues[2] - increment, with every timer tick the value will be incremented by this * amount * amount. When reaching to max value, the current value will be set to min. * It should be non-negative, otherwise the behavior is undefined. */ StartLinear = 0, /** Stops generating of fake data that was triggered by Start commands. * int32Values[1] - VehicleProperty to which command applies. VHAL will stop the * corresponding linear generation for that property. */ StopLinear = 1, /** * Starts JSON-based fake data generation. Caller must provide a string value specifying * the path to fake value JSON file: * stringValue - path to the fake values JSON file */ StartJson = 2, /** * Stops JSON-based fake data generation. No additional arguments needed. */ Start = 1, StopJson = 3, /** * Injects key press event (HAL incorporates UP/DOWN acction and triggers 2 HAL events for every * key-press). Caller must provide the following data: int32Values[2] - Android key code * key-press). We set the enum with high number to leave space for future start/stop commands. * Caller must provide the following data: * int32Values[2] - Android key code * int32Values[3] - target display (0 - for main display, 1 - for instrument cluster, see * VehicleDisplay) */ KeyPress = 2, KeyPress = 100, }; const int32_t kHvacPowerProperties[] = { Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp +28 −52 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <android-base/macros.h> #include "EmulatedVehicleHal.h" #include "JsonFakeValueGenerator.h" #include "LinearFakeValueGenerator.h" #include "Obd2SensorStore.h" namespace android { Loading Loading @@ -88,10 +90,12 @@ static std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorInt EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore) : mPropStore(propStore), mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)), mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)), mFakeValueGenerator(std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1, std::placeholders::_2)) { mRecurrentTimer( std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)), mLinearFakeValueGenerator(std::make_unique<LinearFakeValueGenerator>( std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1))), mJsonFakeValueGenerator(std::make_unique<JsonFakeValueGenerator>( std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1))) { initStaticConfig(); for (size_t i = 0; i < arraysize(kVehicleProperties); i++) { mPropStore->registerProperty(kVehicleProperties[i].config); Loading Loading @@ -328,42 +332,29 @@ std::vector<VehiclePropValue> EmulatedVehicleHal::getAllProperties() const { StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropValue& request) { ALOGI("%s", __func__); const auto& v = request.value; if (v.int32Values.size() < 2) { ALOGE("%s: expected at least 2 elements in int32Values, got: %zu", __func__, v.int32Values.size()); if (!v.int32Values.size()) { ALOGE("%s: expected at least \"command\" field in int32Values", __func__); return StatusCode::INVALID_ARG; } FakeDataCommand command = static_cast<FakeDataCommand>(v.int32Values[0]); int32_t propId = v.int32Values[1]; switch (command) { case FakeDataCommand::Start: { if (!v.int64Values.size()) { ALOGE("%s: interval is not provided in int64Values", __func__); return StatusCode::INVALID_ARG; case FakeDataCommand::StartLinear: { ALOGI("%s, FakeDataCommand::StartLinear", __func__); return mLinearFakeValueGenerator->start(request); } auto interval = std::chrono::nanoseconds(v.int64Values[0]); if (v.floatValues.size() < 3) { ALOGE("%s: expected at least 3 element sin floatValues, got: %zu", __func__, v.floatValues.size()); return StatusCode::INVALID_ARG; case FakeDataCommand::StartJson: { ALOGI("%s, FakeDataCommand::StartJson", __func__); return mJsonFakeValueGenerator->start(request); } float initialValue = v.floatValues[0]; float dispersion = v.floatValues[1]; float increment = v.floatValues[2]; ALOGI("%s, propId: %d, initalValue: %f", __func__, propId, initialValue); mFakeValueGenerator.startGeneratingHalEvents( interval, propId, initialValue, dispersion, increment); break; case FakeDataCommand::StopLinear: { ALOGI("%s, FakeDataCommand::StopLinear", __func__); return mLinearFakeValueGenerator->stop(request); } case FakeDataCommand::Stop: { ALOGI("%s, FakeDataCommand::Stop", __func__); mFakeValueGenerator.stopGeneratingHalEvents(propId); break; case FakeDataCommand::StopJson: { ALOGI("%s, FakeDataCommand::StopJson", __func__); return mJsonFakeValueGenerator->stop(request); } case FakeDataCommand::KeyPress: { ALOGI("%s, FakeDataCommand::KeyPress", __func__); Loading @@ -374,7 +365,6 @@ StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropVa doHalEvent(createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display)); break; } default: { ALOGE("%s: unexpected command: %d", __func__, command); return StatusCode::INVALID_ARG; Loading @@ -396,30 +386,16 @@ VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createHwInputKeyProp( return keyEvent; } void EmulatedVehicleHal::onFakeValueGenerated(int32_t propId, float value) { void EmulatedVehicleHal::onFakeValueGenerated(const VehiclePropValue& value) { ALOGD("%s: %s", __func__, toString(value).c_str()); static constexpr bool shouldUpdateStatus = false; VehiclePropValuePtr updatedPropValue {}; switch (getPropType(propId)) { case VehiclePropertyType::FLOAT: updatedPropValue = getValuePool()->obtainFloat(value); break; case VehiclePropertyType::INT32: updatedPropValue = getValuePool()->obtainInt32(static_cast<int32_t>(value)); break; default: ALOGE("%s: data type for property: 0x%x not supported", __func__, propId); return; } VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value); if (updatedPropValue) { updatedPropValue->prop = propId; updatedPropValue->areaId = 0; // Add area support if necessary. updatedPropValue->timestamp = elapsedRealtimeNano(); updatedPropValue->status = VehiclePropertyStatus::AVAILABLE; mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus); auto changeMode = mPropStore->getConfigOrDie(propId)->changeMode; auto changeMode = mPropStore->getConfigOrDie(value.prop)->changeMode; if (VehiclePropertyChangeMode::ON_CHANGE == changeMode) { doHalEvent(move(updatedPropValue)); } Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h +5 −3 Original line number Diff line number Diff line Loading @@ -30,9 +30,10 @@ #include "vhal_v2_0/VehiclePropertyStore.h" #include "DefaultConfig.h" #include "VehicleEmulator.h" #include "FakeValueGenerator.h" #include "VehicleEmulator.h" namespace android { namespace hardware { namespace automotive { Loading Loading @@ -66,7 +67,7 @@ private: } StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request); void onFakeValueGenerated(int32_t propId, float value); void onFakeValueGenerated(const VehiclePropValue& value); VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay); Loading @@ -84,7 +85,8 @@ private: VehiclePropertyStore* mPropStore; std::unordered_set<int32_t> mHvacPowerProps; RecurrentTimer mRecurrentTimer; FakeValueGenerator mFakeValueGenerator; std::unique_ptr<FakeValueGenerator> mLinearFakeValueGenerator; std::unique_ptr<FakeValueGenerator> mJsonFakeValueGenerator; }; } // impl Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h +20 −88 Original line number Diff line number Diff line Loading @@ -14,15 +14,11 @@ * limitations under the License. */ #ifndef android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_ #define android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_ #include <chrono> #ifndef android_hardware_automotive_vehicle_V2_0_impl_FakeValueGenerator_H_ #define android_hardware_automotive_vehicle_V2_0_impl_FakeValueGenerator_H_ #include <android/hardware/automotive/vehicle/2.0/types.h> #include <vhal_v2_0/RecurrentTimer.h> namespace android { namespace hardware { namespace automotive { Loading @@ -31,89 +27,27 @@ namespace V2_0 { namespace impl { class FakeValueGenerator { private: // In every timer tick we may want to generate new value based on initial value for debug // purpose. It's better to have sequential values to see if events gets delivered in order // to the client. struct GeneratorCfg { float initialValue; // float currentValue; // Should be in range (initialValue +/- dispersion). float dispersion; // Defines minimum and maximum value based on initial value. float increment; // Value that we will be added to currentValue with each timer tick. }; public: using OnHalEvent = std::function<void(int32_t propId, float value)>; FakeValueGenerator(const OnHalEvent& onHalEvent) : mOnHalEvent(onHalEvent), mRecurrentTimer(std::bind(&FakeValueGenerator::onTimer, this, std::placeholders::_1)) {} ~FakeValueGenerator() = default; void startGeneratingHalEvents(std::chrono::nanoseconds interval, int propId, float initialValue, float dispersion, float increment) { MuxGuard g(mLock); removeLocked(propId); mGenCfg.insert({propId, GeneratorCfg { .initialValue = initialValue, .currentValue = initialValue, .dispersion = dispersion, .increment = increment, }}); mRecurrentTimer.registerRecurrentEvent(interval, propId); } void stopGeneratingHalEvents(int propId) { MuxGuard g(mLock); if (propId == 0) { // Remove all. for (auto&& it : mGenCfg) { removeLocked(it.first); } } else { removeLocked(propId); } } private: void removeLocked(int propId) { if (mGenCfg.erase(propId)) { mRecurrentTimer.unregisterRecurrentEvent(propId); } } void onTimer(const std::vector<int32_t>& properties) { MuxGuard g(mLock); for (int32_t propId : properties) { auto& cfg = mGenCfg[propId]; cfg.currentValue += cfg.increment; if (cfg.currentValue > cfg.initialValue + cfg.dispersion) { cfg.currentValue = cfg.initialValue - cfg.dispersion; } mOnHalEvent(propId, cfg.currentValue); } } private: using OnHalEvent = std::function<void(const VehiclePropValue& event)>; using MuxGuard = std::lock_guard<std::mutex>; mutable std::mutex mLock; OnHalEvent mOnHalEvent; RecurrentTimer mRecurrentTimer; std::unordered_map<int32_t, GeneratorCfg> mGenCfg; class FakeValueGenerator { public: virtual ~FakeValueGenerator() = default; /** * Starts generating VHAL events * * @param request in VehiclePropValue with required information to start fake data generation * @return StatusCode of the start request */ virtual StatusCode start(const VehiclePropValue& request) = 0; /** * Stops generating VHAL events * @param request in VehiclePropValue with required information to stop fake data generation * @return StatusCode of the stop request */ virtual StatusCode stop(const VehiclePropValue& request) = 0; }; } // impl } // namespace V2_0 Loading @@ -122,6 +56,4 @@ private: } // namespace hardware } // namespace android #endif //android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_ #endif // android_hardware_automotive_vehicle_V2_0_impl_FakeValueGenerator_H_ Loading
automotive/vehicle/2.0/default/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,8 @@ cc_library_static { "impl/vhal_v2_0/VehicleEmulator.cpp", "impl/vhal_v2_0/PipeComm.cpp", "impl/vhal_v2_0/SocketComm.cpp", "impl/vhal_v2_0/LinearFakeValueGenerator.cpp", "impl/vhal_v2_0/JsonFakeValueGenerator.cpp", ], local_include_dirs: ["common/include/vhal_v2_0"], export_include_dirs: ["impl"], Loading @@ -71,6 +73,7 @@ cc_library_static { "libprotobuf-cpp-lite", ], static_libs: [ "libjsoncpp", "libqemu_pipe", "android.hardware.automotive.vehicle@2.0-libproto-native", ], Loading Loading @@ -107,6 +110,7 @@ cc_binary { "android.hardware.automotive.vehicle@2.0-manager-lib", "android.hardware.automotive.vehicle@2.0-default-impl-lib", "android.hardware.automotive.vehicle@2.0-libproto-native", "libjsoncpp", "libqemu_pipe", ], }
automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h +45 −17 Original line number Diff line number Diff line Loading @@ -42,38 +42,66 @@ constexpr int WHEEL_TICK = (int)VehicleProperty::WHEEL_TICK; constexpr int ALL_WHEELS = (int)(Wheel::LEFT_FRONT | Wheel::RIGHT_FRONT | Wheel::LEFT_REAR | Wheel::RIGHT_REAR); /* * This property is used for test purpose to generate fake events. * * It has the following format: * * int32Values[0] - command (see FakeDataCommand below for possible values) * int32Values[1] - VehicleProperty to which command applies /** * This property is used for test purpose to generate fake events. Here is the test package that * is referencing this property definition: packages/services/Car/tests/vehiclehal_test */ const int32_t kGenerateFakeDataControllingProperty = 0x0666 | VehiclePropertyGroup::VENDOR | VehicleArea::GLOBAL | VehiclePropertyType::MIXED; /** * FakeDataCommand enum defines the supported command type for kGenerateFakeDataControllingProperty. * All those commands can be send independently with each other. And each will override the one sent * previously. * * The controlling property has the following format: * * int32Values[0] - command enum defined in FakeDataCommand * * The format of the arguments is defined for each command type as below: */ enum class FakeDataCommand : int32_t { /** Stops generating of fake data that was triggered by Start command */ Stop = 0, /** * Starts fake data generation. Caller must provide additional data: * Starts linear fake data generation. Caller must provide additional data: * int32Values[1] - VehicleProperty to which command applies * int64Values[0] - periodic interval in nanoseconds * floatValues[0] - initial value * floatValues[1] - dispersion defines min and max range relative to initial value * floatValues[1] - dispersion defines the min/max value relative to initial value, where * max = initial_value + dispersion, min = initial_value - dispersion. * Dispersion should be non-negative, otherwise the behavior is undefined. * floatValues[2] - increment, with every timer tick the value will be incremented by this * amount * amount. When reaching to max value, the current value will be set to min. * It should be non-negative, otherwise the behavior is undefined. */ StartLinear = 0, /** Stops generating of fake data that was triggered by Start commands. * int32Values[1] - VehicleProperty to which command applies. VHAL will stop the * corresponding linear generation for that property. */ StopLinear = 1, /** * Starts JSON-based fake data generation. Caller must provide a string value specifying * the path to fake value JSON file: * stringValue - path to the fake values JSON file */ StartJson = 2, /** * Stops JSON-based fake data generation. No additional arguments needed. */ Start = 1, StopJson = 3, /** * Injects key press event (HAL incorporates UP/DOWN acction and triggers 2 HAL events for every * key-press). Caller must provide the following data: int32Values[2] - Android key code * key-press). We set the enum with high number to leave space for future start/stop commands. * Caller must provide the following data: * int32Values[2] - Android key code * int32Values[3] - target display (0 - for main display, 1 - for instrument cluster, see * VehicleDisplay) */ KeyPress = 2, KeyPress = 100, }; const int32_t kHvacPowerProperties[] = { Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp +28 −52 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ #include <android-base/macros.h> #include "EmulatedVehicleHal.h" #include "JsonFakeValueGenerator.h" #include "LinearFakeValueGenerator.h" #include "Obd2SensorStore.h" namespace android { Loading Loading @@ -88,10 +90,12 @@ static std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorInt EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore) : mPropStore(propStore), mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)), mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)), mFakeValueGenerator(std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1, std::placeholders::_2)) { mRecurrentTimer( std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)), mLinearFakeValueGenerator(std::make_unique<LinearFakeValueGenerator>( std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1))), mJsonFakeValueGenerator(std::make_unique<JsonFakeValueGenerator>( std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1))) { initStaticConfig(); for (size_t i = 0; i < arraysize(kVehicleProperties); i++) { mPropStore->registerProperty(kVehicleProperties[i].config); Loading Loading @@ -328,42 +332,29 @@ std::vector<VehiclePropValue> EmulatedVehicleHal::getAllProperties() const { StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropValue& request) { ALOGI("%s", __func__); const auto& v = request.value; if (v.int32Values.size() < 2) { ALOGE("%s: expected at least 2 elements in int32Values, got: %zu", __func__, v.int32Values.size()); if (!v.int32Values.size()) { ALOGE("%s: expected at least \"command\" field in int32Values", __func__); return StatusCode::INVALID_ARG; } FakeDataCommand command = static_cast<FakeDataCommand>(v.int32Values[0]); int32_t propId = v.int32Values[1]; switch (command) { case FakeDataCommand::Start: { if (!v.int64Values.size()) { ALOGE("%s: interval is not provided in int64Values", __func__); return StatusCode::INVALID_ARG; case FakeDataCommand::StartLinear: { ALOGI("%s, FakeDataCommand::StartLinear", __func__); return mLinearFakeValueGenerator->start(request); } auto interval = std::chrono::nanoseconds(v.int64Values[0]); if (v.floatValues.size() < 3) { ALOGE("%s: expected at least 3 element sin floatValues, got: %zu", __func__, v.floatValues.size()); return StatusCode::INVALID_ARG; case FakeDataCommand::StartJson: { ALOGI("%s, FakeDataCommand::StartJson", __func__); return mJsonFakeValueGenerator->start(request); } float initialValue = v.floatValues[0]; float dispersion = v.floatValues[1]; float increment = v.floatValues[2]; ALOGI("%s, propId: %d, initalValue: %f", __func__, propId, initialValue); mFakeValueGenerator.startGeneratingHalEvents( interval, propId, initialValue, dispersion, increment); break; case FakeDataCommand::StopLinear: { ALOGI("%s, FakeDataCommand::StopLinear", __func__); return mLinearFakeValueGenerator->stop(request); } case FakeDataCommand::Stop: { ALOGI("%s, FakeDataCommand::Stop", __func__); mFakeValueGenerator.stopGeneratingHalEvents(propId); break; case FakeDataCommand::StopJson: { ALOGI("%s, FakeDataCommand::StopJson", __func__); return mJsonFakeValueGenerator->stop(request); } case FakeDataCommand::KeyPress: { ALOGI("%s, FakeDataCommand::KeyPress", __func__); Loading @@ -374,7 +365,6 @@ StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropVa doHalEvent(createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display)); break; } default: { ALOGE("%s: unexpected command: %d", __func__, command); return StatusCode::INVALID_ARG; Loading @@ -396,30 +386,16 @@ VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createHwInputKeyProp( return keyEvent; } void EmulatedVehicleHal::onFakeValueGenerated(int32_t propId, float value) { void EmulatedVehicleHal::onFakeValueGenerated(const VehiclePropValue& value) { ALOGD("%s: %s", __func__, toString(value).c_str()); static constexpr bool shouldUpdateStatus = false; VehiclePropValuePtr updatedPropValue {}; switch (getPropType(propId)) { case VehiclePropertyType::FLOAT: updatedPropValue = getValuePool()->obtainFloat(value); break; case VehiclePropertyType::INT32: updatedPropValue = getValuePool()->obtainInt32(static_cast<int32_t>(value)); break; default: ALOGE("%s: data type for property: 0x%x not supported", __func__, propId); return; } VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value); if (updatedPropValue) { updatedPropValue->prop = propId; updatedPropValue->areaId = 0; // Add area support if necessary. updatedPropValue->timestamp = elapsedRealtimeNano(); updatedPropValue->status = VehiclePropertyStatus::AVAILABLE; mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus); auto changeMode = mPropStore->getConfigOrDie(propId)->changeMode; auto changeMode = mPropStore->getConfigOrDie(value.prop)->changeMode; if (VehiclePropertyChangeMode::ON_CHANGE == changeMode) { doHalEvent(move(updatedPropValue)); } Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h +5 −3 Original line number Diff line number Diff line Loading @@ -30,9 +30,10 @@ #include "vhal_v2_0/VehiclePropertyStore.h" #include "DefaultConfig.h" #include "VehicleEmulator.h" #include "FakeValueGenerator.h" #include "VehicleEmulator.h" namespace android { namespace hardware { namespace automotive { Loading Loading @@ -66,7 +67,7 @@ private: } StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request); void onFakeValueGenerated(int32_t propId, float value); void onFakeValueGenerated(const VehiclePropValue& value); VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay); Loading @@ -84,7 +85,8 @@ private: VehiclePropertyStore* mPropStore; std::unordered_set<int32_t> mHvacPowerProps; RecurrentTimer mRecurrentTimer; FakeValueGenerator mFakeValueGenerator; std::unique_ptr<FakeValueGenerator> mLinearFakeValueGenerator; std::unique_ptr<FakeValueGenerator> mJsonFakeValueGenerator; }; } // impl Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/FakeValueGenerator.h +20 −88 Original line number Diff line number Diff line Loading @@ -14,15 +14,11 @@ * limitations under the License. */ #ifndef android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_ #define android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_ #include <chrono> #ifndef android_hardware_automotive_vehicle_V2_0_impl_FakeValueGenerator_H_ #define android_hardware_automotive_vehicle_V2_0_impl_FakeValueGenerator_H_ #include <android/hardware/automotive/vehicle/2.0/types.h> #include <vhal_v2_0/RecurrentTimer.h> namespace android { namespace hardware { namespace automotive { Loading @@ -31,89 +27,27 @@ namespace V2_0 { namespace impl { class FakeValueGenerator { private: // In every timer tick we may want to generate new value based on initial value for debug // purpose. It's better to have sequential values to see if events gets delivered in order // to the client. struct GeneratorCfg { float initialValue; // float currentValue; // Should be in range (initialValue +/- dispersion). float dispersion; // Defines minimum and maximum value based on initial value. float increment; // Value that we will be added to currentValue with each timer tick. }; public: using OnHalEvent = std::function<void(int32_t propId, float value)>; FakeValueGenerator(const OnHalEvent& onHalEvent) : mOnHalEvent(onHalEvent), mRecurrentTimer(std::bind(&FakeValueGenerator::onTimer, this, std::placeholders::_1)) {} ~FakeValueGenerator() = default; void startGeneratingHalEvents(std::chrono::nanoseconds interval, int propId, float initialValue, float dispersion, float increment) { MuxGuard g(mLock); removeLocked(propId); mGenCfg.insert({propId, GeneratorCfg { .initialValue = initialValue, .currentValue = initialValue, .dispersion = dispersion, .increment = increment, }}); mRecurrentTimer.registerRecurrentEvent(interval, propId); } void stopGeneratingHalEvents(int propId) { MuxGuard g(mLock); if (propId == 0) { // Remove all. for (auto&& it : mGenCfg) { removeLocked(it.first); } } else { removeLocked(propId); } } private: void removeLocked(int propId) { if (mGenCfg.erase(propId)) { mRecurrentTimer.unregisterRecurrentEvent(propId); } } void onTimer(const std::vector<int32_t>& properties) { MuxGuard g(mLock); for (int32_t propId : properties) { auto& cfg = mGenCfg[propId]; cfg.currentValue += cfg.increment; if (cfg.currentValue > cfg.initialValue + cfg.dispersion) { cfg.currentValue = cfg.initialValue - cfg.dispersion; } mOnHalEvent(propId, cfg.currentValue); } } private: using OnHalEvent = std::function<void(const VehiclePropValue& event)>; using MuxGuard = std::lock_guard<std::mutex>; mutable std::mutex mLock; OnHalEvent mOnHalEvent; RecurrentTimer mRecurrentTimer; std::unordered_map<int32_t, GeneratorCfg> mGenCfg; class FakeValueGenerator { public: virtual ~FakeValueGenerator() = default; /** * Starts generating VHAL events * * @param request in VehiclePropValue with required information to start fake data generation * @return StatusCode of the start request */ virtual StatusCode start(const VehiclePropValue& request) = 0; /** * Stops generating VHAL events * @param request in VehiclePropValue with required information to stop fake data generation * @return StatusCode of the stop request */ virtual StatusCode stop(const VehiclePropValue& request) = 0; }; } // impl } // namespace V2_0 Loading @@ -122,6 +56,4 @@ private: } // namespace hardware } // namespace android #endif //android_hardware_automotive_vehicle_V2_0_impl_FakeHalEventGenerator_H_ #endif // android_hardware_automotive_vehicle_V2_0_impl_FakeValueGenerator_H_