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