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 nanoapp->unregisterForBroadcastEvent(eventType,
200 sensor.getTargetGroupMask());
201
202 uint16_t biasEventType;
203 if (sensor.getBiasEventType(&biasEventType)) {
204 // Per API requirements, turn off bias reporting when
205 // unsubscribing from the sensor.
206 nanoapp->unregisterForBroadcastEvent(biasEventType,
207 sensor.getTargetGroupMask());
208 }
209 }
210 } else {
211 // The sensor is being configured to Off, but is already Off (there is
212 // no existing request). We assign to success to be true and no other
213 // operation is required.
214 success = true;
215 }
216 } else if (!nanoappHasRequest) {
217 // The request changes the mode to the enabled state and there was no
218 // existing request. The request is newly created and added to the
219 // multiplexer. The nanoapp is registered for events if this request was
220 // successful.
221 uint16_t biasEventType;
222 if (sensor.getBiasEventType(&biasEventType) && sensor.isCalibrated()) {
223 // Per API requirements, turn on bias reporting for calibrated sensors
224 // by default when subscribed.
225 request.setBiasUpdatesRequested(true);
226 }
227
228 success = addRequest(sensor, request, &requestChanged);
229 if (success) {
230 nanoapp->registerForBroadcastEvent(eventType,
231 sensor.getTargetGroupMask());
232
233 if (request.getBiasUpdatesRequested()) {
234 nanoapp->registerForBroadcastEvent(biasEventType,
235 sensor.getTargetGroupMask());
236 }
237
238 // Deliver last valid event to new clients of on-change sensors
239 if (sensor.getLastEvent() != nullptr) {
240 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
241 eventType, sensor.getLastEvent(), nullptr /* freeCallback */,
242 nanoapp->getInstanceId());
243 }
244 }
245 } else {
246 // Ensure bias events stay requested if they were previously enabled.
247 const SensorRequest &previousRequest =
248 sensor.getRequestMultiplexer().getRequests()[requestIndex];
249 if (previousRequest.getBiasUpdatesRequested()) {
250 request.setBiasUpdatesRequested(true);
251 }
252 // The request changes the mode to the enabled state and there was an
253 // existing request. The existing request is updated.
254 success = updateRequest(sensor, requestIndex, request, &requestChanged);
255 }
256
257 // TODO: Allow translating the sensor request
258
259 if (requestChanged) {
260 // TODO: Send an event to nanoapps to indicate the rate change.
261 }
262
263 if (success) {
264 addSensorRequestLog(nanoapp->getInstanceId(), sensorHandle, request);
265 }
266 }
267 }
268
269 return success;
270 }
271
getSensorInfo(uint32_t sensorHandle,const Nanoapp & nanoapp,struct chreSensorInfo * info) const272 bool SensorRequestManager::getSensorInfo(uint32_t sensorHandle,
273 const Nanoapp &nanoapp,
274 struct chreSensorInfo *info) const {
275 CHRE_ASSERT(info);
276
277 bool success = false;
278 if (sensorHandle >= mSensors.size()) {
279 LOG_INVALID_HANDLE(sensorHandle);
280 } else {
281 mSensors[sensorHandle].populateSensorInfo(info,
282 nanoapp.getTargetApiVersion());
283 success = true;
284 }
285
286 return success;
287 }
288
removeAllRequests(uint32_t sensorHandle)289 bool SensorRequestManager::removeAllRequests(uint32_t sensorHandle) {
290 bool success = false;
291 if (sensorHandle >= mSensors.size()) {
292 LOG_INVALID_HANDLE(sensorHandle);
293 } else {
294 Sensor &sensor = mSensors[sensorHandle];
295 uint8_t sensorType = sensor.getSensorType();
296 uint16_t eventType = getSampleEventTypeForSensorType(sensorType);
297 for (const SensorRequest &request : sensor.getRequests()) {
298 Nanoapp *nanoapp = EventLoopManagerSingleton::get()
299 ->getEventLoop()
300 .findNanoappByInstanceId(request.getInstanceId());
301 if (nanoapp != nullptr) {
302 nanoapp->unregisterForBroadcastEvent(eventType,
303 sensor.getTargetGroupMask());
304 }
305 }
306
307 cancelFlushRequests(sensorHandle);
308 success = removeAllRequests(sensor);
309 }
310
311 return success;
312 }
313
getSensor(uint32_t sensorHandle)314 Sensor *SensorRequestManager::getSensor(uint32_t sensorHandle) {
315 Sensor *sensorPtr = nullptr;
316 if (sensorHandle < mSensors.size()) {
317 sensorPtr = &mSensors[sensorHandle];
318 }
319 return sensorPtr;
320 }
321
getSensorSamplingStatus(uint32_t sensorHandle,struct chreSensorSamplingStatus * status) const322 bool SensorRequestManager::getSensorSamplingStatus(
323 uint32_t sensorHandle, struct chreSensorSamplingStatus *status) const {
324 CHRE_ASSERT(status);
325
326 bool success = false;
327 if (sensorHandle >= mSensors.size()) {
328 LOG_INVALID_HANDLE(sensorHandle);
329 } else {
330 success = mSensors[sensorHandle].getSamplingStatus(status);
331 }
332
333 return success;
334 }
335
getRequests(uint32_t sensorHandle) const336 const DynamicVector<SensorRequest> &SensorRequestManager::getRequests(
337 uint32_t sensorHandle) const {
338 if (sensorHandle >= mSensors.size()) {
339 LOG_INVALID_HANDLE(sensorHandle);
340 sensorHandle = 0;
341 }
342 return mSensors[sensorHandle].getRequests();
343 }
344
configureBiasEvents(Nanoapp * nanoapp,uint32_t sensorHandle,bool enable)345 bool SensorRequestManager::configureBiasEvents(Nanoapp *nanoapp,
346 uint32_t sensorHandle,
347 bool enable) {
348 bool success = false;
349 uint16_t eventType;
350 if (sensorHandle >= mSensors.size()) {
351 LOG_INVALID_HANDLE(sensorHandle);
352 } else if (enable && !mSensors[sensorHandle].isSensorEnabled()) {
353 LOGE("Bias events can't be configured for a disabled sensor!");
354 } else if (mSensors[sensorHandle].getBiasEventType(&eventType)) {
355 Sensor &sensor = mSensors[sensorHandle];
356 size_t requestIndex;
357 bool nanoappHasRequest =
358 sensor.getRequestMultiplexer().findRequest(nanoapp->getInstanceId(),
359 &requestIndex) != nullptr;
360 if (enable && !nanoappHasRequest) {
361 LOGE("0x%" PRIx64
362 " configuring bias events without an existing sensor request",
363 nanoapp->getAppId());
364 } else if (!enable && !nanoappHasRequest) {
365 // Treat configuration request as a success since the nanoapp's request
366 // already has been removed which would result in disabling bias event
367 // updates
368 success = true;
369 } else {
370 SensorRequest previousRequest =
371 sensor.getRequestMultiplexer().getRequests()[requestIndex];
372 previousRequest.setBiasUpdatesRequested(enable);
373 bool requestChanged;
374 success =
375 updateRequest(sensor, requestIndex, previousRequest, &requestChanged);
376 if (success) {
377 if (enable) {
378 nanoapp->registerForBroadcastEvent(eventType,
379 sensor.getTargetGroupMask());
380 } else {
381 nanoapp->unregisterForBroadcastEvent(eventType,
382 sensor.getTargetGroupMask());
383 }
384 }
385 }
386 }
387
388 return success;
389 }
390
getThreeAxisBias(uint32_t sensorHandle,struct chreSensorThreeAxisData * bias) const391 bool SensorRequestManager::getThreeAxisBias(
392 uint32_t sensorHandle, struct chreSensorThreeAxisData *bias) const {
393 CHRE_ASSERT(bias != nullptr);
394
395 bool success = false;
396 if (bias != nullptr) {
397 if (sensorHandle >= mSensors.size()) {
398 LOG_INVALID_HANDLE(sensorHandle);
399 } else {
400 success =
401 mPlatformSensorManager.getThreeAxisBias(mSensors[sensorHandle], bias);
402 }
403 }
404
405 return success;
406 }
407
flushAsync(Nanoapp * nanoapp,uint32_t sensorHandle,const void * cookie)408 bool SensorRequestManager::flushAsync(Nanoapp *nanoapp, uint32_t sensorHandle,
409 const void *cookie) {
410 bool success = false;
411
412 uint32_t nanoappInstanceId = nanoapp->getInstanceId();
413 if (sensorHandle >= mSensors.size()) {
414 LOG_INVALID_HANDLE(sensorHandle);
415 } else if (mSensors[sensorHandle].isOneShot()) {
416 LOGE("Cannot flush a one-shot sensor of type %" PRIu8,
417 mSensors[sensorHandle].getSensorType());
418 } else if (mFlushRequestQueue.full()) {
419 LOG_OOM();
420 } else {
421 mFlushRequestQueue.emplace_back(sensorHandle, nanoappInstanceId, cookie);
422 success = makeFlushRequest(mFlushRequestQueue.back()) == CHRE_ERROR_NONE;
423 if (!success) {
424 mFlushRequestQueue.pop_back();
425 }
426 }
427
428 return success;
429 }
430
releaseSensorDataEvent(uint16_t eventType,void * eventData)431 void SensorRequestManager::releaseSensorDataEvent(uint16_t eventType,
432 void *eventData) {
433 // Remove all requests if it's a one-shot sensor and only after data has been
434 // delivered to all clients.
435 mPlatformSensorManager.releaseSensorDataEvent(eventData);
436 uint8_t sensorType = getSensorTypeForSampleEventType(eventType);
437 uint32_t sensorHandle;
438 if (getDefaultSensorHandle(sensorType, &sensorHandle) &&
439 mSensors[sensorHandle].isOneShot()) {
440 removeAllRequests(sensorHandle);
441 }
442 }
443
handleFlushCompleteEvent(uint32_t sensorHandle,uint32_t flushRequestId,uint8_t errorCode)444 void SensorRequestManager::handleFlushCompleteEvent(uint32_t sensorHandle,
445 uint32_t flushRequestId,
446 uint8_t errorCode) {
447 if (sensorHandle < mSensors.size() &&
448 mSensors[sensorHandle].isFlushRequestPending()) {
449 // Cancel flush request timer before posting to the event queue to ensure
450 // a timeout event isn't processed by CHRE now that the complete event
451 // has been received.
452 mSensors[sensorHandle].cancelPendingFlushRequestTimer();
453
454 auto callback = [](uint16_t /*type*/, void *data, void *extraData) {
455 uint8_t cbErrorCode = NestedDataPtr<uint8_t>(data);
456 uint32_t cbSensorHandle = NestedDataPtr<uint32_t>(extraData);
457 EventLoopManagerSingleton::get()
458 ->getSensorRequestManager()
459 .handleFlushCompleteEventSync(cbErrorCode, cbSensorHandle);
460 };
461
462 EventLoopManagerSingleton::get()->deferCallback(
463 SystemCallbackType::SensorFlushComplete,
464 NestedDataPtr<uint8_t>(errorCode), callback,
465 NestedDataPtr<uint32_t>(sensorHandle));
466 }
467 }
468
handleSensorDataEvent(uint32_t sensorHandle,void * event)469 void SensorRequestManager::handleSensorDataEvent(uint32_t sensorHandle,
470 void *event) {
471 if (sensorHandle >= mSensors.size()) {
472 LOG_INVALID_HANDLE(sensorHandle);
473 mPlatformSensorManager.releaseSensorDataEvent(event);
474 } else {
475 Sensor &sensor = mSensors[sensorHandle];
476 if (sensor.isOnChange()) {
477 updateLastEvent(event);
478 }
479
480 uint16_t eventType =
481 getSampleEventTypeForSensorType(sensor.getSensorType());
482
483 // Only allow dropping continuous sensor events since losing one-shot or
484 // on-change events could result in nanoapps stuck in a bad state.
485 if (sensor.isContinuous()) {
486 EventLoopManagerSingleton::get()
487 ->getEventLoop()
488 .postLowPriorityEventOrFree(eventType, event, sensorDataEventFree,
489 kSystemInstanceId, kBroadcastInstanceId,
490 sensor.getTargetGroupMask());
491 } else {
492 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
493 eventType, event, sensorDataEventFree, kBroadcastInstanceId,
494 sensor.getTargetGroupMask());
495 }
496 }
497 }
498
handleSamplingStatusUpdate(uint32_t sensorHandle,struct chreSensorSamplingStatus * status)499 void SensorRequestManager::handleSamplingStatusUpdate(
500 uint32_t sensorHandle, struct chreSensorSamplingStatus *status) {
501 Sensor *sensor =
502 EventLoopManagerSingleton::get()->getSensorRequestManager().getSensor(
503 sensorHandle);
504 if (sensor == nullptr || sensor->isOneShot()) {
505 releaseSamplingStatusUpdate(status);
506 } else {
507 sensor->setSamplingStatus(*status);
508
509 auto callback = [](uint16_t /*type*/, void *data, void *extraData) {
510 uint32_t cbSensorHandle = NestedDataPtr<uint32_t>(data);
511 auto *cbStatus =
512 static_cast<struct chreSensorSamplingStatus *>(extraData);
513 postSamplingStatus(cbSensorHandle, *cbStatus);
514 EventLoopManagerSingleton::get()
515 ->getSensorRequestManager()
516 .releaseSamplingStatusUpdate(cbStatus);
517 };
518
519 // Schedule a deferred callback to handle sensor status change in the main
520 // thread.
521 EventLoopManagerSingleton::get()->deferCallback(
522 SystemCallbackType::SensorStatusUpdate,
523 NestedDataPtr<uint32_t>(sensorHandle), callback, status);
524 }
525 }
526
handleBiasEvent(uint32_t sensorHandle,void * biasData)527 void SensorRequestManager::handleBiasEvent(uint32_t sensorHandle,
528 void *biasData) {
529 Sensor *sensor =
530 EventLoopManagerSingleton::get()->getSensorRequestManager().getSensor(
531 sensorHandle);
532 CHRE_ASSERT(sensor != nullptr);
533
534 if (sensor == nullptr) {
535 releaseBiasData(biasData);
536 } else {
537 uint16_t eventType;
538 if (!sensor->reportsBiasEvents() || !sensor->getBiasEventType(&eventType)) {
539 LOGE("Received bias event for unsupported sensor type %s",
540 sensor->getSensorName());
541 } else {
542 auto freeCallback = [](uint16_t /* type */, void *data) {
543 EventLoopManagerSingleton::get()
544 ->getSensorRequestManager()
545 .releaseBiasData(data);
546 };
547
548 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
549 eventType, biasData, freeCallback, kBroadcastInstanceId,
550 sensor->getTargetGroupMask());
551 }
552 }
553 }
554
logStateToBuffer(DebugDumpWrapper & debugDump) const555 void SensorRequestManager::logStateToBuffer(DebugDumpWrapper &debugDump) const {
556 debugDump.print("\nSensors:\n");
557 for (uint8_t i = 0; i < mSensors.size(); i++) {
558 for (const auto &request : mSensors[i].getRequests()) {
559 // TODO: Rearrange these prints to be similar to sensor request logs
560 // below
561 debugDump.print(
562 " %s: mode=%d int=%" PRIu64 " lat=%" PRIu64 " nappId=%" PRIu32 "\n",
563 mSensors[i].getSensorTypeName(), static_cast<int>(request.getMode()),
564 request.getInterval().toRawNanoseconds(),
565 request.getLatency().toRawNanoseconds(), request.getInstanceId());
566 }
567 }
568 debugDump.print("\n Last %zu Sensor Requests:\n", mSensorRequestLogs.size());
569 static_assert(kMaxSensorRequestLogs <= INT8_MAX,
570 "kMaxSensorRequestLogs must be <= INT8_MAX");
571 for (int8_t i = static_cast<int8_t>(mSensorRequestLogs.size()) - 1; i >= 0;
572 i--) {
573 const auto &log = mSensorRequestLogs[static_cast<size_t>(i)];
574 const Sensor &sensor = mSensors[log.sensorHandle];
575 debugDump.print(" ts=%" PRIu64 " nappId=%" PRIu32 " type=%s idx=%" PRIu8
576 " mask=%" PRIx16 " mode=%s",
577 log.timestamp.toRawNanoseconds(), log.instanceId,
578 sensor.getSensorTypeName(), sensor.getSensorIndex(),
579 sensor.getTargetGroupMask(), getSensorModeName(log.mode));
580
581 if (sensorModeIsContinuous(log.mode)) {
582 debugDump.print(" int=%" PRIu64 " lat=%" PRIu64,
583 log.interval.toRawNanoseconds(),
584 log.latency.toRawNanoseconds());
585 }
586 debugDump.print("\n");
587 }
588 }
589
postFlushCompleteEvent(uint32_t sensorHandle,uint8_t errorCode,const FlushRequest & request)590 void SensorRequestManager::postFlushCompleteEvent(uint32_t sensorHandle,
591 uint8_t errorCode,
592 const FlushRequest &request) {
593 auto *event = memoryAlloc<chreSensorFlushCompleteEvent>();
594 if (event == nullptr) {
595 LOG_OOM();
596 } else {
597 event->sensorHandle = sensorHandle;
598 event->errorCode = errorCode;
599 event->cookie = request.cookie;
600 memset(event->reserved, 0, sizeof(event->reserved));
601
602 EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
603 CHRE_EVENT_SENSOR_FLUSH_COMPLETE, event, freeEventDataCallback,
604 request.nanoappInstanceId);
605 }
606 }
607
completeFlushRequestAtIndex(size_t index,uint8_t errorCode)608 void SensorRequestManager::completeFlushRequestAtIndex(size_t index,
609 uint8_t errorCode) {
610 if (index < mFlushRequestQueue.size()) {
611 const FlushRequest &request = mFlushRequestQueue[index];
612 uint32_t sensorHandle = request.sensorHandle;
613 if (request.isActive) {
614 mSensors[sensorHandle].clearPendingFlushRequest();
615 }
616
617 postFlushCompleteEvent(sensorHandle, errorCode, request);
618 mFlushRequestQueue.erase(index);
619 }
620 }
621
dispatchNextFlushRequest(uint32_t sensorHandle)622 void SensorRequestManager::dispatchNextFlushRequest(uint32_t sensorHandle) {
623 for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
624 FlushRequest &request = mFlushRequestQueue[i];
625 if (request.sensorHandle == sensorHandle) {
626 uint8_t newRequestErrorCode = makeFlushRequest(request);
627 if (newRequestErrorCode == CHRE_ERROR_NONE) {
628 break;
629 } else {
630 completeFlushRequestAtIndex(i, newRequestErrorCode);
631 i--;
632 }
633 }
634 }
635 }
636
onFlushTimeout(uint32_t sensorHandle)637 void SensorRequestManager::onFlushTimeout(uint32_t sensorHandle) {
638 if (sensorHandle < mSensors.size()) {
639 Sensor &sensor = mSensors[sensorHandle];
640 sensor.setFlushRequestTimerHandle(CHRE_TIMER_INVALID);
641 }
642 }
643
handleFlushCompleteEventSync(uint8_t errorCode,uint32_t sensorHandle)644 void SensorRequestManager::handleFlushCompleteEventSync(uint8_t errorCode,
645 uint32_t sensorHandle) {
646 for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
647 if (mFlushRequestQueue[i].sensorHandle == sensorHandle) {
648 completeFlushRequestAtIndex(i, errorCode);
649 dispatchNextFlushRequest(sensorHandle);
650 break;
651 }
652 }
653 }
654
cancelFlushRequests(uint32_t sensorHandle,uint32_t nanoappInstanceId)655 void SensorRequestManager::cancelFlushRequests(uint32_t sensorHandle,
656 uint32_t nanoappInstanceId) {
657 bool removeAll = (nanoappInstanceId == kSystemInstanceId);
658 for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
659 const FlushRequest &request = mFlushRequestQueue[i];
660 if (request.sensorHandle == sensorHandle &&
661 (request.nanoappInstanceId == nanoappInstanceId || removeAll)) {
662 completeFlushRequestAtIndex(i,
663 CHRE_ERROR_FUNCTION_DISABLED /* errorCode */);
664 i--;
665 }
666 }
667
668 if (!mSensors[sensorHandle].isFlushRequestPending()) {
669 dispatchNextFlushRequest(sensorHandle);
670 }
671 }
672
addSensorRequestLog(uint32_t nanoappInstanceId,uint32_t sensorHandle,const SensorRequest & sensorRequest)673 void SensorRequestManager::addSensorRequestLog(
674 uint32_t nanoappInstanceId, uint32_t sensorHandle,
675 const SensorRequest &sensorRequest) {
676 mSensorRequestLogs.kick_push(SensorRequestLog(
677 SystemTime::getMonotonicTime(), nanoappInstanceId, sensorHandle,
678 sensorRequest.getMode(), sensorRequest.getInterval(),
679 sensorRequest.getLatency()));
680 }
681
addRequest(Sensor & sensor,const SensorRequest & request,bool * requestChanged)682 bool SensorRequestManager::addRequest(Sensor &sensor,
683 const SensorRequest &request,
684 bool *requestChanged) {
685 CHRE_ASSERT(requestChanged != nullptr);
686
687 size_t addIndex;
688 bool success = true;
689 SensorRequestMultiplexer &multiplexer = sensor.getRequestMultiplexer();
690 SensorRequest prevRequest = sensor.getMaximalRequest();
691 if (!multiplexer.addRequest(request, &addIndex, requestChanged)) {
692 *requestChanged = false;
693 success = false;
694 LOG_OOM();
695 } else if (*requestChanged) {
696 success = configurePlatformSensor(sensor, prevRequest);
697 if (!success) {
698 // Remove the newly added request since the platform failed to handle
699 // it. The sensor is expected to maintain the existing request so there is
700 // no need to reset the platform to the last maximal request.
701 multiplexer.removeRequest(addIndex, requestChanged);
702
703 // This is a roll-back operation so the maximal change in the
704 // multiplexer must not have changed. The request changed state is forced
705 // to false.
706 *requestChanged = false;
707 }
708 }
709
710 return success;
711 }
712
updateRequest(Sensor & sensor,size_t updateIndex,const SensorRequest & request,bool * requestChanged)713 bool SensorRequestManager::updateRequest(Sensor &sensor, size_t updateIndex,
714 const SensorRequest &request,
715 bool *requestChanged) {
716 CHRE_ASSERT(requestChanged != nullptr);
717
718 bool success = true;
719 SensorRequestMultiplexer &multiplexer = sensor.getRequestMultiplexer();
720 SensorRequest previousRequest = multiplexer.getRequests()[updateIndex];
721 SensorRequest prevMaxRequest = sensor.getMaximalRequest();
722
723 multiplexer.updateRequest(updateIndex, request, requestChanged);
724 if (*requestChanged) {
725 success = configurePlatformSensor(sensor, prevMaxRequest);
726 if (!success) {
727 // Roll back the request since sending it to the sensor failed. The
728 // request will roll back to the previous maximal. The sensor is
729 // expected to maintain the existing request if a request fails so there
730 // is no need to reset the platform to the last maximal request.
731 multiplexer.updateRequest(updateIndex, previousRequest, requestChanged);
732
733 // This is a roll-back operation so the maximal change in the multiplexer
734 // must not have changed. The request changed state is forced to false.
735 *requestChanged = false;
736 }
737 }
738
739 return success;
740 }
741
removeRequest(Sensor & sensor,size_t removeIndex,bool * requestChanged)742 bool SensorRequestManager::removeRequest(Sensor &sensor, size_t removeIndex,
743 bool *requestChanged) {
744 CHRE_ASSERT(requestChanged != nullptr);
745
746 bool success = true;
747 const SensorRequest prevRequest = sensor.getMaximalRequest();
748 sensor.getRequestMultiplexer().removeRequest(removeIndex, requestChanged);
749 if (*requestChanged) {
750 success = configurePlatformSensor(sensor, prevRequest);
751 if (!success) {
752 LOGE("SensorRequestManager failed to remove a request");
753
754 // If the platform fails to handle this request in a debug build there is
755 // likely an error in the platform. This is not strictly a programming
756 // error but it does make sense to use assert semantics when a platform
757 // fails to handle a request that it had been sent previously.
758 CHRE_ASSERT(false);
759
760 // The request to the platform to set a request when removing has failed
761 // so the request has not changed.
762 *requestChanged = false;
763 }
764 }
765 return success;
766 }
767
removeAllRequests(Sensor & sensor)768 bool SensorRequestManager::removeAllRequests(Sensor &sensor) {
769 bool requestChanged;
770 SensorRequest prevRequest = sensor.getMaximalRequest();
771 sensor.getRequestMultiplexer().removeAllRequests(&requestChanged);
772
773 bool success = true;
774 if (requestChanged) {
775 success = configurePlatformSensor(sensor, prevRequest);
776
777 if (!success) {
778 LOGE("SensorRequestManager failed to remove all requests");
779
780 // If the platform fails to handle this request in a debug build there
781 // is likely an error in the platform. This is not strictly a programming
782 // error but it does make sense to use assert semantics when a platform
783 // fails to handle a request that it had been sent previously.
784 CHRE_ASSERT(false);
785 }
786 }
787
788 return success;
789 }
790
makeFlushRequest(FlushRequest & request)791 uint8_t SensorRequestManager::makeFlushRequest(FlushRequest &request) {
792 uint8_t errorCode = CHRE_ERROR;
793 Sensor &sensor = mSensors[request.sensorHandle];
794 if (!sensor.isSensorEnabled()) {
795 LOGE("Cannot flush on disabled sensor");
796 } else if (!sensor.isFlushRequestPending()) {
797 Nanoseconds now = SystemTime::getMonotonicTime();
798 Nanoseconds deadline = request.deadlineTimestamp;
799 if (now >= deadline) {
800 LOGE("Flush sensor %s failed for nanoapp ID %" PRIu32
801 ": deadline exceeded",
802 sensor.getSensorName(), request.nanoappInstanceId);
803 errorCode = CHRE_ERROR_TIMEOUT;
804 } else if (doMakeFlushRequest(sensor)) {
805 errorCode = CHRE_ERROR_NONE;
806 Nanoseconds delay = deadline - now;
807 request.isActive = true;
808
809 auto callback = [](uint16_t /*type*/, void *data, void * /*extraData*/) {
810 LOGE("Flush request timed out");
811 NestedDataPtr<uint32_t> sensorHandle(data);
812 EventLoopManagerSingleton::get()
813 ->getSensorRequestManager()
814 .onFlushTimeout(sensorHandle);
815
816 // Send a complete event, thus closing out this flush request. If the
817 // request that has just timed out receives a response later, this may
818 // inadvertently close out a new request before it has actually
819 // completed.
820 // TODO: Attach an ID to all flush requests / responses so stale
821 // responses can be properly dropped.
822 EventLoopManagerSingleton::get()
823 ->getSensorRequestManager()
824 .handleFlushCompleteEventSync(CHRE_ERROR_TIMEOUT, sensorHandle);
825 };
826
827 sensor.setFlushRequestTimerHandle(
828 EventLoopManagerSingleton::get()->setDelayedCallback(
829 SystemCallbackType::SensorFlushTimeout,
830 NestedDataPtr<uint32_t>(request.sensorHandle), callback, delay));
831 }
832 } else {
833 // Flush request will be made once the pending request is completed.
834 // Return true so that the nanoapp can wait for a result through the
835 // CHRE_EVENT_SENSOR_FLUSH_COMPLETE event.
836 errorCode = CHRE_ERROR_NONE;
837 }
838
839 return errorCode;
840 }
841
doMakeFlushRequest(Sensor & sensor)842 bool SensorRequestManager::doMakeFlushRequest(Sensor &sensor) {
843 // Set to true before making the request since the request may be a
844 // synchronous request and we may get the complete event before it returns.
845 sensor.setFlushRequestPending(true);
846 // TODO: Refactor code to take the request ID into account so multiple flush
847 // requests can be issued.
848 uint32_t flushRequestId;
849 bool success = mPlatformSensorManager.flush(sensor, &flushRequestId);
850 sensor.setFlushRequestPending(success);
851 return success;
852 }
853
configurePlatformSensor(Sensor & sensor,const SensorRequest & prevSensorRequest)854 bool SensorRequestManager::configurePlatformSensor(
855 Sensor &sensor, const SensorRequest &prevSensorRequest) {
856 bool success = false;
857 const SensorRequest &request = sensor.getMaximalRequest();
858
859 // Ensures that only configureBiasEvents is invoked if that's the only value
860 // that has changed since the previous request since CHRE shouldn't configure
861 // the platform for data events if the sensor data request hasn't changed.
862 bool biasChanged = (request.getBiasUpdatesRequested() !=
863 prevSensorRequest.getBiasUpdatesRequested());
864 bool onlyBiasChanged = request.onlyBiasRequestUpdated(prevSensorRequest);
865 uint64_t currentLatency = 0;
866 bool enable = (request.getMode() != SensorMode::Off);
867 if (enable) {
868 currentLatency = request.getLatency().toRawNanoseconds();
869 }
870
871 // Per platform API requirements, an active sensor subscription must exist
872 // before any bias configuration can be done.
873 if (!onlyBiasChanged &&
874 !mPlatformSensorManager.configureSensor(sensor, request)) {
875 LOGE("Failed to make platform sensor data request");
876 } else if (biasChanged &&
877 !mPlatformSensorManager.configureBiasEvents(
878 sensor, request.getBiasUpdatesRequested(), currentLatency)) {
879 LOGE("Failed to make platform sensor bias request");
880 if (!onlyBiasChanged) {
881 mPlatformSensorManager.configureSensor(sensor, prevSensorRequest);
882 }
883 } else {
884 success = true;
885
886 // Reset last event if an on-change sensor is turned off.
887 if (request.getMode() == SensorMode::Off) {
888 sensor.clearLastEvent();
889 }
890 }
891 return success;
892 }
893
894 } // namespace chre
895