1/*
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>
42#include <HandlerThread.h>
43
44#include "VehiclePropertyAccessControl.h"
45
46namespace android {
47
48// ----------------------------------------------------------------------------
49
50class VehicleNetworkService;
51
52/**
53 * MessageHandler to dispatch HAL callbacks to pre-defined handler thread context.
54 * Init / release is handled in the handler thread to allow upper layer to allocate resource
55 * for the thread.
56 */
57class VehicleHalMessageHandler : public MessageHandler {
58    enum {
59        HAL_EVENT = 0,
60        HAL_ERROR = 1,
61    };
62
63    /**
64     * For dispatching HAL event in batch. Hal events coming in this time frame will be batched
65     * together.
66     */
67    static const int DISPATCH_INTERVAL_MS = 16;
68    static const int NUM_PROPERTY_EVENT_LISTS = 2;
69public:
70    // not passing VNS as sp as this is held by VNS always.
71    VehicleHalMessageHandler(const sp<Looper>& mLooper, VehicleNetworkService& service);
72    virtual ~VehicleHalMessageHandler();
73
74    void handleHalEvent(vehicle_prop_value_t *eventData);
75    void handleHalError(VehicleHalError* error);
76    void handleMockStart();
77
78private:
79    void handleMessage(const Message& message);
80    void doHandleHalEvent();
81    void doHandleHalError();
82
83private:
84    mutable Mutex mLock;
85    const sp<Looper> mLooper;
86    VehicleNetworkService& mService;
87    int mFreeListIndex;
88    List<vehicle_prop_value_t*> mHalPropertyList[NUM_PROPERTY_EVENT_LISTS];
89    int64_t mLastDispatchTime;
90    List<VehicleHalError*> mHalErrors;
91};
92// ----------------------------------------------------------------------------
93class SubscriptionInfo {
94public:
95    float sampleRate;
96    int32_t zones;
97    SubscriptionInfo()
98        : sampleRate(0),
99          zones(0) {};
100    SubscriptionInfo(float aSampleRate, int32_t aZones)
101        : sampleRate(aSampleRate),
102          zones(aZones) {};
103    SubscriptionInfo(const SubscriptionInfo& info)
104        : sampleRate(info.sampleRate),
105          zones(info.zones) {};
106};
107
108// ----------------------------------------------------------------------------
109
110class HalClient : public virtual RefBase {
111public:
112    HalClient(const sp<IVehicleNetworkListener> &listener, pid_t pid, uid_t uid) :
113        mListener(listener),
114        mPid(pid),
115        mUid(uid),
116        mMonitoringHalRestart(false),
117        mMonitoringHalError(false) {
118    }
119
120    ~HalClient() {
121        mSubscriptionInfos.clear();
122    }
123
124    pid_t getPid() {
125        return mPid;
126    }
127
128    uid_t getUid() {
129        return mUid;
130    }
131
132    SubscriptionInfo* getSubscriptionInfo(int32_t property) {
133        Mutex::Autolock autoLock(mLock);
134        ssize_t index = mSubscriptionInfos.indexOfKey(property);
135        if (index < 0) {
136            return NULL;
137        }
138        return &mSubscriptionInfos.editValueAt(index);
139    }
140
141    void setSubscriptionInfo(int32_t property, float sampleRate, int32_t zones) {
142        Mutex::Autolock autoLock(mLock);
143        SubscriptionInfo info(sampleRate, zones);
144        mSubscriptionInfos.add(property, info);
145    }
146
147    bool removePropertyAndCheckIfActive(int32_t property) {
148        Mutex::Autolock autoLock(mLock);
149        mSubscriptionInfos.removeItem(property);
150        return mSubscriptionInfos.size() > 0 || mMonitoringHalRestart || mMonitoringHalError;
151    }
152
153    void removeAllProperties() {
154        Mutex::Autolock autoLock(mLock);
155        mSubscriptionInfos.clear();
156    }
157
158    bool isActive() {
159        Mutex::Autolock autoLock(mLock);
160        return mSubscriptionInfos.size() > 0 || mMonitoringHalRestart || mMonitoringHalError;
161    }
162
163    void setHalRestartMonitoringState(bool state) {
164        Mutex::Autolock autoLock(mLock);
165        mMonitoringHalRestart = state;
166    }
167
168    bool isMonitoringHalRestart() {
169        Mutex::Autolock autoLock(mLock);
170        return mMonitoringHalRestart;
171    }
172
173    void setHalErrorMonitoringState(bool state) {
174        Mutex::Autolock autoLock(mLock);
175        mMonitoringHalError = state;
176    }
177
178    bool isMonitoringHalError() {
179        Mutex::Autolock autoLock(mLock);
180        return mMonitoringHalError;
181    }
182
183    const sp<IVehicleNetworkListener>& getListener() {
184        return mListener;
185    }
186
187    const sp<IBinder> getListenerAsBinder() {
188        return IInterface::asBinder(mListener);
189    }
190
191    // no lock here as this should be called only from single event looper thread
192    void addEvent(vehicle_prop_value_t* event) {
193        mEvents.push_back(event);
194    }
195
196    // no lock here as this should be called only from single event looper thread
197    void clearEvents() {
198        mEvents.clear();
199    }
200
201    // no lock here as this should be called only from single event looper thread
202    List<vehicle_prop_value_t*>& getEventList() {
203        return mEvents;
204    }
205
206    // no lock here as this should be called only from single event looper thread
207    status_t dispatchEvents(){
208        ALOGV("dispatchEvents, num Events:%d", mEvents.size());
209        sp<VehiclePropValueListHolder> events(new VehiclePropValueListHolder(&mEvents,
210                false /*deleteInDestructor */));
211        ASSERT_OR_HANDLE_NO_MEMORY(events.get(), return NO_MEMORY);
212        mListener->onEvents(events);
213        mEvents.clear();
214        return NO_ERROR;
215    }
216
217    void dispatchHalError(int32_t errorCode, int32_t property, int32_t operation) {
218        mListener->onHalError(errorCode, property, operation);
219    }
220
221    void dispatchHalRestart(bool inMocking) {
222        mListener->onHalRestart(inMocking);
223    }
224
225private:
226    mutable Mutex mLock;
227    const sp<IVehicleNetworkListener> mListener;
228    const pid_t mPid;
229    const uid_t mUid;
230    KeyedVector<int32_t, SubscriptionInfo> mSubscriptionInfos;
231    List<vehicle_prop_value_t*> mEvents;
232    bool mMonitoringHalRestart;
233    bool mMonitoringHalError;
234};
235
236class HalClientSpVector : public SortedVector<sp<HalClient> >, public RefBase {
237protected:
238    virtual int do_compare(const void* lhs, const void* rhs) const {
239        sp<HalClient>& lh = * (sp<HalClient> * )(lhs);
240        sp<HalClient>& rh = * (sp<HalClient> * )(rhs);
241        return compare_type(lh.get(), rh.get());
242    }
243};
244
245// ----------------------------------------------------------------------------
246
247/**
248 * Keeps cached value of property values.
249 * For internal property, static property, and on_change property, caching makes sense.
250 */
251class PropertyValueCache {
252public:
253    PropertyValueCache();
254    virtual ~PropertyValueCache();
255    void writeToCache(const vehicle_prop_value_t& value);
256    bool readFromCache(vehicle_prop_value_t* value);
257
258private:
259    KeyedVector<int32_t, vehicle_prop_value_t*> mCache;
260};
261
262// ----------------------------------------------------------------------------
263
264class MockDeathHandler: public IBinder::DeathRecipient {
265public:
266    MockDeathHandler(VehicleNetworkService& vns) :
267        mService(vns) {};
268
269    virtual void binderDied(const wp<IBinder>& who);
270
271private:
272    VehicleNetworkService& mService;
273};
274
275// ----------------------------------------------------------------------------
276class VehicleNetworkService :
277    public BinderService<VehicleNetworkService>,
278    public BnVehicleNetwork,
279    public IBinder::DeathRecipient {
280public:
281    static const char* getServiceName() ANDROID_API { return IVehicleNetwork::SERVICE_NAME; };
282
283    VehicleNetworkService();
284    ~VehicleNetworkService();
285    virtual status_t dump(int fd, const Vector<String16>& args);
286    void release();
287    status_t onHalEvent(const vehicle_prop_value_t *eventData, bool isInjection = false);
288    status_t onHalError(int32_t errorCode, int32_t property, int32_t operation,
289            bool isInjection = false);
290    /**
291     * Called by VehicleHalMessageHandler for batching events
292     */
293    void dispatchHalEvents(List<vehicle_prop_value_t*>& events);
294    void dispatchHalError(VehicleHalError* error);
295    virtual sp<VehiclePropertiesHolder> listProperties(int32_t property = 0);
296    virtual status_t setProperty(const vehicle_prop_value_t& value);
297    virtual status_t getProperty(vehicle_prop_value_t* value);
298    virtual void releaseMemoryFromGet(vehicle_prop_value_t* value);
299    virtual status_t subscribe(const sp<IVehicleNetworkListener> &listener, int32_t property,
300            float sampleRate, int32_t zones);
301    virtual void unsubscribe(const sp<IVehicleNetworkListener> &listener, int32_t property);
302    virtual status_t injectEvent(const vehicle_prop_value_t& value);
303    virtual status_t startMocking(const sp<IVehicleNetworkHalMock>& mock);
304    virtual void stopMocking(const sp<IVehicleNetworkHalMock>& mock);
305    virtual status_t injectHalError(int32_t errorCode, int32_t property, int32_t operation);
306    virtual status_t startErrorListening(const sp<IVehicleNetworkListener> &listener);
307    virtual void stopErrorListening(const sp<IVehicleNetworkListener> &listener);
308    virtual status_t startHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener);
309    virtual void stopHalRestartMonitoring(const sp<IVehicleNetworkListener> &listener);
310    virtual void binderDied(const wp<IBinder>& who);
311    bool isPropertySubsribed(int32_t property);
312
313    void handleHalMockDeath(const wp<IBinder>& who);
314protected:
315    virtual bool isOperationAllowed(int32_t property, bool isWrite);
316private:
317    // RefBase
318    virtual void onFirstRef();
319    status_t loadHal();
320    void closeHal();
321    vehicle_prop_config_t const * findConfigLocked(int32_t property);
322    bool isGettableLocked(int32_t property);
323    bool isSettableLocked(int32_t property, int32_t valueType);
324    bool isSubscribableLocked(int32_t property);
325    static bool isZonedProperty(vehicle_prop_config_t const * config);
326    sp<HalClient> findClientLocked(sp<IBinder>& ibinder);
327    sp<HalClient> findOrCreateClientLocked(sp<IBinder>& ibinder,
328            const sp<IVehicleNetworkListener> &listener);
329    sp<HalClientSpVector> findClientsVectorForPropertyLocked(int32_t property);
330    sp<HalClientSpVector> findOrCreateClientsVectorForPropertyLocked(int32_t property);
331    bool removePropertyFromClientLocked(sp<IBinder>& ibinder, sp<HalClient>& client,
332            int32_t property);
333    void handleHalRestartAndGetClientsToDispatchLocked(List<sp<HalClient> >& clientsToDispatch);
334
335    static int eventCallback(const vehicle_prop_value_t *eventData);
336    static int errorCallback(int32_t errorCode, int32_t property, int32_t operation);
337private:
338    static const int GET_WAIT_US = 100000;
339    static const int MAX_GET_RETRY_FOR_NOT_READY = 50;
340
341    VehiclePropertyAccessControl mVehiclePropertyAccessControl;
342    static VehicleNetworkService* sInstance;
343    sp<HandlerThread> mHandlerThread;
344    sp<VehicleHalMessageHandler> mHandler;
345    mutable Mutex mLock;
346    vehicle_module_t* mModule;
347    vehicle_hw_device_t* mDevice;
348    sp<VehiclePropertiesHolder> mProperties;
349    KeyedVector<sp<IBinder>, sp<HalClient> > mBinderToClientMap;
350    // client subscribing properties
351    KeyedVector<int32_t, sp<HalClientSpVector> > mPropertyToClientsMap;
352    KeyedVector<int32_t, SubscriptionInfo> mSubscriptionInfos;
353    KeyedVector<int32_t, int> mEventsCount;
354    PropertyValueCache mCache;
355    bool mMockingEnabled;
356    sp<IVehicleNetworkHalMock> mHalMock;
357    sp<VehiclePropertiesHolder> mPropertiesForMocking;
358    sp<MockDeathHandler> mHalMockDeathHandler;
359};
360
361};
362
363#endif /* CAR_VEHICLE_NETWORK_SERVICE_H_ */
364