Merge "SensorService flush fixes." into lmp-dev
This commit is contained in:
commit
253c4720af
@ -27,7 +27,7 @@
|
|||||||
#include <gui/BitTube.h>
|
#include <gui/BitTube.h>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 31)
|
#define WAKE_UP_SENSOR_EVENT_NEEDS_ACK (1U << 30)
|
||||||
struct ALooper;
|
struct ALooper;
|
||||||
struct ASensorEvent;
|
struct ASensorEvent;
|
||||||
|
|
||||||
|
@ -807,29 +807,36 @@ status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection
|
|||||||
return sensor->setDelay(connection.get(), handle, ns);
|
return sensor->setDelay(connection.get(), handle, ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
|
status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection) {
|
||||||
int handle) {
|
|
||||||
if (mInitCheck != NO_ERROR) return mInitCheck;
|
if (mInitCheck != NO_ERROR) return mInitCheck;
|
||||||
SensorInterface* sensor = mSensorMap.valueFor(handle);
|
SensorDevice& dev(SensorDevice::getInstance());
|
||||||
if (sensor == NULL) {
|
const int halVersion = dev.getHalDeviceVersion();
|
||||||
return BAD_VALUE;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SensorService::canAccessSensor(const Sensor& sensor) {
|
bool SensorService::canAccessSensor(const Sensor& sensor) {
|
||||||
@ -1034,7 +1041,7 @@ void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t SensorService::SensorEventConnection::sendEvents(
|
status_t SensorService::SensorEventConnection::sendEvents(
|
||||||
sensors_event_t const* buffer, size_t numEvents,
|
sensors_event_t* buffer, size_t numEvents,
|
||||||
sensors_event_t* scratch) {
|
sensors_event_t* scratch) {
|
||||||
// filter out events not for this connection
|
// filter out events not for this connection
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
@ -1042,10 +1049,16 @@ status_t SensorService::SensorEventConnection::sendEvents(
|
|||||||
if (scratch) {
|
if (scratch) {
|
||||||
size_t i=0;
|
size_t i=0;
|
||||||
while (i<numEvents) {
|
while (i<numEvents) {
|
||||||
|
// Flush complete events can be invalidated. If this event has been invalidated
|
||||||
|
// before, ignore and proceed to the next event.
|
||||||
|
if (buffer[i].flags & SENSOR_EVENT_INVALID_FLAG) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
int32_t sensor_handle = buffer[i].sensor;
|
int32_t sensor_handle = buffer[i].sensor;
|
||||||
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
|
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
|
||||||
ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
|
ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
|
||||||
buffer[i].meta_data.sensor);
|
buffer[i].meta_data.sensor);
|
||||||
// Setting sensor_handle to the correct sensor to ensure the sensor events per connection are
|
// Setting sensor_handle to the correct sensor to ensure the sensor events per connection are
|
||||||
// filtered correctly. buffer[i].sensor is zero for meta_data events.
|
// filtered correctly. buffer[i].sensor is zero for meta_data events.
|
||||||
sensor_handle = buffer[i].meta_data.sensor;
|
sensor_handle = buffer[i].meta_data.sensor;
|
||||||
@ -1065,9 +1078,12 @@ status_t SensorService::SensorEventConnection::sendEvents(
|
|||||||
if (rec && rec->getFirstPendingFlushConnection() == this) {
|
if (rec && rec->getFirstPendingFlushConnection() == this) {
|
||||||
rec->removeFirstPendingFlushConnection();
|
rec->removeFirstPendingFlushConnection();
|
||||||
flushInfo.mFirstFlushPending = false;
|
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 ",
|
ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
|
||||||
buffer[i].meta_data.sensor);
|
buffer[i].meta_data.sensor);
|
||||||
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1080,13 +1096,20 @@ status_t SensorService::SensorEventConnection::sendEvents(
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (buffer[i].flags & SENSOR_EVENT_INVALID_FLAG) {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
|
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
|
||||||
// Check if this connection has called flush() on this sensor. Only if
|
// Check if this connection has called flush() on this sensor. Only if
|
||||||
// a flush() has been explicitly called, send a flush_complete_event.
|
// a flush() has been explicitly called, send a flush_complete_event.
|
||||||
SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle);
|
SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle);
|
||||||
if (rec && rec->getFirstPendingFlushConnection() == this) {
|
if (rec && rec->getFirstPendingFlushConnection() == this) {
|
||||||
rec->removeFirstPendingFlushConnection();
|
rec->removeFirstPendingFlushConnection();
|
||||||
scratch[count++] = buffer[i];
|
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;
|
++i;
|
||||||
} else {
|
} else {
|
||||||
@ -1333,27 +1356,7 @@ status_t SensorService::SensorEventConnection::setEventRate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t SensorService::SensorEventConnection::flush() {
|
status_t SensorService::SensorEventConnection::flush() {
|
||||||
SensorDevice& dev(SensorDevice::getInstance());
|
return mService->flushSensor(this);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* data) {
|
int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* data) {
|
||||||
|
@ -45,6 +45,14 @@
|
|||||||
// For older HALs which don't support batching, use a smaller socket buffer size.
|
// For older HALs which don't support batching, use a smaller socket buffer size.
|
||||||
#define SOCKET_BUFFER_SIZE_NON_BATCHED 4 * 1024
|
#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_poll_device_t;
|
||||||
struct sensors_module_t;
|
struct sensors_module_t;
|
||||||
|
|
||||||
@ -148,7 +156,7 @@ class SensorService :
|
|||||||
public:
|
public:
|
||||||
SensorEventConnection(const sp<SensorService>& service, uid_t uid);
|
SensorEventConnection(const sp<SensorService>& 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);
|
sensors_event_t* scratch);
|
||||||
bool hasSensor(int32_t handle) const;
|
bool hasSensor(int32_t handle) const;
|
||||||
bool hasAnySensor() const;
|
bool hasAnySensor() const;
|
||||||
@ -229,7 +237,6 @@ class SensorService :
|
|||||||
DefaultKeyedVector<int, SensorInterface*> mActiveVirtualSensors;
|
DefaultKeyedVector<int, SensorInterface*> mActiveVirtualSensors;
|
||||||
SortedVector< wp<SensorEventConnection> > mActiveConnections;
|
SortedVector< wp<SensorEventConnection> > mActiveConnections;
|
||||||
bool mWakeLockAcquired;
|
bool mWakeLockAcquired;
|
||||||
|
|
||||||
// The size of this vector is constant, only the items are mutable
|
// The size of this vector is constant, only the items are mutable
|
||||||
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
|
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
|
||||||
|
|
||||||
@ -239,7 +246,7 @@ public:
|
|||||||
nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags);
|
nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags);
|
||||||
status_t disable(const sp<SensorEventConnection>& connection, int handle);
|
status_t disable(const sp<SensorEventConnection>& connection, int handle);
|
||||||
status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns);
|
status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns);
|
||||||
status_t flushSensor(const sp<SensorEventConnection>& connection, int handle);
|
status_t flushSensor(const sp<SensorEventConnection>& connection);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user