1 /* 2 * Copyright (C) 2010 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 #include <inttypes.h> 18 #include <math.h> 19 #include <stdint.h> 20 #include <sys/types.h> 21 22 #include <utils/Atomic.h> 23 #include <utils/Errors.h> 24 #include <utils/Singleton.h> 25 26 #include <binder/BinderService.h> 27 #include <binder/Parcel.h> 28 #include <binder/IServiceManager.h> 29 30 #include <hardware/sensors.h> 31 32 #include "SensorDevice.h" 33 #include "SensorService.h" 34 35 namespace android { 36 // --------------------------------------------------------------------------- 37 38 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice) 39 40 SensorDevice::SensorDevice() 41 : mSensorDevice(0), 42 mSensorModule(0) { 43 status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, 44 (hw_module_t const**)&mSensorModule); 45 46 ALOGE_IF(err, "couldn't load %s module (%s)", 47 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 48 49 if (mSensorModule) { 50 err = sensors_open_1(&mSensorModule->common, &mSensorDevice); 51 52 ALOGE_IF(err, "couldn't open device for module %s (%s)", 53 SENSORS_HARDWARE_MODULE_ID, strerror(-err)); 54 55 if (mSensorDevice) { 56 if (mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_1 || 57 mSensorDevice->common.version == SENSORS_DEVICE_API_VERSION_1_2) { 58 ALOGE(">>>> WARNING <<< Upgrade sensor HAL to version 1_3"); 59 } 60 61 sensor_t const* list; 62 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); 63 mActivationCount.setCapacity(count); 64 Info model; 65 for (size_t i=0 ; i<size_t(count) ; i++) { 66 mActivationCount.add(list[i].handle, model); 67 mSensorDevice->activate( 68 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), 69 list[i].handle, 0); 70 } 71 } 72 } 73 } 74 75 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) { 76 if (connected) { 77 Info model; 78 mActivationCount.add(handle, model); 79 mSensorDevice->activate( 80 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, 0); 81 } else { 82 mActivationCount.removeItem(handle); 83 } 84 } 85 86 std::string SensorDevice::dump() const { 87 if (!mSensorModule) return "HAL not initialized\n"; 88 89 String8 result; 90 sensor_t const* list; 91 int count = mSensorModule->get_sensors_list(mSensorModule, &list); 92 93 result.appendFormat("HAL: %s (%s), version %#010x\n", 94 mSensorModule->common.name, 95 mSensorModule->common.author, 96 getHalDeviceVersion()); 97 result.appendFormat("Total %d h/w sensors, %zu running:\n", count, mActivationCount.size()); 98 99 Mutex::Autolock _l(mLock); 100 for (int i = 0 ; i < count ; i++) { 101 const Info& info = mActivationCount.valueFor(list[i].handle); 102 if (info.batchParams.isEmpty()) continue; 103 result.appendFormat("0x%08x) active-count = %zu; ", list[i].handle, 104 info.batchParams.size()); 105 106 result.append("sampling_period(ms) = {"); 107 for (size_t j = 0; j < info.batchParams.size(); j++) { 108 const BatchParams& params = info.batchParams.valueAt(j); 109 result.appendFormat("%.1f%s", params.batchDelay / 1e6f, 110 j < info.batchParams.size() - 1 ? ", " : ""); 111 } 112 result.appendFormat("}, selected = %.1f ms; ", info.bestBatchParams.batchDelay / 1e6f); 113 114 result.append("batching_period(ms) = {"); 115 for (size_t j = 0; j < info.batchParams.size(); j++) { 116 BatchParams params = info.batchParams.valueAt(j); 117 result.appendFormat("%.1f%s", params.batchTimeout / 1e6f, 118 j < info.batchParams.size() - 1 ? ", " : ""); 119 } 120 result.appendFormat("}, selected = %.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f); 121 } 122 return result.string(); 123 } 124 125 ssize_t SensorDevice::getSensorList(sensor_t const** list) { 126 if (!mSensorModule) return NO_INIT; 127 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list); 128 return count; 129 } 130 131 status_t SensorDevice::initCheck() const { 132 return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT; 133 } 134 135 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) { 136 if (!mSensorDevice) return NO_INIT; 137 ssize_t c; 138 do { 139 c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), 140 buffer, count); 141 } while (c == -EINTR); 142 return c; 143 } 144 145 void SensorDevice::autoDisable(void *ident, int handle) { 146 Info& info( mActivationCount.editValueFor(handle) ); 147 Mutex::Autolock _l(mLock); 148 info.removeBatchParamsForIdent(ident); 149 } 150 151 status_t SensorDevice::activate(void* ident, int handle, int enabled) { 152 if (!mSensorDevice) return NO_INIT; 153 status_t err(NO_ERROR); 154 bool actuateHardware = false; 155 156 Mutex::Autolock _l(mLock); 157 Info& info( mActivationCount.editValueFor(handle) ); 158 159 ALOGD_IF(DEBUG_CONNECTIONS, 160 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu", 161 ident, handle, enabled, info.batchParams.size()); 162 163 if (enabled) { 164 ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident)); 165 166 if (isClientDisabledLocked(ident)) { 167 return INVALID_OPERATION; 168 } 169 170 if (info.batchParams.indexOfKey(ident) >= 0) { 171 if (info.numActiveClients() == 1) { 172 // This is the first connection, we need to activate the underlying h/w sensor. 173 actuateHardware = true; 174 } 175 } else { 176 // Log error. Every activate call should be preceded by a batch() call. 177 ALOGE("\t >>>ERROR: activate called without batch"); 178 } 179 } else { 180 ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident)); 181 182 if (info.removeBatchParamsForIdent(ident) >= 0) { 183 if (info.numActiveClients() == 0) { 184 // This is the last connection, we need to de-activate the underlying h/w sensor. 185 actuateHardware = true; 186 } else { 187 const int halVersion = getHalDeviceVersion(); 188 if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { 189 // Call batch for this sensor with the previously calculated best effort 190 // batch_rate and timeout. One of the apps has unregistered for sensor 191 // events, and the best effort batch parameters might have changed. 192 ALOGD_IF(DEBUG_CONNECTIONS, 193 "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle, 194 info.bestBatchParams.flags, info.bestBatchParams.batchDelay, 195 info.bestBatchParams.batchTimeout); 196 mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags, 197 info.bestBatchParams.batchDelay, 198 info.bestBatchParams.batchTimeout); 199 } 200 } 201 } else { 202 // sensor wasn't enabled for this ident 203 } 204 205 if (isClientDisabledLocked(ident)) { 206 return NO_ERROR; 207 } 208 } 209 210 if (actuateHardware) { 211 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, 212 enabled); 213 err = mSensorDevice->activate( 214 reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled); 215 ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle, 216 strerror(-err)); 217 218 if (err != NO_ERROR && enabled) { 219 // Failure when enabling the sensor. Clean up on failure. 220 info.removeBatchParamsForIdent(ident); 221 } 222 } 223 224 // On older devices which do not support batch, call setDelay(). 225 if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.numActiveClients() > 0) { 226 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle, 227 info.bestBatchParams.batchDelay); 228 mSensorDevice->setDelay( 229 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), 230 handle, info.bestBatchParams.batchDelay); 231 } 232 return err; 233 } 234 235 status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs, 236 int64_t maxBatchReportLatencyNs) { 237 if (!mSensorDevice) return NO_INIT; 238 239 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) { 240 samplingPeriodNs = MINIMUM_EVENTS_PERIOD; 241 } 242 243 const int halVersion = getHalDeviceVersion(); 244 if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 && maxBatchReportLatencyNs != 0) { 245 // Batch is not supported on older devices return invalid operation. 246 return INVALID_OPERATION; 247 } 248 249 ALOGD_IF(DEBUG_CONNECTIONS, 250 "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64, 251 ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs); 252 253 Mutex::Autolock _l(mLock); 254 Info& info(mActivationCount.editValueFor(handle)); 255 256 if (info.batchParams.indexOfKey(ident) < 0) { 257 BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs); 258 info.batchParams.add(ident, params); 259 } else { 260 // A batch has already been called with this ident. Update the batch parameters. 261 info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs); 262 } 263 264 BatchParams prevBestBatchParams = info.bestBatchParams; 265 // Find the minimum of all timeouts and batch_rates for this sensor. 266 info.selectBatchParams(); 267 268 ALOGD_IF(DEBUG_CONNECTIONS, 269 "\t>>> curr_period=%" PRId64 " min_period=%" PRId64 270 " curr_timeout=%" PRId64 " min_timeout=%" PRId64, 271 prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay, 272 prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout); 273 274 status_t err(NO_ERROR); 275 // If the min period or min timeout has changed since the last batch call, call batch. 276 if (prevBestBatchParams != info.bestBatchParams) { 277 if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) { 278 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle, 279 info.bestBatchParams.flags, info.bestBatchParams.batchDelay, 280 info.bestBatchParams.batchTimeout); 281 err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags, 282 info.bestBatchParams.batchDelay, 283 info.bestBatchParams.batchTimeout); 284 } else { 285 // For older devices which do not support batch, call setDelay() after activate() is 286 // called. Some older devices may not support calling setDelay before activate(), so 287 // call setDelay in SensorDevice::activate() method. 288 } 289 if (err != NO_ERROR) { 290 ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s", 291 mSensorDevice, handle, 292 info.bestBatchParams.flags, info.bestBatchParams.batchDelay, 293 info.bestBatchParams.batchTimeout, strerror(-err)); 294 info.removeBatchParamsForIdent(ident); 295 } 296 } 297 return err; 298 } 299 300 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) { 301 if (!mSensorDevice) return NO_INIT; 302 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) { 303 samplingPeriodNs = MINIMUM_EVENTS_PERIOD; 304 } 305 Mutex::Autolock _l(mLock); 306 if (isClientDisabledLocked(ident)) return INVALID_OPERATION; 307 Info& info( mActivationCount.editValueFor(handle) ); 308 // If the underlying sensor is NOT in continuous mode, setDelay() should return an error. 309 // Calling setDelay() in batch mode is an invalid operation. 310 if (info.bestBatchParams.batchTimeout != 0) { 311 return INVALID_OPERATION; 312 } 313 ssize_t index = info.batchParams.indexOfKey(ident); 314 if (index < 0) { 315 return BAD_INDEX; 316 } 317 BatchParams& params = info.batchParams.editValueAt(index); 318 params.batchDelay = samplingPeriodNs; 319 info.selectBatchParams(); 320 return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), 321 handle, info.bestBatchParams.batchDelay); 322 } 323 324 int SensorDevice::getHalDeviceVersion() const { 325 if (!mSensorDevice) return -1; 326 return mSensorDevice->common.version; 327 } 328 329 status_t SensorDevice::flush(void* ident, int handle) { 330 if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) { 331 return INVALID_OPERATION; 332 } 333 if (isClientDisabled(ident)) return INVALID_OPERATION; 334 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle); 335 return mSensorDevice->flush(mSensorDevice, handle); 336 } 337 338 bool SensorDevice::isClientDisabled(void* ident) { 339 Mutex::Autolock _l(mLock); 340 return isClientDisabledLocked(ident); 341 } 342 343 bool SensorDevice::isClientDisabledLocked(void* ident) { 344 return mDisabledClients.indexOf(ident) >= 0; 345 } 346 347 void SensorDevice::enableAllSensors() { 348 Mutex::Autolock _l(mLock); 349 mDisabledClients.clear(); 350 const int halVersion = getHalDeviceVersion(); 351 for (size_t i = 0; i< mActivationCount.size(); ++i) { 352 Info& info = mActivationCount.editValueAt(i); 353 if (info.batchParams.isEmpty()) continue; 354 info.selectBatchParams(); 355 const int sensor_handle = mActivationCount.keyAt(i); 356 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ", 357 sensor_handle); 358 status_t err(NO_ERROR); 359 if (halVersion > SENSORS_DEVICE_API_VERSION_1_0) { 360 err = mSensorDevice->batch(mSensorDevice, sensor_handle, 361 info.bestBatchParams.flags, info.bestBatchParams.batchDelay, 362 info.bestBatchParams.batchTimeout); 363 ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err)); 364 } 365 366 if (err == NO_ERROR) { 367 err = mSensorDevice->activate( 368 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), 369 sensor_handle, 1); 370 ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err)); 371 } 372 373 if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0) { 374 err = mSensorDevice->setDelay( 375 reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), 376 sensor_handle, info.bestBatchParams.batchDelay); 377 ALOGE_IF(err, "Error calling setDelay sensor %d (%s)", sensor_handle, strerror(-err)); 378 } 379 } 380 } 381 382 void SensorDevice::disableAllSensors() { 383 Mutex::Autolock _l(mLock); 384 for (size_t i = 0; i< mActivationCount.size(); ++i) { 385 const Info& info = mActivationCount.valueAt(i); 386 // Check if this sensor has been activated previously and disable it. 387 if (info.batchParams.size() > 0) { 388 const int sensor_handle = mActivationCount.keyAt(i); 389 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ", 390 sensor_handle); 391 mSensorDevice->activate( 392 reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), 393 sensor_handle, 0); 394 // Add all the connections that were registered for this sensor to the disabled 395 // clients list. 396 for (size_t j = 0; j < info.batchParams.size(); ++j) { 397 mDisabledClients.add(info.batchParams.keyAt(j)); 398 } 399 } 400 } 401 } 402 403 status_t SensorDevice::injectSensorData(const sensors_event_t *injected_sensor_event) { 404 ALOGD_IF(DEBUG_CONNECTIONS, 405 "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f", 406 injected_sensor_event->sensor, 407 injected_sensor_event->timestamp, injected_sensor_event->data[0], 408 injected_sensor_event->data[1], injected_sensor_event->data[2], 409 injected_sensor_event->data[3], injected_sensor_event->data[4], 410 injected_sensor_event->data[5]); 411 if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) { 412 return INVALID_OPERATION; 413 } 414 return mSensorDevice->inject_sensor_data(mSensorDevice, injected_sensor_event); 415 } 416 417 status_t SensorDevice::setMode(uint32_t mode) { 418 if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) { 419 return INVALID_OPERATION; 420 } 421 return mSensorModule->set_operation_mode(mode); 422 } 423 424 // --------------------------------------------------------------------------- 425 426 int SensorDevice::Info::numActiveClients() { 427 SensorDevice& device(SensorDevice::getInstance()); 428 int num = 0; 429 for (size_t i = 0; i < batchParams.size(); ++i) { 430 if (!device.isClientDisabledLocked(batchParams.keyAt(i))) { 431 ++num; 432 } 433 } 434 return num; 435 } 436 437 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags, 438 int64_t samplingPeriodNs, 439 int64_t maxBatchReportLatencyNs) { 440 ssize_t index = batchParams.indexOfKey(ident); 441 if (index < 0) { 442 ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)", 443 ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index)); 444 return BAD_INDEX; 445 } 446 BatchParams& params = batchParams.editValueAt(index); 447 params.flags = flags; 448 params.batchDelay = samplingPeriodNs; 449 params.batchTimeout = maxBatchReportLatencyNs; 450 return NO_ERROR; 451 } 452 453 void SensorDevice::Info::selectBatchParams() { 454 BatchParams bestParams(0, -1, -1); 455 SensorDevice& device(SensorDevice::getInstance()); 456 457 for (size_t i = 0; i < batchParams.size(); ++i) { 458 if (device.isClientDisabledLocked(batchParams.keyAt(i))) continue; 459 BatchParams params = batchParams.valueAt(i); 460 if (bestParams.batchDelay == -1 || params.batchDelay < bestParams.batchDelay) { 461 bestParams.batchDelay = params.batchDelay; 462 } 463 if (bestParams.batchTimeout == -1 || params.batchTimeout < bestParams.batchTimeout) { 464 bestParams.batchTimeout = params.batchTimeout; 465 } 466 } 467 bestBatchParams = bestParams; 468 } 469 470 ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) { 471 ssize_t idx = batchParams.removeItem(ident); 472 if (idx >= 0) { 473 selectBatchParams(); 474 } 475 return idx; 476 } 477 478 // --------------------------------------------------------------------------- 479 }; // namespace android 480 481