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