diff --git a/include/gui/SensorEventQueue.h b/include/gui/SensorEventQueue.h index 019308d0c..5402f37d8 100644 --- a/include/gui/SensorEventQueue.h +++ b/include/gui/SensorEventQueue.h @@ -27,7 +27,7 @@ #include // ---------------------------------------------------------------------------- -#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 31) +#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 30) struct ALooper; struct ASensorEvent; diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 6c3144b80..ef87e5c9f 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -807,29 +807,36 @@ status_t SensorService::setEventRate(const sp& connection return sensor->setDelay(connection.get(), handle, ns); } -status_t SensorService::flushSensor(const sp& connection, - int handle) { +status_t SensorService::flushSensor(const sp& connection) { if (mInitCheck != NO_ERROR) return mInitCheck; - SensorInterface* sensor = mSensorMap.valueFor(handle); - if (sensor == NULL) { - return BAD_VALUE; + SensorDevice& dev(SensorDevice::getInstance()); + const int halVersion = dev.getHalDeviceVersion(); + status_t err(NO_ERROR); + Mutex::Autolock _l(mLock); + // Loop through all sensors for this connection and call flush on each of them. + for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) { + const int handle = connection->mSensorInfo.keyAt(i); + SensorInterface* sensor = mSensorMap.valueFor(handle); + if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { + ALOGE("flush called on a one-shot sensor"); + err = INVALID_OPERATION; + continue; + } + SensorEventConnection::FlushInfo& flushInfo = connection->mSensorInfo.editValueFor(handle); + if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || isVirtualSensor(handle)) { + // For older devices just increment pending flush count which will send a trivial + // flush complete event. + flushInfo.mPendingFlushEventsToSend++; + } else { + status_t err_flush = sensor->flush(connection.get(), handle); + if (err_flush == NO_ERROR) { + SensorRecord* rec = mActiveSensors.valueFor(handle); + if (rec != NULL) rec->addPendingFlushConnection(connection); + } + err = (err_flush != NO_ERROR) ? err_flush : err; + } } - - if (!verifyCanAccessSensor(sensor->getSensor(), "Tried flushing")) { - return BAD_VALUE; - } - - if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) { - ALOGE("flush called on a one-shot sensor"); - return INVALID_OPERATION; - } - - status_t ret = sensor->flush(connection.get(), handle); - if (ret == NO_ERROR) { - SensorRecord* rec = mActiveSensors.valueFor(handle); - if (rec != NULL) rec->addPendingFlushConnection(connection); - } - return ret; + return err; } bool SensorService::canAccessSensor(const Sensor& sensor) { @@ -1034,7 +1041,7 @@ void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle, } status_t SensorService::SensorEventConnection::sendEvents( - sensors_event_t const* buffer, size_t numEvents, + sensors_event_t* buffer, size_t numEvents, sensors_event_t* scratch) { // filter out events not for this connection size_t count = 0; @@ -1042,10 +1049,16 @@ status_t SensorService::SensorEventConnection::sendEvents( if (scratch) { size_t i=0; while (igetFirstPendingFlushConnection() == this) { rec->removeFirstPendingFlushConnection(); flushInfo.mFirstFlushPending = false; - ++i; + // Invalidate this flush_complete_event so that it cannot be used by other + // connections. + buffer[i].flags |= SENSOR_EVENT_INVALID_FLAG; ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ", - buffer[i].meta_data.sensor); + buffer[i].meta_data.sensor); + ++i; continue; } } @@ -1080,13 +1096,20 @@ status_t SensorService::SensorEventConnection::sendEvents( } do { + if (buffer[i].flags & SENSOR_EVENT_INVALID_FLAG) { + ++i; + continue; + } if (buffer[i].type == SENSOR_TYPE_META_DATA) { - // Check if this connection has called flush() on this sensor. Only if - // a flush() has been explicitly called, send a flush_complete_event. - SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle); - if (rec && rec->getFirstPendingFlushConnection() == this) { + // Check if this connection has called flush() on this sensor. Only if + // a flush() has been explicitly called, send a flush_complete_event. + SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle); + if (rec && rec->getFirstPendingFlushConnection() == this) { rec->removeFirstPendingFlushConnection(); scratch[count++] = buffer[i]; + // Invalidate this flush_complete_event so that it cannot be used by + // other connections. + buffer[i].flags |= SENSOR_EVENT_INVALID_FLAG; } ++i; } else { @@ -1333,27 +1356,7 @@ status_t SensorService::SensorEventConnection::setEventRate( } status_t SensorService::SensorEventConnection::flush() { - SensorDevice& dev(SensorDevice::getInstance()); - const int halVersion = dev.getHalDeviceVersion(); - Mutex::Autolock _l(mConnectionLock); - status_t err(NO_ERROR); - // Loop through all sensors for this connection and call flush on each of them. - for (size_t i = 0; i < mSensorInfo.size(); ++i) { - const int handle = mSensorInfo.keyAt(i); - FlushInfo& flushInfo = mSensorInfo.editValueFor(handle); - if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || mService->isVirtualSensor(handle)) { - // For older devices just increment pending flush count which will send a trivial - // flush complete event. - flushInfo.mPendingFlushEventsToSend++; - } else { - status_t err_flush = mService->flushSensor(this, handle); - if (err_flush != NO_ERROR) { - ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush)); - } - err = (err_flush != NO_ERROR) ? err_flush : err; - } - } - return err; + return mService->flushSensor(this); } int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* data) { diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h index 3717fcb6a..0887f28b5 100644 --- a/services/sensorservice/SensorService.h +++ b/services/sensorservice/SensorService.h @@ -45,6 +45,14 @@ // For older HALs which don't support batching, use a smaller socket buffer size. #define SOCKET_BUFFER_SIZE_NON_BATCHED 4 * 1024 +// Flags for sensors_event_t.flag. Using only the most significant two bits for flags. +// MSB is to invalidate a sensor_event (typically a flush_complete_event) so that +// it won't be used by other connections. +// MSB 2nd bit is used to indicate whether the event needs to be acknowledged or not. +// This is typically used for WAKE_UP sensors. WAKE_UP_SENSOR_EVENT_NEEDS_ACK is defined +// in SensorEveneQueue.h +#define SENSOR_EVENT_INVALID_FLAG (1U << 31) + struct sensors_poll_device_t; struct sensors_module_t; @@ -148,7 +156,7 @@ class SensorService : public: SensorEventConnection(const sp& service, uid_t uid); - status_t sendEvents(sensors_event_t const* buffer, size_t count, + status_t sendEvents(sensors_event_t* buffer, size_t count, sensors_event_t* scratch); bool hasSensor(int32_t handle) const; bool hasAnySensor() const; @@ -229,7 +237,6 @@ class SensorService : DefaultKeyedVector mActiveVirtualSensors; SortedVector< wp > mActiveConnections; bool mWakeLockAcquired; - // The size of this vector is constant, only the items are mutable KeyedVector mLastEventSeen; @@ -239,7 +246,7 @@ public: nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags); status_t disable(const sp& connection, int handle); status_t setEventRate(const sp& connection, int handle, nsecs_t ns); - status_t flushSensor(const sp& connection, int handle); + status_t flushSensor(const sp& connection); }; // ---------------------------------------------------------------------------