diff options
author | Hao Chen <chenhaosjtuacm@google.com> | 2019-11-07 11:55:25 -0800 |
---|---|---|
committer | Hao Chen <chenhaosjtuacm@google.com> | 2019-11-21 16:57:31 -0800 |
commit | fba3ac86cc0f450bd01265313eff65279a38f590 (patch) | |
tree | f1cfeebae703b8a6954ffadd0d13173de9ecb943 /automotive | |
parent | cda8e6e03a37face2ddaccd2a1198c8dd0ef2375 (diff) | |
download | platform_hardware_interfaces-fba3ac86cc0f450bd01265313eff65279a38f590.tar.gz platform_hardware_interfaces-fba3ac86cc0f450bd01265313eff65279a38f590.tar.bz2 platform_hardware_interfaces-fba3ac86cc0f450bd01265313eff65279a38f590.zip |
Applying the vehicle connector to the VHAL
Make VHAL to use the connector/server interfaces instead of talking to
the (faked) vehicle directly. Use passthrough connector for now since we
have not moved to the virtualized scenario yet (but soon :)
Bug: b/141493212
Test: On both Osprey and Hawk. Build and flash the image. If on Osprey, see
go/enable-google-vhal-on-osprey; if on hawk, `aae app vhal apply google`
to enable Google VHAL
```
# no VHAL crash
$ adb logcat
$ vts-tradefed
> run vts-hal-auto -m VtsHalAutomotiveVehicleV2_0Host
# 30 passed, 2 failed, the same as the result before this patch
# See value changed in Vehicle HAL tab, KitchenSink app:
$ python packages/services/Car/tools/emulator/prop_event_simulator.py --property
VEHICLEPROPERTY_HVAC_AC_ON --area 0 --value 1
# unit tests
$ atest packages/services/Car/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/CarPropertyTest.java
```
Change-Id: Iab77a0ae32db2c55b4c65aa8f3e4f73ec9ef2644
Diffstat (limited to 'automotive')
4 files changed, 31 insertions, 167 deletions
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp index ed09859443..f9c25d1d0e 100644 --- a/automotive/vehicle/2.0/default/Android.bp +++ b/automotive/vehicle/2.0/default/Android.bp @@ -58,6 +58,7 @@ cc_library_static { defaults: ["vhal_v2_0_defaults"], srcs: [ "impl/vhal_v2_0/CommConn.cpp", + "impl/vhal_v2_0/EmulatedVehicleConnector.cpp", "impl/vhal_v2_0/EmulatedVehicleHal.cpp", "impl/vhal_v2_0/VehicleEmulator.cpp", "impl/vhal_v2_0/PipeComm.cpp", diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp index d1fd55567e..127eb98e43 100644 --- a/automotive/vehicle/2.0/default/VehicleService.cpp +++ b/automotive/vehicle/2.0/default/VehicleService.cpp @@ -20,8 +20,9 @@ #include <iostream> -#include <vhal_v2_0/VehicleHalManager.h> +#include <vhal_v2_0/EmulatedVehicleConnector.h> #include <vhal_v2_0/EmulatedVehicleHal.h> +#include <vhal_v2_0/VehicleHalManager.h> using namespace android; using namespace android::hardware; @@ -29,9 +30,11 @@ using namespace android::hardware::automotive::vehicle::V2_0; int main(int /* argc */, char* /* argv */ []) { auto store = std::make_unique<VehiclePropertyStore>(); - auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get()); + auto connector = impl::makeEmulatedPassthroughConnector(); + auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get()); auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get()); auto service = std::make_unique<VehicleHalManager>(hal.get()); + connector->setValuePool(hal->getValuePool()); configureRpcThreadpool(4, true /* callerWillJoin */); diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp index dc051d8e53..6508efea2b 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp @@ -87,17 +87,19 @@ static std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorInt return sensorStore; } -EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore) +EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore, + EmulatedVehicleClient* client) : mPropStore(propStore), mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)), mRecurrentTimer( std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)), - mGeneratorHub( - std::bind(&EmulatedVehicleHal::onFakeValueGenerated, this, std::placeholders::_1)) { + mVehicleClient(client) { initStaticConfig(); for (size_t i = 0; i < arraysize(kVehicleProperties); i++) { mPropStore->registerProperty(kVehicleProperties[i].config); } + mVehicleClient->registerPropertyValueCallback( + std::bind(&EmulatedVehicleHal::onPropertyValue, this, std::placeholders::_1)); } VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get( @@ -162,7 +164,8 @@ StatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) { } if (propValue.prop == kGenerateFakeDataControllingProperty) { - StatusCode status = handleGenerateFakeDataRequest(propValue); + // send the generator controlling request to the server + auto status = mVehicleClient->setPropertyFromVehicle(propValue); if (status != StatusCode::OK) { return status; } @@ -186,29 +189,6 @@ StatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) { // Placeholder for future implementation of VMS property in the default hal. For // now, just returns OK; otherwise, hal clients crash with property not supported. return StatusCode::OK; - case AP_POWER_STATE_REPORT: - switch (propValue.value.int32Values[0]) { - case toInt(VehicleApPowerStateReport::DEEP_SLEEP_EXIT): - case toInt(VehicleApPowerStateReport::SHUTDOWN_CANCELLED): - case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL): - // CPMS is in WAIT_FOR_VHAL state, simply move to ON - doHalEvent(createApPowerStateReq(VehicleApPowerStateReq::ON, 0)); - break; - case toInt(VehicleApPowerStateReport::DEEP_SLEEP_ENTRY): - case toInt(VehicleApPowerStateReport::SHUTDOWN_START): - // CPMS is in WAIT_FOR_FINISH state, send the FINISHED command - doHalEvent(createApPowerStateReq(VehicleApPowerStateReq::FINISHED, 0)); - break; - case toInt(VehicleApPowerStateReport::ON): - case toInt(VehicleApPowerStateReport::SHUTDOWN_POSTPONE): - case toInt(VehicleApPowerStateReport::SHUTDOWN_PREPARE): - // Do nothing - break; - default: - // Unknown state - break; - } - break; } } @@ -231,10 +211,16 @@ StatusCode EmulatedVehicleHal::set(const VehiclePropValue& propValue) { /** * After checking all conditions, such as the property is available, a real vhal will * sent the events to Car ECU to take actions. - * Google HAL will just add a timestamp for the value and triggle the callback to android. */ VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(propValue); updatedPropValue->timestamp = elapsedRealtimeNano(); + + // Send the value to the vehicle server, the server will talk to the (real or emulated) car + auto setValueStatus = mVehicleClient->setProperty(*updatedPropValue); + if (setValueStatus != StatusCode::OK) { + return setValueStatus; + } + if (!mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus)) { return StatusCode::INTERNAL_ERROR; } @@ -361,144 +347,19 @@ bool EmulatedVehicleHal::isContinuousProperty(int32_t propId) const { } bool EmulatedVehicleHal::setPropertyFromVehicle(const VehiclePropValue& propValue) { - static constexpr bool shouldUpdateStatus = true; - - if (propValue.prop == kGenerateFakeDataControllingProperty) { - StatusCode status = handleGenerateFakeDataRequest(propValue); - if (status != StatusCode::OK) { - return false; - } - } - - if (mPropStore->writeValue(propValue, shouldUpdateStatus)) { - doHalEvent(getValuePool()->obtain(propValue)); - return true; - } else { - return false; - } + return mVehicleClient->setPropertyFromVehicle(propValue) == StatusCode::OK; } std::vector<VehiclePropValue> EmulatedVehicleHal::getAllProperties() const { return mPropStore->readAllValues(); } -StatusCode EmulatedVehicleHal::handleGenerateFakeDataRequest(const VehiclePropValue& request) { - ALOGI("%s", __func__); - const auto& v = request.value; - 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]); - - switch (command) { - case FakeDataCommand::StartLinear: { - ALOGI("%s, FakeDataCommand::StartLinear", __func__); - if (v.int32Values.size() < 2) { - ALOGE("%s: expected property ID in int32Values", __func__); - return StatusCode::INVALID_ARG; - } - if (!v.int64Values.size()) { - ALOGE("%s: interval is not provided in int64Values", __func__); - return StatusCode::INVALID_ARG; - } - if (v.floatValues.size() < 3) { - ALOGE("%s: expected at least 3 elements in floatValues, got: %zu", __func__, - v.floatValues.size()); - return StatusCode::INVALID_ARG; - } - int32_t cookie = v.int32Values[1]; - mGeneratorHub.registerGenerator(cookie, - std::make_unique<LinearFakeValueGenerator>(request)); - break; - } - case FakeDataCommand::StartJson: { - ALOGI("%s, FakeDataCommand::StartJson", __func__); - if (v.stringValue.empty()) { - ALOGE("%s: path to JSON file is missing", __func__); - return StatusCode::INVALID_ARG; - } - int32_t cookie = std::hash<std::string>()(v.stringValue); - mGeneratorHub.registerGenerator(cookie, - std::make_unique<JsonFakeValueGenerator>(request)); - break; - } - case FakeDataCommand::StopLinear: { - ALOGI("%s, FakeDataCommand::StopLinear", __func__); - if (v.int32Values.size() < 2) { - ALOGE("%s: expected property ID in int32Values", __func__); - return StatusCode::INVALID_ARG; - } - int32_t cookie = v.int32Values[1]; - mGeneratorHub.unregisterGenerator(cookie); - break; - } - case FakeDataCommand::StopJson: { - ALOGI("%s, FakeDataCommand::StopJson", __func__); - if (v.stringValue.empty()) { - ALOGE("%s: path to JSON file is missing", __func__); - return StatusCode::INVALID_ARG; - } - int32_t cookie = std::hash<std::string>()(v.stringValue); - mGeneratorHub.unregisterGenerator(cookie); - break; - } - case FakeDataCommand::KeyPress: { - ALOGI("%s, FakeDataCommand::KeyPress", __func__); - int32_t keyCode = request.value.int32Values[2]; - int32_t display = request.value.int32Values[3]; - doHalEvent( - createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_DOWN, keyCode, display)); - doHalEvent(createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display)); - break; - } - default: { - ALOGE("%s: unexpected command: %d", __func__, command); - return StatusCode::INVALID_ARG; - } - } - return StatusCode::OK; -} - -VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createApPowerStateReq( - VehicleApPowerStateReq state, int32_t param) { - auto req = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 2); - req->prop = toInt(VehicleProperty::AP_POWER_STATE_REQ); - req->areaId = 0; - req->timestamp = elapsedRealtimeNano(); - req->status = VehiclePropertyStatus::AVAILABLE; - req->value.int32Values[0] = toInt(state); - req->value.int32Values[1] = param; - return req; -} - -VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::createHwInputKeyProp( - VehicleHwKeyInputAction action, int32_t keyCode, int32_t targetDisplay) { - auto keyEvent = getValuePool()->obtain(VehiclePropertyType::INT32_VEC, 3); - keyEvent->prop = toInt(VehicleProperty::HW_KEY_INPUT); - keyEvent->areaId = 0; - keyEvent->timestamp = elapsedRealtimeNano(); - keyEvent->status = VehiclePropertyStatus::AVAILABLE; - keyEvent->value.int32Values[0] = toInt(action); - keyEvent->value.int32Values[1] = keyCode; - keyEvent->value.int32Values[2] = targetDisplay; - return keyEvent; -} - -void EmulatedVehicleHal::onFakeValueGenerated(const VehiclePropValue& value) { - ALOGD("%s: %s", __func__, toString(value).c_str()); - static constexpr bool shouldUpdateStatus = false; - +void EmulatedVehicleHal::onPropertyValue(const VehiclePropValue& value) { + static constexpr bool shouldUpdateStatus = true; VehiclePropValuePtr updatedPropValue = getValuePool()->obtain(value); - if (updatedPropValue) { - updatedPropValue->timestamp = value.timestamp; - updatedPropValue->status = VehiclePropertyStatus::AVAILABLE; - mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus); - auto changeMode = mPropStore->getConfigOrDie(value.prop)->changeMode; - if (VehiclePropertyChangeMode::ON_CHANGE == changeMode) { - doHalEvent(std::move(updatedPropValue)); - } + + if (mPropStore->writeValue(*updatedPropValue, shouldUpdateStatus)) { + doHalEvent(std::move(updatedPropValue)); } } diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h index 78895e3db2..98315ec32e 100644 --- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h +++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h @@ -30,6 +30,7 @@ #include "vhal_v2_0/VehiclePropertyStore.h" #include "DefaultConfig.h" +#include "EmulatedVehicleConnector.h" #include "GeneratorHub.h" #include "VehicleEmulator.h" @@ -44,7 +45,8 @@ namespace impl { /** Implementation of VehicleHal that connected to emulator instead of real vehicle network. */ class EmulatedVehicleHal : public EmulatedVehicleHalIface { public: - EmulatedVehicleHal(VehiclePropertyStore* propStore); + EmulatedVehicleHal(VehiclePropertyStore* propStore, + EmulatedVehicleClient* client); ~EmulatedVehicleHal() = default; // Methods from VehicleHal @@ -66,10 +68,7 @@ private: } StatusCode handleGenerateFakeDataRequest(const VehiclePropValue& request); - void onFakeValueGenerated(const VehiclePropValue& value); - VehiclePropValuePtr createApPowerStateReq(VehicleApPowerStateReq req, int32_t param); - VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode, - int32_t targetDisplay); + void onPropertyValue(const VehiclePropValue& value); void onContinuousPropertyTimer(const std::vector<int32_t>& properties); bool isContinuousProperty(int32_t propId) const; @@ -85,7 +84,7 @@ private: VehiclePropertyStore* mPropStore; std::unordered_set<int32_t> mHvacPowerProps; RecurrentTimer mRecurrentTimer; - GeneratorHub mGeneratorHub; + EmulatedVehicleClient* mVehicleClient; }; } // impl |