• Home
  • History
  • Annotate
  • 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  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