summaryrefslogtreecommitdiffstats
path: root/services/sensorservice
diff options
context:
space:
mode:
Diffstat (limited to 'services/sensorservice')
-rw-r--r--services/sensorservice/Android.mk25
-rw-r--r--services/sensorservice/BatteryService.cpp2
-rw-r--r--services/sensorservice/CorrectedGyroSensor.cpp10
-rw-r--r--services/sensorservice/Fusion.cpp16
-rw-r--r--services/sensorservice/GravitySensor.cpp6
-rw-r--r--services/sensorservice/LinearAccelerationSensor.cpp6
-rw-r--r--services/sensorservice/OrientationSensor.cpp9
-rw-r--r--services/sensorservice/RotationVectorSensor.cpp12
-rw-r--r--services/sensorservice/SensorDevice.cpp276
-rw-r--r--services/sensorservice/SensorDevice.h54
-rw-r--r--services/sensorservice/SensorFusion.cpp41
-rw-r--r--services/sensorservice/SensorFusion.h7
-rw-r--r--services/sensorservice/SensorInterface.cpp12
-rw-r--r--services/sensorservice/SensorInterface.h17
-rw-r--r--services/sensorservice/SensorService.cpp398
-rw-r--r--services/sensorservice/SensorService.h52
-rw-r--r--services/sensorservice/main_sensorservice.cpp25
17 files changed, 713 insertions, 255 deletions
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
index dd698c5..4f24ddc 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -12,11 +12,12 @@ LOCAL_SRC_FILES:= \
SensorDevice.cpp \
SensorFusion.cpp \
SensorInterface.cpp \
- SensorService.cpp \
-
+ SensorService.cpp
LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
+LOCAL_CFLAGS += -fvisibility=hidden
+
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhardware \
@@ -27,8 +28,24 @@ LOCAL_SHARED_LIBRARIES := \
libui \
libgui
-
-
LOCAL_MODULE:= libsensorservice
include $(BUILD_SHARED_LIBRARY)
+
+#####################################################################
+# build executable
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ main_sensorservice.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libsensorservice \
+ libbinder \
+ libutils
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE:= sensorservice
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/sensorservice/BatteryService.cpp b/services/sensorservice/BatteryService.cpp
index 70b65ab..38dc749 100644
--- a/services/sensorservice/BatteryService.cpp
+++ b/services/sensorservice/BatteryService.cpp
@@ -33,7 +33,7 @@ namespace android {
BatteryService::BatteryService() {
const sp<IServiceManager> sm(defaultServiceManager());
if (sm != NULL) {
- const String16 name("batteryinfo");
+ const String16 name("batterystats");
mBatteryStatService = sm->getService(name);
}
}
diff --git a/services/sensorservice/CorrectedGyroSensor.cpp b/services/sensorservice/CorrectedGyroSensor.cpp
index 1857443..31487a7 100644
--- a/services/sensorservice/CorrectedGyroSensor.cpp
+++ b/services/sensorservice/CorrectedGyroSensor.cpp
@@ -57,19 +57,19 @@ bool CorrectedGyroSensor::process(sensors_event_t* outEvent,
}
status_t CorrectedGyroSensor::activate(void* ident, bool enabled) {
- mSensorDevice.activate(this, mGyro.getHandle(), enabled);
- return mSensorFusion.activate(this, enabled);
+ mSensorDevice.activate(ident, mGyro.getHandle(), enabled);
+ return mSensorFusion.activate(ident, enabled);
}
status_t CorrectedGyroSensor::setDelay(void* ident, int handle, int64_t ns) {
- mSensorDevice.setDelay(this, mGyro.getHandle(), ns);
- return mSensorFusion.setDelay(this, ns);
+ mSensorDevice.setDelay(ident, mGyro.getHandle(), ns);
+ return mSensorFusion.setDelay(ident, ns);
}
Sensor CorrectedGyroSensor::getSensor() const {
sensor_t hwSensor;
hwSensor.name = "Corrected Gyroscope Sensor";
- hwSensor.vendor = "Google Inc.";
+ hwSensor.vendor = "AOSP";
hwSensor.version = 1;
hwSensor.handle = '_cgy';
hwSensor.type = SENSOR_TYPE_GYROSCOPE;
diff --git a/services/sensorservice/Fusion.cpp b/services/sensorservice/Fusion.cpp
index 93d6127..4f63c31 100644
--- a/services/sensorservice/Fusion.cpp
+++ b/services/sensorservice/Fusion.cpp
@@ -220,22 +220,6 @@ void Fusion::initFusion(const vec4_t& q, float dT)
// initial covariance: Var{ x(t0) }
// TODO: initialize P correctly
P = 0;
-
- // it is unclear how to set the initial covariance. It does affect
- // how quickly the fusion converges. Experimentally it would take
- // about 10 seconds at 200 Hz to estimate the gyro-drift with an
- // initial covariance of 0, and about a second with an initial covariance
- // of about 1 deg/s.
- const float covv = 0;
- const float covu = 0.5f * (float(M_PI) / 180);
- mat33_t& Pv = P[0][0];
- Pv[0][0] = covv;
- Pv[1][1] = covv;
- Pv[2][2] = covv;
- mat33_t& Pu = P[1][1];
- Pu[0][0] = covu;
- Pu[1][1] = covu;
- Pu[2][2] = covu;
}
bool Fusion::hasEstimate() const {
diff --git a/services/sensorservice/GravitySensor.cpp b/services/sensorservice/GravitySensor.cpp
index c57715f..dd1f650 100644
--- a/services/sensorservice/GravitySensor.cpp
+++ b/services/sensorservice/GravitySensor.cpp
@@ -67,17 +67,17 @@ bool GravitySensor::process(sensors_event_t* outEvent,
}
status_t GravitySensor::activate(void* ident, bool enabled) {
- return mSensorFusion.activate(this, enabled);
+ return mSensorFusion.activate(ident, enabled);
}
status_t GravitySensor::setDelay(void* ident, int handle, int64_t ns) {
- return mSensorFusion.setDelay(this, ns);
+ return mSensorFusion.setDelay(ident, ns);
}
Sensor GravitySensor::getSensor() const {
sensor_t hwSensor;
hwSensor.name = "Gravity Sensor";
- hwSensor.vendor = "Google Inc.";
+ hwSensor.vendor = "AOSP";
hwSensor.version = 3;
hwSensor.handle = '_grv';
hwSensor.type = SENSOR_TYPE_GRAVITY;
diff --git a/services/sensorservice/LinearAccelerationSensor.cpp b/services/sensorservice/LinearAccelerationSensor.cpp
index f0054f2..d5f20d2 100644
--- a/services/sensorservice/LinearAccelerationSensor.cpp
+++ b/services/sensorservice/LinearAccelerationSensor.cpp
@@ -51,18 +51,18 @@ bool LinearAccelerationSensor::process(sensors_event_t* outEvent,
}
status_t LinearAccelerationSensor::activate(void* ident, bool enabled) {
- return mGravitySensor.activate(this, enabled);
+ return mGravitySensor.activate(ident, enabled);
}
status_t LinearAccelerationSensor::setDelay(void* ident, int handle, int64_t ns) {
- return mGravitySensor.setDelay(this, handle, ns);
+ return mGravitySensor.setDelay(ident, handle, ns);
}
Sensor LinearAccelerationSensor::getSensor() const {
Sensor gsensor(mGravitySensor.getSensor());
sensor_t hwSensor;
hwSensor.name = "Linear Acceleration Sensor";
- hwSensor.vendor = "Google Inc.";
+ hwSensor.vendor = "AOSP";
hwSensor.version = gsensor.getVersion();
hwSensor.handle = '_lin';
hwSensor.type = SENSOR_TYPE_LINEAR_ACCELERATION;
diff --git a/services/sensorservice/OrientationSensor.cpp b/services/sensorservice/OrientationSensor.cpp
index 037adaa..10b391c 100644
--- a/services/sensorservice/OrientationSensor.cpp
+++ b/services/sensorservice/OrientationSensor.cpp
@@ -33,6 +33,9 @@ OrientationSensor::OrientationSensor()
: mSensorDevice(SensorDevice::getInstance()),
mSensorFusion(SensorFusion::getInstance())
{
+ // FIXME: instead of using the SensorFusion code, we should use
+ // the SENSOR_TYPE_ROTATION_VECTOR instead. This way we could use the
+ // HAL's implementation.
}
bool OrientationSensor::process(sensors_event_t* outEvent,
@@ -63,17 +66,17 @@ bool OrientationSensor::process(sensors_event_t* outEvent,
}
status_t OrientationSensor::activate(void* ident, bool enabled) {
- return mSensorFusion.activate(this, enabled);
+ return mSensorFusion.activate(ident, enabled);
}
status_t OrientationSensor::setDelay(void* ident, int handle, int64_t ns) {
- return mSensorFusion.setDelay(this, ns);
+ return mSensorFusion.setDelay(ident, ns);
}
Sensor OrientationSensor::getSensor() const {
sensor_t hwSensor;
hwSensor.name = "Orientation Sensor";
- hwSensor.vendor = "Google Inc.";
+ hwSensor.vendor = "AOSP";
hwSensor.version = 1;
hwSensor.handle = '_ypr';
hwSensor.type = SENSOR_TYPE_ORIENTATION;
diff --git a/services/sensorservice/RotationVectorSensor.cpp b/services/sensorservice/RotationVectorSensor.cpp
index 5ea9568..a2157b4 100644
--- a/services/sensorservice/RotationVectorSensor.cpp
+++ b/services/sensorservice/RotationVectorSensor.cpp
@@ -53,17 +53,17 @@ bool RotationVectorSensor::process(sensors_event_t* outEvent,
}
status_t RotationVectorSensor::activate(void* ident, bool enabled) {
- return mSensorFusion.activate(this, enabled);
+ return mSensorFusion.activate(ident, enabled);
}
status_t RotationVectorSensor::setDelay(void* ident, int handle, int64_t ns) {
- return mSensorFusion.setDelay(this, ns);
+ return mSensorFusion.setDelay(ident, ns);
}
Sensor RotationVectorSensor::getSensor() const {
sensor_t hwSensor;
hwSensor.name = "Rotation Vector Sensor";
- hwSensor.vendor = "Google Inc.";
+ hwSensor.vendor = "AOSP";
hwSensor.version = 3;
hwSensor.handle = '_rov';
hwSensor.type = SENSOR_TYPE_ROTATION_VECTOR;
@@ -102,17 +102,17 @@ bool GyroDriftSensor::process(sensors_event_t* outEvent,
}
status_t GyroDriftSensor::activate(void* ident, bool enabled) {
- return mSensorFusion.activate(this, enabled);
+ return mSensorFusion.activate(ident, enabled);
}
status_t GyroDriftSensor::setDelay(void* ident, int handle, int64_t ns) {
- return mSensorFusion.setDelay(this, ns);
+ return mSensorFusion.setDelay(ident, ns);
}
Sensor GyroDriftSensor::getSensor() const {
sensor_t hwSensor;
hwSensor.name = "Gyroscope Bias (debug)";
- hwSensor.vendor = "Google Inc.";
+ hwSensor.vendor = "AOSP";
hwSensor.version = 1;
hwSensor.handle = '_gbs';
hwSensor.type = SENSOR_TYPE_ACCELEROMETER;
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index a12529e..19caa5c 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -47,7 +47,7 @@ SensorDevice::SensorDevice()
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
if (mSensorModule) {
- err = sensors_open(&mSensorModule->common, &mSensorDevice);
+ err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
ALOGE_IF(err, "couldn't open device for module %s (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
@@ -59,36 +59,42 @@ SensorDevice::SensorDevice()
Info model;
for (size_t i=0 ; i<size_t(count) ; i++) {
mActivationCount.add(list[i].handle, model);
- mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
+ mSensorDevice->activate(
+ reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
+ list[i].handle, 0);
}
}
}
}
-void SensorDevice::dump(String8& result, char* buffer, size_t SIZE)
+void SensorDevice::dump(String8& result)
{
if (!mSensorModule) return;
sensor_t const* list;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
- snprintf(buffer, SIZE, "%d h/w sensors:\n", int(count));
- result.append(buffer);
+ result.appendFormat("%d h/w sensors:\n", int(count));
Mutex::Autolock _l(mLock);
for (size_t i=0 ; i<size_t(count) ; i++) {
const Info& info = mActivationCount.valueFor(list[i].handle);
- snprintf(buffer, SIZE, "handle=0x%08x, active-count=%d, rates(ms)={ ",
- list[i].handle,
- info.rates.size());
- result.append(buffer);
- for (size_t j=0 ; j<info.rates.size() ; j++) {
- snprintf(buffer, SIZE, "%4.1f%s",
- info.rates.valueAt(j) / 1e6f,
- j<info.rates.size()-1 ? ", " : "");
- result.append(buffer);
+ result.appendFormat("handle=0x%08x, active-count=%d, batch_period(ms)={ ", list[i].handle,
+ info.batchParams.size());
+ for (size_t j = 0; j < info.batchParams.size(); j++) {
+ BatchParams params = info.batchParams.valueAt(j);
+ result.appendFormat("%4.1f%s", params.batchDelay / 1e6f,
+ j < info.batchParams.size() - 1 ? ", " : "");
}
- snprintf(buffer, SIZE, " }, selected=%4.1f ms\n", info.delay / 1e6f);
- result.append(buffer);
+ result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchDelay / 1e6f);
+
+ result.appendFormat("handle=0x%08x, active-count=%d, batch_timeout(ms)={ ", list[i].handle,
+ info.batchParams.size());
+ for (size_t j = 0; j < info.batchParams.size(); j++) {
+ BatchParams params = info.batchParams.valueAt(j);
+ result.appendFormat("%4.1f%s", params.batchTimeout / 1e6f,
+ j < info.batchParams.size() - 1 ? ", " : "");
+ }
+ result.appendFormat(" }, selected=%4.1f ms\n", info.bestBatchParams.batchTimeout / 1e6f);
}
}
@@ -106,7 +112,8 @@ ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
if (!mSensorDevice) return NO_INIT;
ssize_t c;
do {
- c = mSensorDevice->poll(mSensorDevice, buffer, count);
+ c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice),
+ buffer, count);
} while (c == -EINTR);
return c;
}
@@ -114,7 +121,7 @@ ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
void SensorDevice::autoDisable(void *ident, int handle) {
Info& info( mActivationCount.editValueFor(handle) );
Mutex::Autolock _l(mLock);
- info.rates.removeItem(ident);
+ info.removeBatchParamsForIdent(ident);
}
status_t SensorDevice::activate(void* ident, int handle, int enabled)
@@ -123,35 +130,46 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
status_t err(NO_ERROR);
bool actuateHardware = false;
+ Mutex::Autolock _l(mLock);
Info& info( mActivationCount.editValueFor(handle) );
-
ALOGD_IF(DEBUG_CONNECTIONS,
- "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
- ident, handle, enabled, info.rates.size());
+ "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
+ ident, handle, enabled, info.batchParams.size());
if (enabled) {
- Mutex::Autolock _l(mLock);
- ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
- info.rates.indexOfKey(ident));
+ ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%d", info.batchParams.indexOfKey(ident));
- if (info.rates.indexOfKey(ident) < 0) {
- info.rates.add(ident, DEFAULT_EVENTS_PERIOD);
- if (info.rates.size() == 1) {
- actuateHardware = true;
- }
+ if (info.batchParams.indexOfKey(ident) >= 0) {
+ if (info.batchParams.size() == 1) {
+ // This is the first connection, we need to activate the underlying h/w sensor.
+ actuateHardware = true;
+ }
} else {
- // sensor was already activated for this ident
+ // Log error. Every activate call should be preceded by a batch() call.
+ ALOGE("\t >>>ERROR: activate called without batch");
}
} else {
- Mutex::Autolock _l(mLock);
- ALOGD_IF(DEBUG_CONNECTIONS, "... index=%ld",
- info.rates.indexOfKey(ident));
+ ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%d", info.batchParams.indexOfKey(ident));
- ssize_t idx = info.rates.removeItem(ident);
- if (idx >= 0) {
- if (info.rates.size() == 0) {
+ if (info.removeBatchParamsForIdent(ident) >= 0) {
+ if (info.batchParams.size() == 0) {
+ // This is the last connection, we need to de-activate the underlying h/w sensor.
actuateHardware = true;
+ } else {
+ const int halVersion = getHalDeviceVersion();
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
+ // Call batch for this sensor with the previously calculated best effort
+ // batch_rate and timeout. One of the apps has unregistered for sensor
+ // events, and the best effort batch parameters might have changed.
+ ALOGD_IF(DEBUG_CONNECTIONS,
+ "\t>>> actuating h/w batch %d %d %lld %lld ", handle,
+ info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout);
+ mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
+ info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout);
+ }
}
} else {
// sensor wasn't enabled for this ident
@@ -159,41 +177,130 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
}
if (actuateHardware) {
- ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle, enabled);
+ err = mSensorDevice->activate(
+ reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), handle, enabled);
+ ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
+ strerror(-err));
+
+ if (err != NO_ERROR && enabled) {
+ // Failure when enabling the sensor. Clean up on failure.
+ info.removeBatchParamsForIdent(ident);
+ }
+ }
- err = mSensorDevice->activate(mSensorDevice, handle, enabled);
- ALOGE_IF(err, "Error %s sensor %d (%s)",
- enabled ? "activating" : "disabling",
- handle, strerror(-err));
+ // On older devices which do not support batch, call setDelay().
+ if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.batchParams.size() > 0) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %lld ", handle,
+ info.bestBatchParams.batchDelay);
+ mSensorDevice->setDelay(
+ reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
+ handle, info.bestBatchParams.batchDelay);
+ }
+ return err;
+}
- if (err != NO_ERROR) {
- // clean-up on failure
- if (enabled) {
- // failure when enabling the sensor
- Mutex::Autolock _l(mLock);
- info.rates.removeItem(ident);
+status_t SensorDevice::batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs) {
+ if (!mSensorDevice) return NO_INIT;
+
+ if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
+ samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
+ }
+
+ const int halVersion = getHalDeviceVersion();
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
+ if (flags & SENSORS_BATCH_DRY_RUN) {
+ return mSensorDevice->batch(mSensorDevice, handle, flags, samplingPeriodNs,
+ maxBatchReportLatencyNs);
+ } else {
+ // Call h/w with dry run to see if the given parameters are feasible or not. Return if
+ // there is an error.
+ status_t errDryRun(NO_ERROR);
+ errDryRun = mSensorDevice->batch(mSensorDevice, handle, flags | SENSORS_BATCH_DRY_RUN,
+ samplingPeriodNs, maxBatchReportLatencyNs);
+ if (errDryRun != NO_ERROR) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "SensorDevice::batch dry run error %s",
+ strerror(-errDryRun));
+ return errDryRun;
}
}
+ } else if (maxBatchReportLatencyNs != 0) {
+ // Batch is not supported on older devices.
+ return INVALID_OPERATION;
}
- { // scope for the lock
- Mutex::Autolock _l(mLock);
- nsecs_t ns = info.selectDelay();
- mSensorDevice->setDelay(mSensorDevice, handle, ns);
+ ALOGD_IF(DEBUG_CONNECTIONS,
+ "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%lld timeout=%lld",
+ ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
+
+ Mutex::Autolock _l(mLock);
+ Info& info(mActivationCount.editValueFor(handle));
+
+ if (info.batchParams.indexOfKey(ident) < 0) {
+ BatchParams params(flags, samplingPeriodNs, maxBatchReportLatencyNs);
+ info.batchParams.add(ident, params);
+ } else {
+ // A batch has already been called with this ident. Update the batch parameters.
+ info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
}
+ BatchParams prevBestBatchParams = info.bestBatchParams;
+ // Find the minimum of all timeouts and batch_rates for this sensor.
+ info.selectBatchParams();
+
+ ALOGD_IF(DEBUG_CONNECTIONS,
+ "\t>>> curr_period=%lld min_period=%lld curr_timeout=%lld min_timeout=%lld",
+ prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
+ prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
+
+ status_t err(NO_ERROR);
+ // If the min period or min timeout has changed since the last batch call, call batch.
+ if (prevBestBatchParams != info.bestBatchParams) {
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %lld %lld ", handle,
+ info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout);
+ err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
+ info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout);
+ } else {
+ // For older devices which do not support batch, call setDelay() after activate() is
+ // called. Some older devices may not support calling setDelay before activate(), so
+ // call setDelay in SensorDevice::activate() method.
+ }
+ if (err != NO_ERROR) {
+ ALOGE("sensor batch failed %p %d %d %lld %lld err=%s", mSensorDevice, handle,
+ info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
+ info.bestBatchParams.batchTimeout, strerror(-err));
+ info.removeBatchParamsForIdent(ident);
+ }
+ }
return err;
}
-status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns)
+status_t SensorDevice::setDelay(void* ident, int handle, int64_t samplingPeriodNs)
{
if (!mSensorDevice) return NO_INIT;
+ if (samplingPeriodNs < MINIMUM_EVENTS_PERIOD) {
+ samplingPeriodNs = MINIMUM_EVENTS_PERIOD;
+ }
Mutex::Autolock _l(mLock);
Info& info( mActivationCount.editValueFor(handle) );
- status_t err = info.setDelayForIdent(ident, ns);
- if (err < 0) return err;
- ns = info.selectDelay();
- return mSensorDevice->setDelay(mSensorDevice, handle, ns);
+ // If the underlying sensor is NOT in continuous mode, setDelay() should return an error.
+ // Calling setDelay() in batch mode is an invalid operation.
+ if (info.bestBatchParams.batchTimeout != 0) {
+ return INVALID_OPERATION;
+ }
+ ssize_t index = info.batchParams.indexOfKey(ident);
+ if (index < 0) {
+ return BAD_INDEX;
+ }
+ BatchParams& params = info.batchParams.editValueAt(index);
+ params.batchDelay = samplingPeriodNs;
+ info.selectBatchParams();
+ return mSensorDevice->setDelay(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
+ handle, info.bestBatchParams.batchDelay);
}
int SensorDevice::getHalDeviceVersion() const {
@@ -202,31 +309,58 @@ int SensorDevice::getHalDeviceVersion() const {
return mSensorDevice->common.version;
}
+status_t SensorDevice::flush(void* ident, int handle) {
+ if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1) {
+ return INVALID_OPERATION;
+ }
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w flush %d", handle);
+ return mSensorDevice->flush(mSensorDevice, handle);
+}
+
// ---------------------------------------------------------------------------
-status_t SensorDevice::Info::setDelayForIdent(void* ident, int64_t ns)
-{
- ssize_t index = rates.indexOfKey(ident);
+status_t SensorDevice::Info::setBatchParamsForIdent(void* ident, int flags,
+ int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs) {
+ ssize_t index = batchParams.indexOfKey(ident);
if (index < 0) {
- ALOGE("Info::setDelayForIdent(ident=%p, ns=%lld) failed (%s)",
- ident, ns, strerror(-index));
+ ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%lld timeout=%lld) failed (%s)",
+ ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
return BAD_INDEX;
}
- rates.editValueAt(index) = ns;
+ BatchParams& params = batchParams.editValueAt(index);
+ params.flags = flags;
+ params.batchDelay = samplingPeriodNs;
+ params.batchTimeout = maxBatchReportLatencyNs;
return NO_ERROR;
}
-nsecs_t SensorDevice::Info::selectDelay()
-{
- nsecs_t ns = rates.valueAt(0);
- for (size_t i=1 ; i<rates.size() ; i++) {
- nsecs_t cur = rates.valueAt(i);
- if (cur < ns) {
- ns = cur;
+void SensorDevice::Info::selectBatchParams() {
+ BatchParams bestParams(-1, -1, -1);
+
+ if (batchParams.size() > 0) {
+ BatchParams params = batchParams.valueAt(0);
+ bestParams = params;
+ }
+
+ for (size_t i = 1; i < batchParams.size(); ++i) {
+ BatchParams params = batchParams.valueAt(i);
+ if (params.batchDelay < bestParams.batchDelay) {
+ bestParams.batchDelay = params.batchDelay;
+ }
+ if (params.batchTimeout < bestParams.batchTimeout) {
+ bestParams.batchTimeout = params.batchTimeout;
}
}
- delay = ns;
- return ns;
+ bestBatchParams = bestParams;
+}
+
+ssize_t SensorDevice::Info::removeBatchParamsForIdent(void* ident) {
+ ssize_t idx = batchParams.removeItem(ident);
+ if (idx >= 0) {
+ selectBatchParams();
+ }
+ return idx;
}
// ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 227dab6..761b48c 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -31,20 +31,50 @@
namespace android {
// ---------------------------------------------------------------------------
-static const nsecs_t DEFAULT_EVENTS_PERIOD = 200000000; // 5 Hz
-
class SensorDevice : public Singleton<SensorDevice> {
friend class Singleton<SensorDevice>;
- struct sensors_poll_device_t* mSensorDevice;
+ sensors_poll_device_1_t* mSensorDevice;
struct sensors_module_t* mSensorModule;
- mutable Mutex mLock; // protect mActivationCount[].rates
+ static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz
+ mutable Mutex mLock; // protect mActivationCount[].batchParams
// fixed-size array after construction
+
+ // Struct to store all the parameters(samplingPeriod, maxBatchReportLatency and flags) from
+ // batch call. For continous mode clients, maxBatchReportLatency is set to zero.
+ struct BatchParams {
+ int flags;
+ nsecs_t batchDelay, batchTimeout;
+ BatchParams() : flags(0), batchDelay(0), batchTimeout(0) {}
+ BatchParams(int flag, nsecs_t delay, nsecs_t timeout): flags(flag), batchDelay(delay),
+ batchTimeout(timeout) { }
+ bool operator != (const BatchParams& other) {
+ return other.batchDelay != batchDelay || other.batchTimeout != batchTimeout ||
+ other.flags != flags;
+ }
+ };
+
+ // Store batch parameters in the KeyedVector and the optimal batch_rate and timeout in
+ // bestBatchParams. For every batch() call corresponding params are stored in batchParams
+ // vector. A continuous mode request is batch(... timeout=0 ..) followed by activate(). A batch
+ // mode request is batch(... timeout > 0 ...) followed by activate().
+ // Info is a per-sensor data structure which contains the batch parameters for each client that
+ // has registered for this sensor.
struct Info {
- Info() : delay(0) { }
- KeyedVector<void*, nsecs_t> rates;
- nsecs_t delay;
- status_t setDelayForIdent(void* ident, int64_t ns);
- nsecs_t selectDelay();
+ BatchParams bestBatchParams;
+ // Key is the unique identifier(ident) for each client, value is the batch parameters
+ // requested by the client.
+ KeyedVector<void*, BatchParams> batchParams;
+
+ Info() : bestBatchParams(-1, -1, -1) {}
+ // Sets batch parameters for this ident. Returns error if this ident is not already present
+ // in the KeyedVector above.
+ status_t setBatchParamsForIdent(void* ident, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs);
+ // Finds the optimal parameters for batching and stores them in bestBatchParams variable.
+ void selectBatchParams();
+ // Removes batchParams for an ident and re-computes bestBatchParams. Returns the index of
+ // the removed ident. If index >=0, ident is present and successfully removed.
+ ssize_t removeBatchParamsForIdent(void* ident);
};
DefaultKeyedVector<int, Info> mActivationCount;
@@ -55,9 +85,13 @@ public:
int getHalDeviceVersion() const;
ssize_t poll(sensors_event_t* buffer, size_t count);
status_t activate(void* ident, int handle, int enabled);
+ status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs);
+ // Call batch with timeout zero instead of calling setDelay() for newer devices.
status_t setDelay(void* ident, int handle, int64_t ns);
+ status_t flush(void* ident, int handle);
void autoDisable(void *ident, int handle);
- void dump(String8& result, char* buffer, size_t SIZE);
+ void dump(String8& result);
};
// ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorFusion.cpp b/services/sensorservice/SensorFusion.cpp
index d23906d..03f94be 100644
--- a/services/sensorservice/SensorFusion.cpp
+++ b/services/sensorservice/SensorFusion.cpp
@@ -28,6 +28,7 @@ SensorFusion::SensorFusion()
mEnabled(false), mGyroTime(0)
{
sensor_t const* list;
+ Sensor uncalibratedGyro;
ssize_t count = mSensorDevice.getSensorList(&list);
if (count > 0) {
for (size_t i=0 ; i<size_t(count) ; i++) {
@@ -39,28 +40,38 @@ SensorFusion::SensorFusion()
}
if (list[i].type == SENSOR_TYPE_GYROSCOPE) {
mGyro = Sensor(list + i);
- // 200 Hz for gyro events is a good compromise between precision
- // and power/cpu usage.
- mGyroRate = 200;
- mTargetDelayNs = 1000000000LL/mGyroRate;
}
+ if (list[i].type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
+ uncalibratedGyro = Sensor(list + i);
+ }
+ }
+
+ // Use the uncalibrated gyroscope for sensor fusion when available
+ if (uncalibratedGyro.getType() == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
+ mGyro = uncalibratedGyro;
}
+
+ // 200 Hz for gyro events is a good compromise between precision
+ // and power/cpu usage.
+ mEstimatedGyroRate = 200;
+ mTargetDelayNs = 1000000000LL/mEstimatedGyroRate;
mFusion.init();
}
}
void SensorFusion::process(const sensors_event_t& event) {
- if (event.type == SENSOR_TYPE_GYROSCOPE) {
+ if (event.type == mGyro.getType()) {
if (mGyroTime != 0) {
const float dT = (event.timestamp - mGyroTime) / 1000000000.0f;
+ mFusion.handleGyro(vec3_t(event.data), dT);
+ // here we estimate the gyro rate (useful for debugging)
const float freq = 1 / dT;
if (freq >= 100 && freq<1000) { // filter values obviously wrong
const float alpha = 1 / (1 + dT); // 1s time-constant
- mGyroRate = freq + (mGyroRate - freq)*alpha;
+ mEstimatedGyroRate = freq + (mEstimatedGyroRate - freq)*alpha;
}
}
mGyroTime = event.timestamp;
- mFusion.handleGyro(vec3_t(event.data), 1.0f/mGyroRate);
} else if (event.type == SENSOR_TYPE_MAGNETIC_FIELD) {
const vec3_t mag(event.data);
mFusion.handleMag(mag);
@@ -91,6 +102,15 @@ status_t SensorFusion::activate(void* ident, bool enabled) {
}
}
+ if (enabled) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "SensorFusion calling batch ident=%p ", ident);
+ // Activating a sensor in continuous mode is equivalent to calling batch with the default
+ // period and timeout equal to ZERO, followed by a call to activate.
+ mSensorDevice.batch(ident, mAcc.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
+ mSensorDevice.batch(ident, mMag.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
+ mSensorDevice.batch(ident, mGyro.getHandle(), 0, DEFAULT_EVENTS_PERIOD, 0);
+ }
+
mSensorDevice.activate(ident, mAcc.getHandle(), enabled);
mSensorDevice.activate(ident, mMag.getHandle(), enabled);
mSensorDevice.activate(ident, mGyro.getHandle(), enabled);
@@ -125,14 +145,14 @@ int32_t SensorFusion::getMinDelay() const {
return mAcc.getMinDelay();
}
-void SensorFusion::dump(String8& result, char* buffer, size_t SIZE) {
+void SensorFusion::dump(String8& result) {
const Fusion& fusion(mFusion);
- snprintf(buffer, SIZE, "9-axis fusion %s (%d clients), gyro-rate=%7.2fHz, "
+ result.appendFormat("9-axis fusion %s (%d clients), gyro-rate=%7.2fHz, "
"q=< %g, %g, %g, %g > (%g), "
"b=< %g, %g, %g >\n",
mEnabled ? "enabled" : "disabled",
mClients.size(),
- mGyroRate,
+ mEstimatedGyroRate,
fusion.getAttitude().x,
fusion.getAttitude().y,
fusion.getAttitude().z,
@@ -141,7 +161,6 @@ void SensorFusion::dump(String8& result, char* buffer, size_t SIZE) {
fusion.getBias().x,
fusion.getBias().y,
fusion.getBias().z);
- result.append(buffer);
}
// ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorFusion.h b/services/sensorservice/SensorFusion.h
index 4c99bcb..b8f360f 100644
--- a/services/sensorservice/SensorFusion.h
+++ b/services/sensorservice/SensorFusion.h
@@ -37,6 +37,7 @@ class SensorDevice;
class SensorFusion : public Singleton<SensorFusion> {
friend class Singleton<SensorFusion>;
+ static const nsecs_t DEFAULT_EVENTS_PERIOD = 200000000; // 5 Hz
SensorDevice& mSensorDevice;
Sensor mAcc;
@@ -44,7 +45,7 @@ class SensorFusion : public Singleton<SensorFusion> {
Sensor mGyro;
Fusion mFusion;
bool mEnabled;
- float mGyroRate;
+ float mEstimatedGyroRate;
nsecs_t mTargetDelayNs;
nsecs_t mGyroTime;
vec4_t mAttitude;
@@ -60,7 +61,7 @@ public:
mat33_t getRotationMatrix() const { return mFusion.getRotationMatrix(); }
vec4_t getAttitude() const { return mAttitude; }
vec3_t getGyroBias() const { return mFusion.getBias(); }
- float getEstimatedRate() const { return mGyroRate; }
+ float getEstimatedRate() const { return mEstimatedGyroRate; }
status_t activate(void* ident, bool enabled);
status_t setDelay(void* ident, int64_t ns);
@@ -68,7 +69,7 @@ public:
float getPowerUsage() const;
int32_t getMinDelay() const;
- void dump(String8& result, char* buffer, size_t SIZE);
+ void dump(String8& result);
};
diff --git a/services/sensorservice/SensorInterface.cpp b/services/sensorservice/SensorInterface.cpp
index b483b75..f1d1663 100644
--- a/services/sensorservice/SensorInterface.cpp
+++ b/services/sensorservice/SensorInterface.cpp
@@ -32,7 +32,7 @@ SensorInterface::~SensorInterface()
HardwareSensor::HardwareSensor(const sensor_t& sensor)
: mSensorDevice(SensorDevice::getInstance()),
- mSensor(&sensor)
+ mSensor(&sensor, mSensorDevice.getHalDeviceVersion())
{
ALOGI("%s", sensor.name);
}
@@ -50,6 +50,16 @@ status_t HardwareSensor::activate(void* ident, bool enabled) {
return mSensorDevice.activate(ident, mSensor.getHandle(), enabled);
}
+status_t HardwareSensor::batch(void* ident, int handle, int flags,
+ int64_t samplingPeriodNs, int64_t maxBatchReportLatencyNs) {
+ return mSensorDevice.batch(ident, mSensor.getHandle(), flags, samplingPeriodNs,
+ maxBatchReportLatencyNs);
+}
+
+status_t HardwareSensor::flush(void* ident, int handle) {
+ return mSensorDevice.flush(ident, handle);
+}
+
status_t HardwareSensor::setDelay(void* ident, int handle, int64_t ns) {
return mSensorDevice.setDelay(ident, handle, ns);
}
diff --git a/services/sensorservice/SensorInterface.h b/services/sensorservice/SensorInterface.h
index 2e14e57..c295e22 100644
--- a/services/sensorservice/SensorInterface.h
+++ b/services/sensorservice/SensorInterface.h
@@ -38,6 +38,20 @@ public:
virtual status_t activate(void* ident, bool enabled) = 0;
virtual status_t setDelay(void* ident, int handle, int64_t ns) = 0;
+
+ // Not all sensors need to support batching.
+ virtual status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs) {
+ if (maxBatchReportLatencyNs == 0) {
+ return setDelay(ident, handle, samplingPeriodNs);
+ }
+ return -EINVAL;
+ }
+
+ virtual status_t flush(void* ident, int handle) {
+ return -EINVAL;
+ }
+
virtual Sensor getSensor() const = 0;
virtual bool isVirtual() const = 0;
virtual void autoDisable(void *ident, int handle) { }
@@ -59,7 +73,10 @@ public:
const sensors_event_t& event);
virtual status_t activate(void* ident, bool enabled);
+ virtual status_t batch(void* ident, int handle, int flags, int64_t samplingPeriodNs,
+ int64_t maxBatchReportLatencyNs);
virtual status_t setDelay(void* ident, int handle, int64_t ns);
+ virtual status_t flush(void* ident, int handle);
virtual Sensor getSensor() const;
virtual bool isVirtual() const { return false; }
virtual void autoDisable(void *ident, int handle);
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 6481584..555d843 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -93,6 +93,7 @@ void SensorService::onFirstRef()
orientationIndex = i;
break;
case SENSOR_TYPE_GYROSCOPE:
+ case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
hasGyro = true;
break;
case SENSOR_TYPE_GRAVITY:
@@ -108,54 +109,59 @@ void SensorService::onFirstRef()
// registered)
const SensorFusion& fusion(SensorFusion::getInstance());
+ // build the sensor list returned to users
+ mUserSensorList = mSensorList;
+
if (hasGyro) {
- // Always instantiate Android's virtual sensors. Since they are
- // instantiated behind sensors from the HAL, they won't
- // interfere with applications, unless they looks specifically
- // for them (by name).
+ Sensor aSensor;
- registerVirtualSensor( new RotationVectorSensor() );
- registerVirtualSensor( new GravitySensor(list, count) );
- registerVirtualSensor( new LinearAccelerationSensor(list, count) );
+ // Add Android virtual sensors if they're not already
+ // available in the HAL
- // these are optional
- registerVirtualSensor( new OrientationSensor() );
- registerVirtualSensor( new CorrectedGyroSensor(list, count) );
- }
+ aSensor = registerVirtualSensor( new RotationVectorSensor() );
+ if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
+ mUserSensorList.add(aSensor);
+ }
- // build the sensor list returned to users
- mUserSensorList = mSensorList;
+ aSensor = registerVirtualSensor( new GravitySensor(list, count) );
+ if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
+ mUserSensorList.add(aSensor);
+ }
- if (hasGyro) {
- // virtual debugging sensors are not added to mUserSensorList
- registerVirtualSensor( new GyroDriftSensor() );
- }
+ aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
+ if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
+ mUserSensorList.add(aSensor);
+ }
- if (hasGyro &&
- (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR))) {
- // if we have the fancy sensor fusion, and it's not provided by the
- // HAL, use our own (fused) orientation sensor by removing the
- // HAL supplied one form the user list.
- if (orientationIndex >= 0) {
- mUserSensorList.removeItemsAt(orientationIndex);
+ aSensor = registerVirtualSensor( new OrientationSensor() );
+ if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
+ // if we are doing our own rotation-vector, also add
+ // the orientation sensor and remove the HAL provided one.
+ mUserSensorList.replaceAt(aSensor, orientationIndex);
}
+
+ // virtual debugging sensors are not added to mUserSensorList
+ registerVirtualSensor( new CorrectedGyroSensor(list, count) );
+ registerVirtualSensor( new GyroDriftSensor() );
}
// debugging sensor list
- for (size_t i=0 ; i<mSensorList.size() ; i++) {
- switch (mSensorList[i].getType()) {
- case SENSOR_TYPE_GRAVITY:
- case SENSOR_TYPE_LINEAR_ACCELERATION:
- case SENSOR_TYPE_ROTATION_VECTOR:
- if (strstr(mSensorList[i].getVendor().string(), "Google")) {
- mUserSensorListDebug.add(mSensorList[i]);
- }
- break;
- default:
- mUserSensorListDebug.add(mSensorList[i]);
- break;
+ mUserSensorListDebug = mSensorList;
+
+ mSocketBufferSize = SOCKET_BUFFER_SIZE_NON_BATCHED;
+ FILE *fp = fopen("/proc/sys/net/core/wmem_max", "r");
+ char line[128];
+ if (fp != NULL && fgets(line, sizeof(line), fp) != NULL) {
+ line[sizeof(line) - 1] = '\0';
+ sscanf(line, "%u", &mSocketBufferSize);
+ if (mSocketBufferSize > MAX_SOCKET_BUFFER_SIZE_BATCHED) {
+ mSocketBufferSize = MAX_SOCKET_BUFFER_SIZE_BATCHED;
}
}
+ ALOGD("Max socket buffer size %u", mSocketBufferSize);
+ if (fp) {
+ fclose(fp);
+ }
run("SensorService", PRIORITY_URGENT_DISPLAY);
mInitCheck = NO_ERROR;
@@ -163,7 +169,7 @@ void SensorService::onFirstRef()
}
}
-void SensorService::registerSensor(SensorInterface* s)
+Sensor SensorService::registerSensor(SensorInterface* s)
{
sensors_event_t event;
memset(&event, 0, sizeof(event));
@@ -175,12 +181,15 @@ void SensorService::registerSensor(SensorInterface* s)
mSensorMap.add(sensor.getHandle(), s);
// create an entry in the mLastEventSeen array
mLastEventSeen.add(sensor.getHandle(), event);
+
+ return sensor;
}
-void SensorService::registerVirtualSensor(SensorInterface* s)
+Sensor SensorService::registerVirtualSensor(SensorInterface* s)
{
- registerSensor(s);
+ Sensor sensor = registerSensor(s);
mVirtualSensorList.add( s );
+ return sensor;
}
SensorService::~SensorService()
@@ -193,47 +202,92 @@ static const String16 sDump("android.permission.DUMP");
status_t SensorService::dump(int fd, const Vector<String16>& args)
{
- const size_t SIZE = 1024;
- char buffer[SIZE];
String8 result;
if (!PermissionCache::checkCallingPermission(sDump)) {
- snprintf(buffer, SIZE, "Permission Denial: "
+ result.appendFormat("Permission Denial: "
"can't dump SurfaceFlinger from pid=%d, uid=%d\n",
IPCThreadState::self()->getCallingPid(),
IPCThreadState::self()->getCallingUid());
- result.append(buffer);
} else {
Mutex::Autolock _l(mLock);
- snprintf(buffer, SIZE, "Sensor List:\n");
- result.append(buffer);
+ result.append("Sensor List:\n");
for (size_t i=0 ; i<mSensorList.size() ; i++) {
const Sensor& s(mSensorList[i]);
const sensors_event_t& e(mLastEventSeen.valueFor(s.getHandle()));
- snprintf(buffer, SIZE,
- "%-48s| %-32s | 0x%08x | maxRate=%7.2fHz | "
- "last=<%5.1f,%5.1f,%5.1f>\n",
+ result.appendFormat(
+ "%-48s| %-32s | 0x%08x | ",
s.getName().string(),
s.getVendor().string(),
- s.getHandle(),
- s.getMinDelay() ? (1000000.0f / s.getMinDelay()) : 0.0f,
- e.data[0], e.data[1], e.data[2]);
- result.append(buffer);
+ s.getHandle());
+
+ if (s.getMinDelay() > 0) {
+ result.appendFormat(
+ "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
+ } else {
+ result.append(s.getMinDelay() == 0
+ ? "on-demand | "
+ : "one-shot | ");
+ }
+ if (s.getFifoMaxEventCount() > 0) {
+ result.appendFormat("getFifoMaxEventCount=%d events | ", s.getFifoMaxEventCount());
+ } else {
+ result.append("no batching support | ");
+ }
+
+ switch (s.getType()) {
+ case SENSOR_TYPE_ROTATION_VECTOR:
+ case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
+ result.appendFormat(
+ "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
+ e.data[0], e.data[1], e.data[2], e.data[3], e.data[4]);
+ break;
+ case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+ case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
+ result.appendFormat(
+ "last=<%5.1f,%5.1f,%5.1f,%5.1f,%5.1f,%5.1f>\n",
+ e.data[0], e.data[1], e.data[2], e.data[3], e.data[4], e.data[5]);
+ break;
+ case SENSOR_TYPE_GAME_ROTATION_VECTOR:
+ result.appendFormat(
+ "last=<%5.1f,%5.1f,%5.1f,%5.1f>\n",
+ e.data[0], e.data[1], e.data[2], e.data[3]);
+ break;
+ case SENSOR_TYPE_SIGNIFICANT_MOTION:
+ case SENSOR_TYPE_STEP_DETECTOR:
+ result.appendFormat( "last=<%f>\n", e.data[0]);
+ break;
+ case SENSOR_TYPE_STEP_COUNTER:
+ result.appendFormat( "last=<%llu>\n", e.u64.step_counter);
+ break;
+ default:
+ // default to 3 values
+ result.appendFormat(
+ "last=<%5.1f,%5.1f,%5.1f>\n",
+ e.data[0], e.data[1], e.data[2]);
+ break;
+ }
}
- SensorFusion::getInstance().dump(result, buffer, SIZE);
- SensorDevice::getInstance().dump(result, buffer, SIZE);
-
- snprintf(buffer, SIZE, "%d active connections\n",
- mActiveConnections.size());
- result.append(buffer);
- snprintf(buffer, SIZE, "Active sensors:\n");
- result.append(buffer);
+ SensorFusion::getInstance().dump(result);
+ SensorDevice::getInstance().dump(result);
+
+ result.append("Active sensors:\n");
for (size_t i=0 ; i<mActiveSensors.size() ; i++) {
int handle = mActiveSensors.keyAt(i);
- snprintf(buffer, SIZE, "%s (handle=0x%08x, connections=%d)\n",
+ result.appendFormat("%s (handle=0x%08x, connections=%d)\n",
getSensorName(handle).string(),
handle,
mActiveSensors.valueAt(i)->getNumConnections());
- result.append(buffer);
+ }
+
+ result.appendFormat("%u Max Socket Buffer size\n", mSocketBufferSize);
+ result.appendFormat("%d active connections\n", mActiveConnections.size());
+
+ for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
+ sp<SensorEventConnection> connection(mActiveConnections[i].promote());
+ if (connection != 0) {
+ result.appendFormat("Connection Number: %d \n", i);
+ connection->dump(result);
+ }
}
}
write(fd, result.string(), result.size());
@@ -246,7 +300,8 @@ void SensorService::cleanupAutoDisabledSensor(const sp<SensorEventConnection>& c
status_t err = NO_ERROR;
for (int i=0 ; i<count ; i++) {
int handle = buffer[i].sensor;
- if (getSensorType(handle) == SENSOR_TYPE_SIGNIFICANT_MOTION) {
+ int type = buffer[i].type;
+ if (type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
if (connection->hasSensor(handle)) {
sensor = mSensorMap.valueFor(handle);
if (sensor != NULL) {
@@ -262,8 +317,12 @@ bool SensorService::threadLoop()
{
ALOGD("nuSensorService thread starting...");
- const size_t numEventMax = 16;
- const size_t minBufferSize = numEventMax + numEventMax * mVirtualSensorList.size();
+ // each virtual sensor could generate an event per "real" event, that's why we need
+ // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.
+ // in practice, this is too aggressive, but guaranteed to be enough.
+ const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
+ const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());
+
sensors_event_t buffer[minBufferSize];
sensors_event_t scratch[minBufferSize];
SensorDevice& device(SensorDevice::getInstance());
@@ -283,7 +342,7 @@ bool SensorService::threadLoop()
// 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) {
+ if (buffer[i].type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
wakeLockAcquired = true;
break;
@@ -335,7 +394,7 @@ 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) {
+ if (buffer[i].type == 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;
@@ -359,7 +418,6 @@ bool SensorService::threadLoop()
// 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...");
@@ -371,7 +429,6 @@ void SensorService::recordLastValue(
sensors_event_t const * buffer, size_t count)
{
Mutex::Autolock _l(mLock);
-
// record the last event for each sensor
int32_t prev = buffer[0].sensor;
for (size_t i=1 ; i<count ; i++) {
@@ -423,18 +480,6 @@ 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];
@@ -489,7 +534,7 @@ void SensorService::cleanupConnection(SensorEventConnection* c)
}
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
- int handle)
+ int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags)
{
if (mInitCheck != NO_ERROR)
return mInitCheck;
@@ -498,7 +543,6 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
if (sensor == NULL) {
return BAD_VALUE;
}
-
Mutex::Autolock _l(mLock);
SensorRecord* rec = mActiveSensors.valueFor(handle);
if (rec == 0) {
@@ -535,10 +579,33 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection,
handle, connection.get());
}
- // we are setup, now enable the sensor.
- status_t err = sensor->activate(connection.get(), true);
+ nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
+ if (samplingPeriodNs < minDelayNs) {
+ samplingPeriodNs = minDelayNs;
+ }
+
+ ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld",
+ handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
+
+ status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
+ maxBatchReportLatencyNs);
+ if (err == NO_ERROR) {
+ connection->setFirstFlushPending(handle, true);
+ status_t err_flush = sensor->flush(connection.get(), handle);
+ // Flush may return error if the sensor is not activated or the underlying h/w sensor does
+ // not support flush.
+ if (err_flush != NO_ERROR) {
+ connection->setFirstFlushPending(handle, false);
+ }
+ }
+
+ if (err == NO_ERROR) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
+ err = sensor->activate(connection.get(), true);
+ }
+
if (err != NO_ERROR) {
- // enable has failed, reset our state.
+ // batch/activate has failed, reset our state.
cleanupWithoutDisableLocked(connection, handle);
}
return err;
@@ -605,12 +672,22 @@ status_t SensorService::setEventRate(const sp<SensorEventConnection>& connection
ns = minDelayNs;
}
- if (ns < MINIMUM_EVENTS_PERIOD)
- ns = MINIMUM_EVENTS_PERIOD;
-
return sensor->setDelay(connection.get(), handle, ns);
}
+status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection,
+ int handle) {
+ if (mInitCheck != NO_ERROR) return mInitCheck;
+ SensorInterface* sensor = mSensorMap.valueFor(handle);
+ if (sensor == NULL) {
+ return BAD_VALUE;
+ }
+ if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) {
+ ALOGE("flush called on Significant Motion sensor");
+ return INVALID_OPERATION;
+ }
+ return sensor->flush(connection.get(), handle);
+}
// ---------------------------------------------------------------------------
SensorService::SensorRecord::SensorRecord(
@@ -643,8 +720,15 @@ bool SensorService::SensorRecord::removeConnection(
SensorService::SensorEventConnection::SensorEventConnection(
const sp<SensorService>& service, uid_t uid)
- : mService(service), mChannel(new BitTube()), mUid(uid)
+ : mService(service), mUid(uid)
{
+ const SensorDevice& device(SensorDevice::getInstance());
+ if (device.getHalDeviceVersion() >= SENSORS_DEVICE_API_VERSION_1_1) {
+ // Increase socket buffer size to 1MB for batching capabilities.
+ mChannel = new BitTube(service->mSocketBufferSize);
+ } else {
+ mChannel = new BitTube(SOCKET_BUFFER_SIZE_NON_BATCHED);
+ }
}
SensorService::SensorEventConnection::~SensorEventConnection()
@@ -657,10 +741,22 @@ void SensorService::SensorEventConnection::onFirstRef()
{
}
+void SensorService::SensorEventConnection::dump(String8& result) {
+ Mutex::Autolock _l(mConnectionLock);
+ for (size_t i = 0; i < mSensorInfo.size(); ++i) {
+ const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
+ result.appendFormat("\t %s | status: %s | pending flush events %d\n",
+ mService->getSensorName(mSensorInfo.keyAt(i)).string(),
+ flushInfo.mFirstFlushPending ? "First flush pending" :
+ "active",
+ flushInfo.mPendingFlushEventsToSend);
+ }
+}
+
bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
Mutex::Autolock _l(mConnectionLock);
- if (mSensorInfo.indexOf(handle) < 0) {
- mSensorInfo.add(handle);
+ if (mSensorInfo.indexOfKey(handle) < 0) {
+ mSensorInfo.add(handle, FlushInfo());
return true;
}
return false;
@@ -668,7 +764,7 @@ bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
Mutex::Autolock _l(mConnectionLock);
- if (mSensorInfo.remove(handle) >= 0) {
+ if (mSensorInfo.removeItem(handle) >= 0) {
return true;
}
return false;
@@ -676,7 +772,7 @@ bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
Mutex::Autolock _l(mConnectionLock);
- return mSensorInfo.indexOf(handle) >= 0;
+ return mSensorInfo.indexOfKey(handle) >= 0;
}
bool SensorService::SensorEventConnection::hasAnySensor() const {
@@ -684,21 +780,50 @@ bool SensorService::SensorEventConnection::hasAnySensor() const {
return mSensorInfo.size() ? true : false;
}
+void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
+ bool value) {
+ Mutex::Autolock _l(mConnectionLock);
+ ssize_t index = mSensorInfo.indexOfKey(handle);
+ if (index >= 0) {
+ FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+ flushInfo.mFirstFlushPending = value;
+ }
+}
+
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch)
{
// filter out events not for this connection
size_t count = 0;
+
if (scratch) {
Mutex::Autolock _l(mConnectionLock);
size_t i=0;
while (i<numEvents) {
- const int32_t curr = buffer[i].sensor;
- if (mSensorInfo.indexOf(curr) >= 0) {
+ int32_t curr = buffer[i].sensor;
+ if (buffer[i].type == SENSOR_TYPE_META_DATA) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "flush complete event sensor==%d ",
+ buffer[i].meta_data.sensor);
+ // Setting curr to the correct sensor to ensure the sensor events per connection are
+ // filtered correctly. buffer[i].sensor is zero for meta_data events.
+ curr = buffer[i].meta_data.sensor;
+ }
+ ssize_t index = mSensorInfo.indexOfKey(curr);
+ if (index >= 0 && mSensorInfo[index].mFirstFlushPending == true &&
+ buffer[i].type == SENSOR_TYPE_META_DATA) {
+ // This is the first flush before activate is called. Events can now be sent for
+ // this sensor on this connection.
+ ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
+ buffer[i].meta_data.sensor);
+ mSensorInfo.editValueAt(index).mFirstFlushPending = false;
+ }
+ if (index >= 0 && mSensorInfo[index].mFirstFlushPending == false) {
do {
scratch[count++] = buffer[i++];
- } while ((i<numEvents) && (buffer[i].sensor == curr));
+ } while ((i<numEvents) && ((buffer[i].sensor == curr) ||
+ (buffer[i].type == SENSOR_TYPE_META_DATA &&
+ buffer[i].meta_data.sensor == curr)));
} else {
i++;
}
@@ -708,30 +833,75 @@ status_t SensorService::SensorEventConnection::sendEvents(
count = numEvents;
}
+ // Send pending flush events (if any) before sending events from the cache.
+ {
+ ASensorEvent flushCompleteEvent;
+ flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
+ flushCompleteEvent.sensor = 0;
+ Mutex::Autolock _l(mConnectionLock);
+ // Loop through all the sensors for this connection and check if there are any pending
+ // flush complete events to be sent.
+ for (size_t i = 0; i < mSensorInfo.size(); ++i) {
+ FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
+ while (flushInfo.mPendingFlushEventsToSend > 0) {
+ flushCompleteEvent.meta_data.sensor = mSensorInfo.keyAt(i);
+ ssize_t size = SensorEventQueue::write(mChannel, &flushCompleteEvent, 1);
+ if (size < 0) {
+ // ALOGW("dropping %d events on the floor", count);
+ countFlushCompleteEventsLocked(scratch, count);
+ return size;
+ }
+ ALOGD_IF(DEBUG_CONNECTIONS, "sent dropped flush complete event==%d ",
+ flushCompleteEvent.meta_data.sensor);
+ flushInfo.mPendingFlushEventsToSend--;
+ }
+ }
+ }
+
// NOTE: ASensorEvent and sensors_event_t are the same type
ssize_t size = SensorEventQueue::write(mChannel,
reinterpret_cast<ASensorEvent const*>(scratch), count);
if (size == -EAGAIN) {
// the destination doesn't accept events anymore, it's probably
// full. For now, we just drop the events on the floor.
- //ALOGW("dropping %d events on the floor", count);
+ // ALOGW("dropping %d events on the floor", count);
+ Mutex::Autolock _l(mConnectionLock);
+ countFlushCompleteEventsLocked(scratch, count);
return size;
}
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
+void SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
+ sensors_event_t* scratch, const int numEventsDropped) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "dropping %d events ", numEventsDropped);
+ // Count flushComplete events in the events that are about to the dropped. These will be sent
+ // separately before the next batch of events.
+ for (int j = 0; j < numEventsDropped; ++j) {
+ if (scratch[j].type == SENSOR_TYPE_META_DATA) {
+ FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
+ flushInfo.mPendingFlushEventsToSend++;
+ ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
+ flushInfo.mPendingFlushEventsToSend);
+ }
+ }
+ return;
+}
+
sp<BitTube> SensorService::SensorEventConnection::getSensorChannel() const
{
return mChannel;
}
status_t SensorService::SensorEventConnection::enableDisable(
- int handle, bool enabled)
+ int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
+ int reservedFlags)
{
status_t err;
if (enabled) {
- err = mService->enable(this, handle);
+ err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
+ reservedFlags);
} else {
err = mService->disable(this, handle);
}
@@ -739,9 +909,33 @@ status_t SensorService::SensorEventConnection::enableDisable(
}
status_t SensorService::SensorEventConnection::setEventRate(
- int handle, nsecs_t ns)
+ int handle, nsecs_t samplingPeriodNs)
{
- return mService->setEventRate(this, handle, ns);
+ return mService->setEventRate(this, handle, samplingPeriodNs);
+}
+
+status_t SensorService::SensorEventConnection::flush() {
+ SensorDevice& dev(SensorDevice::getInstance());
+ const int halVersion = dev.getHalDeviceVersion();
+ Mutex::Autolock _l(mConnectionLock);
+ status_t err(NO_ERROR);
+ // Loop through all sensors for this connection and call flush on each of them.
+ for (size_t i = 0; i < mSensorInfo.size(); ++i) {
+ const int handle = mSensorInfo.keyAt(i);
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_1) {
+ // For older devices just increment pending flush count which will send a trivial
+ // flush complete event.
+ FlushInfo& flushInfo = mSensorInfo.editValueFor(handle);
+ flushInfo.mPendingFlushEventsToSend++;
+ } else {
+ status_t err_flush = mService->flushSensor(this, handle);
+ if (err_flush != NO_ERROR) {
+ ALOGE("Flush error handle=%d %s", handle, strerror(-err_flush));
+ }
+ err = (err_flush != NO_ERROR) ? err_flush : err;
+ }
+ }
+ return err;
}
// ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index fcdbc7d..6c1691a 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -38,6 +38,9 @@
// ---------------------------------------------------------------------------
#define DEBUG_CONNECTIONS false
+// Max size is 1 MB which is enough to accept a batch of about 10k events.
+#define MAX_SOCKET_BUFFER_SIZE_BATCHED 1024 * 1024
+#define SOCKET_BUFFER_SIZE_NON_BATCHED 4 * 1024
struct sensors_poll_device_t;
struct sensors_module_t;
@@ -50,12 +53,12 @@ class SensorService :
public BnSensorServer,
protected Thread
{
- friend class BinderService<SensorService>;
+ friend class BinderService<SensorService>;
- static const nsecs_t MINIMUM_EVENTS_PERIOD = 1000000; // 1000 Hz
- static const char* WAKE_LOCK_NAME;
+ static const char* WAKE_LOCK_NAME;
- SensorService();
+ static char const* getServiceName() ANDROID_API { return "sensorservice"; }
+ SensorService() ANDROID_API;
virtual ~SensorService();
virtual void onFirstRef();
@@ -73,16 +76,31 @@ class SensorService :
virtual ~SensorEventConnection();
virtual void onFirstRef();
virtual sp<BitTube> getSensorChannel() const;
- virtual status_t enableDisable(int handle, bool enabled);
- virtual status_t setEventRate(int handle, nsecs_t ns);
+ virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,
+ nsecs_t maxBatchReportLatencyNs, int reservedFlags);
+ virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs);
+ virtual status_t flush();
+ // Count the number of flush complete events which are about to be dropped in the buffer.
+ // Increment mPendingFlushEventsToSend in mSensorInfo. These flush complete events will be
+ // sent separately before the next batch of events.
+ void countFlushCompleteEventsLocked(sensors_event_t* scratch, int numEventsDropped);
sp<SensorService> const mService;
- sp<BitTube> const mChannel;
+ sp<BitTube> mChannel;
uid_t mUid;
mutable Mutex mConnectionLock;
- // protected by SensorService::mLock
- SortedVector<int> mSensorInfo;
+ struct FlushInfo {
+ // The number of flush complete events dropped for this sensor is stored here.
+ // They are sent separately before the next batch of events.
+ int mPendingFlushEventsToSend;
+ // Every activate is preceded by a flush. Only after the first flush complete is
+ // received, the events for the sensor are sent on that *connection*.
+ bool mFirstFlushPending;
+ FlushInfo() : mPendingFlushEventsToSend(0), mFirstFlushPending(false) {}
+ };
+ // protected by SensorService::mLock. Key for this vector is the sensor handle.
+ KeyedVector<int, FlushInfo> mSensorInfo;
public:
SensorEventConnection(const sp<SensorService>& service, uid_t uid);
@@ -93,6 +111,8 @@ class SensorService :
bool hasAnySensor() const;
bool addSensor(int32_t handle);
bool removeSensor(int32_t handle);
+ void setFirstFlushPending(int32_t handle, bool value);
+ void dump(String8& result);
uid_t getUid() const { return mUid; }
};
@@ -110,17 +130,16 @@ 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);
+ Sensor registerSensor(SensorInterface* sensor);
+ Sensor registerVirtualSensor(SensorInterface* sensor);
status_t cleanupWithoutDisable(
const sp<SensorEventConnection>& connection, int handle);
status_t cleanupWithoutDisableLocked(
const sp<SensorEventConnection>& connection, int handle);
void cleanupAutoDisabledSensor(const sp<SensorEventConnection>& connection,
- sensors_event_t const* buffer, const int count);
+ sensors_event_t const* buffer, const int count);
// constants
Vector<Sensor> mSensorList;
@@ -129,6 +148,7 @@ class SensorService :
DefaultKeyedVector<int, SensorInterface*> mSensorMap;
Vector<SensorInterface *> mVirtualSensorList;
status_t mInitCheck;
+ size_t mSocketBufferSize;
// protected by mLock
mutable Mutex mLock;
@@ -140,12 +160,12 @@ class SensorService :
KeyedVector<int32_t, sensors_event_t> mLastEventSeen;
public:
- static char const* getServiceName() { return "sensorservice"; }
-
void cleanupConnection(SensorEventConnection* connection);
- status_t enable(const sp<SensorEventConnection>& connection, int handle);
+ status_t enable(const sp<SensorEventConnection>& connection, int handle,
+ nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags);
status_t disable(const sp<SensorEventConnection>& connection, int handle);
status_t setEventRate(const sp<SensorEventConnection>& connection, int handle, nsecs_t ns);
+ status_t flushSensor(const sp<SensorEventConnection>& connection, int handle);
};
// ---------------------------------------------------------------------------
diff --git a/services/sensorservice/main_sensorservice.cpp b/services/sensorservice/main_sensorservice.cpp
new file mode 100644
index 0000000..303b65f
--- /dev/null
+++ b/services/sensorservice/main_sensorservice.cpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/BinderService.h>
+#include "SensorService.h"
+
+using namespace android;
+
+int main(int argc, char** argv) {
+ SensorService::publishAndJoinThreadPool();
+ return 0;
+}