• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, 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:
~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 - this callback function will be called when there are no
91      *                                    more client subscribed to particular property.
92      */
SubscriptionManager(const OnPropertyUnsubscribed & onPropertyUnsubscribed)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:
DeathRecipient(const OnClientDead & onClientDead)147         DeathRecipient(const OnClientDead& onClientDead)
148             : mOnClientDead(onClientDead) {}
149         ~DeathRecipient() = default;
150 
151         DeathRecipient(const DeathRecipient& ) = delete;
152         DeathRecipient& operator=(const DeathRecipient&) = delete;
153 
serviceDied(uint64_t cookie,const wp<::android::hidl::base::V1_0::IBase> &)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