• 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 <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