summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2010-07-22 21:24:39 -0700
committerMathias Agopian <mathias@google.com>2010-07-22 21:24:39 -0700
commitaea786f42cee6a899e8f78fdbf82cb1cac544430 (patch)
tree8e212eff79f6d7c77651bab907768df6b41c2562 /services
parentb54a3c95801da5464bbfcbb551545b543ca4d46c (diff)
downloadframeworks_base-aea786f42cee6a899e8f78fdbf82cb1cac544430.zip
frameworks_base-aea786f42cee6a899e8f78fdbf82cb1cac544430.tar.gz
frameworks_base-aea786f42cee6a899e8f78fdbf82cb1cac544430.tar.bz2
SensorService handles last known state properly
SensorService now correctly sends the last known state of a sensor as soon as a new connection is made. This fixes the issue where, for instance, an application could wait a long time before getting the light or proximity sensor initial state. Change-Id: Ic41392f3626e26c4f15746c7e17c7ecd44bbb10b
Diffstat (limited to 'services')
-rw-r--r--services/sensorservice/SensorService.cpp84
-rw-r--r--services/sensorservice/SensorService.h5
2 files changed, 74 insertions, 15 deletions
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index b79373d..7fcab4c 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -40,11 +40,18 @@ namespace android {
/*
* TODO:
- * - make sure to keep the last value of each event type so we can quickly
- * send something to application when they enable a sensor that is already
- * active (the issue here is that it can take time before a value is
- * produced by the h/w if the rate is low or if it's a one-shot sensor).
* - send sensor info to battery service
+ *
+
+static final int TRANSACTION_noteStartSensor = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
+static final int TRANSACTION_noteStopSensor = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
+
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(uid);
+ _data.writeInt(sensor);
+ mRemote.transact(Stub.TRANSACTION_noteStartSensor, _data, _reply, 0);
+ _reply.readException();
+ *
*/
// ---------------------------------------------------------------------------
@@ -103,8 +110,12 @@ void SensorService::onFirstRef()
LOGE_IF(err, "couldn't open device for module %s (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
+ sensors_event_t event;
+ memset(&event, 0, sizeof(event));
+
struct sensor_t const* list;
int count = mSensorModule->get_sensors_list(mSensorModule, &list);
+ mLastEventSeen.setCapacity(count);
for (int i=0 ; i<count ; i++) {
Sensor sensor(list + i);
LOGI("%s", sensor.getName().string());
@@ -112,6 +123,7 @@ void SensorService::onFirstRef()
if (mSensorDevice) {
mSensorDevice->activate(mSensorDevice, sensor.getHandle(), 0);
}
+ mLastEventSeen.add(sensor.getHandle(), event);
}
if (mSensorDevice) {
@@ -138,6 +150,19 @@ status_t SensorService::dump(int fd, const Vector<String16>& args)
result.append(buffer);
} else {
Mutex::Autolock _l(mLock);
+ snprintf(buffer, SIZE, "Sensor List:\n");
+ result.append(buffer);
+ for (size_t i=0 ; i<mSensorList.size() ; i++) {
+ const Sensor& s(mSensorList[i]);
+ const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
+ snprintf(buffer, SIZE, "%s (vendor=%s, handle=%d, last=<%5.1f,%5.1f,%5.1f>)\n",
+ s.getName().string(),
+ s.getVendor().string(),
+ s.getHandle(),
+ e.data[0], e.data[1], e.data[2]);
+ result.append(buffer);
+ }
+
snprintf(buffer, SIZE, "%d active connections\n",
mActiveConnections.size());
result.append(buffer);
@@ -178,6 +203,19 @@ bool SensorService::threadLoop()
size_t numConnections = activeConnections.size();
if (numConnections) {
Mutex::Autolock _l(mLock);
+
+ // record the last event for each sensor
+ int32_t prev = buffer[0].sensor;
+ for (ssize_t i=1 ; i<count ; i++) {
+ // record the last event of each sensor type in this buffer
+ int32_t curr = buffer[i].sensor;
+ if (curr != prev) {
+ mLastEventSeen.editValueFor(prev) = buffer[i-1];
+ prev = curr;
+ }
+ }
+ mLastEventSeen.editValueFor(prev) = buffer[count-1];
+
for (size_t i=0 ; i<numConnections ; i++) {
sp<SensorEventConnection> connection(activeConnections[i].promote());
if (connection != 0) {
@@ -258,7 +296,16 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
BatteryService::getInstance().enableSensor(handle);
}
} else {
- rec->addConnection(connection);
+ if (rec->addConnection(connection)) {
+ // this sensor is already activated, but we are adding a
+ // connection that uses it. Immediately send down the last
+ // known value of the requested sensor.
+ sensors_event_t scratch;
+ sensors_event_t& event(mLastEventSeen.editValueFor(handle));
+ if (event.version == sizeof(sensors_event_t)) {
+ connection->sendEvents(&event, 1);
+ }
+ }
}
if (err == NO_ERROR) {
// connection now active
@@ -430,18 +477,27 @@ status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t* scratch)
{
// filter out events not for this connection
- size_t count=0, i=0;
- while (i<numEvents) {
- const int32_t curr = buffer[i].sensor;
- if (mSensorInfo.indexOfKey(curr) >= 0) {
- do {
- scratch[count++] = buffer[i++];
- } while ((i<numEvents) && (buffer[i].sensor == curr));
- } else {
- i++;
+ size_t count = 0;
+ if (scratch) {
+ size_t i=0;
+ while (i<numEvents) {
+ const int32_t curr = buffer[i].sensor;
+ if (mSensorInfo.indexOfKey(curr) >= 0) {
+ do {
+ scratch[count++] = buffer[i++];
+ } while ((i<numEvents) && (buffer[i].sensor == curr));
+ } else {
+ i++;
+ }
}
+ } else {
+ scratch = const_cast<sensors_event_t *>(buffer);
+ count = numEvents;
}
+ if (count == 0)
+ return 0;
+
ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));
if (size == -EAGAIN) {
// the destination doesn't accept events anymore, it's probably
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index f77652d..9f37799 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -87,7 +87,7 @@ class SensorService :
SensorEventConnection(const sp<SensorService>& service);
status_t sendEvents(sensors_event_t const* buffer, size_t count,
- sensors_event_t* scratch);
+ sensors_event_t* scratch = NULL);
bool hasSensor(int32_t handle) const;
bool hasAnySensor() const;
bool addSensor(int32_t handle);
@@ -123,6 +123,9 @@ class SensorService :
DefaultKeyedVector<int, SensorRecord*> mActiveSensors;
SortedVector< wp<SensorEventConnection> > mActiveConnections;
+ // The size of this vector is constant, only the items are mutable
+ KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
+
public:
static char const* getServiceName() { return "sensorservice"; }