1 /* 2 * Copyright (c) 2022, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CPP_VHAL_CLIENT_INCLUDE_AIDLVHALCLIENT_H_ 18 #define CPP_VHAL_CLIENT_INCLUDE_AIDLVHALCLIENT_H_ 19 20 #include "IVhalClient.h" 21 22 #include <aidl/android/hardware/automotive/vehicle/BnVehicleCallback.h> 23 #include <aidl/android/hardware/automotive/vehicle/IVehicle.h> 24 #include <android-base/thread_annotations.h> 25 #include <android/binder_auto_utils.h> 26 #include <android/binder_ibinder.h> 27 28 #include <PendingRequestPool.h> 29 #include <VehicleUtils.h> 30 31 #include <atomic> 32 #include <condition_variable> // NOLINT 33 #include <memory> 34 #include <mutex> // NOLINT 35 #include <unordered_map> 36 #include <unordered_set> 37 38 namespace android { 39 namespace frameworks { 40 namespace automotive { 41 namespace vhal { 42 43 namespace aidl_test { 44 45 class AidlVhalClientTest; 46 47 } // namespace aidl_test 48 49 class GetSetValueClient; 50 51 class AidlVhalClient final : public IVhalClient { 52 public: 53 constexpr static char AIDL_VHAL_SERVICE[] = 54 "android.hardware.automotive.vehicle.IVehicle/default"; 55 56 static std::shared_ptr<IVhalClient> create(bool startThreadPool); 57 static std::shared_ptr<IVhalClient> tryCreate(bool startThreadPool); 58 static std::shared_ptr<IVhalClient> tryCreate(const char* descriptor, bool startThreadPool); 59 60 explicit AidlVhalClient( 61 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal); 62 63 AidlVhalClient(std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal, 64 int64_t timeoutInMs); 65 66 ~AidlVhalClient(); 67 68 bool isAidlVhal() override; 69 70 std::unique_ptr<IHalPropValue> createHalPropValue(int32_t propId) override; 71 72 std::unique_ptr<IHalPropValue> createHalPropValue(int32_t propId, int32_t areaId) override; 73 74 void getValue(const IHalPropValue& requestValue, 75 std::shared_ptr<GetValueCallbackFunc> callback) override; 76 77 void setValue(const IHalPropValue& value, 78 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> callback) override; 79 80 // Add the callback that would be called when VHAL binder died. 81 VhalClientResult<void> addOnBinderDiedCallback( 82 std::shared_ptr<OnBinderDiedCallbackFunc> callback) override; 83 84 // Remove a previously added OnBinderDied callback. 85 VhalClientResult<void> removeOnBinderDiedCallback( 86 std::shared_ptr<OnBinderDiedCallbackFunc> callback) override; 87 88 VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> getAllPropConfigs() override; 89 VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> getPropConfigs( 90 std::vector<int32_t> propIds) override; 91 92 std::unique_ptr<ISubscriptionClient> getSubscriptionClient( 93 std::shared_ptr<ISubscriptionCallback> callback) override; 94 95 VhalClientResult< 96 std::vector<::aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResult>> 97 getMinMaxSupportedValue( 98 const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>& 99 propIdAreaIds) override; 100 101 VhalClientResult< 102 std::vector<::aidl::android::hardware::automotive::vehicle::SupportedValuesListResult>> 103 getSupportedValuesLists( 104 const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>& 105 propIdAreaIds) override; 106 107 int32_t getRemoteInterfaceVersion() override; 108 109 // Converts a non-okay status to an error {@code Result}. 110 template <class T> statusToError(const ndk::ScopedAStatus & status,const std::string & msg)111 inline static VhalClientResult<T> statusToError(const ndk::ScopedAStatus& status, 112 const std::string& msg) { 113 using StatusCode = aidl::android::hardware::automotive::vehicle::StatusCode; 114 StatusCode statusCode = StatusCode::INTERNAL_ERROR; 115 if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) { 116 statusCode = static_cast<StatusCode>(status.getServiceSpecificError()); 117 } else if (status.getExceptionCode() == EX_TRANSACTION_FAILED) { 118 if (status.getStatus() != STATUS_DEAD_OBJECT) { 119 // STATUS_DEAD_OBJECT is fatal and should not return TRANSACTION_ERROR. 120 return ClientStatusError(ErrorCode::TRANSACTION_ERROR) 121 << msg << ", error: " << status.getDescription(); 122 } 123 } 124 return ClientStatusError(statusCode) << msg << ", error: " << status.getDescription(); 125 } 126 127 private: 128 friend class aidl_test::AidlVhalClientTest; 129 130 class ILinkUnlinkToDeath { 131 public: 132 virtual ~ILinkUnlinkToDeath() = default; 133 virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 134 void* cookie) = 0; 135 virtual void deleteDeathRecipient(AIBinder_DeathRecipient* recipient) = 0; 136 virtual void setOnUnlinked(AIBinder_DeathRecipient* recipient, 137 AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) = 0; 138 }; 139 140 class DefaultLinkUnlinkImpl final : public ILinkUnlinkToDeath { 141 public: 142 binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 143 void* cookie) override; 144 void deleteDeathRecipient(AIBinder_DeathRecipient* recipient) override; 145 void setOnUnlinked(AIBinder_DeathRecipient* recipient, 146 AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) override; 147 }; 148 149 // A thread-safe class to hold a list of onBinderDied callbacks. 150 class BinderDiedCallbacks final { 151 public: 152 void addCallback(std::shared_ptr<OnBinderDiedCallbackFunc> callback); 153 void invokeCallbacks(); 154 VhalClientResult<void> removeCallback(std::shared_ptr<OnBinderDiedCallbackFunc> callback); 155 void clear(); 156 size_t count(); 157 158 private: 159 std::mutex mBinderDiedCallbacksLock; 160 std::unordered_set<std::shared_ptr<OnBinderDiedCallbackFunc>> mCallbacks 161 GUARDED_BY(mBinderDiedCallbacksLock); 162 }; 163 164 // The cookie structure whose lifecycle is managed by libbinder library. It will be 165 // freed when onBinderUnlinked is called. 166 // This class is thread-safe. 167 class BinderDeathRecipientCookie final { 168 public: 169 BinderDeathRecipientCookie(std::shared_ptr<BinderDiedCallbacks> BinderDiedCallbacks); 170 void onBinderDied(); 171 void onBinderUnlinked(); 172 173 private: 174 // A weak reference to the callbacks wrapper managed by AidlVhalClient. 175 std::weak_ptr<BinderDiedCallbacks> mCallbacksRef; 176 }; 177 178 std::atomic<int64_t> mRequestId = 0; 179 std::shared_ptr<GetSetValueClient> mGetSetValueClient; 180 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal; 181 std::unique_ptr<ILinkUnlinkToDeath> mLinkUnlinkImpl; 182 ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; 183 184 // BinderDiedCallbacks is thread-safe. 185 std::shared_ptr<BinderDiedCallbacks> mOnBinderDiedCallbacks; 186 187 // For test-only. 188 int32_t mTestRemoteInterfaceVersion = 0; 189 190 static void onBinderDied(void* cookie); 191 static void onBinderUnlinked(void* cookie); 192 193 bool linkToDeath(); 194 void onBinderDiedWithContext(); 195 void onBinderUnlinkedWithContext(); 196 197 VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> parseVehiclePropConfigs( 198 const aidl::android::hardware::automotive::vehicle::VehiclePropConfigs& configs); 199 200 // Test-only functions: 201 AidlVhalClient(std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal, 202 int64_t timeoutInMs, std::unique_ptr<ILinkUnlinkToDeath> linkUnlinkImpl); 203 size_t countOnBinderDiedCallbacks(); 204 setTestRemoteInterfaceVersion(int version)205 void setTestRemoteInterfaceVersion(int version) { mTestRemoteInterfaceVersion = version; } 206 }; 207 208 class GetSetValueClient final : 209 public aidl::android::hardware::automotive::vehicle::BnVehicleCallback { 210 public: 211 struct PendingGetValueRequest { 212 std::shared_ptr<AidlVhalClient::GetValueCallbackFunc> callback; 213 int32_t propId; 214 int32_t areaId; 215 }; 216 217 struct PendingSetValueRequest { 218 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> callback; 219 int32_t propId; 220 int32_t areaId; 221 }; 222 223 GetSetValueClient(int64_t timeoutInNs, 224 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal); 225 226 ~GetSetValueClient(); 227 228 ndk::ScopedAStatus onGetValues( 229 const aidl::android::hardware::automotive::vehicle::GetValueResults& results) override; 230 ndk::ScopedAStatus onSetValues( 231 const aidl::android::hardware::automotive::vehicle::SetValueResults& results) override; 232 ndk::ScopedAStatus onPropertyEvent( 233 const aidl::android::hardware::automotive::vehicle::VehiclePropValues& values, 234 int32_t sharedMemoryCount) override; 235 ndk::ScopedAStatus onPropertySetError( 236 const aidl::android::hardware::automotive::vehicle::VehiclePropErrors& errors) override; 237 ndk::ScopedAStatus onSupportedValueChange( 238 const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>& 239 propIdAreaIds) override; 240 241 void getValue(int64_t requestId, const IHalPropValue& requestValue, 242 std::shared_ptr<AidlVhalClient::GetValueCallbackFunc> clientCallback, 243 std::shared_ptr<GetSetValueClient> vhalCallback); 244 void setValue(int64_t requestId, const IHalPropValue& requestValue, 245 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> clientCallback, 246 std::shared_ptr<GetSetValueClient> vhalCallback); 247 248 private: 249 std::mutex mLock; 250 std::unordered_map<int64_t, std::unique_ptr<PendingGetValueRequest>> mPendingGetValueCallbacks 251 GUARDED_BY(mLock); 252 std::unordered_map<int64_t, std::unique_ptr<PendingSetValueRequest>> mPendingSetValueCallbacks 253 GUARDED_BY(mLock); 254 std::unique_ptr<hardware::automotive::vehicle::PendingRequestPool> mPendingRequestPool; 255 std::shared_ptr<android::hardware::automotive::vehicle::PendingRequestPool::TimeoutCallbackFunc> 256 mOnGetValueTimeout; 257 std::shared_ptr<android::hardware::automotive::vehicle::PendingRequestPool::TimeoutCallbackFunc> 258 mOnSetValueTimeout; 259 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal; 260 261 // Add a new GetValue pending request. 262 void addGetValueRequest(int64_t requestId, const IHalPropValue& requestValue, 263 std::shared_ptr<AidlVhalClient::GetValueCallbackFunc> callback); 264 // Add a new SetValue pending request. 265 void addSetValueRequest(int64_t requestId, const IHalPropValue& requestValue, 266 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> callback); 267 // Try to finish the pending GetValue request according to the requestId. If there is an 268 // existing pending request, the request would be finished and returned. Otherwise, if the 269 // request has already timed-out, nullptr would be returned. 270 std::unique_ptr<PendingGetValueRequest> tryFinishGetValueRequest(int64_t requestId); 271 // Try to finish the pending SetValue request according to the requestId. If there is an 272 // existing pending request, the request would be finished and returned. Otherwise, if the 273 // request has already timed-out, nullptr would be returned. 274 std::unique_ptr<PendingSetValueRequest> tryFinishSetValueRequest(int64_t requestId); 275 276 template <class T> 277 std::unique_ptr<T> tryFinishRequest(int64_t requestId, 278 std::unordered_map<int64_t, std::unique_ptr<T>>* callbacks) 279 REQUIRES(mLock); 280 281 void onGetValue(const aidl::android::hardware::automotive::vehicle::GetValueResult& result); 282 void onSetValue(const aidl::android::hardware::automotive::vehicle::SetValueResult& result); 283 284 template <class T> 285 void onTimeout(const std::unordered_set<int64_t>& requestIds, 286 std::unordered_map<int64_t, std::unique_ptr<T>>* callbacks); 287 }; 288 289 class SubscriptionVehicleCallback final : 290 public aidl::android::hardware::automotive::vehicle::BnVehicleCallback { 291 public: 292 explicit SubscriptionVehicleCallback(std::shared_ptr<ISubscriptionCallback> callback); 293 294 ndk::ScopedAStatus onGetValues( 295 const aidl::android::hardware::automotive::vehicle::GetValueResults& results) override; 296 ndk::ScopedAStatus onSetValues( 297 const aidl::android::hardware::automotive::vehicle::SetValueResults& results) override; 298 ndk::ScopedAStatus onPropertyEvent( 299 const aidl::android::hardware::automotive::vehicle::VehiclePropValues& values, 300 int32_t sharedMemoryCount) override; 301 ndk::ScopedAStatus onPropertySetError( 302 const aidl::android::hardware::automotive::vehicle::VehiclePropErrors& errors) override; 303 ndk::ScopedAStatus onSupportedValueChange( 304 const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>& 305 propIdAreaIds) override; 306 307 private: 308 std::shared_ptr<ISubscriptionCallback> mCallback; 309 }; 310 311 class AidlSubscriptionClient final : public internal::SubscriptionClient { 312 public: 313 ~AidlSubscriptionClient(); 314 315 AidlSubscriptionClient( 316 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal, 317 std::shared_ptr<ISubscriptionCallback> callback); 318 319 VhalClientResult<void> subscribe( 320 const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>& 321 options) override EXCLUDES(mLock); 322 VhalClientResult<void> unsubscribe(const std::vector<int32_t>& propIds) override 323 EXCLUDES(mLock); 324 void unsubscribeAll() override EXCLUDES(mLock); 325 326 protected: 327 std::unordered_set<int32_t> getSubscribedPropIds() override; 328 329 private: 330 std::shared_ptr<SubscriptionVehicleCallback> mSubscriptionCallback; 331 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal; 332 333 std::mutex mLock; 334 std::unordered_set<int32_t> mSubscribedPropIds GUARDED_BY(mLock); 335 336 VhalClientResult<void> unsubscribeLocked(const std::vector<int32_t>& propIds) REQUIRES(mLock); 337 }; 338 339 } // namespace vhal 340 } // namespace automotive 341 } // namespace frameworks 342 } // namespace android 343 344 #endif // CPP_VHAL_CLIENT_INCLUDE_AIDLVHALCLIENT_H_ 345