blob: 914081c21fccfa5721209303ed7a665fee89d93f [file] [log] [blame]
keunyounge18e25d2015-08-28 15:57:19 -07001/*
2 * Copyright (C) 2015 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 CAR_VEHICLE_NETWORK_SERVICE_H_
18#define CAR_VEHICLE_NETWORK_SERVICE_H_
19
20#include <stdint.h>
21#include <sys/types.h>
22
23#include <memory>
24
25#include <hardware/hardware.h>
26#include <hardware/vehicle.h>
27
28#include <binder/BinderService.h>
29#include <binder/IBinder.h>
30#include <binder/IPCThreadState.h>
31#include <cutils/compiler.h>
32#include <utils/threads.h>
33#include <utils/KeyedVector.h>
34#include <utils/List.h>
35#include <utils/RefBase.h>
36#include <utils/SortedVector.h>
37#include <utils/StrongPointer.h>
38#include <utils/TypeHelpers.h>
39
40#include <IVehicleNetwork.h>
41#include <IVehicleNetworkListener.h>
Keun-young Park28dd4702015-11-19 18:06:04 -080042#include <HandlerThread.h>
keunyounge18e25d2015-08-28 15:57:19 -070043
44
45namespace android {
46
Keun-young Park28dd4702015-11-19 18:06:04 -080047// ----------------------------------------------------------------------------
48
keunyounge18e25d2015-08-28 15:57:19 -070049class VehicleNetworkService;
50
51/**
52 * MessageHandler to dispatch HAL callbacks to pre-defined handler thread context.
53 * Init / release is handled in the handler thread to allow upper layer to allocate resource
54 * for the thread.
55 */
56class VehicleHalMessageHandler : public MessageHandler {
57 enum {
keunyounge4c90c42015-11-16 18:42:52 -080058 HAL_EVENT = 0,
59 HAL_ERROR = 1,
keunyounge18e25d2015-08-28 15:57:19 -070060 };
61
62 /**
63 * For dispatching HAL event in batch. Hal events coming in this time frame will be batched
64 * together.
65 */
66 static const int DISPATCH_INTERVAL_MS = 16;
Keun-young Park28dd4702015-11-19 18:06:04 -080067 static const int NUM_PROPERTY_EVENT_LISTS = 2;
keunyounge18e25d2015-08-28 15:57:19 -070068public:
Keun-young Park28dd4702015-11-19 18:06:04 -080069 // not passing VNS as sp as this is held by VNS always.
keunyounge18e25d2015-08-28 15:57:19 -070070 VehicleHalMessageHandler(const sp<Looper>& mLooper, VehicleNetworkService& service);
71 virtual ~VehicleHalMessageHandler();
72
keunyounge18e25d2015-08-28 15:57:19 -070073 void handleHalEvent(vehicle_prop_value_t *eventData);
Keun-young Park28dd4702015-11-19 18:06:04 -080074 void handleHalError(VehicleHalError* error);
keunyoung1ab8e182015-09-24 09:25:22 -070075 void handleMockStart();
keunyounge18e25d2015-08-28 15:57:19 -070076
77private:
78 void handleMessage(const Message& message);
keunyounge18e25d2015-08-28 15:57:19 -070079 void doHandleHalEvent();
80 void doHandleHalError();
81
82private:
Keun-young Park28dd4702015-11-19 18:06:04 -080083 mutable Mutex mLock;
Keun-young Park28dd4702015-11-19 18:06:04 -080084 const sp<Looper> mLooper;
keunyounge18e25d2015-08-28 15:57:19 -070085 VehicleNetworkService& mService;
keunyounge18e25d2015-08-28 15:57:19 -070086 int mFreeListIndex;
Keun-young Park28dd4702015-11-19 18:06:04 -080087 List<vehicle_prop_value_t*> mHalPropertyList[NUM_PROPERTY_EVENT_LISTS];
keunyounge18e25d2015-08-28 15:57:19 -070088 int64_t mLastDispatchTime;
Keun-young Park28dd4702015-11-19 18:06:04 -080089 List<VehicleHalError*> mHalErrors;
keunyounge18e25d2015-08-28 15:57:19 -070090};
Keun-young Park0727f952015-12-21 14:30:07 -080091// ----------------------------------------------------------------------------
92class SubscriptionInfo {
93public:
94 float sampleRate;
95 int32_t zones;
96 SubscriptionInfo()
97 : sampleRate(0),
98 zones(0) {};
99 SubscriptionInfo(float aSampleRate, int32_t aZones)
100 : sampleRate(aSampleRate),
101 zones(aZones) {};
102 SubscriptionInfo(const SubscriptionInfo& info)
103 : sampleRate(info.sampleRate),
104 zones(info.zones) {};
105};
keunyounge18e25d2015-08-28 15:57:19 -0700106
107// ----------------------------------------------------------------------------
108
109class HalClient : public virtual RefBase {
110public:
Keun-young Park28dd4702015-11-19 18:06:04 -0800111 HalClient(const sp<IVehicleNetworkListener> &listener, pid_t pid, uid_t uid) :
112 mListener(listener),
113 mPid(pid),
114 mUid(uid),
115 mMonitoringHalRestart(false),
116 mMonitoringHalError(false) {
keunyounge18e25d2015-08-28 15:57:19 -0700117 }
118
119 ~HalClient() {
Keun-young Park0727f952015-12-21 14:30:07 -0800120 mSubscriptionInfos.clear();
keunyounge18e25d2015-08-28 15:57:19 -0700121 }
122
123 pid_t getPid() {
124 return mPid;
125 }
126
127 uid_t getUid() {
128 return mUid;
129 }
130
Keun-young Park0727f952015-12-21 14:30:07 -0800131 SubscriptionInfo* getSubscriptionInfo(int32_t property) {
keunyounge18e25d2015-08-28 15:57:19 -0700132 Mutex::Autolock autoLock(mLock);
Keun-young Park0727f952015-12-21 14:30:07 -0800133 ssize_t index = mSubscriptionInfos.indexOfKey(property);
keunyounge18e25d2015-08-28 15:57:19 -0700134 if (index < 0) {
Keun-young Park0727f952015-12-21 14:30:07 -0800135 return NULL;
keunyounge18e25d2015-08-28 15:57:19 -0700136 }
Keun-young Park0727f952015-12-21 14:30:07 -0800137 return &mSubscriptionInfos.editValueAt(index);
keunyounge18e25d2015-08-28 15:57:19 -0700138 }
139
Keun-young Park0727f952015-12-21 14:30:07 -0800140 void setSubscriptionInfo(int32_t property, float sampleRate, int32_t zones) {
keunyounge18e25d2015-08-28 15:57:19 -0700141 Mutex::Autolock autoLock(mLock);
Keun-young Park0727f952015-12-21 14:30:07 -0800142 SubscriptionInfo info(sampleRate, zones);
143 mSubscriptionInfos.add(property, info);
keunyounge18e25d2015-08-28 15:57:19 -0700144 }
145
146 bool removePropertyAndCheckIfActive(int32_t property) {
Keun-young Park28dd4702015-11-19 18:06:04 -0800147 Mutex::Autolock autoLock(mLock);
Keun-young Park0727f952015-12-21 14:30:07 -0800148 mSubscriptionInfos.removeItem(property);
149 return mSubscriptionInfos.size() > 0 || mMonitoringHalRestart || mMonitoringHalError;
Keun-young Park28dd4702015-11-19 18:06:04 -0800150 }
151
152 void removeAllProperties() {
153 Mutex::Autolock autoLock(mLock);
Keun-young Park0727f952015-12-21 14:30:07 -0800154 mSubscriptionInfos.clear();
Keun-young Park28dd4702015-11-19 18:06:04 -0800155 }
156
157 bool isActive() {
158 Mutex::Autolock autoLock(mLock);
Keun-young Park0727f952015-12-21 14:30:07 -0800159 return mSubscriptionInfos.size() > 0 || mMonitoringHalRestart || mMonitoringHalError;
Keun-young Park28dd4702015-11-19 18:06:04 -0800160 }
161
162 void setHalRestartMonitoringState(bool state) {
163 Mutex::Autolock autoLock(mLock);
164 mMonitoringHalRestart = state;
165 }
166
167 bool isMonitoringHalRestart() {
168 Mutex::Autolock autoLock(mLock);
169 return mMonitoringHalRestart;
170 }
171
172 void setHalErrorMonitoringState(bool state) {
173 Mutex::Autolock autoLock(mLock);
174 mMonitoringHalError = state;
175 }
176
177 bool isMonitoringHalError() {
178 Mutex::Autolock autoLock(mLock);
179 return mMonitoringHalError;
keunyounge18e25d2015-08-28 15:57:19 -0700180 }
181
182 const sp<IVehicleNetworkListener>& getListener() {
183 return mListener;
184 }
185
186 const sp<IBinder> getListenerAsBinder() {
187 return IInterface::asBinder(mListener);
188 }
189
190 // no lock here as this should be called only from single event looper thread
191 void addEvent(vehicle_prop_value_t* event) {
192 mEvents.push_back(event);
193 }
194
195 // no lock here as this should be called only from single event looper thread
196 void clearEvents() {
197 mEvents.clear();
198 }
199
200 // no lock here as this should be called only from single event looper thread
201 List<vehicle_prop_value_t*>& getEventList() {
202 return mEvents;
203 }
204
205 // no lock here as this should be called only from single event looper thread
206 status_t dispatchEvents(){
207 ALOGV("dispatchEvents, num Events:%d", mEvents.size());
208 sp<VehiclePropValueListHolder> events(new VehiclePropValueListHolder(&mEvents,
209 false /*deleteInDestructor */));
210 ASSERT_OR_HANDLE_NO_MEMORY(events.get(), return NO_MEMORY);
211 mListener->onEvents(events);
212 mEvents.clear();
213 return NO_ERROR;
214 }
Keun-young Park28dd4702015-11-19 18:06:04 -0800215
216 void dispatchHalError(int32_t errorCode, int32_t property, int32_t operation) {
217 mListener->onHalError(errorCode, property, operation);
218 }
219
220 void dispatchHalRestart(bool inMocking) {
221 mListener->onHalRestart(inMocking);
222 }
223
keunyounge18e25d2015-08-28 15:57:19 -0700224private:
Keun-young Park28dd4702015-11-19 18:06:04 -0800225 mutable Mutex mLock;
226 const sp<IVehicleNetworkListener> mListener;
227 const pid_t mPid;
228 const uid_t mUid;
Keun-young Park0727f952015-12-21 14:30:07 -0800229 KeyedVector<int32_t, SubscriptionInfo> mSubscriptionInfos;
keunyounge18e25d2015-08-28 15:57:19 -0700230 List<vehicle_prop_value_t*> mEvents;
Keun-young Park28dd4702015-11-19 18:06:04 -0800231 bool mMonitoringHalRestart;
232 bool mMonitoringHalError;
keunyounge18e25d2015-08-28 15:57:19 -0700233};
234
235class HalClientSpVector : public SortedVector<sp<HalClient> >, public RefBase {
236protected:
237 virtual int do_compare(const void* lhs, const void* rhs) const {
238 sp<HalClient>& lh = * (sp<HalClient> * )(lhs);
239 sp<HalClient>& rh = * (sp<HalClient> * )(rhs);
240 return compare_type(lh.get(), rh.get());
241 }
242};
243
244// ----------------------------------------------------------------------------
245
keunyoungd32f4e62015-09-21 11:33:06 -0700246/**
247 * Keeps cached value of property values.
248 * For internal property, static property, and on_change property, caching makes sense.
249 */
250class PropertyValueCache {
251public:
252 PropertyValueCache();
253 virtual ~PropertyValueCache();
254 void writeToCache(const vehicle_prop_value_t& value);
255 bool readFromCache(vehicle_prop_value_t* value);
256
257private:
258 KeyedVector<int32_t, vehicle_prop_value_t*> mCache;
259};
260
261// ----------------------------------------------------------------------------
262
Keun-young Park28dd4702015-11-19 18:06:04 -0800263class MockDeathHandler: public IBinder::DeathRecipient {
264public:
265 MockDeathHandler(VehicleNetworkService& vns) :
266 mService(vns) {};
267
268 virtual void binderDied(const wp<IBinder>& who);
269
270private:
271 VehicleNetworkService& mService;
272};
273
274// ----------------------------------------------------------------------------
keunyounge18e25d2015-08-28 15:57:19 -0700275class VehicleNetworkService :
276 public BinderService<VehicleNetworkService>,
277 public BnVehicleNetwork,
278 public IBinder::DeathRecipient {
279public:
280 static const char* getServiceName() ANDROID_API { return IVehicleNetwork::SERVICE_NAME; };
281
282 VehicleNetworkService();
283 ~VehicleNetworkService();
284 virtual status_t dump(int fd, const Vector<String16>& args);
285 void release();
Keun-young Park28dd4702015-11-19 18:06:04 -0800286 status_t onHalEvent(const vehicle_prop_value_t *eventData, bool isInjection = false);
287 status_t onHalError(int32_t errorCode, int32_t property, int32_t operation,
288 bool isInjection = false);
keunyounge18e25d2015-08-28 15:57:19 -0700289 /**
290 * Called by VehicleHalMessageHandler for batching events
291 */
Keun-young Park28dd4702015-11-19 18:06:04 -0800292 void dispatchHalEvents(List<vehicle_prop_value_t*>& events);
293 void dispatchHalError(VehicleHalError* error);
keunyounge18e25d2015-08-28 15:57:19 -0700294 virtual sp<VehiclePropertiesHolder> listProperties(int32_t property = 0);
295 virtual status_t setProperty(const vehicle_prop_value_t& value);
296 virtual status_t getProperty(vehicle_prop_value_t* value);
297 virtual status_t subscribe(const sp<IVehicleNetworkListener> &listener, int32_t property,
Keun-young Park0727f952015-12-21 14:30:07 -0800298 float sampleRate, int32_t zones);
keunyounge18e25d2015-08-28 15:57:19 -0700299 virtual void unsubscribe(const sp<IVehicleNetworkListener> &listener, int32_t property);
keunyoung1ab8e182015-09-24 09:25:22 -0700300 virtual status_t injectEvent(const vehicle_prop_value_t& value);
301 virtual status_t startMocking(const sp<IVehicleNetworkHalMock>& mock);
302 virtual void stopMocking(const sp<IVehicleNetworkHalMock>& mock);
Keun-young Park28dd4702015-11-19 18:06:04 -0800303 virtual status_t injectHalError(int32_t errorCode, int32_t property, int32_t operation);
304 virtual status_t startErrorListening(const sp<IVehicleNetworkListener> &listener);
305 virtual void stopErrorListening(const sp<IVehicleNetworkListener> &listener);
306 virtual status_t startHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener);
307 virtual void stopHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener);
keunyounge18e25d2015-08-28 15:57:19 -0700308 virtual void binderDied(const wp<IBinder>& who);
keunyoungd32f4e62015-09-21 11:33:06 -0700309 bool isPropertySubsribed(int32_t property);
Keun-young Park28dd4702015-11-19 18:06:04 -0800310
311 void handleHalMockDeath(const wp<IBinder>& who);
Keun-young Park737cdfb2016-02-12 15:11:39 -0800312protected:
313 virtual bool isOperationAllowed(int32_t property, bool isWrite);
keunyounge18e25d2015-08-28 15:57:19 -0700314private:
315 // RefBase
316 virtual void onFirstRef();
317 status_t loadHal();
318 void closeHal();
keunyoung1ab8e182015-09-24 09:25:22 -0700319 vehicle_prop_config_t const * findConfigLocked(int32_t property);
320 bool isGettableLocked(int32_t property);
keunyoung38ba5302015-10-14 13:50:21 -0700321 bool isSettableLocked(int32_t property, int32_t valueType);
keunyoung1ab8e182015-09-24 09:25:22 -0700322 bool isSubscribableLocked(int32_t property);
Keun-young Park0727f952015-12-21 14:30:07 -0800323 static bool isZonedProperty(vehicle_prop_config_t const * config);
Keun-young Park28dd4702015-11-19 18:06:04 -0800324 sp<HalClient> findClientLocked(sp<IBinder>& ibinder);
325 sp<HalClient> findOrCreateClientLocked(sp<IBinder>& ibinder,
326 const sp<IVehicleNetworkListener> &listener);
327 sp<HalClientSpVector> findClientsVectorForPropertyLocked(int32_t property);
328 sp<HalClientSpVector> findOrCreateClientsVectorForPropertyLocked(int32_t property);
329 bool removePropertyFromClientLocked(sp<IBinder>& ibinder, sp<HalClient>& client,
330 int32_t property);
331 void handleHalRestartAndGetClientsToDispatchLocked(List<sp<HalClient> >& clientsToDispatch);
332
keunyounge18e25d2015-08-28 15:57:19 -0700333 static int eventCallback(const vehicle_prop_value_t *eventData);
keunyoung38ba5302015-10-14 13:50:21 -0700334 static int errorCallback(int32_t errorCode, int32_t property, int32_t operation);
keunyounge18e25d2015-08-28 15:57:19 -0700335private:
336 static VehicleNetworkService* sInstance;
Keun-young Park28dd4702015-11-19 18:06:04 -0800337 sp<HandlerThread> mHandlerThread;
keunyounge18e25d2015-08-28 15:57:19 -0700338 sp<VehicleHalMessageHandler> mHandler;
339 mutable Mutex mLock;
340 vehicle_module_t* mModule;
341 vehicle_hw_device_t* mDevice;
342 sp<VehiclePropertiesHolder> mProperties;
343 KeyedVector<sp<IBinder>, sp<HalClient> > mBinderToClientMap;
Keun-young Park28dd4702015-11-19 18:06:04 -0800344 // client subscribing properties
keunyounge18e25d2015-08-28 15:57:19 -0700345 KeyedVector<int32_t, sp<HalClientSpVector> > mPropertyToClientsMap;
Keun-young Park0727f952015-12-21 14:30:07 -0800346 KeyedVector<int32_t, SubscriptionInfo> mSubscriptionInfos;
keunyounge4c90c42015-11-16 18:42:52 -0800347 KeyedVector<int32_t, int> mEventsCount;
keunyoungd32f4e62015-09-21 11:33:06 -0700348 PropertyValueCache mCache;
keunyoung1ab8e182015-09-24 09:25:22 -0700349 bool mMockingEnabled;
350 sp<IVehicleNetworkHalMock> mHalMock;
351 sp<VehiclePropertiesHolder> mPropertiesForMocking;
Keun-young Park28dd4702015-11-19 18:06:04 -0800352 sp<MockDeathHandler> mHalMockDeathHandler;
keunyounge18e25d2015-08-28 15:57:19 -0700353};
354
355};
356
357#endif /* CAR_VEHICLE_NETWORK_SERVICE_H_ */