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