am 2ea0c67d: Merge "Sensor changes." into jb-mr2-dev

* commit '2ea0c67da6770a840d871a69c61bb52d73dadf2b':
  Sensor changes.
This commit is contained in:
Jaikumar Ganesh 2013-04-12 17:25:38 -07:00 committed by Android Git Automerger
commit e4f0dc300a
5 changed files with 124 additions and 41 deletions

View File

@ -20,6 +20,7 @@ LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhardware \
libhardware_legacy \
libutils \
liblog \
libbinder \

View File

@ -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)

View File

@ -52,6 +52,7 @@ class SensorDevice : public Singleton<SensorDevice> {
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);

View File

@ -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,18 @@ 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) {
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 @@ 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<SensorEventConnection> > 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<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 @@ status_t SensorService::enable(const sp<SensorEventConnection>& 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<SensorEventConnection>& 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<SensorEventConnection>& connection,
int handle) {
Mutex::Autolock _l(mLock);
SensorRecord* rec = mActiveSensors.valueFor(handle);
if (rec) {
@ -498,10 +568,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,

View File

@ -53,6 +53,7 @@ class SensorService :
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 @@ class SensorService :
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;