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