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_api/chre/version.h"
20 #include "chre/core/event_loop_manager.h"
21 #include "chre/platform/fatal_error.h"
22 #include "chre/platform/shared/platform_sensor_util.h"
23 #include "chre/util/nested_data_ptr.h"
24 #include "chre/util/system/debug_dump.h"
25
26 #define LOG_INVALID_SENSOR(x) \
27 LOGE("Invalid sensor type %" PRIu8 ": line %d", \
28 static_cast<uint8_t>(x), __LINE__)
29
30 namespace chre {
31 namespace {
32
isSensorRequestValid(const Sensor & sensor,const SensorRequest & sensorRequest)33 bool isSensorRequestValid(const Sensor& sensor,
34 const SensorRequest& sensorRequest) {
35 bool isRequestContinuous = sensorModeIsContinuous(
36 sensorRequest.getMode());
37 bool isRequestOneShot = sensorModeIsOneShot(sensorRequest.getMode());
38 uint64_t requestedInterval = sensorRequest.getInterval().toRawNanoseconds();
39 SensorType sensorType = sensor.getSensorType();
40
41 bool success = true;
42 if (requestedInterval < sensor.getMinInterval()) {
43 success = false;
44 LOGE("Requested interval %" PRIu64 " < sensor's minInterval %" PRIu64,
45 requestedInterval, sensor.getMinInterval());
46 } else if (isRequestContinuous) {
47 if (sensorTypeIsOneShot(sensorType)) {
48 success = false;
49 LOGE("Invalid continuous request for a one-shot sensor.");
50 }
51 } else if (isRequestOneShot) {
52 if (!sensorTypeIsOneShot(sensorType)) {
53 success = false;
54 LOGE("Invalid one-shot request for a continuous sensor.");
55 }
56 }
57 return success;
58 }
59
60 } // namespace
61
SensorRequestManager()62 SensorRequestManager::SensorRequestManager() {
63 mSensorRequests.resize(mSensorRequests.capacity());
64 }
65
~SensorRequestManager()66 SensorRequestManager::~SensorRequestManager() {
67 for (size_t i = 0; i < mSensorRequests.size(); i++) {
68 // Disable sensors that have been enabled previously.
69 if (mSensorRequests[i].isSensorSupported()) {
70 mSensorRequests[i].removeAll();
71 }
72 }
73
74 PlatformSensor::deinit();
75 }
76
init()77 void SensorRequestManager::init() {
78 // The Platform sensor must be initialized prior to interacting with any
79 // sensors.
80 PlatformSensor::init();
81
82 DynamicVector<Sensor> sensors;
83 sensors.reserve(8); // Avoid some initial reallocation churn
84 if (!PlatformSensor::getSensors(&sensors)) {
85 LOGE("Failed to query the platform for sensors");
86 } else if (sensors.empty()) {
87 LOGW("Platform returned zero sensors");
88 } else {
89 for (size_t i = 0; i < sensors.size(); i++) {
90 SensorType sensorType = sensors[i].getSensorType();
91 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
92
93 if (!isValidSensorType(sensorType)) {
94 LOG_INVALID_SENSOR(sensorType);
95 } else if (sensors[i].getMinInterval() == 0) {
96 LOGE("Invalid sensor minInterval: %s", getSensorTypeName(sensorType));
97 } else {
98 mSensorRequests[sensorIndex].setSensor(std::move(sensors[i]));
99 LOGD("Found sensor: %s", getSensorTypeName(sensorType));
100 }
101 }
102 }
103 }
104
getSensorHandle(SensorType sensorType,uint32_t * sensorHandle) const105 bool SensorRequestManager::getSensorHandle(SensorType sensorType,
106 uint32_t *sensorHandle) const {
107 CHRE_ASSERT(sensorHandle);
108
109 bool sensorHandleIsValid = false;
110 if (!isValidSensorType(sensorType)) {
111 LOG_INVALID_SENSOR(sensorType);
112 } else {
113 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
114 sensorHandleIsValid = mSensorRequests[sensorIndex].isSensorSupported();
115 if (sensorHandleIsValid) {
116 *sensorHandle = getSensorHandleFromSensorType(sensorType);
117 }
118 }
119
120 return sensorHandleIsValid;
121 }
122
setSensorRequest(Nanoapp * nanoapp,uint32_t sensorHandle,const SensorRequest & sensorRequest)123 bool SensorRequestManager::setSensorRequest(Nanoapp *nanoapp,
124 uint32_t sensorHandle, const SensorRequest& sensorRequest) {
125 CHRE_ASSERT(nanoapp);
126
127 // Validate the input to ensure that a valid handle has been provided.
128 SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
129 if (!isValidSensorType(sensorType)) {
130 LOG_INVALID_SENSOR(sensorType);
131 return false;
132 }
133
134 // Ensure that the runtime is aware of this sensor type.
135 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
136 SensorRequests& requests = mSensorRequests[sensorIndex];
137 if (!requests.isSensorSupported()) {
138 LOGW("Attempting to configure non-existent sensor");
139 return false;
140 }
141
142 const Sensor& sensor = requests.getSensor();
143 if (!isSensorRequestValid(sensor, sensorRequest)) {
144 return false;
145 }
146
147 size_t requestIndex;
148 uint16_t eventType = getSampleEventTypeForSensorType(sensorType);
149 bool nanoappHasRequest = (requests.find(nanoapp->getInstanceId(),
150 &requestIndex) != nullptr);
151
152 bool success;
153 bool requestChanged;
154 if (sensorRequest.getMode() == SensorMode::Off) {
155 if (nanoappHasRequest) {
156 // The request changes the mode to off and there was an existing request.
157 // The existing request is removed from the multiplexer. The nanoapp is
158 // unregistered from events of this type if this request was successful.
159 success = requests.remove(requestIndex, &requestChanged);
160 if (success) {
161 cancelFlushRequests(sensorType, nanoapp->getInstanceId());
162
163 nanoapp->unregisterForBroadcastEvent(eventType);
164
165 uint16_t biasEventType;
166 if (getSensorBiasEventType(sensorType, &biasEventType)) {
167 // Per API requirements, turn off bias reporting when unsubscribing
168 // from the sensor.
169 nanoapp->unregisterForBroadcastEvent(biasEventType);
170 }
171 }
172 } else {
173 // The sensor is being configured to Off, but is already Off (there is no
174 // existing request). We assign to success to be true and no other
175 // operation is required.
176 requestChanged = false;
177 success = true;
178 }
179 } else if (!nanoappHasRequest) {
180 // The request changes the mode to the enabled state and there was no
181 // existing request. The request is newly created and added to the
182 // multiplexer. The nanoapp is registered for events if this request was
183 // successful.
184 success = requests.add(sensorRequest, &requestChanged);
185 if (success) {
186 nanoapp->registerForBroadcastEvent(eventType);
187
188 // Per API requirements, turn on bias reporting for calibrated sensors
189 // by default when subscribed.
190 uint16_t biasEventType;
191 if (getSensorBiasEventType(sensorType, &biasEventType)
192 && sensorTypeIsCalibrated(sensorType)) {
193 nanoapp->registerForBroadcastEvent(biasEventType);
194 }
195
196 // Deliver last valid event to new clients of on-change sensors
197 if (sensorTypeIsOnChange(sensor.getSensorType()) &&
198 sensor.getLastEvent() != nullptr) {
199 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
200 getSampleEventTypeForSensorType(sensorType), sensor.getLastEvent(),
201 nullptr, nanoapp->getInstanceId());
202 }
203 }
204 } else {
205 // The request changes the mode to the enabled state and there was an
206 // existing request. The existing request is updated.
207 success = requests.update(requestIndex, sensorRequest, &requestChanged);
208 }
209
210 if (requestChanged) {
211 // TODO: Send an event to nanoapps to indicate the rate change.
212 }
213
214 return success;
215 }
216
getSensorInfo(uint32_t sensorHandle,const Nanoapp & nanoapp,struct chreSensorInfo * info) const217 bool SensorRequestManager::getSensorInfo(uint32_t sensorHandle,
218 const Nanoapp& nanoapp,
219 struct chreSensorInfo *info) const {
220 CHRE_ASSERT(info);
221
222 bool success = false;
223
224 // Validate the input to ensure that a valid handle has been provided.
225 SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
226 if (!isValidSensorType(sensorType)) {
227 LOG_INVALID_SENSOR(sensorType);
228 } else {
229 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
230 if (!mSensorRequests[sensorIndex].isSensorSupported()) {
231 LOGW("Attempting to get sensor info for unsupported sensor handle %"
232 PRIu32, sensorHandle);
233 } else {
234 // Platform-independent properties.
235 info->sensorType = getUnsignedIntFromSensorType(sensorType);
236 info->isOnChange = sensorTypeIsOnChange(sensorType);
237 info->isOneShot = sensorTypeIsOneShot(sensorType);
238 info->reportsBiasEvents = sensorTypeReportsBias(sensorType);
239 info->unusedFlags = 0;
240
241 // Platform-specific properties.
242 const Sensor& sensor = mSensorRequests[sensorIndex].getSensor();
243 info->sensorName = sensor.getSensorName();
244
245 // minInterval was added in CHRE API v1.1 - do not attempt to populate for
246 // nanoapps targeting v1.0 as their struct will not be large enough
247 if (nanoapp.getTargetApiVersion() >= CHRE_API_VERSION_1_1) {
248 info->minInterval = sensor.getMinInterval();
249 }
250
251 success = true;
252 }
253 }
254
255 return success;
256 }
257
removeAllRequests(SensorType sensorType)258 bool SensorRequestManager::removeAllRequests(SensorType sensorType) {
259 bool success = false;
260 if (!isValidSensorType(sensorType)) {
261 LOG_INVALID_SENSOR(sensorType);
262 } else {
263 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
264 SensorRequests& requests = mSensorRequests[sensorIndex];
265 uint16_t eventType = getSampleEventTypeForSensorType(sensorType);
266
267 for (const SensorRequest& request : requests.getRequests()) {
268 Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop()
269 .findNanoappByInstanceId(request.getInstanceId());
270 if (nanoapp != nullptr) {
271 nanoapp->unregisterForBroadcastEvent(eventType);
272 }
273 }
274
275 cancelFlushRequests(sensorType);
276 success = requests.removeAll();
277 }
278 return success;
279 }
280
getSensor(SensorType sensorType)281 Sensor *SensorRequestManager::getSensor(SensorType sensorType) {
282 Sensor *sensorPtr = nullptr;
283 if (!isValidSensorType(sensorType)) {
284 LOG_INVALID_SENSOR(sensorType);
285 } else {
286 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
287 if (mSensorRequests[sensorIndex].isSensorSupported()) {
288 sensorPtr = &mSensorRequests[sensorIndex].getSensor();
289 }
290 }
291 return sensorPtr;
292 }
293
getSensorSamplingStatus(uint32_t sensorHandle,struct chreSensorSamplingStatus * status) const294 bool SensorRequestManager::getSensorSamplingStatus(
295 uint32_t sensorHandle, struct chreSensorSamplingStatus *status) const {
296 CHRE_ASSERT(status);
297
298 bool success = false;
299 SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
300 if (!isValidSensorType(sensorType)) {
301 LOG_INVALID_SENSOR(sensorType);
302 } else {
303 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
304 if (mSensorRequests[sensorIndex].isSensorSupported()) {
305 success = mSensorRequests[sensorIndex].getSamplingStatus(status);
306 }
307 }
308 return success;
309 }
310
getRequests(SensorType sensorType) const311 const DynamicVector<SensorRequest>& SensorRequestManager::getRequests(
312 SensorType sensorType) const {
313 size_t sensorIndex = 0;
314 if (!isValidSensorType(sensorType)) {
315 LOG_INVALID_SENSOR(sensorType);
316 } else {
317 sensorIndex = getSensorTypeArrayIndex(sensorType);
318 }
319 return mSensorRequests[sensorIndex].getRequests();
320 }
321
configureBiasEvents(Nanoapp * nanoapp,uint32_t sensorHandle,bool enable)322 bool SensorRequestManager::configureBiasEvents(
323 Nanoapp *nanoapp, uint32_t sensorHandle, bool enable) {
324 bool success = false;
325 uint16_t eventType;
326 SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
327 if (getSensorBiasEventType(sensorType, &eventType)) {
328 if (enable) {
329 nanoapp->registerForBroadcastEvent(eventType);
330 } else {
331 nanoapp->unregisterForBroadcastEvent(eventType);
332 }
333
334 success = true;
335 }
336
337 return success;
338 }
339
getThreeAxisBias(uint32_t sensorHandle,struct chreSensorThreeAxisData * bias) const340 bool SensorRequestManager::getThreeAxisBias(
341 uint32_t sensorHandle, struct chreSensorThreeAxisData *bias) const {
342 CHRE_ASSERT(bias != nullptr);
343
344 bool success = false;
345 if (bias != nullptr) {
346 SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
347 if (!isValidSensorType(sensorType)) {
348 LOG_INVALID_SENSOR(sensorType);
349 } else {
350 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
351 if (mSensorRequests[sensorIndex].isSensorSupported()) {
352 success = mSensorRequests[sensorIndex].getThreeAxisBias(bias);
353 }
354 }
355 }
356
357 return success;
358 }
359
flushAsync(Nanoapp * nanoapp,uint32_t sensorHandle,const void * cookie)360 bool SensorRequestManager::flushAsync(
361 Nanoapp *nanoapp, uint32_t sensorHandle, const void *cookie) {
362 bool success = false;
363
364 uint32_t nanoappInstanceId = nanoapp->getInstanceId();
365 SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
366 // NOTE: One-shot sensors do not support flush per API
367 if (!isValidSensorType(sensorType) || sensorTypeIsOneShot(sensorType)) {
368 LOGE("Cannot flush for sensor type %" PRIu32,
369 static_cast<uint32_t>(sensorType));
370 } else if (mFlushRequestQueue.full()) {
371 LOG_OOM();
372 } else {
373 mFlushRequestQueue.emplace_back(sensorType, nanoappInstanceId, cookie);
374 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
375 success = (mSensorRequests[sensorIndex].makeFlushRequest(
376 mFlushRequestQueue.back()) == CHRE_ERROR_NONE);
377 if (!success) {
378 mFlushRequestQueue.pop_back();
379 }
380 }
381
382 return success;
383 }
384
handleFlushCompleteEvent(uint8_t errorCode,SensorType sensorType)385 void SensorRequestManager::handleFlushCompleteEvent(
386 uint8_t errorCode, SensorType sensorType) {
387 size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
388 if (isValidSensorType(sensorType)
389 && mSensorRequests[sensorIndex].isFlushRequestPending()) {
390
391 // Cancel flush request timer before posting to the event queue to ensure
392 // a timeout event isn't processed by CHRE now that the complete event
393 // has been received.
394 mSensorRequests[sensorIndex].cancelPendingFlushRequestTimer();
395
396 struct CallbackState {
397 uint8_t errorCode;
398 SensorType sensorType;
399 };
400
401 NestedDataPtr<CallbackState> state = {};
402 state.data.errorCode = errorCode;
403 state.data.sensorType = sensorType;
404
405 auto callback = [](uint16_t /* eventType */, void *eventData) {
406 NestedDataPtr<CallbackState> nestedState;
407 nestedState.dataPtr = eventData;
408 EventLoopManagerSingleton::get()->getSensorRequestManager()
409 .handleFlushCompleteEventSync(nestedState.data.errorCode,
410 nestedState.data.sensorType);
411 };
412
413 EventLoopManagerSingleton::get()->deferCallback(
414 SystemCallbackType::SensorFlushComplete, state.dataPtr, callback);
415 }
416 }
417
handleSensorEvent(SensorType sensorType,void * event)418 void SensorRequestManager::handleSensorEvent(SensorType sensorType,
419 void *event) {
420 uint16_t eventType = getSampleEventTypeForSensorType(sensorType);
421 // Only allow dropping continuous sensor events since losing one-shot or
422 // on-change events could result in nanoapps stuck in a bad state.
423 if (sensorTypeIsContinuous(sensorType)) {
424 EventLoopManagerSingleton::get()->getEventLoop().postLowPriorityEventOrFree(
425 eventType, event, sensorDataEventFree);
426 } else {
427 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
428 eventType, event, sensorDataEventFree);
429 }
430 }
431
logStateToBuffer(char * buffer,size_t * bufferPos,size_t bufferSize) const432 void SensorRequestManager::logStateToBuffer(char *buffer, size_t *bufferPos,
433 size_t bufferSize) const {
434 debugDumpPrint(buffer, bufferPos, bufferSize, "\nSensors:\n");
435 for (uint8_t i = 0; i < static_cast<uint8_t>(SensorType::SENSOR_TYPE_COUNT);
436 i++) {
437 SensorType sensor = static_cast<SensorType>(i);
438 if (isValidSensorType(sensor)) {
439 for (const auto& request : getRequests(sensor)) {
440 debugDumpPrint(buffer, bufferPos, bufferSize, " %s: mode=%d"
441 " interval(ns)=%" PRIu64 " latency(ns)=%"
442 PRIu64 " nanoappId=%" PRIu32 "\n",
443 getSensorTypeName(sensor), request.getMode(),
444 request.getInterval().toRawNanoseconds(),
445 request.getLatency().toRawNanoseconds(),
446 request.getInstanceId());
447 }
448 }
449 }
450 }
451
postFlushCompleteEvent(uint32_t sensorHandle,uint8_t errorCode,const FlushRequest & request)452 void SensorRequestManager::postFlushCompleteEvent(
453 uint32_t sensorHandle, uint8_t errorCode, const FlushRequest& request) {
454 auto *event = memoryAlloc<chreSensorFlushCompleteEvent>();
455 if (event == nullptr) {
456 LOG_OOM();
457 } else {
458 event->sensorHandle = sensorHandle;
459 event->errorCode = errorCode;
460 event->cookie = request.cookie;
461 memset(event->reserved, 0, sizeof(event->reserved));
462
463 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
464 CHRE_EVENT_SENSOR_FLUSH_COMPLETE, event, freeEventDataCallback,
465 request.nanoappInstanceId);
466 }
467 }
468
completeFlushRequestAtIndex(size_t index,uint8_t errorCode)469 void SensorRequestManager::completeFlushRequestAtIndex(
470 size_t index, uint8_t errorCode) {
471 if (index < mFlushRequestQueue.size()) {
472 const FlushRequest& request = mFlushRequestQueue[index];
473 SensorType sensorType = request.sensorType;
474 if (request.isActive) {
475 SensorRequests& requests = getSensorRequests(sensorType);
476 requests.clearPendingFlushRequest();
477 }
478
479 uint32_t sensorHandle;
480 if (getSensorHandle(sensorType, &sensorHandle)) {
481 postFlushCompleteEvent(sensorHandle, errorCode, request);
482 }
483 mFlushRequestQueue.erase(index);
484 }
485 }
486
dispatchNextFlushRequest(SensorType sensorType)487 void SensorRequestManager::dispatchNextFlushRequest(SensorType sensorType) {
488 SensorRequests& requests = getSensorRequests(sensorType);
489
490 for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
491 FlushRequest& request = mFlushRequestQueue[i];
492 if (request.sensorType == sensorType) {
493 uint8_t newRequestErrorCode = requests.makeFlushRequest(request);
494 if (newRequestErrorCode == CHRE_ERROR_NONE) {
495 break;
496 } else {
497 completeFlushRequestAtIndex(i, newRequestErrorCode);
498 i--;
499 }
500 }
501 }
502 }
503
handleFlushCompleteEventSync(uint8_t errorCode,SensorType sensorType)504 void SensorRequestManager::handleFlushCompleteEventSync(
505 uint8_t errorCode, SensorType sensorType) {
506 for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
507 if (mFlushRequestQueue[i].sensorType == sensorType) {
508 completeFlushRequestAtIndex(i, errorCode);
509 dispatchNextFlushRequest(sensorType);
510 break;
511 }
512 }
513 }
514
cancelFlushRequests(SensorType sensorType,uint32_t nanoappInstanceId)515 void SensorRequestManager::cancelFlushRequests(
516 SensorType sensorType, uint32_t nanoappInstanceId) {
517 bool removeAll = (nanoappInstanceId == kSystemInstanceId);
518 for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
519 const FlushRequest& request = mFlushRequestQueue[i];
520 if (request.sensorType == sensorType &&
521 (request.nanoappInstanceId == nanoappInstanceId || removeAll)) {
522 completeFlushRequestAtIndex(
523 i, CHRE_ERROR_FUNCTION_DISABLED /* errorCode */);
524 i--;
525 }
526 }
527
528 SensorRequests& requests = getSensorRequests(sensorType);
529 if (!requests.isFlushRequestPending()) {
530 dispatchNextFlushRequest(sensorType);
531 }
532 }
533
find(uint32_t instanceId,size_t * index) const534 const SensorRequest *SensorRequestManager::SensorRequests::find(
535 uint32_t instanceId, size_t *index) const {
536 CHRE_ASSERT(index);
537
538 const auto& requests = mMultiplexer.getRequests();
539 for (size_t i = 0; i < requests.size(); i++) {
540 const SensorRequest& sensorRequest = requests[i];
541 if (sensorRequest.getInstanceId() == instanceId) {
542 *index = i;
543 return &sensorRequest;
544 }
545 }
546
547 return nullptr;
548 }
549
add(const SensorRequest & request,bool * requestChanged)550 bool SensorRequestManager::SensorRequests::add(const SensorRequest& request,
551 bool *requestChanged) {
552 CHRE_ASSERT(requestChanged != nullptr);
553 CHRE_ASSERT(isSensorSupported());
554
555 size_t addIndex;
556 bool success = true;
557 if (!mMultiplexer.addRequest(request, &addIndex, requestChanged)) {
558 *requestChanged = false;
559 success = false;
560 LOG_OOM();
561 } else if (*requestChanged) {
562 success = mSensor->setRequest(mMultiplexer.getCurrentMaximalRequest());
563 if (!success) {
564 // Remove the newly added request since the platform failed to handle it.
565 // The sensor is expected to maintain the existing request so there is no
566 // need to reset the platform to the last maximal request.
567 mMultiplexer.removeRequest(addIndex, requestChanged);
568
569 // This is a roll-back operation so the maximal change in the multiplexer
570 // must not have changed. The request changed state is forced to false.
571 *requestChanged = false;
572 }
573 }
574
575 return success;
576 }
577
remove(size_t removeIndex,bool * requestChanged)578 bool SensorRequestManager::SensorRequests::remove(size_t removeIndex,
579 bool *requestChanged) {
580 CHRE_ASSERT(requestChanged != nullptr);
581 CHRE_ASSERT(isSensorSupported());
582
583 bool success = true;
584 mMultiplexer.removeRequest(removeIndex, requestChanged);
585 if (*requestChanged) {
586 success = mSensor->setRequest(mMultiplexer.getCurrentMaximalRequest());
587 if (!success) {
588 LOGE("SensorRequestManager failed to remove a request");
589
590 // If the platform fails to handle this request in a debug build there is
591 // likely an error in the platform. This is not strictly a programming
592 // error but it does make sense to use assert semantics when a platform
593 // fails to handle a request that it had been sent previously.
594 CHRE_ASSERT(false);
595
596 // The request to the platform to set a request when removing has failed
597 // so the request has not changed.
598 *requestChanged = false;
599 }
600 }
601
602 return success;
603 }
604
update(size_t updateIndex,const SensorRequest & request,bool * requestChanged)605 bool SensorRequestManager::SensorRequests::update(size_t updateIndex,
606 const SensorRequest& request,
607 bool *requestChanged) {
608 CHRE_ASSERT(requestChanged != nullptr);
609 CHRE_ASSERT(isSensorSupported());
610
611 bool success = true;
612 SensorRequest previousRequest = mMultiplexer.getRequests()[updateIndex];
613 mMultiplexer.updateRequest(updateIndex, request, requestChanged);
614 if (*requestChanged) {
615 success = mSensor->setRequest(mMultiplexer.getCurrentMaximalRequest());
616 if (!success) {
617 // Roll back the request since sending it to the sensor failed. The
618 // request will roll back to the previous maximal. The sensor is
619 // expected to maintain the existing request if a request fails so there
620 // is no need to reset the platform to the last maximal request.
621 mMultiplexer.updateRequest(updateIndex, previousRequest, requestChanged);
622
623 // This is a roll-back operation so the maximal change in the multiplexer
624 // must not have changed. The request changed state is forced to false.
625 *requestChanged = false;
626 }
627 }
628
629 return success;
630 }
631
removeAll()632 bool SensorRequestManager::SensorRequests::removeAll() {
633 CHRE_ASSERT(isSensorSupported());
634
635 bool requestChanged;
636 mMultiplexer.removeAllRequests(&requestChanged);
637
638 bool success = true;
639 if (requestChanged) {
640 SensorRequest maximalRequest = mMultiplexer.getCurrentMaximalRequest();
641 success = mSensor->setRequest(maximalRequest);
642 if (!success) {
643 LOGE("SensorRequestManager failed to remove all request");
644
645 // If the platform fails to handle this request in a debug build there is
646 // likely an error in the platform. This is not strictly a programming
647 // error but it does make sense to use assert semantics when a platform
648 // fails to handle a request that it had been sent previously.
649 CHRE_ASSERT(false);
650 }
651 }
652 return success;
653 }
654
makeFlushRequest(FlushRequest & request)655 uint8_t SensorRequestManager::SensorRequests::makeFlushRequest(
656 FlushRequest& request) {
657 uint8_t errorCode = CHRE_ERROR;
658 if (!isSensorSupported()) {
659 LOGE("Cannot flush on unsupported sensor");
660 } else if (mMultiplexer.getRequests().size() == 0) {
661 LOGE("Cannot flush on disabled sensor");
662 } else if (!isFlushRequestPending()) {
663 Nanoseconds now = SystemTime::getMonotonicTime();
664 Nanoseconds deadline = request.deadlineTimestamp;
665 if (now >= deadline) {
666 LOGE("Flush sensor %" PRIu32 " failed for nanoapp ID %" PRIu32
667 ": deadline exceeded", static_cast<uint32_t>(request.sensorType),
668 request.nanoappInstanceId);
669 errorCode = CHRE_ERROR_TIMEOUT;
670 } else if (doMakeFlushRequest()) {
671 errorCode = CHRE_ERROR_NONE;
672 Nanoseconds delay = deadline - now;
673 request.isActive = true;
674
675 NestedDataPtr<SensorType> nestedType = {};
676 nestedType.data = request.sensorType;
677
678 auto callback = [](uint16_t /* eventType */, void * eventData) {
679 LOGE("Flush request timed out.");
680 NestedDataPtr<SensorType> nestedType;
681 nestedType.dataPtr = eventData;
682 // Send a complete event, thus closing out this flush request. If the
683 // request that has just timed out receives a response later, this may
684 // inadvertently close out a new request before it has actually
685 // completed.
686 // TODO: Attach an ID to all flush requests / responses so stale
687 // responses can be properly dropped.
688 EventLoopManagerSingleton::get()->getSensorRequestManager()
689 .handleFlushCompleteEventSync(CHRE_ERROR_TIMEOUT,
690 nestedType.data);
691 };
692
693 mFlushRequestTimerHandle =
694 EventLoopManagerSingleton::get()->setDelayedCallback(
695 SystemCallbackType::SensorFlushTimeout, nestedType.dataPtr,
696 callback, delay);
697 }
698 } else {
699 // Flush request will be made once the pending request is completed.
700 // Return true so that the nanoapp can wait for a result through the
701 // CHRE_EVENT_SENSOR_FLUSH_COMPLETE event.
702 errorCode = CHRE_ERROR_NONE;
703 }
704
705 return errorCode;
706 }
707
clearPendingFlushRequest()708 void SensorRequestManager::SensorRequests::clearPendingFlushRequest() {
709 cancelPendingFlushRequestTimer();
710 mFlushRequestPending = false;
711 }
712
cancelPendingFlushRequestTimer()713 void SensorRequestManager::SensorRequests::cancelPendingFlushRequestTimer() {
714 if (mFlushRequestTimerHandle != CHRE_TIMER_INVALID) {
715 EventLoopManagerSingleton::get()->cancelDelayedCallback(
716 mFlushRequestTimerHandle);
717 mFlushRequestTimerHandle = CHRE_TIMER_INVALID;
718 }
719 }
720
doMakeFlushRequest()721 bool SensorRequestManager::SensorRequests::doMakeFlushRequest() {
722 // Set to true before making the request since it's a synchronous request
723 // and we may get the complete event before it returns.
724 mFlushRequestPending = true;
725 mFlushRequestPending = mSensor->flushAsync();
726 return mFlushRequestPending;
727 }
728
729 } // namespace chre
730