• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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