• 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 <functional>
35 #include <memory>
36 #include <mutex>
37 #include <shared_mutex>
38 #include <unordered_map>
39 #include <vector>
40 
41 namespace android {
42 namespace hardware {
43 namespace automotive {
44 namespace vehicle {
45 
46 namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
47 
48 class DefaultVehicleHal final : public aidlvhal::BnVehicle {
49   public:
50     using CallbackType = std::shared_ptr<aidlvhal::IVehicleCallback>;
51 
52     explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
53 
54     // Test-only
55     DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware, int32_t testInterfaceVersion);
56 
57     ~DefaultVehicleHal();
58 
59     ndk::ScopedAStatus getAllPropConfigs(aidlvhal::VehiclePropConfigs* returnConfigs) override;
60     ndk::ScopedAStatus getValues(const CallbackType& callback,
61                                  const aidlvhal::GetValueRequests& requests) override;
62     ndk::ScopedAStatus setValues(const CallbackType& callback,
63                                  const aidlvhal::SetValueRequests& requests) override;
64     ndk::ScopedAStatus getPropConfigs(const std::vector<int32_t>& props,
65                                       aidlvhal::VehiclePropConfigs* returnConfigs) override;
66     ndk::ScopedAStatus subscribe(const CallbackType& callback,
67                                  const std::vector<aidlvhal::SubscribeOptions>& options,
68                                  int32_t maxSharedMemoryFileCount) override;
69     ndk::ScopedAStatus unsubscribe(const CallbackType& callback,
70                                    const std::vector<int32_t>& propIds) override;
71     ndk::ScopedAStatus returnSharedMemory(const CallbackType& callback,
72                                           int64_t sharedMemoryId) override;
73     ndk::ScopedAStatus getSupportedValuesLists(
74             const std::vector<aidlvhal::PropIdAreaId>& propIdAreaIds,
75             aidlvhal::SupportedValuesListResults* supportedValuesListResults) override;
76     ndk::ScopedAStatus getMinMaxSupportedValue(
77             const std::vector<aidlvhal::PropIdAreaId>& propIdAreaIds,
78             aidlvhal::MinMaxSupportedValueResults* minMaxSupportedValueResults) override;
79     ndk::ScopedAStatus registerSupportedValueChangeCallback(
80             const std::shared_ptr<aidlvhal::IVehicleCallback>& callback,
81             const std::vector<aidlvhal::PropIdAreaId>& propIdAreaIds) override;
82     ndk::ScopedAStatus unregisterSupportedValueChangeCallback(
83             const std::shared_ptr<aidlvhal::IVehicleCallback>& callback,
84             const std::vector<aidlvhal::PropIdAreaId>& propIdAreaIds) override;
85     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
86 
87     IVehicleHardware* getHardware();
88 
89   private:
90     // friend class for unit testing.
91     friend class DefaultVehicleHalTest;
92 
93     using GetValuesClient = GetSetValuesClient<aidlvhal::GetValueResult, aidlvhal::GetValueResults>;
94     using SetValuesClient = GetSetValuesClient<aidlvhal::SetValueResult, aidlvhal::SetValueResults>;
95 
96     // A wrapper for binder lifecycle operations to enable stubbing for test.
97     class BinderLifecycleInterface {
98       public:
99         virtual ~BinderLifecycleInterface() = default;
100 
101         virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
102                                             void* cookie) = 0;
103 
104         virtual bool isAlive(const AIBinder* binder) = 0;
105     };
106 
107     // A real implementation for BinderLifecycleInterface.
108     class BinderLifecycleHandler final : public BinderLifecycleInterface {
109       public:
110         binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
111                                     void* cookie) override;
112 
113         bool isAlive(const AIBinder* binder) override;
114     };
115 
116     // OnBinderDiedContext is a type used as a cookie passed deathRecipient. The deathRecipient's
117     // onBinderDied function takes only a cookie as input and we have to store all the contexts
118     // as the cookie.
119     struct OnBinderDiedContext {
120         DefaultVehicleHal* vhal;
121         const AIBinder* clientId;
122     };
123 
124     // BinderDiedUnlinkedEvent represents either an onBinderDied or an onBinderUnlinked event.
125     struct BinderDiedUnlinkedEvent {
126         // true for onBinderDied, false for onBinderUnlinked.
127         bool forOnBinderDied;
128         const AIBinder* clientId;
129     };
130 
131     // The default timeout of get or set value requests is 30s.
132     // TODO(b/214605968): define TIMEOUT_IN_NANO in IVehicle and allow getValues/setValues/subscribe
133     // to specify custom timeouts.
134     static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000;
135     // heart beat event interval: 3s
136     static constexpr int64_t HEART_BEAT_INTERVAL_IN_NANO = 3'000'000'000;
137     bool mShouldRefreshPropertyConfigs;
138     std::unique_ptr<IVehicleHardware> mVehicleHardware;
139 
140     // PendingRequestPool is thread-safe.
141     std::shared_ptr<PendingRequestPool> mPendingRequestPool;
142     // SubscriptionManager is thread-safe.
143     std::shared_ptr<SubscriptionManager> mSubscriptionManager;
144     // ConcurrentQueue is thread-safe.
145     std::shared_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>> mBatchedEventQueue;
146     // BatchingConsumer is thread-safe.
147     std::shared_ptr<BatchingConsumer<aidlvhal::VehiclePropValue>>
148             mPropertyChangeEventsBatchingConsumer;
149     // Only set once during initialization.
150     std::chrono::nanoseconds mEventBatchingWindow;
151     // Only used for testing.
152     int32_t mTestInterfaceVersion = 0;
153 
154     mutable std::atomic<bool> mConfigInit = false;
155     mutable std::shared_timed_mutex mConfigLock;
156     mutable std::unordered_map<int32_t, aidlvhal::VehiclePropConfig> mConfigsByPropId
157             GUARDED_BY(mConfigLock);
158     mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigLock);
159 
160     std::mutex mLock;
161     std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
162             GUARDED_BY(mLock);
163     std::unordered_map<const AIBinder*, std::shared_ptr<GetValuesClient>> mGetValuesClients
164             GUARDED_BY(mLock);
165     std::unordered_map<const AIBinder*, std::shared_ptr<SetValuesClient>> mSetValuesClients
166             GUARDED_BY(mLock);
167     // mBinderLifecycleHandler is only going to be changed in test.
168     std::unique_ptr<BinderLifecycleInterface> mBinderLifecycleHandler;
169 
170     // Only initialized once.
171     std::shared_ptr<std::function<void()>> mRecurrentAction;
172     // RecurrentTimer is thread-safe.
173     RecurrentTimer mRecurrentTimer;
174 
175     ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
176 
177     // ConcurrentQueue is thread-safe.
178     ConcurrentQueue<BinderDiedUnlinkedEvent> mBinderEvents;
179 
180     // A thread to handle onBinderDied or onBinderUnlinked event.
181     std::thread mOnBinderDiedUnlinkedHandlerThread;
182 
183     android::base::Result<void> checkProperty(const aidlvhal::VehiclePropValue& propValue);
184 
185     android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
186             const std::vector<aidlvhal::GetValueRequest>& requests);
187 
188     android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
189             const std::vector<aidlvhal::SetValueRequest>& requests);
190     VhalResult<void> checkSubscribeOptions(
191             const std::vector<aidlvhal::SubscribeOptions>& options,
192             const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId)
193             REQUIRES_SHARED(mConfigLock);
194 
195     VhalResult<void> checkPermissionHelper(const aidlvhal::VehiclePropValue& value,
196                                            aidlvhal::VehiclePropertyAccess accessToTest) const;
197 
198     VhalResult<void> checkReadPermission(const aidlvhal::VehiclePropValue& value) const;
199 
200     VhalResult<void> checkWritePermission(const aidlvhal::VehiclePropValue& value) const;
201 
202     android::base::Result<aidlvhal::VehiclePropConfig> getConfig(int32_t propId) const;
203 
204     void onBinderDiedWithContext(const AIBinder* clientId);
205 
206     void onBinderUnlinkedWithContext(const AIBinder* clientId);
207 
208     // Registers a onBinderDied callback for the client if not already registered.
209     // Returns true if the client Binder is alive, false otherwise.
210     bool monitorBinderLifeCycleLocked(const AIBinder* clientId) REQUIRES(mLock);
211 
212     bool checkDumpPermission();
213 
214     bool isConfigSupportedForCurrentVhalVersion(const aidlvhal::VehiclePropConfig& config) const;
215 
216     bool getAllPropConfigsFromHardwareLocked() const EXCLUDES(mConfigLock);
217 
218     // The looping handler function to process all onBinderDied or onBinderUnlinked events in
219     // mBinderEvents.
220     void onBinderDiedUnlinkedHandler();
221 
222     size_t countClients();
223 
224     // Handles the property change events in batch.
225     void handleBatchedPropertyEvents(std::vector<aidlvhal::VehiclePropValue>&& batchedEvents);
226 
227     int32_t getVhalInterfaceVersion() const;
228 
229     // Gets mConfigsByPropId, lazy init it if necessary. Note that the reference is only valid in
230     // the scope of the callback and it is guaranteed that read lock is obtained during the
231     // callback.
232     void getConfigsByPropId(
233             std::function<void(const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>&)>
234                     callback) const EXCLUDES(mConfigLock);
235 
236     android::base::Result<aidlvhal::VehicleAreaConfig> getAreaConfigForPropIdAreaId(
237             int32_t propId, int32_t areaId) const;
238     android::base::Result<aidlvhal::HasSupportedValueInfo> getHasSupportedValueInfo(
239             int32_t propId, int32_t areaId) const;
240     // Puts the property change events into a queue so that they can handled in batch.
241     static void batchPropertyChangeEvent(
242             const std::weak_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>>& batchedEventQueue,
243             std::vector<aidlvhal::VehiclePropValue>&& updatedValues);
244 
245     // Gets or creates a {@code T} object for the client to or from {@code clients}.
246     template <class T>
247     static std::shared_ptr<T> getOrCreateClient(
248             std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients,
249             const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool);
250 
251     static void onPropertyChangeEvent(const std::weak_ptr<SubscriptionManager>& subscriptionManager,
252                                       std::vector<aidlvhal::VehiclePropValue>&& updatedValues);
253 
254     static void onPropertySetErrorEvent(
255             const std::weak_ptr<SubscriptionManager>& subscriptionManager,
256             const std::vector<SetValueErrorEvent>& errorEvents);
257 
258     static void onSupportedValueChange(
259             const std::weak_ptr<SubscriptionManager>& subscriptionManager,
260             const std::vector<PropIdAreaId>& updatedPropIdAreaIds);
261 
262     static void checkHealth(IVehicleHardware* hardware,
263                             std::weak_ptr<SubscriptionManager> subscriptionManager);
264 
265     static void onBinderDied(void* cookie);
266 
267     static void onBinderUnlinked(void* cookie);
268 
269     static void parseSubscribeOptions(
270             const std::vector<aidlvhal::SubscribeOptions>& options,
271             const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId,
272             std::vector<aidlvhal::SubscribeOptions>& onChangeSubscriptions,
273             std::vector<aidlvhal::SubscribeOptions>& continuousSubscriptions);
274 
275     // Test-only
276     // Set the default timeout for pending requests.
277     void setTimeout(int64_t timeoutInNano);
278 
279     // Test-only
280     void setBinderLifecycleHandler(std::unique_ptr<BinderLifecycleInterface> impl);
281 };
282 
283 }  // namespace vehicle
284 }  // namespace automotive
285 }  // namespace hardware
286 }  // namespace android
287 
288 #endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
289