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