Merge "Sensor changes." into jb-mr2-dev
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
index a1de3c5..dd698c5 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -20,6 +20,7 @@
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhardware \
+ libhardware_legacy \
libutils \
liblog \
libbinder \
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index a9e3ef4..b256cce 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -181,6 +181,12 @@
return mSensorDevice->setDelay(mSensorDevice, handle, ns);
}
+int SensorDevice::getHalDeviceVersion() const {
+ if (!mSensorDevice) return -1;
+
+ return mSensorDevice->common.version;
+}
+
// ---------------------------------------------------------------------------
status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns)
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 728b6cb..b423f40 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -52,6 +52,7 @@
public:
ssize_t getSensorList(sensor_t const** list);
status_t initCheck() const;
+ int getHalDeviceVersion() const;
ssize_t poll(sensors_event_t* buffer, size_t count);
status_t activate(void* ident, int handle, int enabled);
status_t setDelay(void* ident, int handle, int64_t ns);
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index e3dcd02..9ca6b45 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -38,6 +38,7 @@
#include <gui/SensorEventQueue.h>
#include <hardware/sensors.h>
+#include <hardware_legacy/power.h>
#include "BatteryService.h"
#include "CorrectedGyroSensor.h"
@@ -60,6 +61,8 @@
*
*/
+const char* SensorService::WAKE_LOCK_NAME = "SensorService";
+
SensorService::SensorService()
: mInitCheck(NO_INIT)
{
@@ -237,6 +240,18 @@
return NO_ERROR;
}
+void SensorService::cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
+ sensors_event_t const* buffer, const int count) {
+ for (int i=0 ; i<count ; i++) {
+ int handle = buffer[i].sensor;
+ if (getSensorType(handle) == SENSOR_TYPE_SIGNIFICANT_MOTION) {
+ if (connection->hasSensor(handle)) {
+ cleanupWithoutDisable(connection, handle);
+ }
+ }
+ }
+}
+
bool SensorService::threadLoop()
{
ALOGD("nuSensorService thread starting...");
@@ -249,6 +264,8 @@
const size_t vcount = mVirtualSensorList.size();
ssize_t count;
+ bool wakeLockAcquired = false;
+ const int halVersion = device.getHalDeviceVersion();
do {
count = device.poll(buffer, numEventMax);
if (count<0) {
@@ -256,6 +273,17 @@
break;
}
+ // Poll has returned. Hold a wakelock.
+ // Todo(): add a flag to the sensors definitions to indicate
+ // the sensors which can wake up the AP
+ for (int i = 0; i < count; i++) {
+ if (getSensorType(buffer[i].sensor) == SENSOR_TYPE_SIGNIFICANT_MOTION) {
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
+ wakeLockAcquired = true;
+ break;
+ }
+ }
+
recordLastValue(buffer, count);
// handle virtual sensors
@@ -298,6 +326,17 @@
}
}
+ // handle backward compatibility for RotationVector sensor
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {
+ for (int i = 0; i < count; i++) {
+ if (getSensorType(buffer[i].sensor) == 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;
+ }
+ }
+ }
+
// send our events to clients...
const SortedVector< wp<SensorEventConnection> > activeConnections(
getActiveConnections());
@@ -307,8 +346,14 @@
activeConnections[i].promote());
if (connection != 0) {
connection->sendEvents(buffer, count, scratch);
+ // Some sensors need to be auto disabled after the trigger
+ cleanupAutoDisabledSensor(connection, buffer, count);
}
}
+
+ // We have read the data, upper layers should hold the wakelock.
+ if (wakeLockAcquired) release_wake_lock(WAKE_LOCK_NAME);
+
} while (count >= 0 || Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
@@ -372,6 +417,18 @@
return result;
}
+int SensorService::getSensorType(int handle) const {
+ size_t count = mUserSensorList.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const Sensor& sensor(mUserSensorList[i]);
+ if (sensor.getHandle() == handle) {
+ return sensor.getType();
+ }
+ }
+ return -1;
+}
+
+
Vector<Sensor> SensorService::getSensorList()
{
char value[PROPERTY_VALUE_MAX];
@@ -433,44 +490,48 @@
Mutex::Autolock _l(mLock);
SensorInterface* sensor = mSensorMap.valueFor(handle);
+ SensorRecord* rec = mActiveSensors.valueFor(handle);
+ if (rec == 0) {
+ rec = new SensorRecord(connection);
+ mActiveSensors.add(handle, rec);
+ if (sensor->isVirtual()) {
+ mActiveVirtualSensors.add(handle, sensor);
+ }
+ } else {
+ 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 if it's not a
+ // "continuous" sensor.
+ if (sensor->getSensor().getMinDelay() == 0) {
+ sensors_event_t scratch;
+ sensors_event_t& event(mLastEventSeen.editValueFor(handle));
+ if (event.version == sizeof(sensors_event_t)) {
+ connection->sendEvents(&event, 1);
+ }
+ }
+ }
+ }
+
+ if (connection->addSensor(handle)) {
+ BatteryService::enableSensor(connection->getUid(), handle);
+ // the sensor was added (which means it wasn't already there)
+ // so, see if this connection becomes active
+ if (mActiveConnections.indexOf(connection) < 0) {
+ mActiveConnections.add(connection);
+ }
+ } else {
+ ALOGW("sensor %08x already enabled in connection %p (ignoring)",
+ handle, connection.get());
+ }
+
+
+ // we are setup, now enable the sensor.
status_t err = sensor ? sensor->activate(connection.get(), true) : status_t(BAD_VALUE);
- if (err == NO_ERROR) {
- SensorRecord* rec = mActiveSensors.valueFor(handle);
- if (rec == 0) {
- rec = new SensorRecord(connection);
- mActiveSensors.add(handle, rec);
- if (sensor->isVirtual()) {
- mActiveVirtualSensors.add(handle, sensor);
- }
- } else {
- 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 if it's not a
- // "continuous" sensor.
- if (sensor->getSensor().getMinDelay() == 0) {
- 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
- if (connection->addSensor(handle)) {
- BatteryService::enableSensor(connection->getUid(), handle);
- // the sensor was added (which means it wasn't already there)
- // so, see if this connection becomes active
- if (mActiveConnections.indexOf(connection) < 0) {
- mActiveConnections.add(connection);
- }
- } else {
- ALOGW("sensor %08x already enabled in connection %p (ignoring)",
- handle, connection.get());
- }
- }
+
+ if (err != NO_ERROR) {
+ // enable has failed, reset our state.
+ cleanupWithoutDisable(connection, handle);
}
return err;
}
@@ -481,7 +542,16 @@
if (mInitCheck != NO_ERROR)
return mInitCheck;
- status_t err = NO_ERROR;
+ status_t err = cleanupWithoutDisable(connection, handle);
+ if (err == NO_ERROR) {
+ SensorInterface* sensor = mSensorMap.valueFor(handle);
+ err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
+ }
+ return err;
+}
+
+status_t SensorService::cleanupWithoutDisable(const sp<SensorEventConnection>& connection,
+ int handle) {
Mutex::Autolock _l(mLock);
SensorRecord* rec = mActiveSensors.valueFor(handle);
if (rec) {
@@ -498,10 +568,9 @@
mActiveVirtualSensors.removeItem(handle);
delete rec;
}
- SensorInterface* sensor = mSensorMap.valueFor(handle);
- err = sensor ? sensor->activate(connection.get(), false) : status_t(BAD_VALUE);
+ return NO_ERROR;
}
- return err;
+ return BAD_VALUE;
}
status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection,
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 18591bf..25e5f76 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -53,6 +53,7 @@
friend class BinderService<SensorService>;
static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz
+ static const char* WAKE_LOCK_NAME;
SensorService();
virtual ~SensorService();
@@ -109,10 +110,15 @@
DefaultKeyedVector<int, SensorInterface*> getActiveVirtualSensors() const;
String8 getSensorName(int handle) const;
+ int getSensorType(int handle) const;
void recordLastValue(sensors_event_t const * buffer, size_t count);
static void sortEventBuffer(sensors_event_t* buffer, size_t count);
void registerSensor(SensorInterface* sensor);
void registerVirtualSensor(SensorInterface* sensor);
+ status_t cleanupWithoutDisable(const sp<SensorEventConnection>& connection,
+ int handle);
+ void cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
+ sensors_event_t const* buffer, const int count);
// constants
Vector<Sensor> mSensorList;