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_SubscriptionManager_H_ 18 #define android_hardware_automotive_vehicle_aidl_impl_vhal_include_SubscriptionManager_H_ 19 20 #include <IVehicleHardware.h> 21 #include <VehicleHalTypes.h> 22 #include <VehicleUtils.h> 23 24 #include <aidl/android/hardware/automotive/vehicle/IVehicleCallback.h> 25 #include <android-base/result.h> 26 #include <android-base/thread_annotations.h> 27 28 #include <mutex> 29 #include <optional> 30 #include <unordered_map> 31 #include <unordered_set> 32 #include <vector> 33 34 namespace android { 35 namespace hardware { 36 namespace automotive { 37 namespace vehicle { 38 39 // A class to represent all the subscription configs for a continuous [propId, areaId]. 40 class ContSubConfigs final { 41 public: 42 using ClientIdType = const AIBinder*; 43 44 void addClient(const ClientIdType& clientId, float sampleRateHz); 45 void removeClient(const ClientIdType& clientId); 46 float getMaxSampleRateHz() const; 47 48 private: 49 float mMaxSampleRateHz = 0.; 50 std::unordered_map<ClientIdType, float> mSampleRateHzByClient; 51 52 void refreshMaxSampleRateHz(); 53 }; 54 55 // A thread-safe subscription manager that manages all VHAL subscriptions. 56 class SubscriptionManager final { 57 public: 58 using ClientIdType = const AIBinder*; 59 using CallbackType = 60 std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>; 61 62 explicit SubscriptionManager(IVehicleHardware* vehicleHardware); 63 ~SubscriptionManager(); 64 65 // Subscribes to properties according to {@code SubscribeOptions}. Note that all option must 66 // contain non-empty areaIds field, which contains all area IDs to subscribe. As a result, 67 // the options here is different from the options passed from VHAL client. 68 // Returns error if any of the subscribe options is not valid or one of the properties failed 69 // to subscribe. Part of the properties maybe be subscribed successfully if this function 70 // returns error. Caller is safe to retry since subscribing to an already subscribed property 71 // is okay. 72 // Returns ok if all the options are parsed correctly and all the properties are subscribed. 73 VhalResult<void> subscribe( 74 const CallbackType& callback, 75 const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>& 76 options, 77 bool isContinuousProperty); 78 79 // Unsubscribes from the properties for the client. 80 // Returns error if the client was not subscribed before, or one of the given property was not 81 // subscribed, or one of the property failed to unsubscribe. Caller is safe to retry since 82 // unsubscribing to an already unsubscribed property is okay (it would be ignored). 83 // Returns ok if all the requested properties for the client are unsubscribed. 84 VhalResult<void> unsubscribe(ClientIdType client, const std::vector<int32_t>& propIds); 85 86 // Unsubscribes from all the properties for the client. 87 // Returns error if the client was not subscribed before or one of the subscribed properties 88 // for the client failed to unsubscribe. Caller is safe to retry. 89 // Returns ok if all the properties for the client are unsubscribed. 90 VhalResult<void> unsubscribe(ClientIdType client); 91 92 // For a list of updated properties, returns a map that maps clients subscribing to 93 // the updated properties to a list of updated values. This would only return on-change property 94 // clients that should be informed for the given updated values. 95 std::unordered_map< 96 CallbackType, 97 std::vector<const aidl::android::hardware::automotive::vehicle::VehiclePropValue*>> 98 getSubscribedClients( 99 const std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>& 100 updatedValues); 101 102 // For a list of set property error events, returns a map that maps clients subscribing to the 103 // properties to a list of errors for each client. 104 std::unordered_map<CallbackType, 105 std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropError>> 106 getSubscribedClientsForErrorEvents(const std::vector<SetValueErrorEvent>& errorEvents); 107 108 // Checks whether the sample rate is valid. 109 static bool checkSampleRateHz(float sampleRateHz); 110 111 private: 112 // Friend class for testing. 113 friend class DefaultVehicleHalTest; 114 115 IVehicleHardware* mVehicleHardware; 116 117 mutable std::mutex mLock; 118 std::unordered_map<PropIdAreaId, std::unordered_map<ClientIdType, CallbackType>, 119 PropIdAreaIdHash> 120 mClientsByPropIdArea GUARDED_BY(mLock); 121 std::unordered_map<ClientIdType, std::unordered_set<PropIdAreaId, PropIdAreaIdHash>> 122 mSubscribedPropsByClient GUARDED_BY(mLock); 123 std::unordered_map<PropIdAreaId, ContSubConfigs, PropIdAreaIdHash> mContSubConfigsByPropIdArea 124 GUARDED_BY(mLock); 125 126 VhalResult<void> addContinuousSubscriberLocked(const ClientIdType& clientId, 127 const PropIdAreaId& propIdAreaId, 128 float sampleRateHz) REQUIRES(mLock); 129 VhalResult<void> removeContinuousSubscriberLocked(const ClientIdType& clientId, 130 const PropIdAreaId& propIdAreaId) 131 REQUIRES(mLock); 132 133 VhalResult<void> updateContSubConfigs(const PropIdAreaId& PropIdAreaId, 134 const ContSubConfigs& newConfig) REQUIRES(mLock); 135 136 // Checks whether the manager is empty. For testing purpose. 137 bool isEmpty(); 138 139 // Get the interval in nanoseconds accroding to sample rate. 140 static android::base::Result<int64_t> getIntervalNanos(float sampleRateHz); 141 }; 142 143 } // namespace vehicle 144 } // namespace automotive 145 } // namespace hardware 146 } // namespace android 147 148 #endif // android_hardware_automotive_vehicle_aidl_impl_vhal_include_SubscriptionManager_H_ 149