Loading automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h +46 −71 Original line number Diff line number Diff line Loading @@ -42,10 +42,11 @@ namespace hardware { namespace automotive { namespace vehicle { class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehicle::BnVehicle { namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle; class DefaultVehicleHal final : public aidlvhal::BnVehicle { public: using CallbackType = std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>; using CallbackType = std::shared_ptr<aidlvhal::IVehicleCallback>; explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware); Loading @@ -54,25 +55,15 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi ~DefaultVehicleHal(); ndk::ScopedAStatus getAllPropConfigs( aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs) override; ndk::ScopedAStatus getValues( const CallbackType& callback, const aidl::android::hardware::automotive::vehicle::GetValueRequests& requests) override; ndk::ScopedAStatus setValues( const CallbackType& callback, const aidl::android::hardware::automotive::vehicle::SetValueRequests& requests) override; ndk::ScopedAStatus getPropConfigs( const std::vector<int32_t>& props, aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs) override; ndk::ScopedAStatus subscribe( const CallbackType& callback, const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>& options, ndk::ScopedAStatus getAllPropConfigs(aidlvhal::VehiclePropConfigs* returnConfigs) override; ndk::ScopedAStatus getValues(const CallbackType& callback, const aidlvhal::GetValueRequests& requests) override; ndk::ScopedAStatus setValues(const CallbackType& callback, const aidlvhal::SetValueRequests& requests) override; ndk::ScopedAStatus getPropConfigs(const std::vector<int32_t>& props, aidlvhal::VehiclePropConfigs* returnConfigs) override; ndk::ScopedAStatus subscribe(const CallbackType& callback, const std::vector<aidlvhal::SubscribeOptions>& options, int32_t maxSharedMemoryFileCount) override; ndk::ScopedAStatus unsubscribe(const CallbackType& callback, const std::vector<int32_t>& propIds) override; Loading @@ -86,12 +77,8 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi // friend class for unit testing. friend class DefaultVehicleHalTest; using GetValuesClient = GetSetValuesClient<aidl::android::hardware::automotive::vehicle::GetValueResult, aidl::android::hardware::automotive::vehicle::GetValueResults>; using SetValuesClient = GetSetValuesClient<aidl::android::hardware::automotive::vehicle::SetValueResult, aidl::android::hardware::automotive::vehicle::SetValueResults>; using GetValuesClient = GetSetValuesClient<aidlvhal::GetValueResult, aidlvhal::GetValueResults>; using SetValuesClient = GetSetValuesClient<aidlvhal::SetValueResult, aidlvhal::SetValueResults>; // A wrapper for binder lifecycle operations to enable stubbing for test. class BinderLifecycleInterface { Loading Loading @@ -137,28 +124,27 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi bool mShouldRefreshPropertyConfigs; std::unique_ptr<IVehicleHardware> mVehicleHardware; // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to // lock guard them. std::unordered_map<int32_t, aidl::android::hardware::automotive::vehicle::VehiclePropConfig> mConfigsByPropId; // Only modified in constructor, so thread-safe. std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile; // PendingRequestPool is thread-safe. std::shared_ptr<PendingRequestPool> mPendingRequestPool; // SubscriptionManager is thread-safe. std::shared_ptr<SubscriptionManager> mSubscriptionManager; // ConcurrentQueue is thread-safe. std::shared_ptr<ConcurrentQueue<aidl::android::hardware::automotive::vehicle::VehiclePropValue>> mBatchedEventQueue; std::shared_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>> mBatchedEventQueue; // BatchingConsumer is thread-safe. std::shared_ptr< BatchingConsumer<aidl::android::hardware::automotive::vehicle::VehiclePropValue>> std::shared_ptr<BatchingConsumer<aidlvhal::VehiclePropValue>> mPropertyChangeEventsBatchingConsumer; // Only set once during initialization. std::chrono::nanoseconds mEventBatchingWindow; // Only used for testing. int32_t mTestInterfaceVersion = 0; // mConfigsByPropId and mConfigFile is lazy initialized. mutable std::mutex mConfigInitLock; mutable bool mConfigInit GUARDED_BY(mConfigInitLock) = false; mutable std::unordered_map<int32_t, aidlvhal::VehiclePropConfig> mConfigsByPropId GUARDED_BY(mConfigInitLock); mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigInitLock); std::mutex mLock; std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts GUARDED_BY(mLock); Loading @@ -182,32 +168,23 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi // A thread to handle onBinderDied or onBinderUnlinked event. std::thread mOnBinderDiedUnlinkedHandlerThread; android::base::Result<void> checkProperty( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue); android::base::Result<void> checkProperty(const aidlvhal::VehiclePropValue& propValue); android::base::Result<std::vector<int64_t>> checkDuplicateRequests( const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>& requests); const std::vector<aidlvhal::GetValueRequest>& requests); android::base::Result<std::vector<int64_t>> checkDuplicateRequests( const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>& requests); VhalResult<void> checkSubscribeOptions( const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>& options); const std::vector<aidlvhal::SetValueRequest>& requests); VhalResult<void> checkSubscribeOptions(const std::vector<aidlvhal::SubscribeOptions>& options); VhalResult<void> checkPermissionHelper( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value, aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess accessToTest) const; VhalResult<void> checkPermissionHelper(const aidlvhal::VehiclePropValue& value, aidlvhal::VehiclePropertyAccess accessToTest) const; VhalResult<void> checkReadPermission( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const; VhalResult<void> checkReadPermission(const aidlvhal::VehiclePropValue& value) const; VhalResult<void> checkWritePermission( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const; VhalResult<void> checkWritePermission(const aidlvhal::VehiclePropValue& value) const; android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*> getConfig(int32_t propId) const; android::base::Result<const aidlvhal::VehiclePropConfig*> getConfig(int32_t propId) const; void onBinderDiedWithContext(const AIBinder* clientId); Loading @@ -219,7 +196,7 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi bool checkDumpPermission(); bool getAllPropConfigsFromHardware(); bool getAllPropConfigsFromHardwareLocked() const REQUIRES(mConfigInitLock); // The looping handler function to process all onBinderDied or onBinderUnlinked events in // mBinderEvents. Loading @@ -228,19 +205,19 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi size_t countSubscribeClients(); // Handles the property change events in batch. void handleBatchedPropertyEvents( std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&& batchedEvents); void handleBatchedPropertyEvents(std::vector<aidlvhal::VehiclePropValue>&& batchedEvents); int32_t getVhalInterfaceVersion(); int32_t getVhalInterfaceVersion() const; // Gets mConfigsByPropId, lazy init it if necessary. const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& getConfigsByPropId() const; // Gets mConfigFile, lazy init it if necessary. const ndk::ScopedFileDescriptor* getConfigFile() const; // Puts the property change events into a queue so that they can handled in batch. static void batchPropertyChangeEvent( const std::weak_ptr<ConcurrentQueue< aidl::android::hardware::automotive::vehicle::VehiclePropValue>>& batchedEventQueue, std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&& updatedValues); const std::weak_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>>& batchedEventQueue, std::vector<aidlvhal::VehiclePropValue>&& updatedValues); // Gets or creates a {@code T} object for the client to or from {@code clients}. template <class T> Loading @@ -248,10 +225,8 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients, const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool); static void onPropertyChangeEvent( const std::weak_ptr<SubscriptionManager>& subscriptionManager, std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&& updatedValues); static void onPropertyChangeEvent(const std::weak_ptr<SubscriptionManager>& subscriptionManager, std::vector<aidlvhal::VehiclePropValue>&& updatedValues); static void onPropertySetErrorEvent( const std::weak_ptr<SubscriptionManager>& subscriptionManager, Loading automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp +53 −21 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <VehicleUtils.h> #include <VersionForVehicleProperty.h> #include <android-base/logging.h> #include <android-base/result.h> #include <android-base/stringprintf.h> #include <android/binder_ibinder.h> Loading Loading @@ -71,6 +72,7 @@ using ::android::base::StringPrintf; using ::ndk::ScopedAIBinder_DeathRecipient; using ::ndk::ScopedAStatus; using ::ndk::ScopedFileDescriptor; std::string toString(const std::unordered_set<int64_t>& values) { std::string str = ""; Loading Loading @@ -103,10 +105,7 @@ DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHa : mVehicleHardware(std::move(vehicleHardware)), mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)), mTestInterfaceVersion(testInterfaceVersion) { if (!getAllPropConfigsFromHardware()) { return; } ALOGD("DefaultVehicleHal init"); IVehicleHardware* vehicleHardwarePtr = mVehicleHardware.get(); mSubscriptionManager = std::make_shared<SubscriptionManager>(vehicleHardwarePtr); mEventBatchingWindow = mVehicleHardware->getPropertyOnChangeEventBatchingWindow(); Loading Loading @@ -319,16 +318,18 @@ void DefaultVehicleHal::setTimeout(int64_t timeoutInNano) { mPendingRequestPool = std::make_unique<PendingRequestPool>(timeoutInNano); } int32_t DefaultVehicleHal::getVhalInterfaceVersion() { int32_t DefaultVehicleHal::getVhalInterfaceVersion() const { if (mTestInterfaceVersion != 0) { return mTestInterfaceVersion; } int32_t myVersion = 0; getInterfaceVersion(&myVersion); // getInterfaceVersion is in-reality a const method. const_cast<DefaultVehicleHal*>(this)->getInterfaceVersion(&myVersion); return myVersion; } bool DefaultVehicleHal::getAllPropConfigsFromHardware() { bool DefaultVehicleHal::getAllPropConfigsFromHardwareLocked() const { ALOGD("Get all property configs from hardware"); auto configs = mVehicleHardware->getAllPropertyConfigs(); std::vector<VehiclePropConfig> filteredConfigs; int32_t myVersion = getVhalInterfaceVersion(); Loading Loading @@ -373,22 +374,46 @@ bool DefaultVehicleHal::getAllPropConfigsFromHardware() { return true; } const ScopedFileDescriptor* DefaultVehicleHal::getConfigFile() const { std::scoped_lock lockGuard(mConfigInitLock); if (!mConfigInit) { CHECK(getAllPropConfigsFromHardwareLocked()) << "Failed to get property configs from hardware"; mConfigInit = true; } return mConfigFile.get(); } const std::unordered_map<int32_t, VehiclePropConfig>& DefaultVehicleHal::getConfigsByPropId() const { std::scoped_lock lockGuard(mConfigInitLock); if (!mConfigInit) { CHECK(getAllPropConfigsFromHardwareLocked()) << "Failed to get property configs from hardware"; mConfigInit = true; } return mConfigsByPropId; } ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) { if (mConfigFile != nullptr) { const ScopedFileDescriptor* configFile = getConfigFile(); const auto& configsByPropId = getConfigsByPropId(); if (configFile != nullptr) { output->payloads.clear(); output->sharedMemoryFd.set(dup(mConfigFile->get())); output->sharedMemoryFd.set(dup(configFile->get())); return ScopedAStatus::ok(); } output->payloads.reserve(mConfigsByPropId.size()); for (const auto& [_, config] : mConfigsByPropId) { output->payloads.reserve(configsByPropId.size()); for (const auto& [_, config] : configsByPropId) { output->payloads.push_back(config); } return ScopedAStatus::ok(); } Result<const VehiclePropConfig*> DefaultVehicleHal::getConfig(int32_t propId) const { auto it = mConfigsByPropId.find(propId); if (it == mConfigsByPropId.end()) { const auto& configsByPropId = getConfigsByPropId(); auto it = configsByPropId.find(propId); if (it == configsByPropId.end()) { return Error() << "no config for property, ID: " << propId; } return &(it->second); Loading Loading @@ -634,9 +659,11 @@ ScopedAStatus DefaultVehicleHal::setValues(const CallbackType& callback, ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>& props, VehiclePropConfigs* output) { std::vector<VehiclePropConfig> configs; const auto& configsByPropId = getConfigsByPropId(); for (int32_t prop : props) { if (mConfigsByPropId.find(prop) != mConfigsByPropId.end()) { configs.push_back(mConfigsByPropId[prop]); auto it = configsByPropId.find(prop); if (it != configsByPropId.end()) { configs.push_back(it->second); } else { return ScopedAStatus::fromServiceSpecificErrorWithMessage( toInt(StatusCode::INVALID_ARG), Loading Loading @@ -665,13 +692,15 @@ bool areaConfigsHaveRequiredAccess(const std::vector<VehicleAreaConfig>& areaCon VhalResult<void> DefaultVehicleHal::checkSubscribeOptions( const std::vector<SubscribeOptions>& options) { const auto& configsByPropId = getConfigsByPropId(); for (const auto& option : options) { int32_t propId = option.propId; if (mConfigsByPropId.find(propId) == mConfigsByPropId.end()) { auto it = configsByPropId.find(propId); if (it == configsByPropId.end()) { return StatusError(StatusCode::INVALID_ARG) << StringPrintf("no config for property, ID: %" PRId32, propId); } const VehiclePropConfig& config = mConfigsByPropId[propId]; const VehiclePropConfig& config = it->second; std::vector<VehicleAreaConfig> areaConfigs; if (option.areaIds.empty()) { areaConfigs = config.areaConfigs; Loading Loading @@ -744,10 +773,11 @@ ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback, } std::vector<SubscribeOptions> onChangeSubscriptions; std::vector<SubscribeOptions> continuousSubscriptions; const auto& configsByPropId = getConfigsByPropId(); for (const auto& option : options) { int32_t propId = option.propId; // We have already validate config exists. const VehiclePropConfig& config = mConfigsByPropId[propId]; const VehiclePropConfig& config = configsByPropId.at(propId); SubscribeOptions optionCopy = option; // If areaIds is empty, subscribe to all areas. Loading Loading @@ -871,7 +901,7 @@ VhalResult<void> DefaultVehicleHal::checkPermissionHelper( (areaConfig == nullptr || !hasRequiredAccess(areaConfig->access, accessToTest))) { return StatusError(StatusCode::ACCESS_DENIED) << StringPrintf("Property %" PRId32 " does not have the following access: %" PRId32, propId, accessToTest); propId, static_cast<int32_t>(accessToTest)); } return {}; } Loading Loading @@ -936,17 +966,19 @@ binder_status_t DefaultVehicleHal::dump(int fd, const char** args, uint32_t numA } DumpResult result = mVehicleHardware->dump(options); if (result.refreshPropertyConfigs) { getAllPropConfigsFromHardware(); std::scoped_lock lockGuard(mConfigInitLock); getAllPropConfigsFromHardwareLocked(); } dprintf(fd, "%s", (result.buffer + "\n").c_str()); if (!result.callerShouldDumpState) { return STATUS_OK; } dprintf(fd, "Vehicle HAL State: \n"); const auto& configsByPropId = getConfigsByPropId(); { std::scoped_lock<std::mutex> lockGuard(mLock); dprintf(fd, "Interface version: %" PRId32 "\n", getVhalInterfaceVersion()); dprintf(fd, "Containing %zu property configs\n", mConfigsByPropId.size()); dprintf(fd, "Containing %zu property configs\n", configsByPropId.size()); dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size()); dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size()); dprintf(fd, "Currently have %zu subscribe clients\n", countSubscribeClients()); Loading Loading
automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h +46 −71 Original line number Diff line number Diff line Loading @@ -42,10 +42,11 @@ namespace hardware { namespace automotive { namespace vehicle { class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehicle::BnVehicle { namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle; class DefaultVehicleHal final : public aidlvhal::BnVehicle { public: using CallbackType = std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>; using CallbackType = std::shared_ptr<aidlvhal::IVehicleCallback>; explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware); Loading @@ -54,25 +55,15 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi ~DefaultVehicleHal(); ndk::ScopedAStatus getAllPropConfigs( aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs) override; ndk::ScopedAStatus getValues( const CallbackType& callback, const aidl::android::hardware::automotive::vehicle::GetValueRequests& requests) override; ndk::ScopedAStatus setValues( const CallbackType& callback, const aidl::android::hardware::automotive::vehicle::SetValueRequests& requests) override; ndk::ScopedAStatus getPropConfigs( const std::vector<int32_t>& props, aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs) override; ndk::ScopedAStatus subscribe( const CallbackType& callback, const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>& options, ndk::ScopedAStatus getAllPropConfigs(aidlvhal::VehiclePropConfigs* returnConfigs) override; ndk::ScopedAStatus getValues(const CallbackType& callback, const aidlvhal::GetValueRequests& requests) override; ndk::ScopedAStatus setValues(const CallbackType& callback, const aidlvhal::SetValueRequests& requests) override; ndk::ScopedAStatus getPropConfigs(const std::vector<int32_t>& props, aidlvhal::VehiclePropConfigs* returnConfigs) override; ndk::ScopedAStatus subscribe(const CallbackType& callback, const std::vector<aidlvhal::SubscribeOptions>& options, int32_t maxSharedMemoryFileCount) override; ndk::ScopedAStatus unsubscribe(const CallbackType& callback, const std::vector<int32_t>& propIds) override; Loading @@ -86,12 +77,8 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi // friend class for unit testing. friend class DefaultVehicleHalTest; using GetValuesClient = GetSetValuesClient<aidl::android::hardware::automotive::vehicle::GetValueResult, aidl::android::hardware::automotive::vehicle::GetValueResults>; using SetValuesClient = GetSetValuesClient<aidl::android::hardware::automotive::vehicle::SetValueResult, aidl::android::hardware::automotive::vehicle::SetValueResults>; using GetValuesClient = GetSetValuesClient<aidlvhal::GetValueResult, aidlvhal::GetValueResults>; using SetValuesClient = GetSetValuesClient<aidlvhal::SetValueResult, aidlvhal::SetValueResults>; // A wrapper for binder lifecycle operations to enable stubbing for test. class BinderLifecycleInterface { Loading Loading @@ -137,28 +124,27 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi bool mShouldRefreshPropertyConfigs; std::unique_ptr<IVehicleHardware> mVehicleHardware; // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to // lock guard them. std::unordered_map<int32_t, aidl::android::hardware::automotive::vehicle::VehiclePropConfig> mConfigsByPropId; // Only modified in constructor, so thread-safe. std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile; // PendingRequestPool is thread-safe. std::shared_ptr<PendingRequestPool> mPendingRequestPool; // SubscriptionManager is thread-safe. std::shared_ptr<SubscriptionManager> mSubscriptionManager; // ConcurrentQueue is thread-safe. std::shared_ptr<ConcurrentQueue<aidl::android::hardware::automotive::vehicle::VehiclePropValue>> mBatchedEventQueue; std::shared_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>> mBatchedEventQueue; // BatchingConsumer is thread-safe. std::shared_ptr< BatchingConsumer<aidl::android::hardware::automotive::vehicle::VehiclePropValue>> std::shared_ptr<BatchingConsumer<aidlvhal::VehiclePropValue>> mPropertyChangeEventsBatchingConsumer; // Only set once during initialization. std::chrono::nanoseconds mEventBatchingWindow; // Only used for testing. int32_t mTestInterfaceVersion = 0; // mConfigsByPropId and mConfigFile is lazy initialized. mutable std::mutex mConfigInitLock; mutable bool mConfigInit GUARDED_BY(mConfigInitLock) = false; mutable std::unordered_map<int32_t, aidlvhal::VehiclePropConfig> mConfigsByPropId GUARDED_BY(mConfigInitLock); mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigInitLock); std::mutex mLock; std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts GUARDED_BY(mLock); Loading @@ -182,32 +168,23 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi // A thread to handle onBinderDied or onBinderUnlinked event. std::thread mOnBinderDiedUnlinkedHandlerThread; android::base::Result<void> checkProperty( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue); android::base::Result<void> checkProperty(const aidlvhal::VehiclePropValue& propValue); android::base::Result<std::vector<int64_t>> checkDuplicateRequests( const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>& requests); const std::vector<aidlvhal::GetValueRequest>& requests); android::base::Result<std::vector<int64_t>> checkDuplicateRequests( const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>& requests); VhalResult<void> checkSubscribeOptions( const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>& options); const std::vector<aidlvhal::SetValueRequest>& requests); VhalResult<void> checkSubscribeOptions(const std::vector<aidlvhal::SubscribeOptions>& options); VhalResult<void> checkPermissionHelper( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value, aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess accessToTest) const; VhalResult<void> checkPermissionHelper(const aidlvhal::VehiclePropValue& value, aidlvhal::VehiclePropertyAccess accessToTest) const; VhalResult<void> checkReadPermission( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const; VhalResult<void> checkReadPermission(const aidlvhal::VehiclePropValue& value) const; VhalResult<void> checkWritePermission( const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const; VhalResult<void> checkWritePermission(const aidlvhal::VehiclePropValue& value) const; android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*> getConfig(int32_t propId) const; android::base::Result<const aidlvhal::VehiclePropConfig*> getConfig(int32_t propId) const; void onBinderDiedWithContext(const AIBinder* clientId); Loading @@ -219,7 +196,7 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi bool checkDumpPermission(); bool getAllPropConfigsFromHardware(); bool getAllPropConfigsFromHardwareLocked() const REQUIRES(mConfigInitLock); // The looping handler function to process all onBinderDied or onBinderUnlinked events in // mBinderEvents. Loading @@ -228,19 +205,19 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi size_t countSubscribeClients(); // Handles the property change events in batch. void handleBatchedPropertyEvents( std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&& batchedEvents); void handleBatchedPropertyEvents(std::vector<aidlvhal::VehiclePropValue>&& batchedEvents); int32_t getVhalInterfaceVersion(); int32_t getVhalInterfaceVersion() const; // Gets mConfigsByPropId, lazy init it if necessary. const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& getConfigsByPropId() const; // Gets mConfigFile, lazy init it if necessary. const ndk::ScopedFileDescriptor* getConfigFile() const; // Puts the property change events into a queue so that they can handled in batch. static void batchPropertyChangeEvent( const std::weak_ptr<ConcurrentQueue< aidl::android::hardware::automotive::vehicle::VehiclePropValue>>& batchedEventQueue, std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&& updatedValues); const std::weak_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>>& batchedEventQueue, std::vector<aidlvhal::VehiclePropValue>&& updatedValues); // Gets or creates a {@code T} object for the client to or from {@code clients}. template <class T> Loading @@ -248,10 +225,8 @@ class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehi std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients, const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool); static void onPropertyChangeEvent( const std::weak_ptr<SubscriptionManager>& subscriptionManager, std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&& updatedValues); static void onPropertyChangeEvent(const std::weak_ptr<SubscriptionManager>& subscriptionManager, std::vector<aidlvhal::VehiclePropValue>&& updatedValues); static void onPropertySetErrorEvent( const std::weak_ptr<SubscriptionManager>& subscriptionManager, Loading
automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp +53 −21 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <VehicleUtils.h> #include <VersionForVehicleProperty.h> #include <android-base/logging.h> #include <android-base/result.h> #include <android-base/stringprintf.h> #include <android/binder_ibinder.h> Loading Loading @@ -71,6 +72,7 @@ using ::android::base::StringPrintf; using ::ndk::ScopedAIBinder_DeathRecipient; using ::ndk::ScopedAStatus; using ::ndk::ScopedFileDescriptor; std::string toString(const std::unordered_set<int64_t>& values) { std::string str = ""; Loading Loading @@ -103,10 +105,7 @@ DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHa : mVehicleHardware(std::move(vehicleHardware)), mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)), mTestInterfaceVersion(testInterfaceVersion) { if (!getAllPropConfigsFromHardware()) { return; } ALOGD("DefaultVehicleHal init"); IVehicleHardware* vehicleHardwarePtr = mVehicleHardware.get(); mSubscriptionManager = std::make_shared<SubscriptionManager>(vehicleHardwarePtr); mEventBatchingWindow = mVehicleHardware->getPropertyOnChangeEventBatchingWindow(); Loading Loading @@ -319,16 +318,18 @@ void DefaultVehicleHal::setTimeout(int64_t timeoutInNano) { mPendingRequestPool = std::make_unique<PendingRequestPool>(timeoutInNano); } int32_t DefaultVehicleHal::getVhalInterfaceVersion() { int32_t DefaultVehicleHal::getVhalInterfaceVersion() const { if (mTestInterfaceVersion != 0) { return mTestInterfaceVersion; } int32_t myVersion = 0; getInterfaceVersion(&myVersion); // getInterfaceVersion is in-reality a const method. const_cast<DefaultVehicleHal*>(this)->getInterfaceVersion(&myVersion); return myVersion; } bool DefaultVehicleHal::getAllPropConfigsFromHardware() { bool DefaultVehicleHal::getAllPropConfigsFromHardwareLocked() const { ALOGD("Get all property configs from hardware"); auto configs = mVehicleHardware->getAllPropertyConfigs(); std::vector<VehiclePropConfig> filteredConfigs; int32_t myVersion = getVhalInterfaceVersion(); Loading Loading @@ -373,22 +374,46 @@ bool DefaultVehicleHal::getAllPropConfigsFromHardware() { return true; } const ScopedFileDescriptor* DefaultVehicleHal::getConfigFile() const { std::scoped_lock lockGuard(mConfigInitLock); if (!mConfigInit) { CHECK(getAllPropConfigsFromHardwareLocked()) << "Failed to get property configs from hardware"; mConfigInit = true; } return mConfigFile.get(); } const std::unordered_map<int32_t, VehiclePropConfig>& DefaultVehicleHal::getConfigsByPropId() const { std::scoped_lock lockGuard(mConfigInitLock); if (!mConfigInit) { CHECK(getAllPropConfigsFromHardwareLocked()) << "Failed to get property configs from hardware"; mConfigInit = true; } return mConfigsByPropId; } ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) { if (mConfigFile != nullptr) { const ScopedFileDescriptor* configFile = getConfigFile(); const auto& configsByPropId = getConfigsByPropId(); if (configFile != nullptr) { output->payloads.clear(); output->sharedMemoryFd.set(dup(mConfigFile->get())); output->sharedMemoryFd.set(dup(configFile->get())); return ScopedAStatus::ok(); } output->payloads.reserve(mConfigsByPropId.size()); for (const auto& [_, config] : mConfigsByPropId) { output->payloads.reserve(configsByPropId.size()); for (const auto& [_, config] : configsByPropId) { output->payloads.push_back(config); } return ScopedAStatus::ok(); } Result<const VehiclePropConfig*> DefaultVehicleHal::getConfig(int32_t propId) const { auto it = mConfigsByPropId.find(propId); if (it == mConfigsByPropId.end()) { const auto& configsByPropId = getConfigsByPropId(); auto it = configsByPropId.find(propId); if (it == configsByPropId.end()) { return Error() << "no config for property, ID: " << propId; } return &(it->second); Loading Loading @@ -634,9 +659,11 @@ ScopedAStatus DefaultVehicleHal::setValues(const CallbackType& callback, ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>& props, VehiclePropConfigs* output) { std::vector<VehiclePropConfig> configs; const auto& configsByPropId = getConfigsByPropId(); for (int32_t prop : props) { if (mConfigsByPropId.find(prop) != mConfigsByPropId.end()) { configs.push_back(mConfigsByPropId[prop]); auto it = configsByPropId.find(prop); if (it != configsByPropId.end()) { configs.push_back(it->second); } else { return ScopedAStatus::fromServiceSpecificErrorWithMessage( toInt(StatusCode::INVALID_ARG), Loading Loading @@ -665,13 +692,15 @@ bool areaConfigsHaveRequiredAccess(const std::vector<VehicleAreaConfig>& areaCon VhalResult<void> DefaultVehicleHal::checkSubscribeOptions( const std::vector<SubscribeOptions>& options) { const auto& configsByPropId = getConfigsByPropId(); for (const auto& option : options) { int32_t propId = option.propId; if (mConfigsByPropId.find(propId) == mConfigsByPropId.end()) { auto it = configsByPropId.find(propId); if (it == configsByPropId.end()) { return StatusError(StatusCode::INVALID_ARG) << StringPrintf("no config for property, ID: %" PRId32, propId); } const VehiclePropConfig& config = mConfigsByPropId[propId]; const VehiclePropConfig& config = it->second; std::vector<VehicleAreaConfig> areaConfigs; if (option.areaIds.empty()) { areaConfigs = config.areaConfigs; Loading Loading @@ -744,10 +773,11 @@ ScopedAStatus DefaultVehicleHal::subscribe(const CallbackType& callback, } std::vector<SubscribeOptions> onChangeSubscriptions; std::vector<SubscribeOptions> continuousSubscriptions; const auto& configsByPropId = getConfigsByPropId(); for (const auto& option : options) { int32_t propId = option.propId; // We have already validate config exists. const VehiclePropConfig& config = mConfigsByPropId[propId]; const VehiclePropConfig& config = configsByPropId.at(propId); SubscribeOptions optionCopy = option; // If areaIds is empty, subscribe to all areas. Loading Loading @@ -871,7 +901,7 @@ VhalResult<void> DefaultVehicleHal::checkPermissionHelper( (areaConfig == nullptr || !hasRequiredAccess(areaConfig->access, accessToTest))) { return StatusError(StatusCode::ACCESS_DENIED) << StringPrintf("Property %" PRId32 " does not have the following access: %" PRId32, propId, accessToTest); propId, static_cast<int32_t>(accessToTest)); } return {}; } Loading Loading @@ -936,17 +966,19 @@ binder_status_t DefaultVehicleHal::dump(int fd, const char** args, uint32_t numA } DumpResult result = mVehicleHardware->dump(options); if (result.refreshPropertyConfigs) { getAllPropConfigsFromHardware(); std::scoped_lock lockGuard(mConfigInitLock); getAllPropConfigsFromHardwareLocked(); } dprintf(fd, "%s", (result.buffer + "\n").c_str()); if (!result.callerShouldDumpState) { return STATUS_OK; } dprintf(fd, "Vehicle HAL State: \n"); const auto& configsByPropId = getConfigsByPropId(); { std::scoped_lock<std::mutex> lockGuard(mLock); dprintf(fd, "Interface version: %" PRId32 "\n", getVhalInterfaceVersion()); dprintf(fd, "Containing %zu property configs\n", mConfigsByPropId.size()); dprintf(fd, "Containing %zu property configs\n", configsByPropId.size()); dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size()); dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size()); dprintf(fd, "Currently have %zu subscribe clients\n", countSubscribeClients()); Loading