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