Loading automotive/vehicle/2.0/default/VehicleService.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <android/binder_process.h> #include <utils/Looper.h> #include <vhal_v2_0/EmulatedUserHal.h> #include <vhal_v2_0/EmulatedVehicleConnector.h> #include <vhal_v2_0/EmulatedVehicleHal.h> #include <vhal_v2_0/VehicleHalManager.h> Loading @@ -34,7 +35,8 @@ using namespace android::hardware::automotive::vehicle::V2_0; int main(int /* argc */, char* /* argv */ []) { auto store = std::make_unique<VehiclePropertyStore>(); auto connector = impl::makeEmulatedPassthroughConnector(); auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get()); auto userHal = connector->getEmulatedUserHal(); auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get(), userHal); auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get()); auto service = std::make_unique<VehicleHalManager>(hal.get()); connector->setValuePool(hal->getValuePool()); Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp +78 −0 Original line number Diff line number Diff line Loading @@ -30,11 +30,14 @@ namespace impl { constexpr int INITIAL_USER_INFO = static_cast<int>(VehicleProperty::INITIAL_USER_INFO); constexpr int SWITCH_USER = static_cast<int>(VehicleProperty::SWITCH_USER); constexpr int USER_IDENTIFICATION_ASSOCIATION = static_cast<int>(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION); bool EmulatedUserHal::isSupported(int32_t prop) { switch (prop) { case INITIAL_USER_INFO: case SWITCH_USER: case USER_IDENTIFICATION_ASSOCIATION: return true; default: return false; Loading @@ -50,12 +53,41 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetP return onSetInitialUserInfoResponse(value); case SWITCH_USER: return onSetSwitchUserResponse(value); case USER_IDENTIFICATION_ASSOCIATION: return onSetUserIdentificationAssociation(value); default: return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG)) << "Unsupported property: " << toString(value); } } android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetProperty( int32_t prop) { ALOGV("onGetProperty(%d)", prop); switch (prop) { case INITIAL_USER_INFO: case SWITCH_USER: ALOGE("onGetProperty(): %d is only supported on SET", prop); return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG)) << "only supported on SET"; case USER_IDENTIFICATION_ASSOCIATION: if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) { ALOGI("onGetProperty(%d): returning %s", prop, toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str()); auto value = std::unique_ptr<VehiclePropValue>( new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd)); return value; } ALOGE("onGetProperty(%d): USER_IDENTIFICATION_ASSOCIATION not set by lshal", prop); return android::base::Error(static_cast<int>(StatusCode::NOT_AVAILABLE)) << "not set by lshal"; default: ALOGE("onGetProperty(): %d is not supported", prop); return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG)) << "not supported by User HAL"; } } android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetInitialUserInfoResponse(const VehiclePropValue& value) { if (value.value.int32Values.size() == 0) { Loading Loading @@ -130,6 +162,46 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetS return updatedValue; } android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetUserIdentificationAssociation(const VehiclePropValue& value) { if (value.value.int32Values.size() == 0) { ALOGE("set(USER_IDENTIFICATION_ASSOCIATION): no int32values, ignoring it: %s", toString(value).c_str()); return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG)) << "no int32values on " << toString(value); } if (value.areaId != 0) { ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from lshal; storing it: %s", toString(value).c_str()); mSetUserIdentificationAssociationResponseFromCmd.reset(new VehiclePropValue(value)); return {}; } ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from Android: %s", toString(value).c_str()); int32_t requestId = value.value.int32Values[0]; if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) { ALOGI("replying USER_IDENTIFICATION_ASSOCIATION with lshal value: %s", toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str()); // Not moving response so it can be used on GET requests auto copy = std::unique_ptr<VehiclePropValue>( new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd)); return sendUserHalResponse(std::move(copy), requestId); } // Returns default response auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue); updatedValue->prop = USER_IDENTIFICATION_ASSOCIATION; updatedValue->timestamp = elapsedRealtimeNano(); updatedValue->value.int32Values.resize(1); updatedValue->value.int32Values[0] = requestId; updatedValue->value.stringValue = "Response not set by LSHAL"; ALOGI("no lshal response; replying with an error message: %s", toString(*updatedValue).c_str()); return updatedValue; } android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::sendUserHalResponse( std::unique_ptr<VehiclePropValue> response, int32_t requestId) { switch (response->areaId) { Loading Loading @@ -175,6 +247,12 @@ void EmulatedUserHal::dump(int fd, std::string indent) { } else { dprintf(fd, "%sNo SwitchUser response\n", indent.c_str()); } if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) { dprintf(fd, "%sSetUserIdentificationAssociation response: %s\n", indent.c_str(), toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str()); } else { dprintf(fd, "%sNo SetUserIdentificationAssociation response\n", indent.c_str()); } } } // namespace impl Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h +16 −1 Original line number Diff line number Diff line Loading @@ -46,13 +46,20 @@ class EmulatedUserHal { bool isSupported(int32_t prop); /** * Lets the emulator handle the property. * Lets the emulator set the property. * * @return updated property and StatusCode */ android::base::Result<std::unique_ptr<VehiclePropValue>> onSetProperty( const VehiclePropValue& value); /** * Gets the property value from the emulator. * * @return property value and StatusCode */ android::base::Result<std::unique_ptr<VehiclePropValue>> onGetProperty(int32_t prop); /** * Shows the User HAL emulation help. */ Loading Loading @@ -97,11 +104,19 @@ class EmulatedUserHal { android::base::Result<std::unique_ptr<VehiclePropValue>> onSetSwitchUserResponse( const VehiclePropValue& value); /** * Used to emulate USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for * usage. */ android::base::Result<std::unique_ptr<VehiclePropValue>> onSetUserIdentificationAssociation( const VehiclePropValue& value); android::base::Result<std::unique_ptr<VehiclePropValue>> sendUserHalResponse( std::unique_ptr<VehiclePropValue> response, int32_t requestId); std::unique_ptr<VehiclePropValue> mInitialUserResponseFromCmd; std::unique_ptr<VehiclePropValue> mSwitchUserResponseFromCmd; std::unique_ptr<VehiclePropValue> mSetUserIdentificationAssociationResponseFromCmd; }; } // namespace impl Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp +26 −2 Original line number Diff line number Diff line Loading @@ -92,12 +92,14 @@ static std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorInt return sensorStore; } EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client) EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client, EmulatedUserHal* emulatedUserHal) : mPropStore(propStore), mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)), mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)), mVehicleClient(client) { mVehicleClient(client), mEmulatedUserHal(emulatedUserHal) { initStaticConfig(); for (size_t i = 0; i < arraysize(kVehicleProperties); i++) { mPropStore->registerProperty(kVehicleProperties[i].config); Loading Loading @@ -134,6 +136,8 @@ void EmulatedVehicleHal::getAllPropertiesOverride() { VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get( const VehiclePropValue& requestedPropValue, StatusCode* outStatus) { auto propId = requestedPropValue.prop; ALOGV("get(%d)", propId); auto& pool = *getValuePool(); VehiclePropValuePtr v = nullptr; Loading @@ -147,6 +151,26 @@ VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get( *outStatus = fillObd2DtcInfo(v.get()); break; default: if (mEmulatedUserHal != nullptr && mEmulatedUserHal->isSupported(propId)) { ALOGI("get(): getting value for prop %d from User HAL", propId); const auto& ret = mEmulatedUserHal->onGetProperty(propId); if (!ret.ok()) { ALOGE("get(): User HAL returned error: %s", ret.error().message().c_str()); *outStatus = StatusCode(ret.error().code()); } else { auto value = ret.value().get(); if (value != nullptr) { ALOGI("get(): User HAL returned value: %s", toString(*value).c_str()); v = getValuePool()->obtain(*value); *outStatus = StatusCode::OK; } else { ALOGE("get(): User HAL returned null value"); *outStatus = StatusCode::INTERNAL_ERROR; } } break; } auto internalPropValue = mPropStore->readValueOrNull(requestedPropValue); if (internalPropValue != nullptr) { v = getValuePool()->obtain(*internalPropValue); Loading automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h +4 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "vhal_v2_0/VehiclePropertyStore.h" #include "DefaultConfig.h" #include "EmulatedUserHal.h" #include "EmulatedVehicleConnector.h" #include "GeneratorHub.h" #include "VehicleEmulator.h" Loading @@ -45,8 +46,8 @@ namespace impl { /** Implementation of VehicleHal that connected to emulator instead of real vehicle network. */ class EmulatedVehicleHal : public EmulatedVehicleHalIface { public: EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client); EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client, EmulatedUserHal* emulatedUserHal = nullptr); ~EmulatedVehicleHal() = default; // Methods from VehicleHal Loading Loading @@ -90,6 +91,7 @@ private: bool mInEmulator; bool mInitVhalValueOverride; std::vector<VehiclePropValue> mVehiclePropertiesOverride; EmulatedUserHal* mEmulatedUserHal; }; } // impl Loading Loading
automotive/vehicle/2.0/default/VehicleService.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <android/binder_process.h> #include <utils/Looper.h> #include <vhal_v2_0/EmulatedUserHal.h> #include <vhal_v2_0/EmulatedVehicleConnector.h> #include <vhal_v2_0/EmulatedVehicleHal.h> #include <vhal_v2_0/VehicleHalManager.h> Loading @@ -34,7 +35,8 @@ using namespace android::hardware::automotive::vehicle::V2_0; int main(int /* argc */, char* /* argv */ []) { auto store = std::make_unique<VehiclePropertyStore>(); auto connector = impl::makeEmulatedPassthroughConnector(); auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get()); auto userHal = connector->getEmulatedUserHal(); auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get(), userHal); auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get()); auto service = std::make_unique<VehicleHalManager>(hal.get()); connector->setValuePool(hal->getValuePool()); Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.cpp +78 −0 Original line number Diff line number Diff line Loading @@ -30,11 +30,14 @@ namespace impl { constexpr int INITIAL_USER_INFO = static_cast<int>(VehicleProperty::INITIAL_USER_INFO); constexpr int SWITCH_USER = static_cast<int>(VehicleProperty::SWITCH_USER); constexpr int USER_IDENTIFICATION_ASSOCIATION = static_cast<int>(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION); bool EmulatedUserHal::isSupported(int32_t prop) { switch (prop) { case INITIAL_USER_INFO: case SWITCH_USER: case USER_IDENTIFICATION_ASSOCIATION: return true; default: return false; Loading @@ -50,12 +53,41 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetP return onSetInitialUserInfoResponse(value); case SWITCH_USER: return onSetSwitchUserResponse(value); case USER_IDENTIFICATION_ASSOCIATION: return onSetUserIdentificationAssociation(value); default: return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG)) << "Unsupported property: " << toString(value); } } android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onGetProperty( int32_t prop) { ALOGV("onGetProperty(%d)", prop); switch (prop) { case INITIAL_USER_INFO: case SWITCH_USER: ALOGE("onGetProperty(): %d is only supported on SET", prop); return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG)) << "only supported on SET"; case USER_IDENTIFICATION_ASSOCIATION: if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) { ALOGI("onGetProperty(%d): returning %s", prop, toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str()); auto value = std::unique_ptr<VehiclePropValue>( new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd)); return value; } ALOGE("onGetProperty(%d): USER_IDENTIFICATION_ASSOCIATION not set by lshal", prop); return android::base::Error(static_cast<int>(StatusCode::NOT_AVAILABLE)) << "not set by lshal"; default: ALOGE("onGetProperty(): %d is not supported", prop); return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG)) << "not supported by User HAL"; } } android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetInitialUserInfoResponse(const VehiclePropValue& value) { if (value.value.int32Values.size() == 0) { Loading Loading @@ -130,6 +162,46 @@ android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetS return updatedValue; } android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::onSetUserIdentificationAssociation(const VehiclePropValue& value) { if (value.value.int32Values.size() == 0) { ALOGE("set(USER_IDENTIFICATION_ASSOCIATION): no int32values, ignoring it: %s", toString(value).c_str()); return android::base::Error(static_cast<int>(StatusCode::INVALID_ARG)) << "no int32values on " << toString(value); } if (value.areaId != 0) { ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from lshal; storing it: %s", toString(value).c_str()); mSetUserIdentificationAssociationResponseFromCmd.reset(new VehiclePropValue(value)); return {}; } ALOGD("set(USER_IDENTIFICATION_ASSOCIATION) called from Android: %s", toString(value).c_str()); int32_t requestId = value.value.int32Values[0]; if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) { ALOGI("replying USER_IDENTIFICATION_ASSOCIATION with lshal value: %s", toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str()); // Not moving response so it can be used on GET requests auto copy = std::unique_ptr<VehiclePropValue>( new VehiclePropValue(*mSetUserIdentificationAssociationResponseFromCmd)); return sendUserHalResponse(std::move(copy), requestId); } // Returns default response auto updatedValue = std::unique_ptr<VehiclePropValue>(new VehiclePropValue); updatedValue->prop = USER_IDENTIFICATION_ASSOCIATION; updatedValue->timestamp = elapsedRealtimeNano(); updatedValue->value.int32Values.resize(1); updatedValue->value.int32Values[0] = requestId; updatedValue->value.stringValue = "Response not set by LSHAL"; ALOGI("no lshal response; replying with an error message: %s", toString(*updatedValue).c_str()); return updatedValue; } android::base::Result<std::unique_ptr<VehiclePropValue>> EmulatedUserHal::sendUserHalResponse( std::unique_ptr<VehiclePropValue> response, int32_t requestId) { switch (response->areaId) { Loading Loading @@ -175,6 +247,12 @@ void EmulatedUserHal::dump(int fd, std::string indent) { } else { dprintf(fd, "%sNo SwitchUser response\n", indent.c_str()); } if (mSetUserIdentificationAssociationResponseFromCmd != nullptr) { dprintf(fd, "%sSetUserIdentificationAssociation response: %s\n", indent.c_str(), toString(*mSetUserIdentificationAssociationResponseFromCmd).c_str()); } else { dprintf(fd, "%sNo SetUserIdentificationAssociation response\n", indent.c_str()); } } } // namespace impl Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedUserHal.h +16 −1 Original line number Diff line number Diff line Loading @@ -46,13 +46,20 @@ class EmulatedUserHal { bool isSupported(int32_t prop); /** * Lets the emulator handle the property. * Lets the emulator set the property. * * @return updated property and StatusCode */ android::base::Result<std::unique_ptr<VehiclePropValue>> onSetProperty( const VehiclePropValue& value); /** * Gets the property value from the emulator. * * @return property value and StatusCode */ android::base::Result<std::unique_ptr<VehiclePropValue>> onGetProperty(int32_t prop); /** * Shows the User HAL emulation help. */ Loading Loading @@ -97,11 +104,19 @@ class EmulatedUserHal { android::base::Result<std::unique_ptr<VehiclePropValue>> onSetSwitchUserResponse( const VehiclePropValue& value); /** * Used to emulate USER_IDENTIFICATION_ASSOCIATION - see onSetInitialUserInfoResponse() for * usage. */ android::base::Result<std::unique_ptr<VehiclePropValue>> onSetUserIdentificationAssociation( const VehiclePropValue& value); android::base::Result<std::unique_ptr<VehiclePropValue>> sendUserHalResponse( std::unique_ptr<VehiclePropValue> response, int32_t requestId); std::unique_ptr<VehiclePropValue> mInitialUserResponseFromCmd; std::unique_ptr<VehiclePropValue> mSwitchUserResponseFromCmd; std::unique_ptr<VehiclePropValue> mSetUserIdentificationAssociationResponseFromCmd; }; } // namespace impl Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.cpp +26 −2 Original line number Diff line number Diff line Loading @@ -92,12 +92,14 @@ static std::unique_ptr<Obd2SensorStore> fillDefaultObd2Frame(size_t numVendorInt return sensorStore; } EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client) EmulatedVehicleHal::EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client, EmulatedUserHal* emulatedUserHal) : mPropStore(propStore), mHvacPowerProps(std::begin(kHvacPowerProperties), std::end(kHvacPowerProperties)), mRecurrentTimer(std::bind(&EmulatedVehicleHal::onContinuousPropertyTimer, this, std::placeholders::_1)), mVehicleClient(client) { mVehicleClient(client), mEmulatedUserHal(emulatedUserHal) { initStaticConfig(); for (size_t i = 0; i < arraysize(kVehicleProperties); i++) { mPropStore->registerProperty(kVehicleProperties[i].config); Loading Loading @@ -134,6 +136,8 @@ void EmulatedVehicleHal::getAllPropertiesOverride() { VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get( const VehiclePropValue& requestedPropValue, StatusCode* outStatus) { auto propId = requestedPropValue.prop; ALOGV("get(%d)", propId); auto& pool = *getValuePool(); VehiclePropValuePtr v = nullptr; Loading @@ -147,6 +151,26 @@ VehicleHal::VehiclePropValuePtr EmulatedVehicleHal::get( *outStatus = fillObd2DtcInfo(v.get()); break; default: if (mEmulatedUserHal != nullptr && mEmulatedUserHal->isSupported(propId)) { ALOGI("get(): getting value for prop %d from User HAL", propId); const auto& ret = mEmulatedUserHal->onGetProperty(propId); if (!ret.ok()) { ALOGE("get(): User HAL returned error: %s", ret.error().message().c_str()); *outStatus = StatusCode(ret.error().code()); } else { auto value = ret.value().get(); if (value != nullptr) { ALOGI("get(): User HAL returned value: %s", toString(*value).c_str()); v = getValuePool()->obtain(*value); *outStatus = StatusCode::OK; } else { ALOGE("get(): User HAL returned null value"); *outStatus = StatusCode::INTERNAL_ERROR; } } break; } auto internalPropValue = mPropStore->readValueOrNull(requestedPropValue); if (internalPropValue != nullptr) { v = getValuePool()->obtain(*internalPropValue); Loading
automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleHal.h +4 −2 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include "vhal_v2_0/VehiclePropertyStore.h" #include "DefaultConfig.h" #include "EmulatedUserHal.h" #include "EmulatedVehicleConnector.h" #include "GeneratorHub.h" #include "VehicleEmulator.h" Loading @@ -45,8 +46,8 @@ namespace impl { /** Implementation of VehicleHal that connected to emulator instead of real vehicle network. */ class EmulatedVehicleHal : public EmulatedVehicleHalIface { public: EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client); EmulatedVehicleHal(VehiclePropertyStore* propStore, VehicleHalClient* client, EmulatedUserHal* emulatedUserHal = nullptr); ~EmulatedVehicleHal() = default; // Methods from VehicleHal Loading Loading @@ -90,6 +91,7 @@ private: bool mInEmulator; bool mInitVhalValueOverride; std::vector<VehiclePropValue> mVehiclePropertiesOverride; EmulatedUserHal* mEmulatedUserHal; }; } // impl Loading