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