summaryrefslogtreecommitdiffstats
path: root/services/sensorservice
diff options
context:
space:
mode:
authorAravind Akella <aakella@google.com>2014-09-08 15:45:47 -0700
committerAravind Akella <aakella@google.com>2014-09-10 18:24:18 -0700
commit8493b79e1cff92450076ca7450c4bf4e434a6816 (patch)
treeece62840a560291f7e3453da472750d3fa3aa489 /services/sensorservice
parent9e691c1093fa9c00d82f5a33f5382c2610734ca6 (diff)
downloadframeworks_native-8493b79e1cff92450076ca7450c4bf4e434a6816.zip
frameworks_native-8493b79e1cff92450076ca7450c4bf4e434a6816.tar.gz
frameworks_native-8493b79e1cff92450076ca7450c4bf4e434a6816.tar.bz2
SensorService fixes
i) Significant Motion multiple clients fix. Make a copy of mActiveConnections vector before cleaning up SensorEventConnections when one-shot sensors trigger. ii) Maintain a mapping between flush_complete_events and SensorEventConnections to accurately map flush() API calls and corresponding flush_complete_events iii) Remove all references to 1_1 and 1_2 HALs. iv) Dynamically allocate sensor_event buffers in SensorService main threadLoop. Bug: 17412359 Change-Id: If3c3986197660cafef2d2e0b4dc7582e229cf1c4
Diffstat (limited to 'services/sensorservice')
-rw-r--r--services/sensorservice/SensorService.cpp132
-rw-r--r--services/sensorservice/SensorService.h15
2 files changed, 84 insertions, 63 deletions
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index ef87e5c..b0695ba 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -186,6 +186,11 @@ void SensorService::onFirstRef()
mWakeLockAcquired = false;
run("SensorService", PRIORITY_URGENT_DISPLAY);
mLooper = new Looper(false);
+
+ const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
+ mSensorEventBuffer = new sensors_event_t[minBufferSize];
+ mSensorEventScratch = new sensors_event_t[minBufferSize];
+ mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
mInitCheck = NO_ERROR;
}
}
@@ -350,6 +355,9 @@ void SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnecti
sensors_event_t const* buffer, const int count) {
for (int i=0 ; i<count ; i++) {
int handle = buffer[i].sensor;
+ if (buffer[i].type == SENSOR_TYPE_META_DATA) {
+ handle = buffer[i].meta_data.sensor;
+ }
if (connection->hasSensor(handle)) {
SensorInterface* sensor = mSensorMap.valueFor(handle);
// If this buffer has an event from a one_shot sensor and this connection is registered
@@ -373,25 +381,22 @@ bool SensorService::threadLoop()
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
- sensors_event_t buffer[minBufferSize];
- sensors_event_t scratch[minBufferSize];
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();
SensorEventAckReceiver sender(this);
sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);
- ssize_t count;
const int halVersion = device.getHalDeviceVersion();
do {
- count = device.poll(buffer, numEventMax);
- if (count<0) {
+ ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
+ if (count < 0) {
ALOGE("sensor poll failed (%s)", strerror(-count));
break;
}
// Reset sensors_event_t.flags to zero for all events in the buffer.
for (int i = 0; i < count; i++) {
- buffer[i].flags = 0;
+ mSensorEventBuffer[i].flags = 0;
}
Mutex::Autolock _l(mLock);
// Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The
@@ -401,7 +406,7 @@ bool SensorService::threadLoop()
// releasing the wakelock.
bool bufferHasWakeUpEvent = false;
for (int i = 0; i < count; i++) {
- if (isWakeUpSensorEvent(buffer[i])) {
+ if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {
bufferHasWakeUpEvent = true;
break;
}
@@ -412,11 +417,11 @@ bool SensorService::threadLoop()
mWakeLockAcquired = true;
ALOGD_IF(DEBUG_CONNECTIONS, "acquired wakelock %s", WAKE_LOCK_NAME);
}
- recordLastValueLocked(buffer, count);
+ recordLastValueLocked(mSensorEventBuffer, count);
// handle virtual sensors
if (count && vcount) {
- sensors_event_t const * const event = buffer;
+ sensors_event_t const * const event = mSensorEventBuffer;
const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();
if (activeVirtualSensorCount) {
size_t k = 0;
@@ -437,17 +442,17 @@ bool SensorService::threadLoop()
sensors_event_t out;
SensorInterface* si = mActiveVirtualSensors.valueAt(j);
if (si->process(&out, event[i])) {
- buffer[count + k] = out;
+ mSensorEventBuffer[count + k] = out;
k++;
}
}
}
if (k) {
// record the last synthesized values
- recordLastValueLocked(&buffer[count], k);
+ recordLastValueLocked(&mSensorEventBuffer[count], k);
count += k;
// sort the buffer by time-stamps
- sortEventBuffer(buffer, count);
+ sortEventBuffer(mSensorEventBuffer, count);
}
}
}
@@ -455,10 +460,26 @@ bool SensorService::threadLoop()
// handle backward compatibility for RotationVector sensor
if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
for (int i = 0; i < count; i++) {
- if (buffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
+ if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {
// All the 4 components of the quaternion should be available
// No heading accuracy. Set it to -1
- buffer[i].data[4] = -1;
+ mSensorEventBuffer[i].data[4] = -1;
+ }
+ }
+ }
+
+ // Map flush_complete_events in the buffer to SensorEventConnections which called
+ // flush on the hardware sensor. mapFlushEventsToConnections[i] will be the
+ // SensorEventConnection mapped to the corresponding flush_complete_event in
+ // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).
+ for (int i = 0; i < count; ++i) {
+ mMapFlushEventsToConnections[i] = NULL;
+ if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
+ const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
+ SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);
+ if (rec != NULL) {
+ mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();
+ rec->removeFirstPendingFlushConnection();
}
}
}
@@ -466,13 +487,22 @@ bool SensorService::threadLoop()
// Send our events to clients. Check the state of wake lock for each client and release the
// lock if none of the clients need it.
bool needsWakeLock = false;
- for (size_t i=0 ; i < mActiveConnections.size(); i++) {
- sp<SensorEventConnection> connection(mActiveConnections[i].promote());
+ // Make a copy of the connection vector as some connections may be removed during the
+ // course of this loop (especially when one-shot sensor events are present in the
+ // sensor_event buffer).
+ const SortedVector< wp<SensorEventConnection> > activeConnections(mActiveConnections);
+ size_t numConnections = activeConnections.size();
+ for (size_t i=0 ; i < numConnections; ++i) {
+ sp<SensorEventConnection> connection(activeConnections[i].promote());
if (connection != 0) {
- connection->sendEvents(buffer, count, scratch);
+ connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
+ mMapFlushEventsToConnections);
needsWakeLock |= connection->needsWakeLock();
- // Some sensors need to be auto disabled after the trigger
- cleanupAutoDisabledSensorLocked(connection, buffer, count);
+ // If the connection has one-shot sensors, it may be cleaned up after first trigger.
+ // Early check for one-shot sensors.
+ if (connection->hasOneShotSensors()) {
+ cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count);
+ }
}
}
@@ -481,7 +511,7 @@ bool SensorService::threadLoop()
mWakeLockAcquired = false;
ALOGD_IF(DEBUG_CONNECTIONS, "released wakelock %s", WAKE_LOCK_NAME);
}
- } while (count >= 0 || Thread::exitPending());
+ } while (!Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
abort();
@@ -823,7 +853,7 @@ status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection)
continue;
}
SensorEventConnection::FlushInfo& flushInfo = connection->mSensorInfo.editValueFor(handle);
- if (halVersion < SENSORS_DEVICE_API_VERSION_1_1 || isVirtualSensor(handle)) {
+ if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
// For older devices just increment pending flush count which will send a trivial
// flush complete event.
flushInfo.mPendingFlushEventsToSend++;
@@ -1030,6 +1060,17 @@ bool SensorService::SensorEventConnection::hasAnySensor() const {
return mSensorInfo.size() ? true : false;
}
+bool SensorService::SensorEventConnection::hasOneShotSensors() const {
+ Mutex::Autolock _l(mConnectionLock);
+ for (size_t i = 0; i < mSensorInfo.size(); ++i) {
+ const int handle = mSensorInfo.keyAt(i);
+ if (mService->getSensorFromHandle(handle).getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
+ return true;
+ }
+ }
+ return false;
+}
+
void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
bool value) {
Mutex::Autolock _l(mConnectionLock);
@@ -1042,19 +1083,14 @@ void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t* buffer, size_t numEvents,
- sensors_event_t* scratch) {
+ sensors_event_t* scratch,
+ SensorEventConnection const * const * mapFlushEventsToConnections) {
// filter out events not for this connection
size_t count = 0;
Mutex::Autolock _l(mConnectionLock);
if (scratch) {
size_t i=0;
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;
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
@@ -1073,19 +1109,13 @@ status_t SensorService::SensorEventConnection::sendEvents(
FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
// Check if there is a pending flush_complete event for this sensor on this connection.
- if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true) {
- SensorService::SensorRecord *rec = mService->getSensorRecord(sensor_handle);
- if (rec && rec->getFirstPendingFlushConnection() == this) {
- rec->removeFirstPendingFlushConnection();
- flushInfo.mFirstFlushPending = false;
- // 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);
- ++i;
- continue;
- }
+ if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
+ this == mapFlushEventsToConnections[i]) {
+ flushInfo.mFirstFlushPending = false;
+ ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
+ buffer[i].meta_data.sensor);
+ ++i;
+ continue;
}
// If there is a pending flush complete event for this sensor on this connection,
@@ -1096,27 +1126,21 @@ status_t SensorService::SensorEventConnection::sendEvents(
}
do {
- if (buffer[i].flags & SENSOR_EVENT_INVALID_FLAG) {
- ++i;
- continue;
- }
+ // Keep copying events into the scratch buffer as long as they are regular
+ // sensor_events are from the same sensor_handle OR they are flush_complete_events
+ // from the same sensor_handle AND the current connection is mapped to the
+ // corresponding flush_complete_event.
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) {
- rec->removeFirstPendingFlushConnection();
+ if (this == mapFlushEventsToConnections[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;
} else {
// Regular sensor event, just copy it to the scratch buffer.
scratch[count++] = buffer[i++];
}
- } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle) ||
+ } while ((i<numEvents) && ((buffer[i].sensor == sensor_handle &&
+ buffer[i].type != SENSOR_TYPE_META_DATA) ||
(buffer[i].type == SENSOR_TYPE_META_DATA &&
buffer[i].meta_data.sensor == sensor_handle)));
}
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 0887f28..9654f65 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -45,14 +45,6 @@
// 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;
@@ -157,9 +149,11 @@ class SensorService :
SensorEventConnection(const sp<SensorService>& service, uid_t uid);
status_t sendEvents(sensors_event_t* buffer, size_t count,
- sensors_event_t* scratch);
+ sensors_event_t* scratch,
+ SensorEventConnection const * const * mapFlushEventsToConnections = NULL);
bool hasSensor(int32_t handle) const;
bool hasAnySensor() const;
+ bool hasOneShotSensors() const;
bool addSensor(int32_t handle);
bool removeSensor(int32_t handle);
void setFirstFlushPending(int32_t handle, bool value);
@@ -237,6 +231,9 @@ class SensorService :
DefaultKeyedVector<int, SensorInterface*> mActiveVirtualSensors;
SortedVector< wp<SensorEventConnection> > mActiveConnections;
bool mWakeLockAcquired;
+ sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
+ SensorEventConnection const **mMapFlushEventsToConnections;
+
// The size of this vector is constant, only the items are mutable
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;