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