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