1 /* 2 * Copyright (C) 2016 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_V2_0_SubscriptionManager_H_ 18 #define android_hardware_automotive_vehicle_V2_0_SubscriptionManager_H_ 19 20 #include <memory> 21 #include <map> 22 #include <set> 23 #include <list> 24 25 #include <android/log.h> 26 #include <hidl/HidlSupport.h> 27 #include <utils/SortedVector.h> 28 29 #include <android/hardware/automotive/vehicle/2.0/IVehicle.h> 30 31 #include "ConcurrentQueue.h" 32 #include "VehicleObjectPool.h" 33 34 namespace android { 35 namespace hardware { 36 namespace automotive { 37 namespace vehicle { 38 namespace V2_0 { 39 40 class HalClient : public android::RefBase { 41 public: 42 HalClient(const sp<IVehicleCallback> &callback) 43 : mCallback(callback) {} 44 45 virtual ~HalClient() {} 46 public: 47 sp<IVehicleCallback> getCallback() const { 48 return mCallback; 49 } 50 51 void addOrUpdateSubscription(const SubscribeOptions &opts); 52 bool isSubscribed(int32_t propId, int32_t areaId, SubscribeFlags flags); 53 std::vector<int32_t> getSubscribedProperties() const; 54 55 private: 56 const sp<IVehicleCallback> mCallback; 57 58 std::map<int32_t, SubscribeOptions> mSubscriptions; 59 }; 60 61 class HalClientVector : private SortedVector<sp<HalClient>> , public RefBase { 62 public: 63 virtual ~HalClientVector() {} 64 65 inline void addOrUpdate(const sp<HalClient> &client) { 66 SortedVector::add(client); 67 } 68 69 using SortedVector::remove; 70 using SortedVector::size; 71 using SortedVector::indexOf; 72 using SortedVector::itemAt; 73 using SortedVector::isEmpty; 74 }; 75 76 struct HalClientValues { 77 sp<HalClient> client; 78 std::list<VehiclePropValue *> values; 79 }; 80 81 using ClientId = uint64_t; 82 83 class SubscriptionManager { 84 public: 85 using OnPropertyUnsubscribed = std::function<void(int32_t)>; 86 87 /** 88 * Constructs SubscriptionManager 89 * 90 * @param onPropertyUnsubscribed - this callback function will be called when there are no 91 * more client subscribed to particular property. 92 */ 93 SubscriptionManager(const OnPropertyUnsubscribed& onPropertyUnsubscribed) 94 : mOnPropertyUnsubscribed(onPropertyUnsubscribed), 95 mCallbackDeathRecipient(new DeathRecipient( 96 std::bind(&SubscriptionManager::onCallbackDead, this, std::placeholders::_1))) 97 {} 98 99 ~SubscriptionManager() = default; 100 101 /** 102 * Updates subscription. Returns the vector of properties subscription that 103 * needs to be updated in VehicleHAL. 104 */ 105 StatusCode addOrUpdateSubscription(ClientId clientId, 106 const sp<IVehicleCallback>& callback, 107 const hidl_vec<SubscribeOptions>& optionList, 108 std::list<SubscribeOptions>* outUpdatedOptions); 109 110 /** 111 * Returns a list of IVehicleCallback -> list of VehiclePropValue ready for 112 * dispatching to its clients. 113 */ 114 std::list<HalClientValues> distributeValuesToClients( 115 const std::vector<recyclable_ptr<VehiclePropValue>>& propValues, 116 SubscribeFlags flags) const; 117 118 std::list<sp<HalClient>> getSubscribedClients(int32_t propId, 119 int32_t area, 120 SubscribeFlags flags) const; 121 /** 122 * If there are no clients subscribed to given properties than callback function provided 123 * in the constructor will be called. 124 */ 125 void unsubscribe(ClientId clientId, int32_t propId); 126 private: 127 std::list<sp<HalClient>> getSubscribedClientsLocked(int32_t propId, 128 int32_t area, 129 SubscribeFlags flags) const; 130 131 bool updateHalEventSubscriptionLocked(const SubscribeOptions &opts, SubscribeOptions* out); 132 133 void addClientToPropMapLocked(int32_t propId, const sp<HalClient>& client); 134 135 sp<HalClientVector> getClientsForPropertyLocked(int32_t propId) const; 136 137 sp<HalClient> getOrCreateHalClientLocked(ClientId callingPid, 138 const sp<IVehicleCallback>& callback); 139 140 void onCallbackDead(uint64_t cookie); 141 142 private: 143 using OnClientDead = std::function<void(uint64_t)>; 144 145 class DeathRecipient : public hidl_death_recipient { 146 public: 147 DeathRecipient(const OnClientDead& onClientDead) 148 : mOnClientDead(onClientDead) {} 149 ~DeathRecipient() = default; 150 151 DeathRecipient(const DeathRecipient& ) = delete; 152 DeathRecipient& operator=(const DeathRecipient&) = delete; 153 154 void serviceDied(uint64_t cookie, 155 const wp<::android::hidl::base::V1_0::IBase>& /* who */) override { 156 mOnClientDead(cookie); 157 } 158 private: 159 OnClientDead mOnClientDead; 160 }; 161 162 private: 163 using MuxGuard = std::lock_guard<std::mutex>; 164 165 mutable std::mutex mLock; 166 167 std::map<ClientId, sp<HalClient>> mClients; 168 std::map<int32_t, sp<HalClientVector>> mPropToClients; 169 std::map<int32_t, SubscribeOptions> mHalEventSubscribeOptions; 170 171 OnPropertyUnsubscribed mOnPropertyUnsubscribed; 172 sp<DeathRecipient> mCallbackDeathRecipient; 173 }; 174 175 176 } // namespace V2_0 177 } // namespace vehicle 178 } // namespace automotive 179 } // namespace hardware 180 } // namespace android 181 182 183 #endif // android_hardware_automotive_vehicle_V2_0_SubscriptionManager_H_ 184