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