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(); 57 static std::shared_ptr<IVhalClient> tryCreate(); 58 static std::shared_ptr<IVhalClient> tryCreate(const char* descriptor); 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 int32_t getRemoteInterfaceVersion() override; 96 97 // Converts a non-okay status to an error {@code Result}. 98 template <class T> statusToError(const ndk::ScopedAStatus & status,const std::string & msg)99 inline static VhalClientResult<T> statusToError(const ndk::ScopedAStatus& status, 100 const std::string& msg) { 101 using StatusCode = aidl::android::hardware::automotive::vehicle::StatusCode; 102 StatusCode statusCode = StatusCode::INTERNAL_ERROR; 103 if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) { 104 statusCode = static_cast<StatusCode>(status.getServiceSpecificError()); 105 } else if (status.getExceptionCode() == EX_TRANSACTION_FAILED) { 106 if (status.getStatus() != STATUS_DEAD_OBJECT) { 107 // STATUS_DEAD_OBJECT is fatal and should not return TRANSACTION_ERROR. 108 return ClientStatusError(ErrorCode::TRANSACTION_ERROR) 109 << msg << ", error: " << status.getDescription(); 110 } 111 } 112 return ClientStatusError(statusCode) << msg << ", error: " << status.getDescription(); 113 } 114 115 private: 116 friend class aidl_test::AidlVhalClientTest; 117 118 class ILinkUnlinkToDeath { 119 public: 120 virtual ~ILinkUnlinkToDeath() = default; 121 virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 122 void* cookie) = 0; 123 virtual void deleteDeathRecipient(AIBinder_DeathRecipient* recipient) = 0; 124 virtual void setOnUnlinked(AIBinder_DeathRecipient* recipient, 125 AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) = 0; 126 }; 127 128 class DefaultLinkUnlinkImpl final : public ILinkUnlinkToDeath { 129 public: 130 binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 131 void* cookie) override; 132 void deleteDeathRecipient(AIBinder_DeathRecipient* recipient) override; 133 void setOnUnlinked(AIBinder_DeathRecipient* recipient, 134 AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) override; 135 }; 136 137 std::atomic<int64_t> mRequestId = 0; 138 std::shared_ptr<GetSetValueClient> mGetSetValueClient; 139 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal; 140 std::unique_ptr<ILinkUnlinkToDeath> mLinkUnlinkImpl; 141 ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; 142 143 std::mutex mLock; 144 std::unordered_set<std::shared_ptr<OnBinderDiedCallbackFunc>> mOnBinderDiedCallbacks 145 GUARDED_BY(mLock); 146 std::condition_variable mDeathRecipientUnlinkedCv; 147 bool mDeathRecipientUnlinked GUARDED_BY(mLock) = false; 148 149 static void onBinderDied(void* cookie); 150 static void onBinderUnlinked(void* cookie); 151 152 void onBinderDiedWithContext(); 153 void onBinderUnlinkedWithContext(); 154 155 VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> parseVehiclePropConfigs( 156 const aidl::android::hardware::automotive::vehicle::VehiclePropConfigs& configs); 157 158 // Test-only functions: 159 AidlVhalClient(std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal, 160 int64_t timeoutInMs, std::unique_ptr<ILinkUnlinkToDeath> linkUnlinkImpl); 161 size_t countOnBinderDiedCallbacks(); 162 }; 163 164 class GetSetValueClient final : 165 public aidl::android::hardware::automotive::vehicle::BnVehicleCallback { 166 public: 167 struct PendingGetValueRequest { 168 std::shared_ptr<AidlVhalClient::GetValueCallbackFunc> callback; 169 int32_t propId; 170 int32_t areaId; 171 }; 172 173 struct PendingSetValueRequest { 174 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> callback; 175 int32_t propId; 176 int32_t areaId; 177 }; 178 179 GetSetValueClient(int64_t timeoutInNs, 180 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal); 181 182 ~GetSetValueClient(); 183 184 ndk::ScopedAStatus onGetValues( 185 const aidl::android::hardware::automotive::vehicle::GetValueResults& results) override; 186 ndk::ScopedAStatus onSetValues( 187 const aidl::android::hardware::automotive::vehicle::SetValueResults& results) override; 188 ndk::ScopedAStatus onPropertyEvent( 189 const aidl::android::hardware::automotive::vehicle::VehiclePropValues& values, 190 int32_t sharedMemoryCount) override; 191 ndk::ScopedAStatus onPropertySetError( 192 const aidl::android::hardware::automotive::vehicle::VehiclePropErrors& errors) override; 193 ndk::ScopedAStatus onSupportedValueChange( 194 const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>& 195 propIdAreaIds) override; 196 197 void getValue(int64_t requestId, const IHalPropValue& requestValue, 198 std::shared_ptr<AidlVhalClient::GetValueCallbackFunc> clientCallback, 199 std::shared_ptr<GetSetValueClient> vhalCallback); 200 void setValue(int64_t requestId, const IHalPropValue& requestValue, 201 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> clientCallback, 202 std::shared_ptr<GetSetValueClient> vhalCallback); 203 204 private: 205 std::mutex mLock; 206 std::unordered_map<int64_t, std::unique_ptr<PendingGetValueRequest>> mPendingGetValueCallbacks 207 GUARDED_BY(mLock); 208 std::unordered_map<int64_t, std::unique_ptr<PendingSetValueRequest>> mPendingSetValueCallbacks 209 GUARDED_BY(mLock); 210 std::unique_ptr<hardware::automotive::vehicle::PendingRequestPool> mPendingRequestPool; 211 std::shared_ptr<android::hardware::automotive::vehicle::PendingRequestPool::TimeoutCallbackFunc> 212 mOnGetValueTimeout; 213 std::shared_ptr<android::hardware::automotive::vehicle::PendingRequestPool::TimeoutCallbackFunc> 214 mOnSetValueTimeout; 215 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal; 216 217 // Add a new GetValue pending request. 218 void addGetValueRequest(int64_t requestId, const IHalPropValue& requestValue, 219 std::shared_ptr<AidlVhalClient::GetValueCallbackFunc> callback); 220 // Add a new SetValue pending request. 221 void addSetValueRequest(int64_t requestId, const IHalPropValue& requestValue, 222 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> callback); 223 // Try to finish the pending GetValue request according to the requestId. If there is an 224 // existing pending request, the request would be finished and returned. Otherwise, if the 225 // request has already timed-out, nullptr would be returned. 226 std::unique_ptr<PendingGetValueRequest> tryFinishGetValueRequest(int64_t requestId); 227 // Try to finish the pending SetValue request according to the requestId. If there is an 228 // existing pending request, the request would be finished and returned. Otherwise, if the 229 // request has already timed-out, nullptr would be returned. 230 std::unique_ptr<PendingSetValueRequest> tryFinishSetValueRequest(int64_t requestId); 231 232 template <class T> 233 std::unique_ptr<T> tryFinishRequest(int64_t requestId, 234 std::unordered_map<int64_t, std::unique_ptr<T>>* callbacks) 235 REQUIRES(mLock); 236 237 void onGetValue(const aidl::android::hardware::automotive::vehicle::GetValueResult& result); 238 void onSetValue(const aidl::android::hardware::automotive::vehicle::SetValueResult& result); 239 240 template <class T> 241 void onTimeout(const std::unordered_set<int64_t>& requestIds, 242 std::unordered_map<int64_t, std::unique_ptr<T>>* callbacks); 243 }; 244 245 class SubscriptionVehicleCallback final : 246 public aidl::android::hardware::automotive::vehicle::BnVehicleCallback { 247 public: 248 explicit SubscriptionVehicleCallback(std::shared_ptr<ISubscriptionCallback> callback); 249 250 ndk::ScopedAStatus onGetValues( 251 const aidl::android::hardware::automotive::vehicle::GetValueResults& results) override; 252 ndk::ScopedAStatus onSetValues( 253 const aidl::android::hardware::automotive::vehicle::SetValueResults& results) override; 254 ndk::ScopedAStatus onPropertyEvent( 255 const aidl::android::hardware::automotive::vehicle::VehiclePropValues& values, 256 int32_t sharedMemoryCount) override; 257 ndk::ScopedAStatus onPropertySetError( 258 const aidl::android::hardware::automotive::vehicle::VehiclePropErrors& errors) override; 259 ndk::ScopedAStatus onSupportedValueChange( 260 const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>& 261 propIdAreaIds) override; 262 263 private: 264 std::shared_ptr<ISubscriptionCallback> mCallback; 265 }; 266 267 class AidlSubscriptionClient final : public ISubscriptionClient { 268 public: 269 ~AidlSubscriptionClient() = default; 270 271 AidlSubscriptionClient( 272 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal, 273 std::shared_ptr<ISubscriptionCallback> callback); 274 275 VhalClientResult<void> subscribe( 276 const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>& 277 options) override; 278 VhalClientResult<void> unsubscribe(const std::vector<int32_t>& propIds) override; 279 280 private: 281 std::shared_ptr<SubscriptionVehicleCallback> mSubscriptionCallback; 282 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal; 283 }; 284 285 } // namespace vhal 286 } // namespace automotive 287 } // namespace frameworks 288 } // namespace android 289 290 #endif // CPP_VHAL_CLIENT_INCLUDE_AIDLVHALCLIENT_H_ 291