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