123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729 |
- /*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include "chre/core/sensor_request_manager.h"
- #include "chre_api/chre/version.h"
- #include "chre/core/event_loop_manager.h"
- #include "chre/platform/fatal_error.h"
- #include "chre/platform/shared/platform_sensor_util.h"
- #include "chre/util/nested_data_ptr.h"
- #include "chre/util/system/debug_dump.h"
- #define LOG_INVALID_SENSOR(x) \
- LOGE("Invalid sensor type %" PRIu8 ": line %d", \
- static_cast<uint8_t>(x), __LINE__)
- namespace chre {
- namespace {
- bool isSensorRequestValid(const Sensor& sensor,
- const SensorRequest& sensorRequest) {
- bool isRequestContinuous = sensorModeIsContinuous(
- sensorRequest.getMode());
- bool isRequestOneShot = sensorModeIsOneShot(sensorRequest.getMode());
- uint64_t requestedInterval = sensorRequest.getInterval().toRawNanoseconds();
- SensorType sensorType = sensor.getSensorType();
- bool success = true;
- if (requestedInterval < sensor.getMinInterval()) {
- success = false;
- LOGE("Requested interval %" PRIu64 " < sensor's minInterval %" PRIu64,
- requestedInterval, sensor.getMinInterval());
- } else if (isRequestContinuous) {
- if (sensorTypeIsOneShot(sensorType)) {
- success = false;
- LOGE("Invalid continuous request for a one-shot sensor.");
- }
- } else if (isRequestOneShot) {
- if (!sensorTypeIsOneShot(sensorType)) {
- success = false;
- LOGE("Invalid one-shot request for a continuous sensor.");
- }
- }
- return success;
- }
- } // namespace
- SensorRequestManager::SensorRequestManager() {
- mSensorRequests.resize(mSensorRequests.capacity());
- }
- SensorRequestManager::~SensorRequestManager() {
- for (size_t i = 0; i < mSensorRequests.size(); i++) {
- // Disable sensors that have been enabled previously.
- if (mSensorRequests[i].isSensorSupported()) {
- mSensorRequests[i].removeAll();
- }
- }
- PlatformSensor::deinit();
- }
- void SensorRequestManager::init() {
- // The Platform sensor must be initialized prior to interacting with any
- // sensors.
- PlatformSensor::init();
- DynamicVector<Sensor> sensors;
- sensors.reserve(8); // Avoid some initial reallocation churn
- if (!PlatformSensor::getSensors(&sensors)) {
- LOGE("Failed to query the platform for sensors");
- } else if (sensors.empty()) {
- LOGW("Platform returned zero sensors");
- } else {
- for (size_t i = 0; i < sensors.size(); i++) {
- SensorType sensorType = sensors[i].getSensorType();
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- if (!isValidSensorType(sensorType)) {
- LOG_INVALID_SENSOR(sensorType);
- } else if (sensors[i].getMinInterval() == 0) {
- LOGE("Invalid sensor minInterval: %s", getSensorTypeName(sensorType));
- } else {
- mSensorRequests[sensorIndex].setSensor(std::move(sensors[i]));
- LOGD("Found sensor: %s", getSensorTypeName(sensorType));
- }
- }
- }
- }
- bool SensorRequestManager::getSensorHandle(SensorType sensorType,
- uint32_t *sensorHandle) const {
- CHRE_ASSERT(sensorHandle);
- bool sensorHandleIsValid = false;
- if (!isValidSensorType(sensorType)) {
- LOG_INVALID_SENSOR(sensorType);
- } else {
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- sensorHandleIsValid = mSensorRequests[sensorIndex].isSensorSupported();
- if (sensorHandleIsValid) {
- *sensorHandle = getSensorHandleFromSensorType(sensorType);
- }
- }
- return sensorHandleIsValid;
- }
- bool SensorRequestManager::setSensorRequest(Nanoapp *nanoapp,
- uint32_t sensorHandle, const SensorRequest& sensorRequest) {
- CHRE_ASSERT(nanoapp);
- // Validate the input to ensure that a valid handle has been provided.
- SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
- if (!isValidSensorType(sensorType)) {
- LOG_INVALID_SENSOR(sensorType);
- return false;
- }
- // Ensure that the runtime is aware of this sensor type.
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- SensorRequests& requests = mSensorRequests[sensorIndex];
- if (!requests.isSensorSupported()) {
- LOGW("Attempting to configure non-existent sensor");
- return false;
- }
- const Sensor& sensor = requests.getSensor();
- if (!isSensorRequestValid(sensor, sensorRequest)) {
- return false;
- }
- size_t requestIndex;
- uint16_t eventType = getSampleEventTypeForSensorType(sensorType);
- bool nanoappHasRequest = (requests.find(nanoapp->getInstanceId(),
- &requestIndex) != nullptr);
- bool success;
- bool requestChanged;
- if (sensorRequest.getMode() == SensorMode::Off) {
- if (nanoappHasRequest) {
- // The request changes the mode to off and there was an existing request.
- // The existing request is removed from the multiplexer. The nanoapp is
- // unregistered from events of this type if this request was successful.
- success = requests.remove(requestIndex, &requestChanged);
- if (success) {
- cancelFlushRequests(sensorType, nanoapp->getInstanceId());
- nanoapp->unregisterForBroadcastEvent(eventType);
- uint16_t biasEventType;
- if (getSensorBiasEventType(sensorType, &biasEventType)) {
- // Per API requirements, turn off bias reporting when unsubscribing
- // from the sensor.
- nanoapp->unregisterForBroadcastEvent(biasEventType);
- }
- }
- } else {
- // The sensor is being configured to Off, but is already Off (there is no
- // existing request). We assign to success to be true and no other
- // operation is required.
- requestChanged = false;
- success = true;
- }
- } else if (!nanoappHasRequest) {
- // The request changes the mode to the enabled state and there was no
- // existing request. The request is newly created and added to the
- // multiplexer. The nanoapp is registered for events if this request was
- // successful.
- success = requests.add(sensorRequest, &requestChanged);
- if (success) {
- nanoapp->registerForBroadcastEvent(eventType);
- // Per API requirements, turn on bias reporting for calibrated sensors
- // by default when subscribed.
- uint16_t biasEventType;
- if (getSensorBiasEventType(sensorType, &biasEventType)
- && sensorTypeIsCalibrated(sensorType)) {
- nanoapp->registerForBroadcastEvent(biasEventType);
- }
- // Deliver last valid event to new clients of on-change sensors
- if (sensorTypeIsOnChange(sensor.getSensorType()) &&
- sensor.getLastEvent() != nullptr) {
- EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
- getSampleEventTypeForSensorType(sensorType), sensor.getLastEvent(),
- nullptr, nanoapp->getInstanceId());
- }
- }
- } else {
- // The request changes the mode to the enabled state and there was an
- // existing request. The existing request is updated.
- success = requests.update(requestIndex, sensorRequest, &requestChanged);
- }
- if (requestChanged) {
- // TODO: Send an event to nanoapps to indicate the rate change.
- }
- return success;
- }
- bool SensorRequestManager::getSensorInfo(uint32_t sensorHandle,
- const Nanoapp& nanoapp,
- struct chreSensorInfo *info) const {
- CHRE_ASSERT(info);
- bool success = false;
- // Validate the input to ensure that a valid handle has been provided.
- SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
- if (!isValidSensorType(sensorType)) {
- LOG_INVALID_SENSOR(sensorType);
- } else {
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- if (!mSensorRequests[sensorIndex].isSensorSupported()) {
- LOGW("Attempting to get sensor info for unsupported sensor handle %"
- PRIu32, sensorHandle);
- } else {
- // Platform-independent properties.
- info->sensorType = getUnsignedIntFromSensorType(sensorType);
- info->isOnChange = sensorTypeIsOnChange(sensorType);
- info->isOneShot = sensorTypeIsOneShot(sensorType);
- info->reportsBiasEvents = sensorTypeReportsBias(sensorType);
- info->unusedFlags = 0;
- // Platform-specific properties.
- const Sensor& sensor = mSensorRequests[sensorIndex].getSensor();
- info->sensorName = sensor.getSensorName();
- // minInterval was added in CHRE API v1.1 - do not attempt to populate for
- // nanoapps targeting v1.0 as their struct will not be large enough
- if (nanoapp.getTargetApiVersion() >= CHRE_API_VERSION_1_1) {
- info->minInterval = sensor.getMinInterval();
- }
- success = true;
- }
- }
- return success;
- }
- bool SensorRequestManager::removeAllRequests(SensorType sensorType) {
- bool success = false;
- if (!isValidSensorType(sensorType)) {
- LOG_INVALID_SENSOR(sensorType);
- } else {
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- SensorRequests& requests = mSensorRequests[sensorIndex];
- uint16_t eventType = getSampleEventTypeForSensorType(sensorType);
- for (const SensorRequest& request : requests.getRequests()) {
- Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop()
- .findNanoappByInstanceId(request.getInstanceId());
- if (nanoapp != nullptr) {
- nanoapp->unregisterForBroadcastEvent(eventType);
- }
- }
- cancelFlushRequests(sensorType);
- success = requests.removeAll();
- }
- return success;
- }
- Sensor *SensorRequestManager::getSensor(SensorType sensorType) {
- Sensor *sensorPtr = nullptr;
- if (!isValidSensorType(sensorType)) {
- LOG_INVALID_SENSOR(sensorType);
- } else {
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- if (mSensorRequests[sensorIndex].isSensorSupported()) {
- sensorPtr = &mSensorRequests[sensorIndex].getSensor();
- }
- }
- return sensorPtr;
- }
- bool SensorRequestManager::getSensorSamplingStatus(
- uint32_t sensorHandle, struct chreSensorSamplingStatus *status) const {
- CHRE_ASSERT(status);
- bool success = false;
- SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
- if (!isValidSensorType(sensorType)) {
- LOG_INVALID_SENSOR(sensorType);
- } else {
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- if (mSensorRequests[sensorIndex].isSensorSupported()) {
- success = mSensorRequests[sensorIndex].getSamplingStatus(status);
- }
- }
- return success;
- }
- const DynamicVector<SensorRequest>& SensorRequestManager::getRequests(
- SensorType sensorType) const {
- size_t sensorIndex = 0;
- if (!isValidSensorType(sensorType)) {
- LOG_INVALID_SENSOR(sensorType);
- } else {
- sensorIndex = getSensorTypeArrayIndex(sensorType);
- }
- return mSensorRequests[sensorIndex].getRequests();
- }
- bool SensorRequestManager::configureBiasEvents(
- Nanoapp *nanoapp, uint32_t sensorHandle, bool enable) {
- bool success = false;
- uint16_t eventType;
- SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
- if (getSensorBiasEventType(sensorType, &eventType)) {
- if (enable) {
- nanoapp->registerForBroadcastEvent(eventType);
- } else {
- nanoapp->unregisterForBroadcastEvent(eventType);
- }
- success = true;
- }
- return success;
- }
- bool SensorRequestManager::getThreeAxisBias(
- uint32_t sensorHandle, struct chreSensorThreeAxisData *bias) const {
- CHRE_ASSERT(bias != nullptr);
- bool success = false;
- if (bias != nullptr) {
- SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
- if (!isValidSensorType(sensorType)) {
- LOG_INVALID_SENSOR(sensorType);
- } else {
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- if (mSensorRequests[sensorIndex].isSensorSupported()) {
- success = mSensorRequests[sensorIndex].getThreeAxisBias(bias);
- }
- }
- }
- return success;
- }
- bool SensorRequestManager::flushAsync(
- Nanoapp *nanoapp, uint32_t sensorHandle, const void *cookie) {
- bool success = false;
- uint32_t nanoappInstanceId = nanoapp->getInstanceId();
- SensorType sensorType = getSensorTypeFromSensorHandle(sensorHandle);
- // NOTE: One-shot sensors do not support flush per API
- if (!isValidSensorType(sensorType) || sensorTypeIsOneShot(sensorType)) {
- LOGE("Cannot flush for sensor type %" PRIu32,
- static_cast<uint32_t>(sensorType));
- } else if (mFlushRequestQueue.full()) {
- LOG_OOM();
- } else {
- mFlushRequestQueue.emplace_back(sensorType, nanoappInstanceId, cookie);
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- success = (mSensorRequests[sensorIndex].makeFlushRequest(
- mFlushRequestQueue.back()) == CHRE_ERROR_NONE);
- if (!success) {
- mFlushRequestQueue.pop_back();
- }
- }
- return success;
- }
- void SensorRequestManager::handleFlushCompleteEvent(
- uint8_t errorCode, SensorType sensorType) {
- size_t sensorIndex = getSensorTypeArrayIndex(sensorType);
- if (isValidSensorType(sensorType)
- && mSensorRequests[sensorIndex].isFlushRequestPending()) {
- // Cancel flush request timer before posting to the event queue to ensure
- // a timeout event isn't processed by CHRE now that the complete event
- // has been received.
- mSensorRequests[sensorIndex].cancelPendingFlushRequestTimer();
- struct CallbackState {
- uint8_t errorCode;
- SensorType sensorType;
- };
- NestedDataPtr<CallbackState> state = {};
- state.data.errorCode = errorCode;
- state.data.sensorType = sensorType;
- auto callback = [](uint16_t /* eventType */, void *eventData) {
- NestedDataPtr<CallbackState> nestedState;
- nestedState.dataPtr = eventData;
- EventLoopManagerSingleton::get()->getSensorRequestManager()
- .handleFlushCompleteEventSync(nestedState.data.errorCode,
- nestedState.data.sensorType);
- };
- EventLoopManagerSingleton::get()->deferCallback(
- SystemCallbackType::SensorFlushComplete, state.dataPtr, callback);
- }
- }
- void SensorRequestManager::handleSensorEvent(SensorType sensorType,
- void *event) {
- uint16_t eventType = getSampleEventTypeForSensorType(sensorType);
- // Only allow dropping continuous sensor events since losing one-shot or
- // on-change events could result in nanoapps stuck in a bad state.
- if (sensorTypeIsContinuous(sensorType)) {
- EventLoopManagerSingleton::get()->getEventLoop().postLowPriorityEventOrFree(
- eventType, event, sensorDataEventFree);
- } else {
- EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
- eventType, event, sensorDataEventFree);
- }
- }
- void SensorRequestManager::logStateToBuffer(char *buffer, size_t *bufferPos,
- size_t bufferSize) const {
- debugDumpPrint(buffer, bufferPos, bufferSize, "\nSensors:\n");
- for (uint8_t i = 0; i < static_cast<uint8_t>(SensorType::SENSOR_TYPE_COUNT);
- i++) {
- SensorType sensor = static_cast<SensorType>(i);
- if (isValidSensorType(sensor)) {
- for (const auto& request : getRequests(sensor)) {
- debugDumpPrint(buffer, bufferPos, bufferSize, " %s: mode=%d"
- " interval(ns)=%" PRIu64 " latency(ns)=%"
- PRIu64 " nanoappId=%" PRIu32 "\n",
- getSensorTypeName(sensor), request.getMode(),
- request.getInterval().toRawNanoseconds(),
- request.getLatency().toRawNanoseconds(),
- request.getInstanceId());
- }
- }
- }
- }
- void SensorRequestManager::postFlushCompleteEvent(
- uint32_t sensorHandle, uint8_t errorCode, const FlushRequest& request) {
- auto *event = memoryAlloc<chreSensorFlushCompleteEvent>();
- if (event == nullptr) {
- LOG_OOM();
- } else {
- event->sensorHandle = sensorHandle;
- event->errorCode = errorCode;
- event->cookie = request.cookie;
- memset(event->reserved, 0, sizeof(event->reserved));
- EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
- CHRE_EVENT_SENSOR_FLUSH_COMPLETE, event, freeEventDataCallback,
- request.nanoappInstanceId);
- }
- }
- void SensorRequestManager::completeFlushRequestAtIndex(
- size_t index, uint8_t errorCode) {
- if (index < mFlushRequestQueue.size()) {
- const FlushRequest& request = mFlushRequestQueue[index];
- SensorType sensorType = request.sensorType;
- if (request.isActive) {
- SensorRequests& requests = getSensorRequests(sensorType);
- requests.clearPendingFlushRequest();
- }
- uint32_t sensorHandle;
- if (getSensorHandle(sensorType, &sensorHandle)) {
- postFlushCompleteEvent(sensorHandle, errorCode, request);
- }
- mFlushRequestQueue.erase(index);
- }
- }
- void SensorRequestManager::dispatchNextFlushRequest(SensorType sensorType) {
- SensorRequests& requests = getSensorRequests(sensorType);
- for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
- FlushRequest& request = mFlushRequestQueue[i];
- if (request.sensorType == sensorType) {
- uint8_t newRequestErrorCode = requests.makeFlushRequest(request);
- if (newRequestErrorCode == CHRE_ERROR_NONE) {
- break;
- } else {
- completeFlushRequestAtIndex(i, newRequestErrorCode);
- i--;
- }
- }
- }
- }
- void SensorRequestManager::handleFlushCompleteEventSync(
- uint8_t errorCode, SensorType sensorType) {
- for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
- if (mFlushRequestQueue[i].sensorType == sensorType) {
- completeFlushRequestAtIndex(i, errorCode);
- dispatchNextFlushRequest(sensorType);
- break;
- }
- }
- }
- void SensorRequestManager::cancelFlushRequests(
- SensorType sensorType, uint32_t nanoappInstanceId) {
- bool removeAll = (nanoappInstanceId == kSystemInstanceId);
- for (size_t i = 0; i < mFlushRequestQueue.size(); i++) {
- const FlushRequest& request = mFlushRequestQueue[i];
- if (request.sensorType == sensorType &&
- (request.nanoappInstanceId == nanoappInstanceId || removeAll)) {
- completeFlushRequestAtIndex(
- i, CHRE_ERROR_FUNCTION_DISABLED /* errorCode */);
- i--;
- }
- }
- SensorRequests& requests = getSensorRequests(sensorType);
- if (!requests.isFlushRequestPending()) {
- dispatchNextFlushRequest(sensorType);
- }
- }
- const SensorRequest *SensorRequestManager::SensorRequests::find(
- uint32_t instanceId, size_t *index) const {
- CHRE_ASSERT(index);
- const auto& requests = mMultiplexer.getRequests();
- for (size_t i = 0; i < requests.size(); i++) {
- const SensorRequest& sensorRequest = requests[i];
- if (sensorRequest.getInstanceId() == instanceId) {
- *index = i;
- return &sensorRequest;
- }
- }
- return nullptr;
- }
- bool SensorRequestManager::SensorRequests::add(const SensorRequest& request,
- bool *requestChanged) {
- CHRE_ASSERT(requestChanged != nullptr);
- CHRE_ASSERT(isSensorSupported());
- size_t addIndex;
- bool success = true;
- if (!mMultiplexer.addRequest(request, &addIndex, requestChanged)) {
- *requestChanged = false;
- success = false;
- LOG_OOM();
- } else if (*requestChanged) {
- success = mSensor->setRequest(mMultiplexer.getCurrentMaximalRequest());
- if (!success) {
- // Remove the newly added request since the platform failed to handle it.
- // The sensor is expected to maintain the existing request so there is no
- // need to reset the platform to the last maximal request.
- mMultiplexer.removeRequest(addIndex, requestChanged);
- // This is a roll-back operation so the maximal change in the multiplexer
- // must not have changed. The request changed state is forced to false.
- *requestChanged = false;
- }
- }
- return success;
- }
- bool SensorRequestManager::SensorRequests::remove(size_t removeIndex,
- bool *requestChanged) {
- CHRE_ASSERT(requestChanged != nullptr);
- CHRE_ASSERT(isSensorSupported());
- bool success = true;
- mMultiplexer.removeRequest(removeIndex, requestChanged);
- if (*requestChanged) {
- success = mSensor->setRequest(mMultiplexer.getCurrentMaximalRequest());
- if (!success) {
- LOGE("SensorRequestManager failed to remove a request");
- // If the platform fails to handle this request in a debug build there is
- // likely an error in the platform. This is not strictly a programming
- // error but it does make sense to use assert semantics when a platform
- // fails to handle a request that it had been sent previously.
- CHRE_ASSERT(false);
- // The request to the platform to set a request when removing has failed
- // so the request has not changed.
- *requestChanged = false;
- }
- }
- return success;
- }
- bool SensorRequestManager::SensorRequests::update(size_t updateIndex,
- const SensorRequest& request,
- bool *requestChanged) {
- CHRE_ASSERT(requestChanged != nullptr);
- CHRE_ASSERT(isSensorSupported());
- bool success = true;
- SensorRequest previousRequest = mMultiplexer.getRequests()[updateIndex];
- mMultiplexer.updateRequest(updateIndex, request, requestChanged);
- if (*requestChanged) {
- success = mSensor->setRequest(mMultiplexer.getCurrentMaximalRequest());
- if (!success) {
- // Roll back the request since sending it to the sensor failed. The
- // request will roll back to the previous maximal. The sensor is
- // expected to maintain the existing request if a request fails so there
- // is no need to reset the platform to the last maximal request.
- mMultiplexer.updateRequest(updateIndex, previousRequest, requestChanged);
- // This is a roll-back operation so the maximal change in the multiplexer
- // must not have changed. The request changed state is forced to false.
- *requestChanged = false;
- }
- }
- return success;
- }
- bool SensorRequestManager::SensorRequests::removeAll() {
- CHRE_ASSERT(isSensorSupported());
- bool requestChanged;
- mMultiplexer.removeAllRequests(&requestChanged);
- bool success = true;
- if (requestChanged) {
- SensorRequest maximalRequest = mMultiplexer.getCurrentMaximalRequest();
- success = mSensor->setRequest(maximalRequest);
- if (!success) {
- LOGE("SensorRequestManager failed to remove all request");
- // If the platform fails to handle this request in a debug build there is
- // likely an error in the platform. This is not strictly a programming
- // error but it does make sense to use assert semantics when a platform
- // fails to handle a request that it had been sent previously.
- CHRE_ASSERT(false);
- }
- }
- return success;
- }
- uint8_t SensorRequestManager::SensorRequests::makeFlushRequest(
- FlushRequest& request) {
- uint8_t errorCode = CHRE_ERROR;
- if (!isSensorSupported()) {
- LOGE("Cannot flush on unsupported sensor");
- } else if (mMultiplexer.getRequests().size() == 0) {
- LOGE("Cannot flush on disabled sensor");
- } else if (!isFlushRequestPending()) {
- Nanoseconds now = SystemTime::getMonotonicTime();
- Nanoseconds deadline = request.deadlineTimestamp;
- if (now >= deadline) {
- LOGE("Flush sensor %" PRIu32 " failed for nanoapp ID %" PRIu32
- ": deadline exceeded", static_cast<uint32_t>(request.sensorType),
- request.nanoappInstanceId);
- errorCode = CHRE_ERROR_TIMEOUT;
- } else if (doMakeFlushRequest()) {
- errorCode = CHRE_ERROR_NONE;
- Nanoseconds delay = deadline - now;
- request.isActive = true;
- NestedDataPtr<SensorType> nestedType = {};
- nestedType.data = request.sensorType;
- auto callback = [](uint16_t /* eventType */, void * eventData) {
- LOGE("Flush request timed out.");
- NestedDataPtr<SensorType> nestedType;
- nestedType.dataPtr = eventData;
- // Send a complete event, thus closing out this flush request. If the
- // request that has just timed out receives a response later, this may
- // inadvertently close out a new request before it has actually
- // completed.
- // TODO: Attach an ID to all flush requests / responses so stale
- // responses can be properly dropped.
- EventLoopManagerSingleton::get()->getSensorRequestManager()
- .handleFlushCompleteEventSync(CHRE_ERROR_TIMEOUT,
- nestedType.data);
- };
- mFlushRequestTimerHandle =
- EventLoopManagerSingleton::get()->setDelayedCallback(
- SystemCallbackType::SensorFlushTimeout, nestedType.dataPtr,
- callback, delay);
- }
- } else {
- // Flush request will be made once the pending request is completed.
- // Return true so that the nanoapp can wait for a result through the
- // CHRE_EVENT_SENSOR_FLUSH_COMPLETE event.
- errorCode = CHRE_ERROR_NONE;
- }
- return errorCode;
- }
- void SensorRequestManager::SensorRequests::clearPendingFlushRequest() {
- cancelPendingFlushRequestTimer();
- mFlushRequestPending = false;
- }
- void SensorRequestManager::SensorRequests::cancelPendingFlushRequestTimer() {
- if (mFlushRequestTimerHandle != CHRE_TIMER_INVALID) {
- EventLoopManagerSingleton::get()->cancelDelayedCallback(
- mFlushRequestTimerHandle);
- mFlushRequestTimerHandle = CHRE_TIMER_INVALID;
- }
- }
- bool SensorRequestManager::SensorRequests::doMakeFlushRequest() {
- // Set to true before making the request since it's a synchronous request
- // and we may get the complete event before it returns.
- mFlushRequestPending = true;
- mFlushRequestPending = mSensor->flushAsync();
- return mFlushRequestPending;
- }
- } // namespace chre
|