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