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