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 sampleRate); 45 void removeClient(const ClientIdType& clientId); 46 float getMaxSampleRate(); 47 48 private: 49 float mMaxSampleRate = 0.; 50 std::unordered_map<ClientIdType, float> mSampleRates; 51 52 void refreshMaxSampleRate(); 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* hardware); 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 // Gets the sample rate for the continuous property. Returns {@code std::nullopt} if the 103 // property has not been subscribed before or is not a continuous property. 104 std::optional<float> getSampleRate(const ClientIdType& clientId, int32_t propId, 105 int32_t areaId); 106 107 // Checks whether the sample rate is valid. 108 static bool checkSampleRate(float sampleRate); 109 110 private: 111 // Friend class for testing. 112 friend class DefaultVehicleHalTest; 113 114 IVehicleHardware* mVehicleHardware; 115 116 mutable std::mutex mLock; 117 std::unordered_map<PropIdAreaId, std::unordered_map<ClientIdType, CallbackType>, 118 PropIdAreaIdHash> 119 mClientsByPropIdArea GUARDED_BY(mLock); 120 std::unordered_map<ClientIdType, std::unordered_set<PropIdAreaId, PropIdAreaIdHash>> 121 mSubscribedPropsByClient GUARDED_BY(mLock); 122 std::unordered_map<PropIdAreaId, ContSubConfigs, PropIdAreaIdHash> mContSubConfigsByPropIdArea 123 GUARDED_BY(mLock); 124 125 VhalResult<void> updateSampleRateLocked(const ClientIdType& clientId, 126 const PropIdAreaId& propIdAreaId, float sampleRate) 127 REQUIRES(mLock); 128 VhalResult<void> removeSampleRateLocked(const ClientIdType& clientId, 129 const PropIdAreaId& propIdAreaId) REQUIRES(mLock); 130 131 // Checks whether the manager is empty. For testing purpose. 132 bool isEmpty(); 133 134 // Get the interval in nanoseconds accroding to sample rate. 135 static android::base::Result<int64_t> getInterval(float sampleRate); 136 }; 137 138 } // namespace vehicle 139 } // namespace automotive 140 } // namespace hardware 141 } // namespace android 142 143 #endif // android_hardware_automotive_vehicle_aidl_impl_vhal_include_SubscriptionManager_H_ 144