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: HalClient(const sp<IVehicleCallback> & callback)42 HalClient(const sp<IVehicleCallback> &callback) 43 : mCallback(callback) {} 44 ~HalClient()45 virtual ~HalClient() {} 46 public: getCallback()47 sp<IVehicleCallback> getCallback() const { 48 return mCallback; 49 } 50 51 void addOrUpdateSubscription(const SubscribeOptions &opts); 52 bool isSubscribed(int32_t propId, 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: ~HalClientVector()63 virtual ~HalClientVector() {} 64 addOrUpdate(const sp<HalClient> & client)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 - called when no more clients are subscribed to the property. 91 */ SubscriptionManager(const OnPropertyUnsubscribed & onPropertyUnsubscribed)92 SubscriptionManager(const OnPropertyUnsubscribed& onPropertyUnsubscribed) 93 : mOnPropertyUnsubscribed(onPropertyUnsubscribed), 94 mCallbackDeathRecipient(new DeathRecipient( 95 std::bind(&SubscriptionManager::onCallbackDead, this, std::placeholders::_1))) 96 {} 97 98 ~SubscriptionManager() = default; 99 100 /** 101 * Updates subscription. Returns the vector of properties subscription that 102 * needs to be updated in VehicleHAL. 103 */ 104 StatusCode addOrUpdateSubscription(ClientId clientId, 105 const sp<IVehicleCallback>& callback, 106 const hidl_vec<SubscribeOptions>& optionList, 107 std::list<SubscribeOptions>* outUpdatedOptions); 108 109 /** 110 * Returns a list of IVehicleCallback -> list of VehiclePropValue ready for 111 * dispatching to its clients. 112 */ 113 std::list<HalClientValues> distributeValuesToClients( 114 const std::vector<recyclable_ptr<VehiclePropValue>>& propValues, 115 SubscribeFlags flags) const; 116 117 std::list<sp<HalClient>> getSubscribedClients(int32_t propId, SubscribeFlags flags) const; 118 /** 119 * If there are no clients subscribed to given properties than callback function provided 120 * in the constructor will be called. 121 */ 122 void unsubscribe(ClientId clientId, int32_t propId); 123 private: 124 std::list<sp<HalClient>> getSubscribedClientsLocked(int32_t propId, 125 SubscribeFlags flags) const; 126 127 bool updateHalEventSubscriptionLocked(const SubscribeOptions& opts, SubscribeOptions* out); 128 129 void addClientToPropMapLocked(int32_t propId, const sp<HalClient>& client); 130 131 sp<HalClientVector> getClientsForPropertyLocked(int32_t propId) const; 132 133 sp<HalClient> getOrCreateHalClientLocked(ClientId callingPid, 134 const sp<IVehicleCallback>& callback); 135 136 void onCallbackDead(uint64_t cookie); 137 138 private: 139 using OnClientDead = std::function<void(uint64_t)>; 140 141 class DeathRecipient : public hidl_death_recipient { 142 public: DeathRecipient(const OnClientDead & onClientDead)143 DeathRecipient(const OnClientDead& onClientDead) 144 : mOnClientDead(onClientDead) {} 145 ~DeathRecipient() = default; 146 147 DeathRecipient(const DeathRecipient& ) = delete; 148 DeathRecipient& operator=(const DeathRecipient&) = delete; 149 serviceDied(uint64_t cookie,const wp<::android::hidl::base::V1_0::IBase> &)150 void serviceDied(uint64_t cookie, 151 const wp<::android::hidl::base::V1_0::IBase>& /* who */) override { 152 mOnClientDead(cookie); 153 } 154 private: 155 OnClientDead mOnClientDead; 156 }; 157 158 private: 159 using MuxGuard = std::lock_guard<std::mutex>; 160 161 mutable std::mutex mLock; 162 163 std::map<ClientId, sp<HalClient>> mClients; 164 std::map<int32_t, sp<HalClientVector>> mPropToClients; 165 std::map<int32_t, SubscribeOptions> mHalEventSubscribeOptions; 166 167 OnPropertyUnsubscribed mOnPropertyUnsubscribed; 168 sp<DeathRecipient> mCallbackDeathRecipient; 169 }; 170 171 172 } // namespace V2_0 173 } // namespace vehicle 174 } // namespace automotive 175 } // namespace hardware 176 } // namespace android 177 178 179 #endif // android_hardware_automotive_vehicle_V2_0_SubscriptionManager_H_ 180