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#define LOG_TAG "VehicleNetwork.Lib"
17
18#include <binder/IServiceManager.h>
19#include <binder/ProcessState.h>
20#include <utils/threads.h>
21
22#include <hardware/vehicle.h>
23
24#include <VehicleNetwork.h>
25
26namespace android {
27
28VehicleNetworkEventMessageHandler::VehicleNetworkEventMessageHandler(const sp<Looper>& looper,
29            sp<VehicleNetworkListener>& listener) :
30            mLooper(looper),
31            mListener(listener) {
32
33}
34
35VehicleNetworkEventMessageHandler::~VehicleNetworkEventMessageHandler() {
36    Mutex::Autolock autoLock(mLock);
37    mEvents.clear();
38    for (VehicleHalError* e : mHalErrors) {
39        delete e;
40    }
41    mHalErrors.clear();
42    mHalRestartEvents.clear();
43}
44
45void VehicleNetworkEventMessageHandler::handleHalEvents(sp<VehiclePropValueListHolder>& events) {
46    Mutex::Autolock autoLock(mLock);
47    mEvents.push_back(events);
48    mLooper->sendMessage(this, Message(EVENT_EVENTS));
49}
50
51void VehicleNetworkEventMessageHandler::handleHalError(int32_t errorCode, int32_t property,
52        int32_t operation) {
53    Mutex::Autolock autoLock(mLock);
54    VehicleHalError* error = new VehicleHalError(errorCode, property, operation);
55    if (error == NULL) {
56        ALOGE("VehicleNetworkEventMessageHandler::handleHalError, new failed");
57        return;
58    }
59    mHalErrors.push_back(error);
60    mLooper->sendMessage(this, Message(EVENT_HAL_ERROR));
61}
62
63void VehicleNetworkEventMessageHandler::handleHalRestart(bool inMocking) {
64    Mutex::Autolock autoLock(mLock);
65    mHalRestartEvents.push_back(inMocking);
66    mLooper->sendMessage(this, Message(EVENT_HAL_RESTART));
67}
68
69void VehicleNetworkEventMessageHandler::doHandleHalEvents() {
70    sp<VehiclePropValueListHolder> values;
71    do {
72        Mutex::Autolock autoLock(mLock);
73        if (mEvents.size() > 0) {
74            auto itr = mEvents.begin();
75            values = *itr;
76            mEvents.erase(itr);
77        }
78    } while (false);
79    if (values.get() != NULL) {
80        mListener->onEvents(values);
81    }
82}
83
84void VehicleNetworkEventMessageHandler::doHandleHalError() {
85    VehicleHalError* error = NULL;
86    do {
87        Mutex::Autolock autoLock(mLock);
88        if (mHalErrors.size() > 0) {
89            auto itr = mHalErrors.begin();
90            error = *itr;
91            mHalErrors.erase(itr);
92        }
93    } while (false);
94    if (error != NULL) {
95        mListener->onHalError(error->errorCode, error->property, error->operation);
96        delete error;
97    }
98}
99
100void VehicleNetworkEventMessageHandler::doHandleHalRestart() {
101    bool shouldDispatch = false;
102    bool inMocking = false;
103    do {
104        Mutex::Autolock autoLock(mLock);
105        if (mHalRestartEvents.size() > 0) {
106            auto itr = mHalRestartEvents.begin();
107            inMocking = *itr;
108            mHalRestartEvents.erase(itr);
109            shouldDispatch = true;
110        }
111    } while (false);
112    if (shouldDispatch) {
113        mListener->onHalRestart(inMocking);
114    }
115}
116
117void VehicleNetworkEventMessageHandler::handleMessage(const Message& message) {
118    switch (message.what) {
119    case EVENT_EVENTS:
120        doHandleHalEvents();
121        break;
122    case EVENT_HAL_ERROR:
123        doHandleHalError();
124        break;
125    case EVENT_HAL_RESTART:
126        doHandleHalRestart();
127        break;
128    }
129}
130
131// ----------------------------------------------------------------------------
132
133sp<VehicleNetwork> VehicleNetwork::createVehicleNetwork(sp<VehicleNetworkListener>& listener) {
134    sp<IBinder> binder = defaultServiceManager()->getService(
135            String16(IVehicleNetwork::SERVICE_NAME));
136    sp<VehicleNetwork> vn;
137    if (binder != NULL) {
138        sp<IVehicleNetwork> ivn(interface_cast<IVehicleNetwork>(binder));
139        vn = new VehicleNetwork(ivn, listener);
140        if (vn != NULL) {
141            // in case thread pool is not started, start it.
142            ProcessState::self()->startThreadPool();
143        }
144    }
145    return vn;
146}
147
148VehicleNetwork::VehicleNetwork(sp<IVehicleNetwork>& vehicleNetwork,
149        sp<VehicleNetworkListener> &listener) :
150        mService(vehicleNetwork),
151        mClientListener(listener) {
152}
153
154VehicleNetwork::~VehicleNetwork() {
155    sp<IVehicleNetwork> service = getService();
156    IInterface::asBinder(service)->unlinkToDeath(this);
157    service->stopHalRestartMonitoring(this);
158    mHandlerThread->quit();
159}
160
161void VehicleNetwork::onFirstRef() {
162    Mutex::Autolock autoLock(mLock);
163    mHandlerThread = new HandlerThread();
164    status_t r = mHandlerThread->start("VNS.NATIVE_LOOP");
165    if (r != NO_ERROR) {
166        ALOGE("cannot start handler thread, error:%d", r);
167        return;
168    }
169    sp<VehicleNetworkEventMessageHandler> handler(
170            new VehicleNetworkEventMessageHandler(mHandlerThread->getLooper(), mClientListener));
171    ASSERT_ALWAYS_ON_NO_MEMORY(handler.get());
172    mEventHandler = handler;
173    IInterface::asBinder(mService)->linkToDeath(this);
174    mService->startHalRestartMonitoring(this);
175}
176
177status_t VehicleNetwork::setInt32Property(int32_t property, int32_t value) {
178    vehicle_prop_value_t v;
179    v.prop = property;
180    v.value_type = VEHICLE_VALUE_TYPE_INT32;
181    v.value.int32_value = value;
182    return setProperty(v);
183}
184
185status_t VehicleNetwork::getInt32Property(int32_t property, int32_t* value, int64_t* timestamp) {
186    vehicle_prop_value_t v;
187    v.prop = property;
188    // do not check error as it is always safe to access members for this data type.
189    // saves one if for normal flow.
190    status_t r = getProperty(&v);
191    *value = v.value.int32_value;
192    *timestamp = v.timestamp;
193    return r;
194}
195
196status_t VehicleNetwork::setInt64Property(int32_t property, int64_t value) {
197    vehicle_prop_value_t v;
198    v.prop = property;
199    v.value_type = VEHICLE_VALUE_TYPE_INT64;
200    v.value.int64_value = value;
201    return setProperty(v);
202}
203
204status_t VehicleNetwork::getInt64Property(int32_t property, int64_t* value, int64_t* timestamp) {
205    vehicle_prop_value_t v;
206    v.prop = property;
207    status_t r = getProperty(&v);
208    *value = v.value.int64_value;
209    *timestamp = v.timestamp;
210    return r;
211}
212
213status_t VehicleNetwork::setFloatProperty(int32_t property, float value) {
214    vehicle_prop_value_t v;
215    v.prop = property;
216    v.value_type = VEHICLE_VALUE_TYPE_FLOAT;
217    v.value.float_value = value;
218    return setProperty(v);
219}
220
221status_t VehicleNetwork::getFloatProperty(int32_t property, float* value, int64_t* timestamp) {
222    vehicle_prop_value_t v;
223    v.prop = property;
224    status_t r = getProperty(&v);
225    *value = v.value.float_value;
226    *timestamp = v.timestamp;
227    return r;
228}
229
230status_t VehicleNetwork::setStringProperty(int32_t property, const String8& value) {
231    vehicle_prop_value_t v;
232    v.prop = property;
233    v.value_type = VEHICLE_VALUE_TYPE_STRING;
234    v.value.str_value.data = (uint8_t*)value.string();
235    v.value.str_value.len = value.length();
236    return setProperty(v);
237}
238
239status_t VehicleNetwork::getStringProperty(int32_t property, String8& value, int64_t* timestamp) {
240    vehicle_prop_value_t v;
241    v.prop = property;
242    v.value.str_value.len = 0;
243    status_t r = getProperty(&v);
244    if (r == NO_ERROR) {
245        value.setTo((char*)v.value.str_value.data, v.value.str_value.len);
246    }
247    *timestamp = v.timestamp;
248    return r;
249}
250
251sp<VehiclePropertiesHolder> VehicleNetwork::listProperties(int32_t property) {
252    return getService()->listProperties(property);
253}
254
255status_t VehicleNetwork::setProperty(const vehicle_prop_value_t& value) {
256    return getService()->setProperty(value);
257}
258
259status_t VehicleNetwork::getProperty(vehicle_prop_value_t* value) {
260    return getService()->getProperty(value);
261}
262
263status_t VehicleNetwork::subscribe(int32_t property, float sampleRate, int32_t zones) {
264    return getService()->subscribe(this, property, sampleRate, zones);
265}
266
267void VehicleNetwork::unsubscribe(int32_t property) {
268    getService()->unsubscribe(this, property);
269}
270
271status_t VehicleNetwork::injectEvent(const vehicle_prop_value_t& value) {
272    return getService()->injectEvent(value);
273}
274
275status_t VehicleNetwork::startMocking(const sp<IVehicleNetworkHalMock>& mock) {
276    return getService()->startMocking(mock);
277}
278
279void VehicleNetwork::stopMocking(const sp<IVehicleNetworkHalMock>& mock) {
280    getService()->stopMocking(mock);
281}
282
283status_t VehicleNetwork::startErrorListening() {
284    return getService()->startErrorListening(this);
285}
286
287void VehicleNetwork::stopErrorListening() {
288    getService()->stopErrorListening(this);
289}
290
291void VehicleNetwork::binderDied(const wp<IBinder>& who) {
292    ALOGE("service died");
293    do {
294        Mutex::Autolock autoLock(mLock);
295        sp<IBinder> ibinder = who.promote();
296        ibinder->unlinkToDeath(this);
297        sp<IBinder> binder = defaultServiceManager()->getService(
298                String16(IVehicleNetwork::SERVICE_NAME));
299        mService = interface_cast<IVehicleNetwork>(binder);
300        IInterface::asBinder(mService)->linkToDeath(this);
301        mService->startHalRestartMonitoring(this);
302    } while (false);
303    onHalRestart(false);
304}
305
306sp<IVehicleNetwork> VehicleNetwork::getService() {
307    Mutex::Autolock autoLock(mLock);
308    return mService;
309}
310
311sp<VehicleNetworkEventMessageHandler> VehicleNetwork::getEventHandler() {
312    Mutex::Autolock autoLock(mLock);
313    return mEventHandler;
314}
315
316void VehicleNetwork::onEvents(sp<VehiclePropValueListHolder>& events) {
317    getEventHandler()->handleHalEvents(events);
318}
319
320void VehicleNetwork::onHalError(int32_t errorCode, int32_t property, int32_t operation) {
321    getEventHandler()->handleHalError(errorCode, property, operation);
322}
323
324void VehicleNetwork::onHalRestart(bool inMocking) {
325    getEventHandler()->handleHalRestart(inMocking);
326}
327}; // namespace android
328