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