blob: 2a4c548e8ba7135f2dc67032316498122c4aa84b [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 */
Keun-young Park28dd4702015-11-19 18:06:04 -080016#define LOG_TAG "VehicleNetwork.Lib"
keunyounge18e25d2015-08-28 15:57:19 -070017
Keun-young Park809b5472016-05-20 13:27:28 -070018#include <assert.h>
keunyounge18e25d2015-08-28 15:57:19 -070019#include <binder/IServiceManager.h>
20#include <binder/ProcessState.h>
21#include <utils/threads.h>
22
23#include <hardware/vehicle.h>
24
25#include <VehicleNetwork.h>
26
27namespace android {
28
Keun-young Park28dd4702015-11-19 18:06:04 -080029VehicleNetworkEventMessageHandler::VehicleNetworkEventMessageHandler(const sp<Looper>& looper,
30 sp<VehicleNetworkListener>& listener) :
31 mLooper(looper),
32 mListener(listener) {
33
34}
35
36VehicleNetworkEventMessageHandler::~VehicleNetworkEventMessageHandler() {
37 Mutex::Autolock autoLock(mLock);
38 mEvents.clear();
39 for (VehicleHalError* e : mHalErrors) {
40 delete e;
41 }
42 mHalErrors.clear();
43 mHalRestartEvents.clear();
Pavel Maltsevb0324b42016-09-27 21:00:41 -070044 mSetValueEvents.clear();
Keun-young Park28dd4702015-11-19 18:06:04 -080045}
46
47void VehicleNetworkEventMessageHandler::handleHalEvents(sp<VehiclePropValueListHolder>& events) {
48 Mutex::Autolock autoLock(mLock);
49 mEvents.push_back(events);
50 mLooper->sendMessage(this, Message(EVENT_EVENTS));
51}
52
53void VehicleNetworkEventMessageHandler::handleHalError(int32_t errorCode, int32_t property,
54 int32_t operation) {
55 Mutex::Autolock autoLock(mLock);
56 VehicleHalError* error = new VehicleHalError(errorCode, property, operation);
57 if (error == NULL) {
58 ALOGE("VehicleNetworkEventMessageHandler::handleHalError, new failed");
59 return;
60 }
61 mHalErrors.push_back(error);
62 mLooper->sendMessage(this, Message(EVENT_HAL_ERROR));
63}
64
65void VehicleNetworkEventMessageHandler::handleHalRestart(bool inMocking) {
66 Mutex::Autolock autoLock(mLock);
67 mHalRestartEvents.push_back(inMocking);
68 mLooper->sendMessage(this, Message(EVENT_HAL_RESTART));
69}
70
Pavel Maltsevb0324b42016-09-27 21:00:41 -070071void VehicleNetworkEventMessageHandler::handleOnPropertySet(const vehicle_prop_value_t& value) {
72 Mutex::Autolock autoLock(mLock);
Keun-young Park7151bb32016-10-12 21:14:19 -070073 mSetValueEvents.push_back(VehiclePropValueUtil::allocVehiclePropValue(value));
Pavel Maltsevb0324b42016-09-27 21:00:41 -070074 mLooper->sendMessage(this, Message(EVENT_ON_SET));
75}
76
Keun-young Park28dd4702015-11-19 18:06:04 -080077void VehicleNetworkEventMessageHandler::doHandleHalEvents() {
78 sp<VehiclePropValueListHolder> values;
79 do {
80 Mutex::Autolock autoLock(mLock);
81 if (mEvents.size() > 0) {
82 auto itr = mEvents.begin();
83 values = *itr;
84 mEvents.erase(itr);
85 }
86 } while (false);
87 if (values.get() != NULL) {
88 mListener->onEvents(values);
89 }
90}
91
92void VehicleNetworkEventMessageHandler::doHandleHalError() {
93 VehicleHalError* error = NULL;
94 do {
95 Mutex::Autolock autoLock(mLock);
96 if (mHalErrors.size() > 0) {
97 auto itr = mHalErrors.begin();
98 error = *itr;
99 mHalErrors.erase(itr);
100 }
101 } while (false);
102 if (error != NULL) {
103 mListener->onHalError(error->errorCode, error->property, error->operation);
104 delete error;
105 }
106}
107
108void VehicleNetworkEventMessageHandler::doHandleHalRestart() {
109 bool shouldDispatch = false;
110 bool inMocking = false;
111 do {
112 Mutex::Autolock autoLock(mLock);
113 if (mHalRestartEvents.size() > 0) {
114 auto itr = mHalRestartEvents.begin();
115 inMocking = *itr;
116 mHalRestartEvents.erase(itr);
117 shouldDispatch = true;
118 }
119 } while (false);
120 if (shouldDispatch) {
121 mListener->onHalRestart(inMocking);
122 }
123}
124
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700125void VehicleNetworkEventMessageHandler::doHandleOnPropertySet() {
126 vehicle_prop_value_t* value = nullptr;
127 {
128 Mutex::Autolock autoLock(mLock);
129 if (!mSetValueEvents.empty()) {
130 auto itr = mSetValueEvents.begin();
131 value = *itr;
132 mSetValueEvents.erase(itr);
133 }
134 }
135 if (value != nullptr) {
136 mListener->onPropertySet(*value);
137 VehiclePropValueUtil::deleteMembers(value);
138 delete value;
139 }
140}
141
Keun-young Park28dd4702015-11-19 18:06:04 -0800142void VehicleNetworkEventMessageHandler::handleMessage(const Message& message) {
143 switch (message.what) {
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700144 case EVENT_EVENTS:
145 doHandleHalEvents();
146 break;
147 case EVENT_HAL_ERROR:
148 doHandleHalError();
149 break;
150 case EVENT_HAL_RESTART:
151 doHandleHalRestart();
152 break;
153 case EVENT_ON_SET:
154 doHandleOnPropertySet();
155 break;
Keun-young Park28dd4702015-11-19 18:06:04 -0800156 }
157}
158
159// ----------------------------------------------------------------------------
160
Keun-young Park809b5472016-05-20 13:27:28 -0700161static const int MAX_SERVICE_RETRY = 4;
162
keunyounge18e25d2015-08-28 15:57:19 -0700163sp<VehicleNetwork> VehicleNetwork::createVehicleNetwork(sp<VehicleNetworkListener>& listener) {
Keun-young Park809b5472016-05-20 13:27:28 -0700164 sp<IBinder> binder;
165 int retry = 0;
166 while (true) {
167 binder = defaultServiceManager()->getService(String16(IVehicleNetwork::SERVICE_NAME));
168 if (binder.get() != NULL) {
169 break;
170 }
171 retry++;
172 if (retry > MAX_SERVICE_RETRY) {
173 ALOGE("cannot get VNS, will crash");
174 break;
keunyounge18e25d2015-08-28 15:57:19 -0700175 }
176 }
Keun-young Park809b5472016-05-20 13:27:28 -0700177 ASSERT_ALWAYS_ON_NO_MEMORY(binder.get());
178 sp<IVehicleNetwork> ivn(interface_cast<IVehicleNetwork>(binder));
179 sp<VehicleNetwork> vn;
180 vn = new VehicleNetwork(ivn, listener);
181 ASSERT_ALWAYS_ON_NO_MEMORY(vn.get());
182 // in case thread pool is not started, start it.
183 ProcessState::self()->startThreadPool();
keunyounge18e25d2015-08-28 15:57:19 -0700184 return vn;
185}
186
187VehicleNetwork::VehicleNetwork(sp<IVehicleNetwork>& vehicleNetwork,
188 sp<VehicleNetworkListener> &listener) :
189 mService(vehicleNetwork),
190 mClientListener(listener) {
191}
192
193VehicleNetwork::~VehicleNetwork() {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800194 sp<IVehicleNetwork> service = getService();
195 IInterface::asBinder(service)->unlinkToDeath(this);
196 service->stopHalRestartMonitoring(this);
Keun-young Park28dd4702015-11-19 18:06:04 -0800197 mHandlerThread->quit();
198}
199
200void VehicleNetwork::onFirstRef() {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800201 Mutex::Autolock autoLock(mLock);
Keun-young Park28dd4702015-11-19 18:06:04 -0800202 mHandlerThread = new HandlerThread();
203 status_t r = mHandlerThread->start("VNS.NATIVE_LOOP");
204 if (r != NO_ERROR) {
205 ALOGE("cannot start handler thread, error:%d", r);
206 return;
207 }
208 sp<VehicleNetworkEventMessageHandler> handler(
209 new VehicleNetworkEventMessageHandler(mHandlerThread->getLooper(), mClientListener));
210 ASSERT_ALWAYS_ON_NO_MEMORY(handler.get());
211 mEventHandler = handler;
212 IInterface::asBinder(mService)->linkToDeath(this);
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800213 mService->startHalRestartMonitoring(this);
keunyounge18e25d2015-08-28 15:57:19 -0700214}
215
216status_t VehicleNetwork::setInt32Property(int32_t property, int32_t value) {
217 vehicle_prop_value_t v;
218 v.prop = property;
219 v.value_type = VEHICLE_VALUE_TYPE_INT32;
220 v.value.int32_value = value;
221 return setProperty(v);
222}
223
224status_t VehicleNetwork::getInt32Property(int32_t property, int32_t* value, int64_t* timestamp) {
225 vehicle_prop_value_t v;
226 v.prop = property;
227 // do not check error as it is always safe to access members for this data type.
228 // saves one if for normal flow.
229 status_t r = getProperty(&v);
230 *value = v.value.int32_value;
231 *timestamp = v.timestamp;
232 return r;
233}
234
235status_t VehicleNetwork::setInt64Property(int32_t property, int64_t value) {
236 vehicle_prop_value_t v;
237 v.prop = property;
238 v.value_type = VEHICLE_VALUE_TYPE_INT64;
239 v.value.int64_value = value;
240 return setProperty(v);
241}
242
243status_t VehicleNetwork::getInt64Property(int32_t property, int64_t* value, int64_t* timestamp) {
244 vehicle_prop_value_t v;
245 v.prop = property;
246 status_t r = getProperty(&v);
247 *value = v.value.int64_value;
248 *timestamp = v.timestamp;
249 return r;
250}
251
252status_t VehicleNetwork::setFloatProperty(int32_t property, float value) {
253 vehicle_prop_value_t v;
254 v.prop = property;
255 v.value_type = VEHICLE_VALUE_TYPE_FLOAT;
256 v.value.float_value = value;
257 return setProperty(v);
258}
259
260status_t VehicleNetwork::getFloatProperty(int32_t property, float* value, int64_t* timestamp) {
261 vehicle_prop_value_t v;
262 v.prop = property;
263 status_t r = getProperty(&v);
264 *value = v.value.float_value;
265 *timestamp = v.timestamp;
266 return r;
267}
268
269status_t VehicleNetwork::setStringProperty(int32_t property, const String8& value) {
270 vehicle_prop_value_t v;
271 v.prop = property;
272 v.value_type = VEHICLE_VALUE_TYPE_STRING;
273 v.value.str_value.data = (uint8_t*)value.string();
274 v.value.str_value.len = value.length();
275 return setProperty(v);
276}
277
278status_t VehicleNetwork::getStringProperty(int32_t property, String8& value, int64_t* timestamp) {
279 vehicle_prop_value_t v;
280 v.prop = property;
keunyoung7d74e6d2015-10-14 15:43:10 -0700281 v.value.str_value.len = 0;
keunyounge18e25d2015-08-28 15:57:19 -0700282 status_t r = getProperty(&v);
283 if (r == NO_ERROR) {
284 value.setTo((char*)v.value.str_value.data, v.value.str_value.len);
285 }
286 *timestamp = v.timestamp;
287 return r;
288}
289
290sp<VehiclePropertiesHolder> VehicleNetwork::listProperties(int32_t property) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800291 return getService()->listProperties(property);
keunyounge18e25d2015-08-28 15:57:19 -0700292}
293
294status_t VehicleNetwork::setProperty(const vehicle_prop_value_t& value) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800295 return getService()->setProperty(value);
keunyounge18e25d2015-08-28 15:57:19 -0700296}
297
298status_t VehicleNetwork::getProperty(vehicle_prop_value_t* value) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800299 return getService()->getProperty(value);
keunyounge18e25d2015-08-28 15:57:19 -0700300}
301
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700302status_t VehicleNetwork::subscribe(int32_t property, float sampleRate, int32_t zones,
303 int32_t flags) {
304 return getService()->subscribe(this, property, sampleRate, zones, flags);
keunyounge18e25d2015-08-28 15:57:19 -0700305}
306
307void VehicleNetwork::unsubscribe(int32_t property) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800308 getService()->unsubscribe(this, property);
keunyounge18e25d2015-08-28 15:57:19 -0700309}
310
Keun-young Park28dd4702015-11-19 18:06:04 -0800311status_t VehicleNetwork::injectEvent(const vehicle_prop_value_t& value) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800312 return getService()->injectEvent(value);
Keun-young Park28dd4702015-11-19 18:06:04 -0800313}
314
315status_t VehicleNetwork::startMocking(const sp<IVehicleNetworkHalMock>& mock) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800316 return getService()->startMocking(mock);
Keun-young Park28dd4702015-11-19 18:06:04 -0800317}
318
319void VehicleNetwork::stopMocking(const sp<IVehicleNetworkHalMock>& mock) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800320 getService()->stopMocking(mock);
Keun-young Park28dd4702015-11-19 18:06:04 -0800321}
322
323status_t VehicleNetwork::startErrorListening() {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800324 return getService()->startErrorListening(this);
Keun-young Park28dd4702015-11-19 18:06:04 -0800325}
326
327void VehicleNetwork::stopErrorListening() {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800328 getService()->stopErrorListening(this);
Keun-young Park28dd4702015-11-19 18:06:04 -0800329}
330
keunyounge18e25d2015-08-28 15:57:19 -0700331void VehicleNetwork::binderDied(const wp<IBinder>& who) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800332 ALOGE("service died");
333 do {
334 Mutex::Autolock autoLock(mLock);
335 sp<IBinder> ibinder = who.promote();
336 ibinder->unlinkToDeath(this);
337 sp<IBinder> binder = defaultServiceManager()->getService(
338 String16(IVehicleNetwork::SERVICE_NAME));
339 mService = interface_cast<IVehicleNetwork>(binder);
340 IInterface::asBinder(mService)->linkToDeath(this);
341 mService->startHalRestartMonitoring(this);
342 } while (false);
343 onHalRestart(false);
344}
345
346sp<IVehicleNetwork> VehicleNetwork::getService() {
347 Mutex::Autolock autoLock(mLock);
348 return mService;
349}
350
351sp<VehicleNetworkEventMessageHandler> VehicleNetwork::getEventHandler() {
352 Mutex::Autolock autoLock(mLock);
353 return mEventHandler;
keunyounge18e25d2015-08-28 15:57:19 -0700354}
355
Keun-young Park28dd4702015-11-19 18:06:04 -0800356void VehicleNetwork::onEvents(sp<VehiclePropValueListHolder>& events) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800357 getEventHandler()->handleHalEvents(events);
keunyounge18e25d2015-08-28 15:57:19 -0700358}
359
Keun-young Park28dd4702015-11-19 18:06:04 -0800360void VehicleNetwork::onHalError(int32_t errorCode, int32_t property, int32_t operation) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800361 getEventHandler()->handleHalError(errorCode, property, operation);
Keun-young Park28dd4702015-11-19 18:06:04 -0800362}
363
364void VehicleNetwork::onHalRestart(bool inMocking) {
Keun-young Parkaaeffaf2015-11-25 17:24:10 -0800365 getEventHandler()->handleHalRestart(inMocking);
Keun-young Park28dd4702015-11-19 18:06:04 -0800366}
Pavel Maltsevb0324b42016-09-27 21:00:41 -0700367
368void VehicleNetwork::onPropertySet(const vehicle_prop_value_t& value) {
369 getEventHandler()->handleOnPropertySet(value);
370}
keunyounge18e25d2015-08-28 15:57:19 -0700371}; // namespace android