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