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             // Only unregister if nanoapp no longer has an outstanding request
200             // for a sensor + target group mask.
201             uint16_t activeMask =
202                 getActiveTargetGroupMask(nanoapp->getInstanceId(), sensorType);
203             uint16_t inactiveMask = sensor.getTargetGroupMask() & ~activeMask;
204             if (inactiveMask != 0) {
205               nanoapp->unregisterForBroadcastEvent(eventType, inactiveMask);
206 
207               uint16_t biasEventType;
208               if (sensor.getBiasEventType(&biasEventType)) {
209                 // Per API requirements, turn off bias reporting when
210                 // unsubscribing from the sensor.
211                 nanoapp->unregisterForBroadcastEvent(biasEventType,
212                                                      inactiveMask);
213               }
214             }
215           }
216         } else {
217           // The sensor is being configured to Off, but is already Off (there is
218           // no existing request). We assign to success to be true and no other
219           // operation is required.
220           success = true;
221         }
222       } else if (!nanoappHasRequest) {
223         // The request changes the mode to the enabled state and there was no
224         // existing request. The request is newly created and added to the
225         // multiplexer. The nanoapp is registered for events if this request was
226         // successful.
227         uint16_t biasEventType;
228         if (sensor.getBiasEventType(&biasEventType) && sensor.isCalibrated()) {
229           // Per API requirements, turn on bias reporting for calibrated sensors
230           // by default when subscribed.
231           request.setBiasUpdatesRequested(true);
232         }
233 
234         success = addRequest(sensor, request, &requestChanged);
235         if (success) {
236           nanoapp->registerForBroadcastEvent(eventType,
237                                              sensor.getTargetGroupMask());
238 
239           if (request.getBiasUpdatesRequested()) {
240             nanoapp->registerForBroadcastEvent(biasEventType,
241                                                sensor.getTargetGroupMask());
242           }
243 
244           // Deliver last valid event to new clients of on-change sensors
245           if (sensor.getLastEvent() != nullptr) {
246             EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
247                 eventType, sensor.getLastEvent(), nullptr /* freeCallback */,
248                 nanoapp->getInstanceId());
249           }
250         }
251       } else {
252         // Ensure bias events stay requested if they were previously enabled.
253         const SensorRequest &previousRequest =
254             sensor.getRequestMultiplexer().getRequests()[requestIndex];
255         if (previousRequest.getBiasUpdatesRequested()) {
256           request.setBiasUpdatesRequested(true);
257         }
258         // The request changes the mode to the enabled state and there was an
259         // existing request. The existing request is updated.
260         success = updateRequest(sensor, requestIndex, request, &requestChanged);
261       }
262 
263       // TODO: Allow translating the sensor request
264 
265       if (requestChanged) {
266         // TODO: Send an event to nanoapps to indicate the rate change.
267       }
268 
269       if (success) {
270         addSensorRequestLog(nanoapp->getInstanceId(), sensorHandle, request);
271       }
272     }
273   }
274 
275   return success;
276 }
277 
getSensorInfo(uint32_t sensorHandle,const Nanoapp & nanoapp,struct chreSensorInfo * info) const278 bool SensorRequestManager::getSensorInfo(uint32_t sensorHandle,
279                                          const Nanoapp &nanoapp,
280                                          struct chreSensorInfo *info) const {
281   CHRE_ASSERT(info);
282 
283   bool success = false;
284   if (sensorHandle >= mSensors.size()) {
285     LOG_INVALID_HANDLE(sensorHandle);
286   } else {
287     mSensors[sensorHandle].populateSensorInfo(info,
288                                               nanoapp.getTargetApiVersion());
289     success = true;
290   }
291 
292   return success;
293 }
294 
removeAllRequests(uint32_t sensorHandle)295 bool SensorRequestManager::removeAllRequests(uint32_t sensorHandle) {
296   bool success = false;
297   if (sensorHandle >= mSensors.size()) {
298     LOG_INVALID_HANDLE(sensorHandle);
299   } else {
300     Sensor &sensor = mSensors[sensorHandle];
301     uint8_t sensorType = sensor.getSensorType();
302     uint16_t eventType = getSampleEventTypeForSensorType(sensorType);
303     for (const SensorRequest &request : sensor.getRequests()) {
304       Nanoapp *nanoapp = EventLoopManagerSingleton::get()
305                              ->getEventLoop()
306                              .findNanoappByInstanceId(request.getInstanceId());
307       if (nanoapp != nullptr) {
308         nanoapp->unregisterForBroadcastEvent(eventType,
309                                              sensor.getTargetGroupMask());
310       }
311     }
312 
313     cancelFlushRequests(sensorHandle);
314     success = removeAllRequests(sensor);
315   }
316 
317   return success;
318 }
319 
getSensor(uint32_t sensorHandle)320 Sensor *SensorRequestManager::getSensor(uint32_t sensorHandle) {
321   Sensor *sensorPtr = nullptr;
322   if (sensorHandle < mSensors.size()) {
323     sensorPtr = &mSensors[sensorHandle];
324   }
325   return sensorPtr;
326 }
327 
getSensorSamplingStatus(uint32_t sensorHandle,struct chreSensorSamplingStatus * status) const328 bool SensorRequestManager::getSensorSamplingStatus(
329     uint32_t sensorHandle, struct chreSensorSamplingStatus *status) const {
330   CHRE_ASSERT(status);
331 
332   bool success = false;
333   if (sensorHandle >= mSensors.size()) {
334     LOG_INVALID_HANDLE(sensorHandle);
335   } else {
336     success = mSensors[sensorHandle].getSamplingStatus(status);
337   }
338 
339   return success;
340 }
341 
getRequests(uint32_t sensorHandle) const342 const DynamicVector<SensorRequest> &SensorRequestManager::getRequests(
343     uint32_t sensorHandle) const {
344   if (sensorHandle >= mSensors.size()) {
345     LOG_INVALID_HANDLE(sensorHandle);
346     sensorHandle = 0;
347   }
348   return mSensors[sensorHandle].getRequests();
349 }
350 
configureBiasEvents(Nanoapp * nanoapp,uint32_t sensorHandle,bool enable)351 bool SensorRequestManager::configureBiasEvents(Nanoapp *nanoapp,
352                                                uint32_t sensorHandle,
353                                                bool enable) {
354   bool success = false;
355   uint16_t eventType;
356   if (sensorHandle >= mSensors.size()) {
357     LOG_INVALID_HANDLE(sensorHandle);
358   } else if (enable && !mSensors[sensorHandle].isSensorEnabled()) {
359     LOGE("Bias events can't be configured for a disabled sensor!");
360   } else if (mSensors[sensorHandle].getBiasEventType(&eventType)) {
361     Sensor &sensor = mSensors[sensorHandle];
362     size_t requestIndex;
363     bool nanoappHasRequest =
364         sensor.getRequestMultiplexer().findRequest(nanoapp->getInstanceId(),
365                                                    &requestIndex) != nullptr;
366     if (enable && !nanoappHasRequest) {
367       LOGE("0x%" PRIx64
368            " configuring bias events without an existing sensor request",
369            nanoapp->getAppId());
370     } else if (!enable && !nanoappHasRequest) {
371       // Treat configuration request as a success since the nanoapp's request
372       // already has been removed which would result in disabling bias event
373       // updates
374       success = true;
375     } else {
376       SensorRequest previousRequest =
377           sensor.getRequestMultiplexer().getRequests()[requestIndex];
378       previousRequest.setBiasUpdatesRequested(enable);
379       bool requestChanged;
380       success =
381           updateRequest(sensor, requestIndex, previousRequest, &requestChanged);
382       if (success) {
383         if (enable) {
384           nanoapp->registerForBroadcastEvent(eventType,
385                                              sensor.getTargetGroupMask());
386         } else {
387           nanoapp->unregisterForBroadcastEvent(eventType,
388                                                sensor.getTargetGroupMask());
389         }
390       }
391     }
392   }
393 
394   return success;
395 }
396 
getThreeAxisBias(uint32_t sensorHandle,struct chreSensorThreeAxisData * bias) const397 bool SensorRequestManager::getThreeAxisBias(
398     uint32_t sensorHandle, struct chreSensorThreeAxisData *bias) const {
399   CHRE_ASSERT(bias != nullptr);
400 
401   bool success = false;
402   if (bias != nullptr) {
403     if (sensorHandle >= mSensors.size()) {
404       LOG_INVALID_HANDLE(sensorHandle);
405     } else {
406       success =
407           mPlatformSensorManager.getThreeAxisBias(mSensors[sensorHandle], bias);
408     }
409   }
410 
411   return success;
412 }
413 
flushAsync(Nanoapp * nanoapp,uint32_t sensorHandle,const void * cookie)414 bool SensorRequestManager::flushAsync(Nanoapp *nanoapp, uint32_t sensorHandle,
415                                       const void *cookie) {
416   bool success = false;
417 
418   uint32_t nanoappInstanceId = nanoapp->getInstanceId();
419   if (sensorHandle >= mSensors.size()) {
420     LOG_INVALID_HANDLE(sensorHandle);
421   } else if (mSensors[sensorHandle].isOneShot()) {
422     LOGE("Cannot flush a one-shot sensor of type %" PRIu8,
423          mSensors[sensorHandle].getSensorType());
424   } else if (mFlushRequestQueue.full()) {
425     LOG_OOM();
426   } else {
427     mFlushRequestQueue.emplace_back(sensorHandle, nanoappInstanceId, cookie);
428     success = makeFlushRequest(mFlushRequestQueue.back()) == CHRE_ERROR_NONE;
429     if (!success) {
430       mFlushRequestQueue.pop_back();
431     }
432   }
433 
434   return success;
435 }
436 
releaseSensorDataEvent(uint16_t eventType,void * eventData)437 void SensorRequestManager::releaseSensorDataEvent(uint16_t eventType,
438                                                   void *eventData) {
439   // Remove all requests if it's a one-shot sensor and only after data has been
440   // delivered to all clients.
441   mPlatformSensorManager.releaseSensorDataEvent(eventData);
442   uint8_t sensorType = getSensorTypeForSampleEventType(eventType);
443   uint32_t sensorHandle;
444   if (getDefaultSensorHandle(sensorType, &sensorHandle) &&
445       mSensors[sensorHandle].isOneShot()) {
446     removeAllRequests(sensorHandle);
447   }
448 }
449 
handleFlushCompleteEvent(uint32_t sensorHandle,uint32_t flushRequestId,uint8_t errorCode)450 void SensorRequestManager::handleFlushCompleteEvent(uint32_t sensorHandle,
451                                                     uint32_t flushRequestId,
452                                                     uint8_t errorCode) {
453   if (sensorHandle < mSensors.size() &&
454       mSensors[sensorHandle].isFlushRequestPending()) {
455     // Cancel flush request timer before posting to the event queue to ensure
456     // a timeout event isn't processed by CHRE now that the complete event
457     // has been received.
458     mSensors[sensorHandle].cancelPendingFlushRequestTimer();
459 
460     auto callback = [](uint16_t /*type*/, void *data, void *extraData) {
461       uint8_t cbErrorCode = NestedDataPtr<uint8_t>(data);
462       uint32_t cbSensorHandle = NestedDataPtr<uint32_t>(extraData);
463       EventLoopManagerSingleton::get()
464           ->getSensorRequestManager()
465           .handleFlushCompleteEventSync(cbErrorCode, cbSensorHandle);
466     };
467 
468     EventLoopManagerSingleton::get()->deferCallback(
469         SystemCallbackType::SensorFlushComplete,
470         NestedDataPtr<uint8_t>(errorCode), callback,
471         NestedDataPtr<uint32_t>(sensorHandle));
472   }
473 }
474 
handleSensorDataEvent(uint32_t sensorHandle,void * event)475 void SensorRequestManager::handleSensorDataEvent(uint32_t sensorHandle,
476                                                  void *event) {
477   if (sensorHandle >= mSensors.size()) {
478     LOG_INVALID_HANDLE(sensorHandle);
479     mPlatformSensorManager.releaseSensorDataEvent(event);
480   } else {
481     Sensor &sensor = mSensors[sensorHandle];
482     if (sensor.isOnChange()) {
483       updateLastEvent(event);
484     }
485 
486     uint16_t eventType =
487         getSampleEventTypeForSensorType(sensor.getSensorType());
488 
489     // Only allow dropping continuous sensor events since losing one-shot or
490     // on-change events could result in nanoapps stuck in a bad state.
491     if (sensor.isContinuous()) {
492       EventLoopManagerSingleton::get()
493           ->getEventLoop()
494           .postLowPriorityEventOrFree(eventType, event, sensorDataEventFree,
495                                       kSystemInstanceId, kBroadcastInstanceId,
496                                       sensor.getTargetGroupMask());
497     } else {
498       EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
499           eventType, event, sensorDataEventFree, kBroadcastInstanceId,
500           sensor.getTargetGroupMask());
501     }
502   }
503 }
504 
handleSamplingStatusUpdate(uint32_t sensorHandle,struct chreSensorSamplingStatus * status)505 void SensorRequestManager::handleSamplingStatusUpdate(
506     uint32_t sensorHandle, struct chreSensorSamplingStatus *status) {
507   Sensor *sensor =
508       EventLoopManagerSingleton::get()->getSensorRequestManager().getSensor(
509           sensorHandle);
510   if (sensor == nullptr || sensor->isOneShot()) {
511     releaseSamplingStatusUpdate(status);
512   } else {
513     sensor->setSamplingStatus(*status);
514 
515     auto callback = [](uint16_t /*type*/, void *data, void *extraData) {
516       uint32_t cbSensorHandle = NestedDataPtr<uint32_t>(data);
517       auto *cbStatus =
518           static_cast<struct chreSensorSamplingStatus *>(extraData);
519       postSamplingStatus(cbSensorHandle, *cbStatus);
520       EventLoopManagerSingleton::get()
521           ->getSensorRequestManager()
522           .releaseSamplingStatusUpdate(cbStatus);
523     };
524 
525     // Schedule a deferred callback to handle sensor status change in the main
526     // thread.
527     EventLoopManagerSingleton::get()->deferCallback(
528         SystemCallbackType::SensorStatusUpdate,
529         NestedDataPtr<uint32_t>(sensorHandle), callback, status);
530   }
531 }
532 
handleBiasEvent(uint32_t sensorHandle,void * biasData)533 void SensorRequestManager::handleBiasEvent(uint32_t sensorHandle,
534                                            void *biasData) {
535   Sensor *sensor =
536       EventLoopManagerSingleton::get()->getSensorRequestManager().getSensor(
537           sensorHandle);
538   CHRE_ASSERT(sensor != nullptr);
539 
540   if (sensor == nullptr) {
541     releaseBiasData(biasData);
542   } else {
543     uint16_t eventType;
544     if (!sensor->reportsBiasEvents() || !sensor->getBiasEventType(&eventType)) {
545       LOGE("Received bias event for unsupported sensor type %s",
546            sensor->getSensorName());
547     } else {
548       auto freeCallback = [](uint16_t /* type */, void *data) {
549         EventLoopManagerSingleton::get()
550             ->getSensorRequestManager()
551             .releaseBiasData(data);
552       };
553 
554       EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
555           eventType, biasData, freeCallback, kBroadcastInstanceId,
556           sensor->getTargetGroupMask());
557     }
558   }
559 }
560 
logStateToBuffer(DebugDumpWrapper & debugDump) const561 void SensorRequestManager::logStateToBuffer(DebugDumpWrapper &debugDump) const {
562   debugDump.print("\nSensors:\n");
563   for (uint8_t i = 0; i < mSensors.size(); i++) {
564     for (const auto &request : mSensors[i].getRequests()) {
565       // TODO: Rearrange these prints to be similar to sensor request logs
566       // below
567       debugDump.print(
568           " %s: mode=%d int=%" PRIu64 " lat=%" PRIu64 " nappId=%" PRIu32 "\n",
569           mSensors[i].getSensorTypeName(), static_cast<int>(request.getMode()),
570           request.getInterval().toRawNanoseconds(),
571           request.getLatency().toRawNanoseconds(), request.getInstanceId());
572     }
573   }
574   debugDump.print("\n Last %zu Sensor Requests:\n", mSensorRequestLogs.size());
575   static_assert(kMaxSensorRequestLogs <= INT8_MAX,
576                 "kMaxSensorRequestLogs must be <= INT8_MAX");
577   for (int8_t i = static_cast<int8_t>(mSensorRequestLogs.size()) - 1; i >= 0;
578        i--) {
579     const auto &log = mSensorRequestLogs[static_cast<size_t>(i)];
580     const Sensor &sensor = mSensors[log.sensorHandle];
581     debugDump.print("  ts=%" PRIu64 " nappId=%" PRIu32 " type=%s idx=%" PRIu8
582                     " mask=%" PRIx16 " mode=%s",
583                     log.timestamp.toRawNanoseconds(), log.instanceId,
584                     sensor.getSensorTypeName(), sensor.getSensorIndex(),
585                     sensor.getTargetGroupMask(), getSensorModeName(log.mode));
586 
587     if (sensorModeIsContinuous(log.mode)) {
588       debugDump.print(" int=%" PRIu64 " lat=%" PRIu64,
589                       log.interval.toRawNanoseconds(),
590                       log.latency.toRawNanoseconds());
591     }
592     debugDump.print("\n");
593   }
594 }
595 
postFlushCompleteEvent(uint32_t sensorHandle,uint8_t errorCode,const FlushRequest & request)596 void SensorRequestManager::postFlushCompleteEvent(uint32_t sensorHandle,
597                                                   uint8_t errorCode,
598                                                   const FlushRequest &request) {
599   auto *event = memoryAlloc<chreSensorFlushCompleteEvent>();
600   if (event == nullptr) {
601     LOG_OOM();
602   } else {
603     event->sensorHandle = sensorHandle;
604     event->errorCode = errorCode;
605     event->cookie = request.cookie;
606     memset(event->reserved, 0, sizeof(event->reserved));
607 
608     EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
609         CHRE_EVENT_SENSOR_FLUSH_COMPLETE, event, freeEventDataCallback,
610         request.nanoappInstanceId);
611   }
612 }
613 
completeFlushRequestAtIndex(size_t index,uint8_t errorCode)614 void SensorRequestManager::completeFlushRequestAtIndex(size_t index,
615                                                        uint8_t errorCode) {
616   if (index < mFlushRequestQueue.size()) {
617     const FlushRequest &request = mFlushRequestQueue[index];
618     uint32_t sensorHandle = request.sensorHandle;
619     if (request.isActive) {
620       mSensors[sensorHandle].clearPendingFlushRequest();
621     }
622 
623     postFlushCompleteEvent(sensorHandle, errorCode, request);
624     mFlushRequestQueue.erase(index);
625   }
626 }
627 
dispatchNextFlushRequest(uint32_t sensorHandle)628 void SensorRequestManager::dispatchNextFlushRequest(uint32_t sensorHandle) {
629   for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
630     FlushRequest &request = mFlushRequestQueue[i];
631     if (request.sensorHandle == sensorHandle) {
632       uint8_t newRequestErrorCode = makeFlushRequest(request);
633       if (newRequestErrorCode == CHRE_ERROR_NONE) {
634         break;
635       } else {
636         completeFlushRequestAtIndex(i, newRequestErrorCode);
637         i--;
638       }
639     }
640   }
641 }
642 
onFlushTimeout(uint32_t sensorHandle)643 void SensorRequestManager::onFlushTimeout(uint32_t sensorHandle) {
644   if (sensorHandle < mSensors.size()) {
645     Sensor &sensor = mSensors[sensorHandle];
646     sensor.setFlushRequestTimerHandle(CHRE_TIMER_INVALID);
647   }
648 }
649 
handleFlushCompleteEventSync(uint8_t errorCode,uint32_t sensorHandle)650 void SensorRequestManager::handleFlushCompleteEventSync(uint8_t errorCode,
651                                                         uint32_t sensorHandle) {
652   for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
653     if (mFlushRequestQueue[i].sensorHandle == sensorHandle) {
654       completeFlushRequestAtIndex(i, errorCode);
655       dispatchNextFlushRequest(sensorHandle);
656       break;
657     }
658   }
659 }
660 
cancelFlushRequests(uint32_t sensorHandle,uint32_t nanoappInstanceId)661 void SensorRequestManager::cancelFlushRequests(uint32_t sensorHandle,
662                                                uint32_t nanoappInstanceId) {
663   bool removeAll = (nanoappInstanceId == kSystemInstanceId);
664   for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
665     const FlushRequest &request = mFlushRequestQueue[i];
666     if (request.sensorHandle == sensorHandle &&
667         (request.nanoappInstanceId == nanoappInstanceId || removeAll)) {
668       completeFlushRequestAtIndex(i,
669                                   CHRE_ERROR_FUNCTION_DISABLED /* errorCode */);
670       i--;
671     }
672   }
673 
674   if (!mSensors[sensorHandle].isFlushRequestPending()) {
675     dispatchNextFlushRequest(sensorHandle);
676   }
677 }
678 
addSensorRequestLog(uint32_t nanoappInstanceId,uint32_t sensorHandle,const SensorRequest & sensorRequest)679 void SensorRequestManager::addSensorRequestLog(
680     uint32_t nanoappInstanceId, uint32_t sensorHandle,
681     const SensorRequest &sensorRequest) {
682   mSensorRequestLogs.kick_push(SensorRequestLog(
683       SystemTime::getMonotonicTime(), nanoappInstanceId, sensorHandle,
684       sensorRequest.getMode(), sensorRequest.getInterval(),
685       sensorRequest.getLatency()));
686 }
687 
addRequest(Sensor & sensor,const SensorRequest & request,bool * requestChanged)688 bool SensorRequestManager::addRequest(Sensor &sensor,
689                                       const SensorRequest &request,
690                                       bool *requestChanged) {
691   CHRE_ASSERT(requestChanged != nullptr);
692 
693   size_t addIndex;
694   bool success = true;
695   SensorRequestMultiplexer &multiplexer = sensor.getRequestMultiplexer();
696   SensorRequest prevRequest = sensor.getMaximalRequest();
697   if (!multiplexer.addRequest(request, &addIndex, requestChanged)) {
698     *requestChanged = false;
699     success = false;
700     LOG_OOM();
701   } else if (*requestChanged) {
702     success = configurePlatformSensor(sensor, prevRequest);
703     if (!success) {
704       // Remove the newly added request since the platform failed to handle
705       // it. The sensor is expected to maintain the existing request so there is
706       // no need to reset the platform to the last maximal request.
707       multiplexer.removeRequest(addIndex, requestChanged);
708 
709       // This is a roll-back operation so the maximal change in the
710       // multiplexer must not have changed. The request changed state is forced
711       // to false.
712       *requestChanged = false;
713     }
714   }
715 
716   return success;
717 }
718 
updateRequest(Sensor & sensor,size_t updateIndex,const SensorRequest & request,bool * requestChanged)719 bool SensorRequestManager::updateRequest(Sensor &sensor, size_t updateIndex,
720                                          const SensorRequest &request,
721                                          bool *requestChanged) {
722   CHRE_ASSERT(requestChanged != nullptr);
723 
724   bool success = true;
725   SensorRequestMultiplexer &multiplexer = sensor.getRequestMultiplexer();
726   SensorRequest previousRequest = multiplexer.getRequests()[updateIndex];
727   SensorRequest prevMaxRequest = sensor.getMaximalRequest();
728 
729   multiplexer.updateRequest(updateIndex, request, requestChanged);
730   if (*requestChanged) {
731     success = configurePlatformSensor(sensor, prevMaxRequest);
732     if (!success) {
733       // Roll back the request since sending it to the sensor failed. The
734       // request will roll back to the previous maximal. The sensor is
735       // expected to maintain the existing request if a request fails so there
736       // is no need to reset the platform to the last maximal request.
737       multiplexer.updateRequest(updateIndex, previousRequest, requestChanged);
738 
739       // This is a roll-back operation so the maximal change in the multiplexer
740       // must not have changed. The request changed state is forced to false.
741       *requestChanged = false;
742     }
743   }
744 
745   return success;
746 }
747 
removeRequest(Sensor & sensor,size_t removeIndex,bool * requestChanged)748 bool SensorRequestManager::removeRequest(Sensor &sensor, size_t removeIndex,
749                                          bool *requestChanged) {
750   CHRE_ASSERT(requestChanged != nullptr);
751 
752   bool success = true;
753   const SensorRequest prevRequest = sensor.getMaximalRequest();
754   sensor.getRequestMultiplexer().removeRequest(removeIndex, requestChanged);
755   if (*requestChanged) {
756     success = configurePlatformSensor(sensor, prevRequest);
757     if (!success) {
758       LOGE("SensorRequestManager failed to remove a request");
759 
760       // If the platform fails to handle this request in a debug build there is
761       // likely an error in the platform. This is not strictly a programming
762       // error but it does make sense to use assert semantics when a platform
763       // fails to handle a request that it had been sent previously.
764       CHRE_ASSERT(false);
765 
766       // The request to the platform to set a request when removing has failed
767       // so the request has not changed.
768       *requestChanged = false;
769     }
770   }
771   return success;
772 }
773 
removeAllRequests(Sensor & sensor)774 bool SensorRequestManager::removeAllRequests(Sensor &sensor) {
775   bool requestChanged;
776   SensorRequest prevRequest = sensor.getMaximalRequest();
777   sensor.getRequestMultiplexer().removeAllRequests(&requestChanged);
778 
779   bool success = true;
780   if (requestChanged) {
781     success = configurePlatformSensor(sensor, prevRequest);
782 
783     if (!success) {
784       LOGE("SensorRequestManager failed to remove all requests");
785 
786       // If the platform fails to handle this request in a debug build there
787       // is likely an error in the platform. This is not strictly a programming
788       // error but it does make sense to use assert semantics when a platform
789       // fails to handle a request that it had been sent previously.
790       CHRE_ASSERT(false);
791     }
792   }
793 
794   return success;
795 }
796 
makeFlushRequest(FlushRequest & request)797 uint8_t SensorRequestManager::makeFlushRequest(FlushRequest &request) {
798   uint8_t errorCode = CHRE_ERROR;
799   Sensor &sensor = mSensors[request.sensorHandle];
800   if (!sensor.isSensorEnabled()) {
801     LOGE("Cannot flush on disabled sensor");
802   } else if (!sensor.isFlushRequestPending()) {
803     Nanoseconds now = SystemTime::getMonotonicTime();
804     Nanoseconds deadline = request.deadlineTimestamp;
805     if (now >= deadline) {
806       LOGE("Flush sensor %s failed for nanoapp ID %" PRIu32
807            ": deadline exceeded",
808            sensor.getSensorName(), request.nanoappInstanceId);
809       errorCode = CHRE_ERROR_TIMEOUT;
810     } else if (doMakeFlushRequest(sensor)) {
811       errorCode = CHRE_ERROR_NONE;
812       Nanoseconds delay = deadline - now;
813       request.isActive = true;
814 
815       auto callback = [](uint16_t /*type*/, void *data, void * /*extraData*/) {
816         LOGE("Flush request timed out");
817         NestedDataPtr<uint32_t> sensorHandle(data);
818         EventLoopManagerSingleton::get()
819             ->getSensorRequestManager()
820             .onFlushTimeout(sensorHandle);
821 
822         // Send a complete event, thus closing out this flush request. If the
823         // request that has just timed out receives a response later, this may
824         // inadvertently close out a new request before it has actually
825         // completed.
826         // TODO: Attach an ID to all flush requests / responses so stale
827         // responses can be properly dropped.
828         EventLoopManagerSingleton::get()
829             ->getSensorRequestManager()
830             .handleFlushCompleteEventSync(CHRE_ERROR_TIMEOUT, sensorHandle);
831       };
832 
833       sensor.setFlushRequestTimerHandle(
834           EventLoopManagerSingleton::get()->setDelayedCallback(
835               SystemCallbackType::SensorFlushTimeout,
836               NestedDataPtr<uint32_t>(request.sensorHandle), callback, delay));
837     }
838   } else {
839     // Flush request will be made once the pending request is completed.
840     // Return true so that the nanoapp can wait for a result through the
841     // CHRE_EVENT_SENSOR_FLUSH_COMPLETE event.
842     errorCode = CHRE_ERROR_NONE;
843   }
844 
845   return errorCode;
846 }
847 
doMakeFlushRequest(Sensor & sensor)848 bool SensorRequestManager::doMakeFlushRequest(Sensor &sensor) {
849   // Set to true before making the request since the request may be a
850   // synchronous request and we may get the complete event before it returns.
851   sensor.setFlushRequestPending(true);
852   // TODO: Refactor code to take the request ID into account so multiple flush
853   // requests can be issued.
854   uint32_t flushRequestId;
855   bool success = mPlatformSensorManager.flush(sensor, &flushRequestId);
856   sensor.setFlushRequestPending(success);
857   return success;
858 }
859 
configurePlatformSensor(Sensor & sensor,const SensorRequest & prevSensorRequest)860 bool SensorRequestManager::configurePlatformSensor(
861     Sensor &sensor, const SensorRequest &prevSensorRequest) {
862   bool success = false;
863   const SensorRequest &request = sensor.getMaximalRequest();
864 
865   // Ensures that only configureBiasEvents is invoked if that's the only value
866   // that has changed since the previous request since CHRE shouldn't configure
867   // the platform for data events if the sensor data request hasn't changed.
868   bool biasChanged = (request.getBiasUpdatesRequested() !=
869                       prevSensorRequest.getBiasUpdatesRequested());
870   bool onlyBiasChanged = request.onlyBiasRequestUpdated(prevSensorRequest);
871   uint64_t currentLatency = 0;
872   bool enable = (request.getMode() != SensorMode::Off);
873   if (enable) {
874     currentLatency = request.getLatency().toRawNanoseconds();
875   }
876 
877   // Per platform API requirements, an active sensor subscription must exist
878   // before any bias configuration can be done.
879   if (!onlyBiasChanged &&
880       !mPlatformSensorManager.configureSensor(sensor, request)) {
881     LOGE("Failed to make platform sensor data request");
882   } else if (biasChanged &&
883              !mPlatformSensorManager.configureBiasEvents(
884                  sensor, request.getBiasUpdatesRequested(), currentLatency)) {
885     LOGE("Failed to make platform sensor bias request");
886     if (!onlyBiasChanged) {
887       mPlatformSensorManager.configureSensor(sensor, prevSensorRequest);
888     }
889   } else {
890     success = true;
891 
892     // Reset last event if an on-change sensor is turned off.
893     if (request.getMode() == SensorMode::Off) {
894       sensor.clearLastEvent();
895     }
896   }
897   return success;
898 }
899 
getActiveTargetGroupMask(uint32_t nanoappInstanceId,uint8_t sensorType)900 uint16_t SensorRequestManager::getActiveTargetGroupMask(
901     uint32_t nanoappInstanceId, uint8_t sensorType) {
902   uint16_t mask = 0;
903   for (Sensor &sensor : mSensors) {
904     if (sensor.getSensorType() == sensorType) {
905       size_t index;
906       if (sensor.getRequestMultiplexer().findRequest(nanoappInstanceId,
907                                                      &index) != nullptr) {
908         mask |= sensor.getTargetGroupMask();
909         break;
910       }
911     }
912   }
913 
914   return mask;
915 }
916 
917 }  // namespace chre
918