diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk index a1de3c5d8..dd698c562 100644 --- a/services/sensorservice/Android.mk +++ b/services/sensorservice/Android.mk @@ -20,6 +20,7 @@ LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\" LOCAL_SHARED_LIBRARIES := \ libcutils \ libhardware \ + libhardware_legacy \ libutils \ liblog \ libbinder \ diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp index a9e3ef4f1..b256cce35 100644 --- a/services/sensorservice/SensorDevice.cpp +++ b/services/sensorservice/SensorDevice.cpp @@ -181,6 +181,12 @@ status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns) 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 728b6cb86..b423f40da 100644 --- a/services/sensorservice/SensorDevice.h +++ b/services/sensorservice/SensorDevice.h @@ -52,6 +52,7 @@ class SensorDevice : public Singleton { 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 e3dcd0287..9ca6b457c 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -38,6 +38,7 @@ #include #include +#include #include "BatteryService.h" #include "CorrectedGyroSensor.h" @@ -60,6 +61,8 @@ namespace android { * */ +const char* SensorService::WAKE_LOCK_NAME = "SensorService"; + SensorService::SensorService() : mInitCheck(NO_INIT) { @@ -237,6 +240,18 @@ status_t SensorService::dump(int fd, const Vector& args) return NO_ERROR; } +void SensorService::cleanupAutoDisabledSensor(const sp& connection, + sensors_event_t const* buffer, const int count) { + for (int i=0 ; ihasSensor(handle)) { + cleanupWithoutDisable(connection, handle); + } + } + } +} + bool SensorService::threadLoop() { ALOGD("nuSensorService thread starting..."); @@ -249,6 +264,8 @@ bool SensorService::threadLoop() 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 @@ bool SensorService::threadLoop() 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 @@ 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 (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 > activeConnections( getActiveConnections()); @@ -307,8 +346,14 @@ bool SensorService::threadLoop() 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 @@ String8 SensorService::getSensorName(int handle) const { return result; } +int SensorService::getSensorType(int handle) const { + size_t count = mUserSensorList.size(); + for (size_t i=0 ; i SensorService::getSensorList() { char value[PROPERTY_VALUE_MAX]; @@ -433,44 +490,48 @@ status_t SensorService::enable(const sp& connection, 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 @@ status_t SensorService::disable(const sp& connection, 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& connection, + int handle) { Mutex::Autolock _l(mLock); SensorRecord* rec = mActiveSensors.valueFor(handle); if (rec) { @@ -498,10 +568,9 @@ status_t SensorService::disable(const sp& connection, 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& connection, diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h index 18591bf2b..25e5f764b 100644 --- a/services/sensorservice/SensorService.h +++ b/services/sensorservice/SensorService.h @@ -53,6 +53,7 @@ class SensorService : friend class BinderService; static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz + static const char* WAKE_LOCK_NAME; SensorService(); virtual ~SensorService(); @@ -109,10 +110,15 @@ class SensorService : DefaultKeyedVector 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& connection, + int handle); + void cleanupAutoDisabledSensor(const sp& connection, + sensors_event_t const* buffer, const int count); // constants Vector mSensorList;