• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
18 #define android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
19 
20 #include <ConnectedClient.h>
21 #include <ParcelableUtils.h>
22 #include <PendingRequestPool.h>
23 #include <RecurrentTimer.h>
24 #include <SubscriptionManager.h>
25 
26 #include <ConcurrentQueue.h>
27 #include <IVehicleHardware.h>
28 #include <VehicleUtils.h>
29 #include <aidl/android/hardware/automotive/vehicle/BnVehicle.h>
30 #include <android-base/expected.h>
31 #include <android-base/thread_annotations.h>
32 #include <android/binder_auto_utils.h>
33 
34 #include <memory>
35 #include <mutex>
36 #include <shared_mutex>
37 #include <unordered_map>
38 #include <vector>
39 
40 namespace android {
41 namespace hardware {
42 namespace automotive {
43 namespace vehicle {
44 
45 class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehicle::BnVehicle {
46   public:
47     using CallbackType =
48             std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
49 
50     explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
51 
52     ~DefaultVehicleHal();
53 
54     ndk::ScopedAStatus getAllPropConfigs(
55             aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
56             override;
57     ndk::ScopedAStatus getValues(
58             const CallbackType& callback,
59             const aidl::android::hardware::automotive::vehicle::GetValueRequests& requests)
60             override;
61     ndk::ScopedAStatus setValues(
62             const CallbackType& callback,
63             const aidl::android::hardware::automotive::vehicle::SetValueRequests& requests)
64             override;
65     ndk::ScopedAStatus getPropConfigs(
66             const std::vector<int32_t>& props,
67             aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
68             override;
69     ndk::ScopedAStatus subscribe(
70             const CallbackType& callback,
71             const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
72                     options,
73             int32_t maxSharedMemoryFileCount) override;
74     ndk::ScopedAStatus unsubscribe(const CallbackType& callback,
75                                    const std::vector<int32_t>& propIds) override;
76     ndk::ScopedAStatus returnSharedMemory(const CallbackType& callback,
77                                           int64_t sharedMemoryId) override;
78     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
79 
80     IVehicleHardware* getHardware();
81 
82   private:
83     // friend class for unit testing.
84     friend class DefaultVehicleHalTest;
85 
86     using GetValuesClient =
87             GetSetValuesClient<aidl::android::hardware::automotive::vehicle::GetValueResult,
88                                aidl::android::hardware::automotive::vehicle::GetValueResults>;
89     using SetValuesClient =
90             GetSetValuesClient<aidl::android::hardware::automotive::vehicle::SetValueResult,
91                                aidl::android::hardware::automotive::vehicle::SetValueResults>;
92 
93     // A thread safe class to maintain an increasing request ID for each subscribe client. This
94     // class is safe to pass to async callbacks.
95     class SubscribeIdByClient {
96       public:
97         int64_t getId(const CallbackType& callback);
98 
99       private:
100         std::mutex mLock;
101         std::unordered_map<const AIBinder*, int64_t> mIds GUARDED_BY(mLock);
102     };
103 
104     // A thread safe class to store all subscribe clients. This class is safe to pass to async
105     // callbacks.
106     class SubscriptionClients {
107       public:
SubscriptionClients(std::shared_ptr<PendingRequestPool> pool)108         SubscriptionClients(std::shared_ptr<PendingRequestPool> pool) : mPendingRequestPool(pool) {}
109 
110         std::shared_ptr<SubscriptionClient> maybeAddClient(const CallbackType& callback);
111 
112         std::shared_ptr<SubscriptionClient> getClient(const CallbackType& callback);
113 
114         void removeClient(const AIBinder* clientId);
115 
116         size_t countClients();
117 
118       private:
119         std::mutex mLock;
120         std::unordered_map<const AIBinder*, std::shared_ptr<SubscriptionClient>> mClients
121                 GUARDED_BY(mLock);
122         // PendingRequestPool is thread-safe.
123         std::shared_ptr<PendingRequestPool> mPendingRequestPool;
124     };
125 
126     // A wrapper for binder operations to enable stubbing for test.
127     class IBinder {
128       public:
129         virtual ~IBinder() = default;
130 
131         virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
132                                             void* cookie) = 0;
133 
134         virtual bool isAlive(const AIBinder* binder) = 0;
135     };
136 
137     // A real implementation for IBinder.
138     class AIBinderImpl final : public IBinder {
139       public:
140         binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
141                                     void* cookie) override;
142 
143         bool isAlive(const AIBinder* binder) override;
144     };
145 
146     // OnBinderDiedContext is a type used as a cookie passed deathRecipient. The deathRecipient's
147     // onBinderDied function takes only a cookie as input and we have to store all the contexts
148     // as the cookie.
149     struct OnBinderDiedContext {
150         DefaultVehicleHal* vhal;
151         const AIBinder* clientId;
152     };
153 
154     // BinderDiedUnlinkedEvent represents either an onBinderDied or an onBinderUnlinked event.
155     struct BinderDiedUnlinkedEvent {
156         // true for onBinderDied, false for onBinderUnlinked.
157         bool onBinderDied;
158         const AIBinder* clientId;
159     };
160 
161     // The default timeout of get or set value requests is 30s.
162     // TODO(b/214605968): define TIMEOUT_IN_NANO in IVehicle and allow getValues/setValues/subscribe
163     // to specify custom timeouts.
164     static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000;
165     // heart beat event interval: 3s
166     static constexpr int64_t HEART_BEAT_INTERVAL_IN_NANO = 3'000'000'000;
167     std::unique_ptr<IVehicleHardware> mVehicleHardware;
168 
169     // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to
170     // lock guard them.
171     std::unordered_map<int32_t, aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
172             mConfigsByPropId;
173     // Only modified in constructor, so thread-safe.
174     std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile;
175     // PendingRequestPool is thread-safe.
176     std::shared_ptr<PendingRequestPool> mPendingRequestPool;
177     // SubscriptionManager is thread-safe.
178     std::shared_ptr<SubscriptionManager> mSubscriptionManager;
179 
180     std::mutex mLock;
181     std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
182             GUARDED_BY(mLock);
183     std::unordered_map<const AIBinder*, std::shared_ptr<GetValuesClient>> mGetValuesClients
184             GUARDED_BY(mLock);
185     std::unordered_map<const AIBinder*, std::shared_ptr<SetValuesClient>> mSetValuesClients
186             GUARDED_BY(mLock);
187     // SubscriptionClients is thread-safe.
188     std::shared_ptr<SubscriptionClients> mSubscriptionClients;
189     // mBinderImpl is only going to be changed in test.
190     std::unique_ptr<IBinder> mBinderImpl;
191 
192     // Only initialized once.
193     std::shared_ptr<std::function<void()>> mRecurrentAction;
194     // RecurrentTimer is thread-safe.
195     RecurrentTimer mRecurrentTimer;
196 
197     ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
198 
199     // ConcurrentQueue is thread-safe.
200     ConcurrentQueue<BinderDiedUnlinkedEvent> mBinderEvents;
201 
202     // A thread to handle onBinderDied or onBinderUnlinked event.
203     std::thread mOnBinderDiedUnlinkedHandlerThread;
204 
205     android::base::Result<void> checkProperty(
206             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
207 
208     android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
209             const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>&
210                     requests);
211 
212     android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
213             const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
214                     requests);
215 
216     VhalResult<void> checkSubscribeOptions(
217             const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
218                     options);
219 
220     VhalResult<void> checkReadPermission(
221             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
222 
223     VhalResult<void> checkWritePermission(
224             const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
225 
226     android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*>
227     getConfig(int32_t propId) const;
228 
229     void onBinderDiedWithContext(const AIBinder* clientId);
230 
231     void onBinderUnlinkedWithContext(const AIBinder* clientId);
232 
233     // Registers a onBinderDied callback for the client if not already registered.
234     // Returns true if the client Binder is alive, false otherwise.
235     bool monitorBinderLifeCycleLocked(const AIBinder* clientId) REQUIRES(mLock);
236 
237     bool checkDumpPermission();
238 
239     // The looping handler function to process all onBinderDied or onBinderUnlinked events in
240     // mBinderEvents.
241     void onBinderDiedUnlinkedHandler();
242 
243     // Gets or creates a {@code T} object for the client to or from {@code clients}.
244     template <class T>
245     static std::shared_ptr<T> getOrCreateClient(
246             std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients,
247             const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool);
248 
249     static void onPropertyChangeEvent(
250             std::weak_ptr<SubscriptionManager> subscriptionManager,
251             const std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&
252                     updatedValues);
253 
254     static void checkHealth(IVehicleHardware* hardware,
255                             std::weak_ptr<SubscriptionManager> subscriptionManager);
256 
257     static void onBinderDied(void* cookie);
258 
259     static void onBinderUnlinked(void* cookie);
260 
261     // Test-only
262     // Set the default timeout for pending requests.
263     void setTimeout(int64_t timeoutInNano);
264 
265     // Test-only
266     void setBinderImpl(std::unique_ptr<IBinder> impl);
267 };
268 
269 }  // namespace vehicle
270 }  // namespace automotive
271 }  // namespace hardware
272 }  // namespace android
273 
274 #endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
275