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