1 /* 2 * Copyright (C) 2016 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 "chre/core/sensor_request_manager.h" 18 19 #include "chre/core/event_loop_manager.h" 20 #include "chre/util/nested_data_ptr.h" 21 #include "chre/util/system/debug_dump.h" 22 #include "chre_api/chre/version.h" 23 24 #define LOG_INVALID_HANDLE(x) \ 25 LOGE("Invalid sensor handle %" PRIu32 ": line %d", x, __LINE__) 26 27 namespace chre { 28 namespace { 29 30 bool isSensorRequestValid(const Sensor &sensor, 31 const SensorRequest &sensorRequest) { 32 bool isRequestOneShot = sensorModeIsOneShot(sensorRequest.getMode()); 33 bool isRequestOff = sensorRequest.getMode() == SensorMode::Off; 34 uint64_t requestedInterval = sensorRequest.getInterval().toRawNanoseconds(); 35 bool isRequestPassive = sensorModeIsPassive(sensorRequest.getMode()); 36 37 bool success = false; 38 if (requestedInterval < sensor.getMinInterval()) { 39 LOGE("Requested interval %" PRIu64 " < sensor's minInterval %" PRIu64, 40 requestedInterval, sensor.getMinInterval()); 41 } else if (!isRequestOff && isRequestOneShot != sensor.isOneShot()) { 42 LOGE("Invalid request type for sensor reporting mode"); 43 } else if (isRequestPassive && !sensor.supportsPassiveMode()) { 44 LOGE("Passive mode not supported"); 45 } else { 46 success = true; 47 } 48 return success; 49 } 50 51 /** 52 * A helper function that updates the last event of a sensor in the main thread. 53 * 54 * @param eventData A non-null pointer to the sensor's CHRE event data. 55 */ 56 void updateLastEvent(void *eventData) { 57 CHRE_ASSERT(eventData); 58 59 auto callback = [](uint16_t /* type */, void *data) { 60 auto *sensorData = static_cast<ChreSensorData *>(data); 61 Sensor *sensor = 62 EventLoopManagerSingleton::get()->getSensorRequestManager().getSensor( 63 sensorData->header.sensorHandle); 64 65 // Mark last event as valid only if the sensor is enabled. Event data may 66 // arrive after sensor is disabled. 67 if (sensor != nullptr && 68 sensor->getMaximalRequest().getMode() != SensorMode::Off) { 69 sensor->setLastEvent(sensorData); 70 } 71 }; 72 73 // Schedule a deferred callback. 74 EventLoopManagerSingleton::get()->deferCallback( 75 SystemCallbackType::SensorLastEventUpdate, eventData, callback); 76 } 77 78 void sensorDataEventFree(uint16_t eventType, void *eventData) { 79 EventLoopManagerSingleton::get() 80 ->getSensorRequestManager() 81 .releaseSensorDataEvent(eventType, eventData); 82 } 83 84 /** 85 * Posts a CHRE_EVENT_SENSOR_SAMPLING_CHANGE event to the specified Nanoapp. 86 * 87 * @param instanceId The instance ID of the nanoapp with an open request. 88 * @param sensorHandle The handle of the sensor. 89 * @param status A reference of the sampling status to be posted. 90 */ 91 void postSamplingStatusEvent(uint32_t instanceId, uint32_t sensorHandle, 92 const struct chreSensorSamplingStatus &status) { 93 auto *event = memoryAlloc<struct chreSensorSamplingStatusEvent>(); 94 if (event == nullptr) { 95 LOG_OOM(); 96 } else { 97 event->sensorHandle = sensorHandle; 98 event->status = status; 99 100 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie( 101 CHRE_EVENT_SENSOR_SAMPLING_CHANGE, event, freeEventDataCallback, 102 instanceId); 103 } 104 } 105 106 /** 107 * Sets the latest sampling status for a given sensor and notifies all listening 108 * nanoapps of the latest update. 109 * 110 * @param sensorHandle The handle of the sensor. 111 * @param status A reference of the sampling status to be updated. 112 */ 113 void updateSamplingStatus(uint32_t sensorHandle, 114 struct chreSensorSamplingStatus &status) { 115 Sensor *sensor = 116 EventLoopManagerSingleton::get()->getSensorRequestManager().getSensor( 117 sensorHandle); 118 119 if (sensor != nullptr && !sensor->isOneShot()) { 120 sensor->setSamplingStatus(status); 121 122 // Only post to Nanoapps with an open request. 123 const DynamicVector<SensorRequest> &requests = 124 EventLoopManagerSingleton::get()->getSensorRequestManager().getRequests( 125 sensorHandle); 126 for (const auto &req : requests) { 127 postSamplingStatusEvent(req.getInstanceId(), sensorHandle, status); 128 } 129 } 130 } 131 132 } // namespace 133 134 SensorRequestManager::~SensorRequestManager() { 135 for (size_t i = 0; i < mSensors.size(); i++) { 136 // Disable sensors that have been enabled previously. 137 removeAllRequests(mSensors[i]); 138 } 139 } 140 141 void SensorRequestManager::init() { 142 // The Platform sensor must be initialized prior to interacting with any 143 // sensors. 144 mPlatformSensorManager.init(); 145 146 mSensors = mPlatformSensorManager.getSensors(); 147 } 148 149 bool SensorRequestManager::getSensorHandle(uint8_t sensorType, 150 uint32_t *sensorHandle) const { 151 CHRE_ASSERT(sensorHandle); 152 153 bool sensorHandleIsValid = false; 154 for (uint32_t i = 0; i < mSensors.size(); i++) { 155 if (mSensors[i].getSensorType() == sensorType) { 156 sensorHandleIsValid = true; 157 *sensorHandle = i; 158 break; 159 } 160 } 161 162 return sensorHandleIsValid; 163 } 164 165 bool SensorRequestManager::setSensorRequest( 166 Nanoapp *nanoapp, uint32_t sensorHandle, 167 const SensorRequest &sensorRequest) { 168 CHRE_ASSERT(nanoapp); 169 170 bool success = false; 171 bool requestChanged = false; 172 173 if (sensorHandle >= mSensors.size()) { 174 LOG_INVALID_HANDLE(sensorHandle); 175 } else { 176 Sensor &sensor = mSensors[sensorHandle]; 177 if (isSensorRequestValid(sensor, sensorRequest)) { 178 size_t requestIndex; 179 uint8_t sensorType = sensor.getSensorType(); 180 uint16_t eventType = getSampleEventTypeForSensorType(sensorType); 181 bool nanoappHasRequest = 182 sensor.getRequestMultiplexer().findRequest(nanoapp->getInstanceId(), 183 &requestIndex) != nullptr; 184 185 if (sensorRequest.getMode() == SensorMode::Off) { 186 if (nanoappHasRequest) { 187 // The request changes the mode to off and there was an existing 188 // request. The existing request is removed from the multiplexer. The 189 // nanoapp is unregistered from events of this type if this request 190 // was successful. 191 success = removeRequest(sensor, requestIndex, &requestChanged); 192 if (success) { 193 cancelFlushRequests(sensorHandle, nanoapp->getInstanceId()); 194 195 nanoapp->unregisterForBroadcastEvent(eventType); 196 197 uint16_t biasEventType; 198 if (sensor.getBiasEventType(&biasEventType)) { 199 // Per API requirements, turn off bias reporting when 200 // unsubscribing from the sensor. 201 nanoapp->unregisterForBroadcastEvent(biasEventType); 202 } 203 } 204 } else { 205 // The sensor is being configured to Off, but is already Off (there is 206 // no existing request). We assign to success to be true and no other 207 // operation is required. 208 success = true; 209 } 210 } else if (!nanoappHasRequest) { 211 // The request changes the mode to the enabled state and there was no 212 // existing request. The request is newly created and added to the 213 // multiplexer. The nanoapp is registered for events if this request was 214 // successful. 215 success = addRequest(sensor, sensorRequest, &requestChanged); 216 if (success) { 217 nanoapp->registerForBroadcastEvent(eventType); 218 219 // Per API requirements, turn on bias reporting for calibrated sensors 220 // by default when subscribed. 221 uint16_t biasEventType; 222 if (sensor.getBiasEventType(&biasEventType) && 223 sensor.isCalibrated()) { 224 nanoapp->registerForBroadcastEvent(biasEventType); 225 } 226 227 // Deliver last valid event to new clients of on-change sensors 228 if (sensor.getLastEvent() != nullptr) { 229 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie( 230 eventType, sensor.getLastEvent(), nullptr /* freeCallback */, 231 nanoapp->getInstanceId()); 232 } 233 } 234 } else { 235 // The request changes the mode to the enabled state and there was an 236 // existing request. The existing request is updated. 237 success = 238 updateRequest(sensor, requestIndex, sensorRequest, &requestChanged); 239 } 240 241 // TODO: Allow translating the sensor request 242 243 if (requestChanged) { 244 // TODO: Send an event to nanoapps to indicate the rate change. 245 } 246 247 if (success) { 248 addSensorRequestLog(nanoapp->getInstanceId(), sensorType, 249 sensorRequest); 250 } 251 } 252 } 253 254 return success; 255 } 256 257 bool SensorRequestManager::getSensorInfo(uint32_t sensorHandle, 258 const Nanoapp &nanoapp, 259 struct chreSensorInfo *info) const { 260 CHRE_ASSERT(info); 261 262 bool success = false; 263 if (sensorHandle >= mSensors.size()) { 264 LOG_INVALID_HANDLE(sensorHandle); 265 } else { 266 mSensors[sensorHandle].populateSensorInfo(info, 267 nanoapp.getTargetApiVersion()); 268 success = true; 269 } 270 271 return success; 272 } 273 274 bool SensorRequestManager::removeAllRequests(uint32_t sensorHandle) { 275 bool success = false; 276 if (sensorHandle >= mSensors.size()) { 277 LOG_INVALID_HANDLE(sensorHandle); 278 } else { 279 Sensor &sensor = mSensors[sensorHandle]; 280 uint8_t sensorType = sensor.getSensorType(); 281 uint16_t eventType = getSampleEventTypeForSensorType(sensorType); 282 for (const SensorRequest &request : sensor.getRequests()) { 283 Nanoapp *nanoapp = EventLoopManagerSingleton::get() 284 ->getEventLoop() 285 .findNanoappByInstanceId(request.getInstanceId()); 286 if (nanoapp != nullptr) { 287 nanoapp->unregisterForBroadcastEvent(eventType); 288 } 289 } 290 291 cancelFlushRequests(sensorHandle); 292 success = removeAllRequests(sensor); 293 } 294 295 return success; 296 } 297 298 Sensor *SensorRequestManager::getSensor(uint32_t sensorHandle) { 299 Sensor *sensorPtr = nullptr; 300 if (sensorHandle < mSensors.size()) { 301 sensorPtr = &mSensors[sensorHandle]; 302 } 303 return sensorPtr; 304 } 305 306 bool SensorRequestManager::getSensorSamplingStatus( 307 uint32_t sensorHandle, struct chreSensorSamplingStatus *status) const { 308 CHRE_ASSERT(status); 309 310 bool success = false; 311 if (sensorHandle >= mSensors.size()) { 312 LOG_INVALID_HANDLE(sensorHandle); 313 } else { 314 success = mSensors[sensorHandle].getSamplingStatus(status); 315 } 316 317 return success; 318 } 319 320 const DynamicVector<SensorRequest> &SensorRequestManager::getRequests( 321 uint32_t sensorHandle) const { 322 if (sensorHandle >= mSensors.size()) { 323 LOG_INVALID_HANDLE(sensorHandle); 324 sensorHandle = 0; 325 } 326 return mSensors[sensorHandle].getRequests(); 327 } 328 329 bool SensorRequestManager::configureBiasEvents(Nanoapp *nanoapp, 330 uint32_t sensorHandle, 331 bool enable) { 332 bool success = false; 333 if (sensorHandle >= mSensors.size()) { 334 LOG_INVALID_HANDLE(sensorHandle); 335 } else if (enable && !mSensors[sensorHandle].isSensorEnabled()) { 336 LOGE("Bias events can't be configured for a disabled sensor!"); 337 } else { 338 uint16_t eventType; 339 Sensor &sensor = mSensors[sensorHandle]; 340 if (sensor.getBiasEventType(&eventType)) { 341 uint64_t currentLatency = 0; 342 if (enable) { 343 currentLatency = 344 sensor.getMaximalRequest().getLatency().toRawNanoseconds(); 345 } 346 success = mPlatformSensorManager.configureBiasEvents(sensor, enable, 347 currentLatency); 348 349 if (success) { 350 if (enable) { 351 nanoapp->registerForBroadcastEvent(eventType); 352 } else { 353 nanoapp->unregisterForBroadcastEvent(eventType); 354 } 355 } 356 } 357 } 358 359 return success; 360 } 361 362 bool SensorRequestManager::getThreeAxisBias( 363 uint32_t sensorHandle, struct chreSensorThreeAxisData *bias) const { 364 CHRE_ASSERT(bias != nullptr); 365 366 bool success = false; 367 if (bias != nullptr) { 368 if (sensorHandle >= mSensors.size()) { 369 LOG_INVALID_HANDLE(sensorHandle); 370 } else { 371 success = 372 mPlatformSensorManager.getThreeAxisBias(mSensors[sensorHandle], bias); 373 } 374 } 375 376 return success; 377 } 378 379 bool SensorRequestManager::flushAsync(Nanoapp *nanoapp, uint32_t sensorHandle, 380 const void *cookie) { 381 bool success = false; 382 383 uint32_t nanoappInstanceId = nanoapp->getInstanceId(); 384 if (sensorHandle >= mSensors.size()) { 385 LOG_INVALID_HANDLE(sensorHandle); 386 } else if (mSensors[sensorHandle].isOneShot()) { 387 LOGE("Cannot flush a one-shot sensor of type %" PRIu8, 388 mSensors[sensorHandle].getSensorType()); 389 } else if (mFlushRequestQueue.full()) { 390 LOG_OOM(); 391 } else { 392 mFlushRequestQueue.emplace_back(sensorHandle, nanoappInstanceId, cookie); 393 success = makeFlushRequest(mFlushRequestQueue.back()) == CHRE_ERROR_NONE; 394 if (!success) { 395 mFlushRequestQueue.pop_back(); 396 } 397 } 398 399 return success; 400 } 401 402 void SensorRequestManager::releaseSensorDataEvent(uint16_t eventType, 403 void *eventData) { 404 // Remove all requests if it's a one-shot sensor and only after data has been 405 // delivered to all clients. 406 mPlatformSensorManager.releaseSensorDataEvent(eventData); 407 uint8_t sensorType = getSensorTypeForSampleEventType(eventType); 408 uint32_t sensorHandle; 409 if (getSensorHandle(sensorType, &sensorHandle) && 410 mSensors[sensorHandle].isOneShot()) { 411 removeAllRequests(sensorHandle); 412 } 413 } 414 415 void SensorRequestManager::handleFlushCompleteEvent(uint32_t sensorHandle, 416 uint32_t flushRequestId, 417 uint8_t errorCode) { 418 if (sensorHandle < mSensors.size() && 419 mSensors[sensorHandle].isFlushRequestPending()) { 420 // Cancel flush request timer before posting to the event queue to ensure 421 // a timeout event isn't processed by CHRE now that the complete event 422 // has been received. 423 mSensors[sensorHandle].cancelPendingFlushRequestTimer(); 424 425 struct CallbackState { 426 uint8_t errorCode; 427 uint32_t sensorHandle; 428 }; 429 430 auto *cbState = memoryAlloc<CallbackState>(); 431 if (cbState == nullptr) { 432 LOG_OOM(); 433 } else { 434 cbState->errorCode = errorCode; 435 cbState->sensorHandle = sensorHandle; 436 437 auto callback = [](uint16_t /* eventType */, void *eventData) { 438 auto *cbState = static_cast<CallbackState *>(eventData); 439 EventLoopManagerSingleton::get() 440 ->getSensorRequestManager() 441 .handleFlushCompleteEventSync(cbState->errorCode, 442 cbState->sensorHandle); 443 memoryFree(cbState); 444 }; 445 446 EventLoopManagerSingleton::get()->deferCallback( 447 SystemCallbackType::SensorFlushComplete, cbState, callback); 448 } 449 } 450 } 451 452 void SensorRequestManager::handleSensorDataEvent(uint32_t sensorHandle, 453 void *event) { 454 if (sensorHandle >= mSensors.size()) { 455 LOG_INVALID_HANDLE(sensorHandle); 456 mPlatformSensorManager.releaseSensorDataEvent(event); 457 } else { 458 if (mSensors[sensorHandle].isOnChange()) { 459 updateLastEvent(event); 460 } 461 462 uint16_t eventType = 463 getSampleEventTypeForSensorType(mSensors[sensorHandle].getSensorType()); 464 465 // Only allow dropping continuous sensor events since losing one-shot or 466 // on-change events could result in nanoapps stuck in a bad state. 467 if (mSensors[sensorHandle].isContinuous()) { 468 EventLoopManagerSingleton::get() 469 ->getEventLoop() 470 .postLowPriorityEventOrFree(eventType, event, sensorDataEventFree); 471 } else { 472 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie( 473 eventType, event, sensorDataEventFree); 474 } 475 } 476 } 477 478 void SensorRequestManager::handleSamplingStatusUpdate( 479 uint32_t sensorHandle, struct chreSensorSamplingStatus *status) { 480 struct StatusUpdate { 481 uint32_t sensorHandle; 482 struct chreSensorSamplingStatus *status; 483 }; 484 auto *cbData = memoryAlloc<struct StatusUpdate>(); 485 if (cbData == nullptr) { 486 LOG_OOM(); 487 } else { 488 cbData->sensorHandle = sensorHandle; 489 cbData->status = status; 490 491 auto callback = [](uint16_t /* type */, void *data) { 492 auto cbData = static_cast<struct StatusUpdate *>(data); 493 updateSamplingStatus(cbData->sensorHandle, *cbData->status); 494 EventLoopManagerSingleton::get() 495 ->getSensorRequestManager() 496 .releaseSamplingStatusUpdate(cbData->status); 497 memoryFree(cbData); 498 }; 499 500 // Schedule a deferred callback to handle sensor status change in the main 501 // thread. 502 EventLoopManagerSingleton::get()->deferCallback( 503 SystemCallbackType::SensorStatusUpdate, cbData, callback); 504 } 505 } 506 507 void SensorRequestManager::handleBiasEvent(uint32_t sensorHandle, 508 void *biasData) { 509 Sensor *sensor = 510 EventLoopManagerSingleton::get()->getSensorRequestManager().getSensor( 511 sensorHandle); 512 CHRE_ASSERT(sensor != nullptr); 513 514 if (sensor == nullptr) { 515 releaseBiasData(biasData); 516 } else { 517 uint16_t eventType; 518 if (!sensor->reportsBiasEvents() || !sensor->getBiasEventType(&eventType)) { 519 LOGE("Received bias event for unsupported sensor type %s", 520 sensor->getSensorName()); 521 } else { 522 auto freeCallback = [](uint16_t /* type */, void *data) { 523 EventLoopManagerSingleton::get() 524 ->getSensorRequestManager() 525 .releaseBiasData(data); 526 }; 527 528 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie( 529 eventType, biasData, freeCallback); 530 } 531 } 532 } 533 534 void SensorRequestManager::logStateToBuffer(DebugDumpWrapper &debugDump) const { 535 debugDump.print("\nSensors:\n"); 536 for (uint8_t i = 0; i < mSensors.size(); i++) { 537 for (const auto &request : mSensors[i].getRequests()) { 538 // TODO: Rearrange these prints to be similar to sensor request logs 539 // below 540 debugDump.print( 541 " %s: mode=%d int=%" PRIu64 " lat=%" PRIu64 " nappId=%" PRIu32 "\n", 542 mSensors[i].getSensorTypeName(), request.getMode(), 543 request.getInterval().toRawNanoseconds(), 544 request.getLatency().toRawNanoseconds(), request.getInstanceId()); 545 } 546 } 547 debugDump.print("\n Last %zu Sensor Requests:\n", mSensorRequestLogs.size()); 548 static_assert(kMaxSensorRequestLogs <= INT8_MAX, 549 "kMaxSensorRequestLogs must be <= INT8_MAX"); 550 for (int8_t i = static_cast<int8_t>(mSensorRequestLogs.size()) - 1; i >= 0; 551 i--) { 552 const auto &log = mSensorRequestLogs[static_cast<size_t>(i)]; 553 uint32_t sensorHandle; 554 if (getSensorHandle(log.sensorType, &sensorHandle)) { 555 debugDump.print(" ts=%" PRIu64 " nappId=%" PRIu32 " sensType=%s mode=%s", 556 log.timestamp.toRawNanoseconds(), log.instanceId, 557 mSensors[sensorHandle].getSensorTypeName(), 558 getSensorModeName(log.mode)); 559 } 560 561 if (sensorModeIsContinuous(log.mode)) { 562 debugDump.print(" int=%" PRIu64 " lat=%" PRIu64, 563 log.interval.toRawNanoseconds(), 564 log.latency.toRawNanoseconds()); 565 } 566 debugDump.print("\n"); 567 } 568 } 569 570 void SensorRequestManager::postFlushCompleteEvent(uint32_t sensorHandle, 571 uint8_t errorCode, 572 const FlushRequest &request) { 573 auto *event = memoryAlloc<chreSensorFlushCompleteEvent>(); 574 if (event == nullptr) { 575 LOG_OOM(); 576 } else { 577 event->sensorHandle = sensorHandle; 578 event->errorCode = errorCode; 579 event->cookie = request.cookie; 580 memset(event->reserved, 0, sizeof(event->reserved)); 581 582 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie( 583 CHRE_EVENT_SENSOR_FLUSH_COMPLETE, event, freeEventDataCallback, 584 request.nanoappInstanceId); 585 } 586 } 587 588 void SensorRequestManager::completeFlushRequestAtIndex(size_t index, 589 uint8_t errorCode) { 590 if (index < mFlushRequestQueue.size()) { 591 const FlushRequest &request = mFlushRequestQueue[index]; 592 uint32_t sensorHandle = request.sensorHandle; 593 if (request.isActive) { 594 mSensors[sensorHandle].clearPendingFlushRequest(); 595 } 596 597 postFlushCompleteEvent(sensorHandle, errorCode, request); 598 mFlushRequestQueue.erase(index); 599 } 600 } 601 602 void SensorRequestManager::dispatchNextFlushRequest(uint32_t sensorHandle) { 603 for (size_t i = 0; i < mFlushRequestQueue.size(); i++) { 604 FlushRequest &request = mFlushRequestQueue[i]; 605 if (request.sensorHandle == sensorHandle) { 606 uint8_t newRequestErrorCode = makeFlushRequest(request); 607 if (newRequestErrorCode == CHRE_ERROR_NONE) { 608 break; 609 } else { 610 completeFlushRequestAtIndex(i, newRequestErrorCode); 611 i--; 612 } 613 } 614 } 615 } 616 617 void SensorRequestManager::onFlushTimeout(uint32_t sensorHandle) { 618 if (sensorHandle < mSensors.size()) { 619 Sensor &sensor = mSensors[sensorHandle]; 620 sensor.setFlushRequestTimerHandle(CHRE_TIMER_INVALID); 621 } 622 } 623 624 void SensorRequestManager::handleFlushCompleteEventSync(uint8_t errorCode, 625 uint32_t sensorHandle) { 626 for (size_t i = 0; i < mFlushRequestQueue.size(); i++) { 627 if (mFlushRequestQueue[i].sensorHandle == sensorHandle) { 628 completeFlushRequestAtIndex(i, errorCode); 629 dispatchNextFlushRequest(sensorHandle); 630 break; 631 } 632 } 633 } 634 635 void SensorRequestManager::cancelFlushRequests(uint32_t sensorHandle, 636 uint32_t nanoappInstanceId) { 637 bool removeAll = (nanoappInstanceId == kSystemInstanceId); 638 for (size_t i = 0; i < mFlushRequestQueue.size(); i++) { 639 const FlushRequest &request = mFlushRequestQueue[i]; 640 if (request.sensorHandle == sensorHandle && 641 (request.nanoappInstanceId == nanoappInstanceId || removeAll)) { 642 completeFlushRequestAtIndex(i, 643 CHRE_ERROR_FUNCTION_DISABLED /* errorCode */); 644 i--; 645 } 646 } 647 648 if (!mSensors[sensorHandle].isFlushRequestPending()) { 649 dispatchNextFlushRequest(sensorHandle); 650 } 651 } 652 653 void SensorRequestManager::addSensorRequestLog( 654 uint32_t nanoappInstanceId, uint8_t sensorType, 655 const SensorRequest &sensorRequest) { 656 mSensorRequestLogs.kick_push(SensorRequestLog( 657 SystemTime::getMonotonicTime(), nanoappInstanceId, sensorType, 658 sensorRequest.getMode(), sensorRequest.getInterval(), 659 sensorRequest.getLatency())); 660 } 661 662 bool SensorRequestManager::addRequest(Sensor &sensor, 663 const SensorRequest &request, 664 bool *requestChanged) { 665 CHRE_ASSERT(requestChanged != nullptr); 666 667 size_t addIndex; 668 bool success = true; 669 SensorRequestMultiplexer &multiplexer = sensor.getRequestMultiplexer(); 670 if (!multiplexer.addRequest(request, &addIndex, requestChanged)) { 671 *requestChanged = false; 672 success = false; 673 LOG_OOM(); 674 } else if (*requestChanged) { 675 success = configurePlatformSensor(sensor); 676 if (!success) { 677 // Remove the newly added request since the platform failed to handle 678 // it. The sensor is expected to maintain the existing request so there is 679 // no need to reset the platform to the last maximal request. 680 multiplexer.removeRequest(addIndex, requestChanged); 681 682 // This is a roll-back operation so the maximal change in the 683 // multiplexer must not have changed. The request changed state is forced 684 // to false. 685 *requestChanged = false; 686 } 687 } 688 689 return success; 690 } 691 692 bool SensorRequestManager::updateRequest(Sensor &sensor, size_t updateIndex, 693 const SensorRequest &request, 694 bool *requestChanged) { 695 CHRE_ASSERT(requestChanged != nullptr); 696 697 bool success = true; 698 SensorRequestMultiplexer &multiplexer = sensor.getRequestMultiplexer(); 699 SensorRequest previousRequest = multiplexer.getRequests()[updateIndex]; 700 multiplexer.updateRequest(updateIndex, request, requestChanged); 701 if (*requestChanged) { 702 success = configurePlatformSensor(sensor); 703 if (!success) { 704 // Roll back the request since sending it to the sensor failed. The 705 // request will roll back to the previous maximal. The sensor is 706 // expected to maintain the existing request if a request fails so there 707 // is no need to reset the platform to the last maximal request. 708 multiplexer.updateRequest(updateIndex, previousRequest, requestChanged); 709 710 // This is a roll-back operation so the maximal change in the multiplexer 711 // must not have changed. The request changed state is forced to false. 712 *requestChanged = false; 713 } 714 } 715 716 return success; 717 } 718 719 bool SensorRequestManager::removeRequest(Sensor &sensor, size_t removeIndex, 720 bool *requestChanged) { 721 CHRE_ASSERT(requestChanged != nullptr); 722 723 bool success = true; 724 sensor.getRequestMultiplexer().removeRequest(removeIndex, requestChanged); 725 if (*requestChanged) { 726 success = configurePlatformSensor(sensor); 727 if (!success) { 728 LOGE("SensorRequestManager failed to remove a request"); 729 730 // If the platform fails to handle this request in a debug build there is 731 // likely an error in the platform. This is not strictly a programming 732 // error but it does make sense to use assert semantics when a platform 733 // fails to handle a request that it had been sent previously. 734 CHRE_ASSERT(false); 735 736 // The request to the platform to set a request when removing has failed 737 // so the request has not changed. 738 *requestChanged = false; 739 } 740 } 741 return success; 742 } 743 744 bool SensorRequestManager::removeAllRequests(Sensor &sensor) { 745 bool requestChanged; 746 sensor.getRequestMultiplexer().removeAllRequests(&requestChanged); 747 748 bool success = true; 749 if (requestChanged) { 750 success = configurePlatformSensor(sensor); 751 752 if (!success) { 753 LOGE("SensorRequestManager failed to remove all request"); 754 755 // If the platform fails to handle this request in a debug build there 756 // is likely an error in the platform. This is not strictly a programming 757 // error but it does make sense to use assert semantics when a platform 758 // fails to handle a request that it had been sent previously. 759 CHRE_ASSERT(false); 760 } 761 } 762 763 return success; 764 } 765 766 uint8_t SensorRequestManager::makeFlushRequest(FlushRequest &request) { 767 uint8_t errorCode = CHRE_ERROR; 768 Sensor &sensor = mSensors[request.sensorHandle]; 769 if (!sensor.isSensorEnabled()) { 770 LOGE("Cannot flush on disabled sensor"); 771 } else if (!sensor.isFlushRequestPending()) { 772 Nanoseconds now = SystemTime::getMonotonicTime(); 773 Nanoseconds deadline = request.deadlineTimestamp; 774 if (now >= deadline) { 775 LOGE("Flush sensor %s failed for nanoapp ID %" PRIu32 776 ": deadline exceeded", 777 sensor.getSensorName(), request.nanoappInstanceId); 778 errorCode = CHRE_ERROR_TIMEOUT; 779 } else if (doMakeFlushRequest(sensor)) { 780 errorCode = CHRE_ERROR_NONE; 781 Nanoseconds delay = deadline - now; 782 request.isActive = true; 783 784 NestedDataPtr<uint32_t> index(request.sensorHandle); 785 786 auto callback = [](uint16_t /* eventType */, void *eventData) { 787 LOGE("Flush request timed out."); 788 NestedDataPtr<uint32_t> nestedIndex; 789 nestedIndex.dataPtr = eventData; 790 EventLoopManagerSingleton::get() 791 ->getSensorRequestManager() 792 .onFlushTimeout(nestedIndex.data); 793 794 // Send a complete event, thus closing out this flush request. If the 795 // request that has just timed out receives a response later, this may 796 // inadvertently close out a new request before it has actually 797 // completed. 798 // TODO: Attach an ID to all flush requests / responses so stale 799 // responses can be properly dropped. 800 EventLoopManagerSingleton::get() 801 ->getSensorRequestManager() 802 .handleFlushCompleteEventSync(CHRE_ERROR_TIMEOUT, nestedIndex.data); 803 }; 804 805 sensor.setFlushRequestTimerHandle( 806 EventLoopManagerSingleton::get()->setDelayedCallback( 807 SystemCallbackType::SensorFlushTimeout, index.dataPtr, callback, 808 delay)); 809 } 810 } else { 811 // Flush request will be made once the pending request is completed. 812 // Return true so that the nanoapp can wait for a result through the 813 // CHRE_EVENT_SENSOR_FLUSH_COMPLETE event. 814 errorCode = CHRE_ERROR_NONE; 815 } 816 817 return errorCode; 818 } 819 820 bool SensorRequestManager::doMakeFlushRequest(Sensor &sensor) { 821 // Set to true before making the request since the request may be a 822 // synchronous request and we may get the complete event before it returns. 823 sensor.setFlushRequestPending(true); 824 // TODO: Refactor code to take the request ID into account so multiple flush 825 // requests can be issued. 826 uint32_t flushRequestId; 827 bool success = mPlatformSensorManager.flush(sensor, &flushRequestId); 828 sensor.setFlushRequestPending(success); 829 return success; 830 } 831 832 bool SensorRequestManager::configurePlatformSensor(Sensor &sensor) { 833 bool success = false; 834 const SensorRequest &request = sensor.getMaximalRequest(); 835 if (!mPlatformSensorManager.configureSensor(sensor, request)) { 836 LOGE("Failed to make platform sensor request"); 837 } else { 838 success = true; 839 840 // Reset last event if an on-change sensor is turned off. 841 if (request.getMode() == SensorMode::Off) { 842 sensor.clearLastEvent(); 843 } 844 } 845 return success; 846 } 847 848 } // namespace chre 849