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
This commit is contained in:
parent
cf51001dbf
commit
3560fb24b6
@ -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,7 +477,9 @@ status_t SensorService::SensorEventConnection::sendEvents(
|
||||
sensors_event_t* scratch)
|
||||
{
|
||||
// filter out events not for this connection
|
||||
size_t count=0, i=0;
|
||||
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) {
|
||||
@ -441,6 +490,13 @@ status_t SensorService::SensorEventConnection::sendEvents(
|
||||
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) {
|
||||
|
@ -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"; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user