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