diff options
Diffstat (limited to 'services/sensorservice/SensorService.cpp')
-rw-r--r-- | services/sensorservice/SensorService.cpp | 161 |
1 files changed, 122 insertions, 39 deletions
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index e3dcd02..6481584 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 @@ namespace android { * */ +const char* SensorService::WAKE_LOCK_NAME = "SensorService"; + SensorService::SensorService() : mInitCheck(NO_INIT) { @@ -237,6 +240,24 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) return NO_ERROR; } +void SensorService::cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection, + sensors_event_t const* buffer, const int count) { + SensorInterface* sensor; + status_t err = NO_ERROR; + for (int i=0 ; i<count ; i++) { + int handle = buffer[i].sensor; + if (getSensorType(handle) == SENSOR_TYPE_SIGNIFICANT_MOTION) { + if (connection->hasSensor(handle)) { + sensor = mSensorMap.valueFor(handle); + if (sensor != NULL) { + sensor->autoDisable(connection.get(), handle); + } + cleanupWithoutDisable(connection, handle); + } + } + } +} + bool SensorService::threadLoop() { ALOGD("nuSensorService thread starting..."); @@ -249,6 +270,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 +279,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 +332,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<SensorEventConnection> > activeConnections( getActiveConnections()); @@ -307,8 +352,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 +423,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<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]; @@ -431,47 +494,53 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, if (mInitCheck != NO_ERROR) return mInitCheck; - Mutex::Autolock _l(mLock); SensorInterface* sensor = mSensorMap.valueFor(handle); - 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 (sensor == NULL) { + return BAD_VALUE; + } + + Mutex::Autolock _l(mLock); + SensorRecord* rec = mActiveSensors.valueFor(handle); + if (rec == 0) { + rec = new SensorRecord(connection); + mActiveSensors.add(handle, rec); + if (sensor->isVirtual()) { + mActiveVirtualSensors.add(handle, sensor); } - 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 { + 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); } - } else { - ALOGW("sensor %08x already enabled in connection %p (ignoring)", - handle, connection.get()); } } } + + 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->activate(connection.get(), true); + if (err != NO_ERROR) { + // enable has failed, reset our state. + cleanupWithoutDisableLocked(connection, handle); + } return err; } @@ -481,8 +550,23 @@ status_t SensorService::disable(const sp<SensorEventConnection>& connection, if (mInitCheck != NO_ERROR) return mInitCheck; - status_t err = NO_ERROR; Mutex::Autolock _l(mLock); + status_t err = cleanupWithoutDisableLocked(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); + return cleanupWithoutDisableLocked(connection, handle); +} + +status_t SensorService::cleanupWithoutDisableLocked( + const sp<SensorEventConnection>& connection, int handle) { SensorRecord* rec = mActiveSensors.valueFor(handle); if (rec) { // see if this connection becomes inactive @@ -498,10 +582,9 @@ status_t SensorService::disable(const sp<SensorEventConnection>& 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<SensorEventConnection>& connection, |