• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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