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 #include "SensorDevice.h" 17 #include "SensorService.h" 18 19 #include <android-base/logging.h> 20 #include <sensors/convert.h> 21 #include <utils/Atomic.h> 22 #include <utils/Errors.h> 23 #include <utils/Singleton.h> 24 25 #include <chrono> 26 #include <cinttypes> 27 #include <thread> 28 29 using android::hardware::hidl_vec; 30 31 using namespace android::hardware::sensors::V1_0; 32 using namespace android::hardware::sensors::V1_0::implementation; 33 34 35 namespace android { 36 // --------------------------------------------------------------------------- 37 38 ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice) 39 40 static status_t StatusFromResult(Result result) { 41 switch (result) { 42 case Result::OK: 43 return OK; 44 case Result::BAD_VALUE: 45 return BAD_VALUE; 46 case Result::PERMISSION_DENIED: 47 return PERMISSION_DENIED; 48 case Result::INVALID_OPERATION: 49 return INVALID_OPERATION; 50 case Result::NO_MEMORY: 51 return NO_MEMORY; 52 } 53 } 54 55 SensorDevice::SensorDevice() : mHidlTransportErrors(20) { 56 if (!connectHidlService()) { 57 return; 58 } 59 60 float minPowerMa = 0.001; // 1 microAmp 61 62 checkReturn(mSensors->getSensorsList( 63 [&](const auto &list) { 64 const size_t count = list.size(); 65 66 mActivationCount.setCapacity(count); 67 Info model; 68 for (size_t i=0 ; i < count; i++) { 69 sensor_t sensor; 70 convertToSensor(list[i], &sensor); 71 // Sanity check and clamp power if it is 0 (or close) 72 if (sensor.power < minPowerMa) { 73 ALOGE("Reported power %f not deemed sane, clamping to %f", 74 sensor.power, minPowerMa); 75 sensor.power = minPowerMa; 76 } 77 mSensorList.push_back(sensor); 78 79 mActivationCount.add(list[i].sensorHandle, model); 80 81 checkReturn(mSensors->activate(list[i].sensorHandle, 0 /* enabled */)); 82 } 83 })); 84 85 mIsDirectReportSupported = 86 (checkReturn(mSensors->unregisterDirectChannel(-1)) != Result::INVALID_OPERATION); 87 } 88 89 bool SensorDevice::connectHidlService() { 90 // SensorDevice may wait upto 100ms * 10 = 1s for hidl service. 91 constexpr auto RETRY_DELAY = std::chrono::milliseconds(100); 92 size_t retry = 10; 93 94 while (true) { 95 int initStep = 0; 96 mSensors = ISensors::getService(); 97 if (mSensors != nullptr) { 98 ++initStep; 99 // Poke ISensor service. If it has lingering connection from previous generation of 100 // system server, it will kill itself. There is no intention to handle the poll result, 101 // which will be done since the size is 0. 102 if(mSensors->poll(0, [](auto, const auto &, const auto &) {}).isOk()) { 103 // ok to continue 104 break; 105 } 106 // hidl service is restarting, pointer is invalid. 107 mSensors = nullptr; 108 } 109 110 if (--retry <= 0) { 111 ALOGE("Cannot connect to ISensors hidl service!"); 112 break; 113 } 114 // Delay 100ms before retry, hidl service is expected to come up in short time after 115 // crash. 116 ALOGI("%s unsuccessful, try again soon (remaining retry %zu).", 117 (initStep == 0) ? "getService()" : "poll() check", retry); 118 std::this_thread::sleep_for(RETRY_DELAY); 119 } 120 return (mSensors != nullptr); 121 } 122 123 void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) { 124 // not need to check mSensors because this is is only called after successful poll() 125 if (connected) { 126 Info model; 127 mActivationCount.add(handle, model); 128 checkReturn(mSensors->activate(handle, 0 /* enabled */)); 129 } else { 130 mActivationCount.removeItem(handle); 131 } 132 } 133 134 std::string SensorDevice::dump() const { 135 if (mSensors == nullptr) return "HAL not initialized\n"; 136 137 String8 result; 138 result.appendFormat("Total %zu h/w sensors, %zu running:\n", 139 mSensorList.size(), mActivationCount.size()); 140 141 Mutex::Autolock _l(mLock); 142 for (const auto & s : mSensorList) { 143 int32_t handle = s.handle; 144 const Info& info = mActivationCount.valueFor(handle); 145 if (info.batchParams.isEmpty()) continue; 146 147 result.appendFormat("0x%08x) active-count = %zu; ", handle, info.batchParams.size()); 148 149 result.append("sampling_period(ms) = {"); 150 for (size_t j = 0; j < info.batchParams.size(); j++) { 151 const BatchParams& params = info.batchParams[j]; 152 result.appendFormat("%.1f%s", params.mTSample / 1e6f, 153 j < info.batchParams.size() - 1 ? ", " : ""); 154 } 155 result.appendFormat("}, selected = %.2f ms; ", info.bestBatchParams.mTSample / 1e6f); 156 157 result.append("batching_period(ms) = {"); 158 for (size_t j = 0; j < info.batchParams.size(); j++) { 159 const BatchParams& params = info.batchParams[j]; 160 result.appendFormat("%.1f%s", params.mTBatch / 1e6f, 161 j < info.batchParams.size() - 1 ? ", " : ""); 162 } 163 result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 1e6f); 164 } 165 166 return result.string(); 167 } 168 169 ssize_t SensorDevice::getSensorList(sensor_t const** list) { 170 *list = &mSensorList[0]; 171 172 return mSensorList.size(); 173 } 174 175 status_t SensorDevice::initCheck() const { 176 return mSensors != NULL ? NO_ERROR : NO_INIT; 177 } 178 179 ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) { 180 if (mSensors == nullptr) return NO_INIT; 181 182 ssize_t err; 183 int numHidlTransportErrors = 0; 184 bool hidlTransportError = false; 185 186 do { 187 auto ret = mSensors->poll( 188 count, 189 [&](auto result, 190 const auto &events, 191 const auto &dynamicSensorsAdded) { 192 if (result == Result::OK) { 193 convertToSensorEvents(events, dynamicSensorsAdded, buffer); 194 err = (ssize_t)events.size(); 195 } else { 196 err = StatusFromResult(result); 197 } 198 }); 199 200 if (ret.isOk()) { 201 hidlTransportError = false; 202 } else { 203 hidlTransportError = true; 204 numHidlTransportErrors++; 205 if (numHidlTransportErrors > 50) { 206 // Log error and bail 207 ALOGE("Max Hidl transport errors this cycle : %d", numHidlTransportErrors); 208 handleHidlDeath(ret.description()); 209 } else { 210 std::this_thread::sleep_for(std::chrono::milliseconds(10)); 211 } 212 } 213 } while (hidlTransportError); 214 215 if(numHidlTransportErrors > 0) { 216 ALOGE("Saw %d Hidl transport failures", numHidlTransportErrors); 217 HidlTransportErrorLog errLog(time(NULL), numHidlTransportErrors); 218 mHidlTransportErrors.add(errLog); 219 mTotalHidlTransportErrors++; 220 } 221 222 return err; 223 } 224 225 void SensorDevice::autoDisable(void *ident, int handle) { 226 Info& info( mActivationCount.editValueFor(handle) ); 227 Mutex::Autolock _l(mLock); 228 info.removeBatchParamsForIdent(ident); 229 } 230 231 status_t SensorDevice::activate(void* ident, int handle, int enabled) { 232 if (mSensors == nullptr) return NO_INIT; 233 234 status_t err(NO_ERROR); 235 bool actuateHardware = false; 236 237 Mutex::Autolock _l(mLock); 238 Info& info( mActivationCount.editValueFor(handle) ); 239 240 ALOGD_IF(DEBUG_CONNECTIONS, 241 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu", 242 ident, handle, enabled, info.batchParams.size()); 243 244 if (enabled) { 245 ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident)); 246 247 if (isClientDisabledLocked(ident)) { 248 ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d", 249 ident, handle); 250 return INVALID_OPERATION; 251 } 252 253 if (info.batchParams.indexOfKey(ident) >= 0) { 254 if (info.numActiveClients() == 1) { 255 // This is the first connection, we need to activate the underlying h/w sensor. 256 actuateHardware = true; 257 } 258 } else { 259 // Log error. Every activate call should be preceded by a batch() call. 260 ALOGE("\t >>>ERROR: activate called without batch"); 261 } 262 } else { 263 ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident)); 264 265 // If a connected dynamic sensor is deactivated, remove it from the 266 // dictionary. 267 auto it = mConnectedDynamicSensors.find(handle); 268 if (it != mConnectedDynamicSensors.end()) { 269 delete it->second; 270 mConnectedDynamicSensors.erase(it); 271 } 272 273 if (info.removeBatchParamsForIdent(ident) >= 0) { 274 if (info.numActiveClients() == 0) { 275 // This is the last connection, we need to de-activate the underlying h/w sensor. 276 actuateHardware = true; 277 } else { 278 // Call batch for this sensor with the previously calculated best effort 279 // batch_rate and timeout. One of the apps has unregistered for sensor 280 // events, and the best effort batch parameters might have changed. 281 ALOGD_IF(DEBUG_CONNECTIONS, 282 "\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64, handle, 283 info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch); 284 checkReturn(mSensors->batch( 285 handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch)); 286 } 287 } else { 288 // sensor wasn't enabled for this ident 289 } 290 291 if (isClientDisabledLocked(ident)) { 292 return NO_ERROR; 293 } 294 } 295 296 if (actuateHardware) { 297 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, 298 enabled); 299 err = StatusFromResult(checkReturn(mSensors->activate(handle, enabled))); 300 ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle, 301 strerror(-err)); 302 303 if (err != NO_ERROR && enabled) { 304 // Failure when enabling the sensor. Clean up on failure. 305 info.removeBatchParamsForIdent(ident); 306 } 307 } 308 309 return err; 310 } 311 312 status_t SensorDevice::batch( 313 void* ident, 314 int handle, 315 int flags, 316 int64_t samplingPeriodNs, 317 int64_t maxBatchReportLatencyNs) { 318 if (mSensors == nullptr) return NO_INIT; 319 320 if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) { 321 samplingPeriodNs = MINIMUM_EVENTS_PERIOD; 322 } 323 if (maxBatchReportLatencyNs < 0) { 324 maxBatchReportLatencyNs = 0; 325 } 326 327 ALOGD_IF(DEBUG_CONNECTIONS, 328 "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64, 329 ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs); 330 331 Mutex::Autolock _l(mLock); 332 Info& info(mActivationCount.editValueFor(handle)); 333 334 if (info.batchParams.indexOfKey(ident) < 0) { 335 BatchParams params(samplingPeriodNs, maxBatchReportLatencyNs); 336 info.batchParams.add(ident, params); 337 } else { 338 // A batch has already been called with this ident. Update the batch parameters. 339 info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs); 340 } 341 342 BatchParams prevBestBatchParams = info.bestBatchParams; 343 // Find the minimum of all timeouts and batch_rates for this sensor. 344 info.selectBatchParams(); 345 346 ALOGD_IF(DEBUG_CONNECTIONS, 347 "\t>>> curr_period=%" PRId64 " min_period=%" PRId64 348 " curr_timeout=%" PRId64 " min_timeout=%" PRId64, 349 prevBestBatchParams.mTSample, info.bestBatchParams.mTSample, 350 prevBestBatchParams.mTBatch, info.bestBatchParams.mTBatch); 351 352 status_t err(NO_ERROR); 353 // If the min period or min timeout has changed since the last batch call, call batch. 354 if (prevBestBatchParams != info.bestBatchParams) { 355 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH 0x%08x %" PRId64 " %" PRId64, handle, 356 info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch); 357 err = StatusFromResult( 358 checkReturn(mSensors->batch( 359 handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch))); 360 if (err != NO_ERROR) { 361 ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s", 362 mSensors.get(), handle, info.bestBatchParams.mTSample, 363 info.bestBatchParams.mTBatch, strerror(-err)); 364 info.removeBatchParamsForIdent(ident); 365 } 366 } 367 return err; 368 } 369 370 status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs) { 371 return batch(ident, handle, 0, samplingPeriodNs, 0); 372 } 373 374 int SensorDevice::getHalDeviceVersion() const { 375 if (mSensors == nullptr) return -1; 376 return SENSORS_DEVICE_API_VERSION_1_4; 377 } 378 379 status_t SensorDevice::flush(void* ident, int handle) { 380 if (mSensors == nullptr) return NO_INIT; 381 if (isClientDisabled(ident)) return INVALID_OPERATION; 382 ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle); 383 return StatusFromResult(checkReturn(mSensors->flush(handle))); 384 } 385 386 bool SensorDevice::isClientDisabled(void* ident) { 387 Mutex::Autolock _l(mLock); 388 return isClientDisabledLocked(ident); 389 } 390 391 bool SensorDevice::isClientDisabledLocked(void* ident) { 392 return mDisabledClients.indexOf(ident) >= 0; 393 } 394 395 void SensorDevice::enableAllSensors() { 396 if (mSensors == nullptr) return; 397 Mutex::Autolock _l(mLock); 398 mDisabledClients.clear(); 399 ALOGI("cleared mDisabledClients"); 400 for (size_t i = 0; i< mActivationCount.size(); ++i) { 401 Info& info = mActivationCount.editValueAt(i); 402 if (info.batchParams.isEmpty()) continue; 403 info.selectBatchParams(); 404 const int sensor_handle = mActivationCount.keyAt(i); 405 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> reenable actuating h/w sensor enable handle=%d ", 406 sensor_handle); 407 status_t err = StatusFromResult( 408 checkReturn(mSensors->batch( 409 sensor_handle, 410 info.bestBatchParams.mTSample, 411 info.bestBatchParams.mTBatch))); 412 ALOGE_IF(err, "Error calling batch on sensor %d (%s)", sensor_handle, strerror(-err)); 413 414 if (err == NO_ERROR) { 415 err = StatusFromResult( 416 checkReturn(mSensors->activate(sensor_handle, 1 /* enabled */))); 417 ALOGE_IF(err, "Error activating sensor %d (%s)", sensor_handle, strerror(-err)); 418 } 419 } 420 } 421 422 void SensorDevice::disableAllSensors() { 423 if (mSensors == nullptr) return; 424 Mutex::Autolock _l(mLock); 425 for (size_t i = 0; i< mActivationCount.size(); ++i) { 426 const Info& info = mActivationCount.valueAt(i); 427 // Check if this sensor has been activated previously and disable it. 428 if (info.batchParams.size() > 0) { 429 const int sensor_handle = mActivationCount.keyAt(i); 430 ALOGD_IF(DEBUG_CONNECTIONS, "\t>> actuating h/w sensor disable handle=%d ", 431 sensor_handle); 432 checkReturn(mSensors->activate(sensor_handle, 0 /* enabled */)); 433 434 // Add all the connections that were registered for this sensor to the disabled 435 // clients list. 436 for (size_t j = 0; j < info.batchParams.size(); ++j) { 437 mDisabledClients.add(info.batchParams.keyAt(j)); 438 ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j)); 439 } 440 } 441 } 442 } 443 444 status_t SensorDevice::injectSensorData( 445 const sensors_event_t *injected_sensor_event) { 446 if (mSensors == nullptr) return NO_INIT; 447 ALOGD_IF(DEBUG_CONNECTIONS, 448 "sensor_event handle=%d ts=%" PRId64 " data=%.2f, %.2f, %.2f %.2f %.2f %.2f", 449 injected_sensor_event->sensor, 450 injected_sensor_event->timestamp, injected_sensor_event->data[0], 451 injected_sensor_event->data[1], injected_sensor_event->data[2], 452 injected_sensor_event->data[3], injected_sensor_event->data[4], 453 injected_sensor_event->data[5]); 454 455 Event ev; 456 convertFromSensorEvent(*injected_sensor_event, &ev); 457 458 return StatusFromResult(checkReturn(mSensors->injectSensorData(ev))); 459 } 460 461 status_t SensorDevice::setMode(uint32_t mode) { 462 if (mSensors == nullptr) return NO_INIT; 463 return StatusFromResult( 464 checkReturn(mSensors->setOperationMode( 465 static_cast<hardware::sensors::V1_0::OperationMode>(mode)))); 466 } 467 468 int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) { 469 if (mSensors == nullptr) return NO_INIT; 470 Mutex::Autolock _l(mLock); 471 472 SharedMemType type; 473 switch (memory->type) { 474 case SENSOR_DIRECT_MEM_TYPE_ASHMEM: 475 type = SharedMemType::ASHMEM; 476 break; 477 case SENSOR_DIRECT_MEM_TYPE_GRALLOC: 478 type = SharedMemType::GRALLOC; 479 break; 480 default: 481 return BAD_VALUE; 482 } 483 484 SharedMemFormat format; 485 if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) { 486 return BAD_VALUE; 487 } 488 format = SharedMemFormat::SENSORS_EVENT; 489 490 SharedMemInfo mem = { 491 .type = type, 492 .format = format, 493 .size = static_cast<uint32_t>(memory->size), 494 .memoryHandle = memory->handle, 495 }; 496 497 int32_t ret; 498 checkReturn(mSensors->registerDirectChannel(mem, 499 [&ret](auto result, auto channelHandle) { 500 if (result == Result::OK) { 501 ret = channelHandle; 502 } else { 503 ret = StatusFromResult(result); 504 } 505 })); 506 return ret; 507 } 508 509 void SensorDevice::unregisterDirectChannel(int32_t channelHandle) { 510 if (mSensors == nullptr) return; 511 Mutex::Autolock _l(mLock); 512 checkReturn(mSensors->unregisterDirectChannel(channelHandle)); 513 } 514 515 int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, 516 int32_t channelHandle, const struct sensors_direct_cfg_t *config) { 517 if (mSensors == nullptr) return NO_INIT; 518 Mutex::Autolock _l(mLock); 519 520 RateLevel rate; 521 switch(config->rate_level) { 522 case SENSOR_DIRECT_RATE_STOP: 523 rate = RateLevel::STOP; 524 break; 525 case SENSOR_DIRECT_RATE_NORMAL: 526 rate = RateLevel::NORMAL; 527 break; 528 case SENSOR_DIRECT_RATE_FAST: 529 rate = RateLevel::FAST; 530 break; 531 case SENSOR_DIRECT_RATE_VERY_FAST: 532 rate = RateLevel::VERY_FAST; 533 break; 534 default: 535 return BAD_VALUE; 536 } 537 538 int32_t ret; 539 checkReturn(mSensors->configDirectReport(sensorHandle, channelHandle, rate, 540 [&ret, rate] (auto result, auto token) { 541 if (rate == RateLevel::STOP) { 542 ret = StatusFromResult(result); 543 } else { 544 if (result == Result::OK) { 545 ret = token; 546 } else { 547 ret = StatusFromResult(result); 548 } 549 } 550 })); 551 552 return ret; 553 } 554 555 // --------------------------------------------------------------------------- 556 557 int SensorDevice::Info::numActiveClients() { 558 SensorDevice& device(SensorDevice::getInstance()); 559 int num = 0; 560 for (size_t i = 0; i < batchParams.size(); ++i) { 561 if (!device.isClientDisabledLocked(batchParams.keyAt(i))) { 562 ++num; 563 } 564 } 565 return num; 566 } 567 568 status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int, 569 int64_t samplingPeriodNs, 570 int64_t maxBatchReportLatencyNs) { 571 ssize_t index = batchParams.indexOfKey(ident); 572 if (index < 0) { 573 ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 574 " timeout=%" PRId64 ") failed (%s)", 575 ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index)); 576 return BAD_INDEX; 577 } 578 BatchParams& params = batchParams.editValueAt(index); 579 params.mTSample = samplingPeriodNs; 580 params.mTBatch = maxBatchReportLatencyNs; 581 return NO_ERROR; 582 } 583 584 void SensorDevice::Info::selectBatchParams() { 585 BatchParams bestParams; // default to max Tsample and max Tbatch 586 SensorDevice& device(SensorDevice::getInstance()); 587 588 for (size_t i = 0; i < batchParams.size(); ++i) { 589 if (device.isClientDisabledLocked(batchParams.keyAt(i))) { 590 continue; 591 } 592 bestParams.merge(batchParams[i]); 593 } 594 // if mTBatch <= mTSample, it is in streaming mode. set mTbatch to 0 to demand this explicitly. 595 if (bestParams.mTBatch <= bestParams.mTSample) { 596 bestParams.mTBatch = 0; 597 } 598 bestBatchParams = bestParams; 599 } 600 601 ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) { 602 ssize_t idx = batchParams.removeItem(ident); 603 if (idx >= 0) { 604 selectBatchParams(); 605 } 606 return idx; 607 } 608 609 void SensorDevice::notifyConnectionDestroyed(void* ident) { 610 Mutex::Autolock _l(mLock); 611 mDisabledClients.remove(ident); 612 } 613 614 bool SensorDevice::isDirectReportSupported() const { 615 return mIsDirectReportSupported; 616 } 617 618 void SensorDevice::convertToSensorEvent( 619 const Event &src, sensors_event_t *dst) { 620 ::android::hardware::sensors::V1_0::implementation::convertToSensorEvent( 621 src, dst); 622 623 if (src.sensorType == SensorType::DYNAMIC_SENSOR_META) { 624 const DynamicSensorInfo &dyn = src.u.dynamic; 625 626 dst->dynamic_sensor_meta.connected = dyn.connected; 627 dst->dynamic_sensor_meta.handle = dyn.sensorHandle; 628 if (dyn.connected) { 629 auto it = mConnectedDynamicSensors.find(dyn.sensorHandle); 630 CHECK(it != mConnectedDynamicSensors.end()); 631 632 dst->dynamic_sensor_meta.sensor = it->second; 633 634 memcpy(dst->dynamic_sensor_meta.uuid, 635 dyn.uuid.data(), 636 sizeof(dst->dynamic_sensor_meta.uuid)); 637 } 638 } 639 } 640 641 void SensorDevice::convertToSensorEvents( 642 const hidl_vec<Event> &src, 643 const hidl_vec<SensorInfo> &dynamicSensorsAdded, 644 sensors_event_t *dst) { 645 // Allocate a sensor_t structure for each dynamic sensor added and insert 646 // it into the dictionary of connected dynamic sensors keyed by handle. 647 for (size_t i = 0; i < dynamicSensorsAdded.size(); ++i) { 648 const SensorInfo &info = dynamicSensorsAdded[i]; 649 650 auto it = mConnectedDynamicSensors.find(info.sensorHandle); 651 CHECK(it == mConnectedDynamicSensors.end()); 652 653 sensor_t *sensor = new sensor_t; 654 convertToSensor(info, sensor); 655 656 mConnectedDynamicSensors.insert( 657 std::make_pair(sensor->handle, sensor)); 658 } 659 660 for (size_t i = 0; i < src.size(); ++i) { 661 convertToSensorEvent(src[i], &dst[i]); 662 } 663 } 664 665 void SensorDevice::handleHidlDeath(const std::string & detail) { 666 // restart is the only option at present. 667 LOG_ALWAYS_FATAL("Abort due to ISensors hidl service failure, detail: %s.", detail.c_str()); 668 } 669 670 // --------------------------------------------------------------------------- 671 }; // namespace android 672