Sensor changes.
1. Some sensors can wake up the AP. Add wakelocks. 2. Handle backward compatibility for rotation vector heading accuracy. 3. Cleanup auto disabled sensors. 4. Fix race condition between enable and dispatch. Change-Id: I39dddf12e208d83cd288201986ee994312555820
This commit is contained in:
parent
53dc9044bf
commit
4342fdf14f
@ -20,6 +20,7 @@ LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcutils \
|
||||
libhardware \
|
||||
libhardware_legacy \
|
||||
libutils \
|
||||
liblog \
|
||||
libbinder \
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user