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 26 namespace android { 27 28 VehicleNetworkEventMessageHandler::VehicleNetworkEventMessageHandler(const sp<Looper>& looper, 29 sp<VehicleNetworkListener>& listener) : 30 mLooper(looper), 31 mListener(listener) { 32 33 } 34 35 VehicleNetworkEventMessageHandler::~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 45 void VehicleNetworkEventMessageHandler::handleHalEvents(sp<VehiclePropValueListHolder>& events) { 46 Mutex::Autolock autoLock(mLock); 47 mEvents.push_back(events); 48 mLooper->sendMessage(this, Message(EVENT_EVENTS)); 49 } 50 51 void 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 63 void VehicleNetworkEventMessageHandler::handleHalRestart(bool inMocking) { 64 Mutex::Autolock autoLock(mLock); 65 mHalRestartEvents.push_back(inMocking); 66 mLooper->sendMessage(this, Message(EVENT_HAL_RESTART)); 67 } 68 69 void 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 84 void 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 100 void 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 117 void 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 133 sp<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 148 VehicleNetwork::VehicleNetwork(sp<IVehicleNetwork>& vehicleNetwork, 149 sp<VehicleNetworkListener> &listener) : 150 mService(vehicleNetwork), 151 mClientListener(listener) { 152 } 153 154 VehicleNetwork::~VehicleNetwork() { 155 sp<IVehicleNetwork> service = getService(); 156 IInterface::asBinder(service)->unlinkToDeath(this); 157 service->stopHalRestartMonitoring(this); 158 mHandlerThread->quit(); 159 } 160 161 void 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 177 status_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 185 status_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 196 status_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 204 status_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 213 status_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 221 status_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 230 status_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 239 status_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 251 sp<VehiclePropertiesHolder> VehicleNetwork::listProperties(int32_t property) { 252 return getService()->listProperties(property); 253 } 254 255 status_t VehicleNetwork::setProperty(const vehicle_prop_value_t& value) { 256 return getService()->setProperty(value); 257 } 258 259 status_t VehicleNetwork::getProperty(vehicle_prop_value_t* value) { 260 return getService()->getProperty(value); 261 } 262 263 status_t VehicleNetwork::subscribe(int32_t property, float sampleRate, int32_t zones) { 264 return getService()->subscribe(this, property, sampleRate, zones); 265 } 266 267 void VehicleNetwork::unsubscribe(int32_t property) { 268 getService()->unsubscribe(this, property); 269 } 270 271 status_t VehicleNetwork::injectEvent(const vehicle_prop_value_t& value) { 272 return getService()->injectEvent(value); 273 } 274 275 status_t VehicleNetwork::startMocking(const sp<IVehicleNetworkHalMock>& mock) { 276 return getService()->startMocking(mock); 277 } 278 279 void VehicleNetwork::stopMocking(const sp<IVehicleNetworkHalMock>& mock) { 280 getService()->stopMocking(mock); 281 } 282 283 status_t VehicleNetwork::startErrorListening() { 284 return getService()->startErrorListening(this); 285 } 286 287 void VehicleNetwork::stopErrorListening() { 288 getService()->stopErrorListening(this); 289 } 290 291 void 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 306 sp<IVehicleNetwork> VehicleNetwork::getService() { 307 Mutex::Autolock autoLock(mLock); 308 return mService; 309 } 310 311 sp<VehicleNetworkEventMessageHandler> VehicleNetwork::getEventHandler() { 312 Mutex::Autolock autoLock(mLock); 313 return mEventHandler; 314 } 315 316 void VehicleNetwork::onEvents(sp<VehiclePropValueListHolder>& events) { 317 getEventHandler()->handleHalEvents(events); 318 } 319 320 void VehicleNetwork::onHalError(int32_t errorCode, int32_t property, int32_t operation) { 321 getEventHandler()->handleHalError(errorCode, property, operation); 322 } 323 324 void VehicleNetwork::onHalRestart(bool inMocking) { 325 getEventHandler()->handleHalRestart(inMocking); 326 } 327 }; // namespace android 328