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 <memory> 33 #include <mutex> // NOLINT 34 #include <unordered_map> 35 #include <unordered_set> 36 37 namespace android { 38 namespace frameworks { 39 namespace automotive { 40 namespace vhal { 41 42 namespace aidl_test { 43 44 class AidlVhalClientTest; 45 46 } // namespace aidl_test 47 48 class GetSetValueClient; 49 50 class AidlVhalClient final : public IVhalClient { 51 public: 52 constexpr static char AIDL_VHAL_SERVICE[] = 53 "android.hardware.automotive.vehicle.IVehicle/default"; 54 55 static std::shared_ptr<IVhalClient> create(); 56 static std::shared_ptr<IVhalClient> tryCreate(); 57 static std::shared_ptr<IVhalClient> tryCreate(const char* descriptor); 58 59 explicit AidlVhalClient( 60 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal); 61 62 AidlVhalClient(std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal, 63 int64_t timeoutInMs); 64 65 ~AidlVhalClient(); 66 67 bool isAidlVhal() override; 68 69 std::unique_ptr<IHalPropValue> createHalPropValue(int32_t propId) override; 70 71 std::unique_ptr<IHalPropValue> createHalPropValue(int32_t propId, int32_t areaId) override; 72 73 void getValue(const IHalPropValue& requestValue, 74 std::shared_ptr<GetValueCallbackFunc> callback) override; 75 76 void setValue(const IHalPropValue& value, 77 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> callback) override; 78 79 // Add the callback that would be called when VHAL binder died. 80 VhalClientResult<void> addOnBinderDiedCallback( 81 std::shared_ptr<OnBinderDiedCallbackFunc> callback) override; 82 83 // Remove a previously added OnBinderDied callback. 84 VhalClientResult<void> removeOnBinderDiedCallback( 85 std::shared_ptr<OnBinderDiedCallbackFunc> callback) override; 86 87 VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> getAllPropConfigs() override; 88 VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> getPropConfigs( 89 std::vector<int32_t> propIds) override; 90 91 std::unique_ptr<ISubscriptionClient> getSubscriptionClient( 92 std::shared_ptr<ISubscriptionCallback> callback) override; 93 94 // Converts a non-okay status to an error {@code Result}. 95 template <class T> statusToError(const ndk::ScopedAStatus & status,const std::string & msg)96 inline static VhalClientResult<T> statusToError(const ndk::ScopedAStatus& status, 97 const std::string& msg) { 98 using StatusCode = aidl::android::hardware::automotive::vehicle::StatusCode; 99 StatusCode statusCode = StatusCode::INTERNAL_ERROR; 100 if (status.getExceptionCode() == EX_SERVICE_SPECIFIC) { 101 statusCode = static_cast<StatusCode>(status.getServiceSpecificError()); 102 } else if (status.getExceptionCode() == EX_TRANSACTION_FAILED) { 103 if (status.getStatus() != STATUS_DEAD_OBJECT) { 104 // STATUS_DEAD_OBJECT is fatal and should not return TRANSACTION_ERROR. 105 return ClientStatusError(ErrorCode::TRANSACTION_ERROR) 106 << msg << ", error: " << status.getDescription(); 107 } 108 } 109 return ClientStatusError(statusCode) << msg << ", error: " << status.getDescription(); 110 } 111 112 private: 113 friend class aidl_test::AidlVhalClientTest; 114 115 class ILinkUnlinkToDeath { 116 public: 117 virtual ~ILinkUnlinkToDeath() = default; 118 virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 119 void* cookie) = 0; 120 virtual binder_status_t unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 121 void* cookie) = 0; 122 }; 123 124 class DefaultLinkUnlinkImpl final : public ILinkUnlinkToDeath { 125 public: 126 binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 127 void* cookie) override; 128 binder_status_t unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, 129 void* cookie) override; 130 }; 131 132 std::atomic<int64_t> mRequestId = 0; 133 std::shared_ptr<GetSetValueClient> mGetSetValueClient; 134 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal; 135 std::unique_ptr<ILinkUnlinkToDeath> mLinkUnlinkImpl; 136 ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; 137 138 std::mutex mLock; 139 std::unordered_set<std::shared_ptr<OnBinderDiedCallbackFunc>> mOnBinderDiedCallbacks 140 GUARDED_BY(mLock); 141 142 static void onBinderDied(void* cookie); 143 static void onBinderUnlinked(void* cookie); 144 145 void onBinderDiedWithContext(); 146 void onBinderUnlinkedWithContext(); 147 148 VhalClientResult<std::vector<std::unique_ptr<IHalPropConfig>>> parseVehiclePropConfigs( 149 const aidl::android::hardware::automotive::vehicle::VehiclePropConfigs& configs); 150 151 // Test-only functions: 152 AidlVhalClient(std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal, 153 int64_t timeoutInMs, std::unique_ptr<ILinkUnlinkToDeath> linkUnlinkImpl); 154 size_t countOnBinderDiedCallbacks(); 155 }; 156 157 class GetSetValueClient final : 158 public aidl::android::hardware::automotive::vehicle::BnVehicleCallback { 159 public: 160 struct PendingGetValueRequest { 161 std::shared_ptr<AidlVhalClient::GetValueCallbackFunc> callback; 162 int32_t propId; 163 int32_t areaId; 164 }; 165 166 struct PendingSetValueRequest { 167 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> callback; 168 int32_t propId; 169 int32_t areaId; 170 }; 171 172 GetSetValueClient(int64_t timeoutInNs, 173 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal); 174 175 ~GetSetValueClient(); 176 177 ndk::ScopedAStatus onGetValues( 178 const aidl::android::hardware::automotive::vehicle::GetValueResults& results) override; 179 ndk::ScopedAStatus onSetValues( 180 const aidl::android::hardware::automotive::vehicle::SetValueResults& results) override; 181 ndk::ScopedAStatus onPropertyEvent( 182 const aidl::android::hardware::automotive::vehicle::VehiclePropValues& values, 183 int32_t sharedMemoryCount) override; 184 ndk::ScopedAStatus onPropertySetError( 185 const aidl::android::hardware::automotive::vehicle::VehiclePropErrors& errors) override; 186 187 void getValue(int64_t requestId, const IHalPropValue& requestValue, 188 std::shared_ptr<AidlVhalClient::GetValueCallbackFunc> clientCallback, 189 std::shared_ptr<GetSetValueClient> vhalCallback); 190 void setValue(int64_t requestId, const IHalPropValue& requestValue, 191 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> clientCallback, 192 std::shared_ptr<GetSetValueClient> vhalCallback); 193 194 private: 195 std::mutex mLock; 196 std::unordered_map<int64_t, std::unique_ptr<PendingGetValueRequest>> mPendingGetValueCallbacks 197 GUARDED_BY(mLock); 198 std::unordered_map<int64_t, std::unique_ptr<PendingSetValueRequest>> mPendingSetValueCallbacks 199 GUARDED_BY(mLock); 200 std::unique_ptr<hardware::automotive::vehicle::PendingRequestPool> mPendingRequestPool; 201 std::shared_ptr<android::hardware::automotive::vehicle::PendingRequestPool::TimeoutCallbackFunc> 202 mOnGetValueTimeout; 203 std::shared_ptr<android::hardware::automotive::vehicle::PendingRequestPool::TimeoutCallbackFunc> 204 mOnSetValueTimeout; 205 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal; 206 207 // Add a new GetValue pending request. 208 void addGetValueRequest(int64_t requestId, const IHalPropValue& requestValue, 209 std::shared_ptr<AidlVhalClient::GetValueCallbackFunc> callback); 210 // Add a new SetValue pending request. 211 void addSetValueRequest(int64_t requestId, const IHalPropValue& requestValue, 212 std::shared_ptr<AidlVhalClient::SetValueCallbackFunc> callback); 213 // Try to finish the pending GetValue request according to the requestId. If there is an 214 // existing pending request, the request would be finished and returned. Otherwise, if the 215 // request has already timed-out, nullptr would be returned. 216 std::unique_ptr<PendingGetValueRequest> tryFinishGetValueRequest(int64_t requestId); 217 // Try to finish the pending SetValue request according to the requestId. If there is an 218 // existing pending request, the request would be finished and returned. Otherwise, if the 219 // request has already timed-out, nullptr would be returned. 220 std::unique_ptr<PendingSetValueRequest> tryFinishSetValueRequest(int64_t requestId); 221 222 template <class T> 223 std::unique_ptr<T> tryFinishRequest(int64_t requestId, 224 std::unordered_map<int64_t, std::unique_ptr<T>>* callbacks) 225 REQUIRES(mLock); 226 227 void onGetValue(const aidl::android::hardware::automotive::vehicle::GetValueResult& result); 228 void onSetValue(const aidl::android::hardware::automotive::vehicle::SetValueResult& result); 229 230 template <class T> 231 void onTimeout(const std::unordered_set<int64_t>& requestIds, 232 std::unordered_map<int64_t, std::unique_ptr<T>>* callbacks); 233 }; 234 235 class SubscriptionVehicleCallback final : 236 public aidl::android::hardware::automotive::vehicle::BnVehicleCallback { 237 public: 238 explicit SubscriptionVehicleCallback(std::shared_ptr<ISubscriptionCallback> callback); 239 240 ndk::ScopedAStatus onGetValues( 241 const aidl::android::hardware::automotive::vehicle::GetValueResults& results) override; 242 ndk::ScopedAStatus onSetValues( 243 const aidl::android::hardware::automotive::vehicle::SetValueResults& results) override; 244 ndk::ScopedAStatus onPropertyEvent( 245 const aidl::android::hardware::automotive::vehicle::VehiclePropValues& values, 246 int32_t sharedMemoryCount) override; 247 ndk::ScopedAStatus onPropertySetError( 248 const aidl::android::hardware::automotive::vehicle::VehiclePropErrors& errors) override; 249 250 private: 251 std::shared_ptr<ISubscriptionCallback> mCallback; 252 }; 253 254 class AidlSubscriptionClient final : public ISubscriptionClient { 255 public: 256 ~AidlSubscriptionClient() = default; 257 258 AidlSubscriptionClient( 259 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> hal, 260 std::shared_ptr<ISubscriptionCallback> callback); 261 262 VhalClientResult<void> subscribe( 263 const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>& 264 options) override; 265 VhalClientResult<void> unsubscribe(const std::vector<int32_t>& propIds) override; 266 267 private: 268 std::shared_ptr<SubscriptionVehicleCallback> mSubscriptionCallback; 269 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicle> mHal; 270 }; 271 272 } // namespace vhal 273 } // namespace automotive 274 } // namespace frameworks 275 } // namespace android 276 277 #endif // CPP_VHAL_CLIENT_INCLUDE_AIDLVHALCLIENT_H_ 278