/* * Copyright (c) 2022, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CPP_VHAL_CLIENT_INCLUDE_AIDLVHALCLIENT_H_ #define CPP_VHAL_CLIENT_INCLUDE_AIDLVHALCLIENT_H_ #include "IVhalClient.h" #include #include #include #include #include #include #include #include #include #include // NOLINT #include #include namespace android { namespace frameworks { namespace automotive { namespace vhal { namespace aidl_test { class AidlVhalClientTest; } // namespace aidl_test class GetSetValueClient; class AidlVhalClient final : public IVhalClient { public: constexpr static char AIDL_VHAL_SERVICE[] = "android.hardware.automotive.vehicle.IVehicle/default"; static std::shared_ptr create(); static std::shared_ptr tryCreate(); static std::shared_ptr tryCreate(const char* descriptor); explicit AidlVhalClient( std::shared_ptr hal); AidlVhalClient(std::shared_ptr hal, int64_t timeoutInMs); ~AidlVhalClient(); bool isAidlVhal() override; std::unique_ptr createHalPropValue(int32_t propId) override; std::unique_ptr createHalPropValue(int32_t propId, int32_t areaId) override; void getValue(const IHalPropValue& requestValue, std::shared_ptr callback) override; void setValue(const IHalPropValue& value, std::shared_ptr callback) override; // Add the callback that would be called when VHAL binder died. VhalClientResult addOnBinderDiedCallback( std::shared_ptr callback) override; // Remove a previously added OnBinderDied callback. VhalClientResult removeOnBinderDiedCallback( std::shared_ptr callback) override; VhalClientResult>> getAllPropConfigs() override; VhalClientResult>> getPropConfigs( std::vector propIds) override; std::unique_ptr getSubscriptionClient( std::shared_ptr callback) override; int32_t getRemoteInterfaceVersion() override; // Converts a non-okay status to an error {@code Result}. template inline static VhalClientResult statusToError(const ndk::ScopedAStatus& status, const std::string& msg) { using StatusCode = aidl::android::hardware::automotive::vehicle::StatusCode; StatusCode statusCode = StatusCode::INTERNAL_ERROR; if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) { statusCode = static_cast(status.getServiceSpecificError()); } else if (status.getExceptionCode() == EX_TRANSACTION_FAILED) { if (status.getStatus() != STATUS_DEAD_OBJECT) { // STATUS_DEAD_OBJECT is fatal and should not return TRANSACTION_ERROR. return ClientStatusError(ErrorCode::TRANSACTION_ERROR) << msg << ", error: " << status.getDescription(); } } return ClientStatusError(statusCode) << msg << ", error: " << status.getDescription(); } private: friend class aidl_test::AidlVhalClientTest; class ILinkUnlinkToDeath { public: virtual ~ILinkUnlinkToDeath() = default; virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) = 0; virtual binder_status_t unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) = 0; }; class DefaultLinkUnlinkImpl final : public ILinkUnlinkToDeath { public: binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) override; binder_status_t unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) override; }; std::atomic mRequestId = 0; std::shared_ptr mGetSetValueClient; std::shared_ptr mHal; std::unique_ptr mLinkUnlinkImpl; ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; std::mutex mLock; std::unordered_set> mOnBinderDiedCallbacks GUARDED_BY(mLock); static void onBinderDied(void* cookie); static void onBinderUnlinked(void* cookie); void onBinderDiedWithContext(); void onBinderUnlinkedWithContext(); VhalClientResult>> parseVehiclePropConfigs( const aidl::android::hardware::automotive::vehicle::VehiclePropConfigs& configs); // Test-only functions: AidlVhalClient(std::shared_ptr hal, int64_t timeoutInMs, std::unique_ptr linkUnlinkImpl); size_t countOnBinderDiedCallbacks(); }; class GetSetValueClient final : public aidl::android::hardware::automotive::vehicle::BnVehicleCallback { public: struct PendingGetValueRequest { std::shared_ptr callback; int32_t propId; int32_t areaId; }; struct PendingSetValueRequest { std::shared_ptr callback; int32_t propId; int32_t areaId; }; GetSetValueClient(int64_t timeoutInNs, std::shared_ptr mHal); ~GetSetValueClient(); ndk::ScopedAStatus onGetValues( const aidl::android::hardware::automotive::vehicle::GetValueResults& results) override; ndk::ScopedAStatus onSetValues( const aidl::android::hardware::automotive::vehicle::SetValueResults& results) override; ndk::ScopedAStatus onPropertyEvent( const aidl::android::hardware::automotive::vehicle::VehiclePropValues& values, int32_t sharedMemoryCount) override; ndk::ScopedAStatus onPropertySetError( const aidl::android::hardware::automotive::vehicle::VehiclePropErrors& errors) override; void getValue(int64_t requestId, const IHalPropValue& requestValue, std::shared_ptr clientCallback, std::shared_ptr vhalCallback); void setValue(int64_t requestId, const IHalPropValue& requestValue, std::shared_ptr clientCallback, std::shared_ptr vhalCallback); private: std::mutex mLock; std::unordered_map> mPendingGetValueCallbacks GUARDED_BY(mLock); std::unordered_map> mPendingSetValueCallbacks GUARDED_BY(mLock); std::unique_ptr mPendingRequestPool; std::shared_ptr mOnGetValueTimeout; std::shared_ptr mOnSetValueTimeout; std::shared_ptr mHal; // Add a new GetValue pending request. void addGetValueRequest(int64_t requestId, const IHalPropValue& requestValue, std::shared_ptr callback); // Add a new SetValue pending request. void addSetValueRequest(int64_t requestId, const IHalPropValue& requestValue, std::shared_ptr callback); // Try to finish the pending GetValue request according to the requestId. If there is an // existing pending request, the request would be finished and returned. Otherwise, if the // request has already timed-out, nullptr would be returned. std::unique_ptr tryFinishGetValueRequest(int64_t requestId); // Try to finish the pending SetValue request according to the requestId. If there is an // existing pending request, the request would be finished and returned. Otherwise, if the // request has already timed-out, nullptr would be returned. std::unique_ptr tryFinishSetValueRequest(int64_t requestId); template std::unique_ptr tryFinishRequest(int64_t requestId, std::unordered_map>* callbacks) REQUIRES(mLock); void onGetValue(const aidl::android::hardware::automotive::vehicle::GetValueResult& result); void onSetValue(const aidl::android::hardware::automotive::vehicle::SetValueResult& result); template void onTimeout(const std::unordered_set& requestIds, std::unordered_map>* callbacks); }; class SubscriptionVehicleCallback final : public aidl::android::hardware::automotive::vehicle::BnVehicleCallback { public: explicit SubscriptionVehicleCallback(std::shared_ptr callback); ndk::ScopedAStatus onGetValues( const aidl::android::hardware::automotive::vehicle::GetValueResults& results) override; ndk::ScopedAStatus onSetValues( const aidl::android::hardware::automotive::vehicle::SetValueResults& results) override; ndk::ScopedAStatus onPropertyEvent( const aidl::android::hardware::automotive::vehicle::VehiclePropValues& values, int32_t sharedMemoryCount) override; ndk::ScopedAStatus onPropertySetError( const aidl::android::hardware::automotive::vehicle::VehiclePropErrors& errors) override; private: std::shared_ptr mCallback; }; class AidlSubscriptionClient final : public ISubscriptionClient { public: ~AidlSubscriptionClient() = default; AidlSubscriptionClient( std::shared_ptr hal, std::shared_ptr callback); VhalClientResult subscribe( const std::vector& options) override; VhalClientResult unsubscribe(const std::vector& propIds) override; private: std::shared_ptr mSubscriptionCallback; std::shared_ptr mHal; }; } // namespace vhal } // namespace automotive } // namespace frameworks } // namespace android #endif // CPP_VHAL_CLIENT_INCLUDE_AIDLVHALCLIENT_H_