summaryrefslogtreecommitdiffstats
path: root/services/sensorservice
diff options
context:
space:
mode:
authorRicardo Cerqueira <cyanogenmod@cerqueira.org>2010-12-22 00:32:55 +0000
committerRicardo Cerqueira <github@cerqueira.org>2011-11-18 00:14:32 +0000
commitde78c41fddfc96a19b3051fa0cde785e25105e5f (patch)
treeee2c57ca568d051cce24764611baf88f03058120 /services/sensorservice
parentf1d359a9af7c0226288c3fe4c5c4045ccbb54aa7 (diff)
downloadframeworks_base-de78c41fddfc96a19b3051fa0cde785e25105e5f.zip
frameworks_base-de78c41fddfc96a19b3051fa0cde785e25105e5f.tar.gz
frameworks_base-de78c41fddfc96a19b3051fa0cde785e25105e5f.tar.bz2
sensors: Add support for old libsensors HAL
Enable with TARGET_USES_OLD_LIBSENSORS_HAL:=true Change-Id: Ib430d8305148f337dd111c80be60ddd151ea5926 sensors: Improve support for old libsensors HAL Some devices (harmony, at least) claim to support the nuSensors SENSORS_HARDWARE_POLL, which was breaking the compatibility check. This removes that check from runtime and makes it exclusively a compile-time option.. Change-Id: Ide4262e5dec296d96aa896d676a06985fe09aef1 sensors: Fix sensorId/sensorType logic in back-compat layer As it was, the code was only working on devices where the ID matched the the sensorType. This isn't necessarily true on every device (and definititely isn't on some) Change-Id: I70a5d827c5a6406b5edacc334705edb43e6f5638 sensors: Simplify the data translation in the back-compat hook Since the sensor data comes in a union, we don't need to do a copy for every possible entry, we just need one per type. This cuts us down from 6 data copies on every poll to just 2. Change-Id: I755f3018ad38be1b7fa04528143507204b4df605 sensors: More compatibility fixes Some of the old HAL "magic values" aren't magic anymore, so discard them instead of trying to react like the pre-2.3 implementation. This had the potential of causing infinite loops on some libsensors (it was doing it on yamaha's) Change-Id: Id792faa6a454428040ae2973e386f3a25c904c8e sensors: Add handle-to-type mapping in back-compat layer The result of the old API data_poll is an int, which should represent a handle to the actualy sensor. That handle must be mapped to the sensor type, which is required by the new API. I was wrongly assuming the handle and the type were the same, and that isn't necessarily true; the only reason this was working is because the java client API appears to be still doing its own handle-to-type mapping and mostly ignoring the type value set at the native layer Change-Id: Ibe6209b91cf96aa885a05d6091155ee7ef929211 sensors: Add workaround for Foxconn's broken sensor data FIH has a tendency to add in-kernel "shortcuts" for stuff that's usually controlled in userspace, and disabling the screen+backlight on proximity was one of those. That implementation is, however, buggy, and on top of that it's colliding with the standard userspace implementation. This should be corrected at the sensors HAL, but reimplementing that has been a work-in-progress for quite some time now and still isn't functional. So, for now, toggle a workaround with TARGET_HAS_FOXCONN_SENSORS, and convert the data into the kind of values the framework expects. Change-Id: Ib974af729ce0511668c835b9078831330b874a1f Add TARGET_SENSORS_NO_OPEN_CHECK for betelgeuse (Folio100) support sensors.tegra.so on betelgeuse return -22 on both sensors_control_open, sensors_data_open, but sensors are OK after those two calls. Change-Id: Iabe14f9ed26ff182041f447cf278408ada62ef81 sensors: Fix ALS and PS lag on back-compat layer These 2 sensors only report values on change, instead of continuously generating samples at 'setDelay' intervals like most others. If only these 2 (or any one of them is enabled), we can't wait for the usual 64 samples to be taken before reporting them to the framework, since that'll make them visibly laggy. This patch causes any sample from these sensors to trigger an immediate report to the client. Change-Id: Id5932376858c30323bff07ac4b38856dc200d074 sensors: Add dummy light sensor for p990/p999 This is necessary for the rest of userspace to recognize its existence and toggle it for auto-brightness. It doesn't generate actual light values, though; all backlight adjustments are made in-kernel. Change-Id: I0e546b4740720bd34d1e1d85a96b295fcc697106 sensors: Allow target to override max range of proximity sensor If a proximity sensor rarely or never reaches its maxRange, the device will frequently lock up after the sensor is triggered (by a call, for example), since it'll get stuck in the "active" state. Set TARGET_PROXIMITY_SENSOR_LIMIT := <value> with the distance from which the sensor will turn off to override those cases Change-Id: I31fa2e5b9bd40ed6d80a1d5b0c147ed265f94c3a Change-Id: Ib430d8305148f337dd111c80be60ddd151ea5926a
Diffstat (limited to 'services/sensorservice')
-rw-r--r--services/sensorservice/Android.mk23
-rw-r--r--services/sensorservice/SensorDevice.cpp214
-rw-r--r--services/sensorservice/SensorDevice.h7
-rw-r--r--services/sensorservice/sensors_deprecated.h75
4 files changed, 308 insertions, 11 deletions
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
index 6a302c0..792ee28 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -16,6 +16,29 @@ LOCAL_SRC_FILES:= \
LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
+ifeq ($(TARGET_USES_OLD_LIBSENSORS_HAL),true)
+ LOCAL_CFLAGS += -DENABLE_SENSORS_COMPAT
+endif
+
+ifeq ($(TARGET_SENSORS_NO_OPEN_CHECK),true)
+ LOCAL_CFLAGS += -DSENSORS_NO_OPEN_CHECK
+endif
+
+ifeq ($(TARGET_HAS_FOXCONN_SENSORS),true)
+ LOCAL_CFLAGS += -DFOXCONN_SENSORS
+endif
+
+ifneq ($(TARGET_PROXIMITY_SENSOR_LIMIT),)
+ LOCAL_CFLAGS += -DPROXIMITY_LIES=$(TARGET_PROXIMITY_SENSOR_LIMIT)
+endif
+
+ifneq ($(filter p990 p999 p970, $(TARGET_BOOTLOADER_BOARD_NAME)),)
+ LOCAL_CFLAGS += -DUSE_LGE_ALS_DUMMY
+ ifeq ($(TARGET_BOOTLOADER_BOARD_NAME),p970)
+ LOCAL_CFLAGS += -DUSE_LGE_ALS_OMAP3
+ endif
+endif
+
LOCAL_SHARED_LIBRARIES := \
libcutils \
libhardware \
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index d82a7e2..88d738c 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -31,6 +31,11 @@
#include "SensorDevice.h"
#include "SensorService.h"
+#include "sensors_deprecated.h"
+#ifdef USE_LGE_ALS_DUMMY
+#include <fcntl.h>
+#endif
+
namespace android {
// ---------------------------------------------------------------------------
class BatteryService : public Singleton<BatteryService> {
@@ -98,8 +103,31 @@ ANDROID_SINGLETON_STATIC_INSTANCE(BatteryService)
ANDROID_SINGLETON_STATIC_INSTANCE(SensorDevice)
+#ifdef USE_LGE_ALS_DUMMY
+static ssize_t addDummyLGESensor(sensor_t const **list, ssize_t count) {
+ struct sensor_t dummy_light = {
+ name : "Dummy LGE-Star light sensor",
+ vendor : "CyanogenMod",
+ version : 1,
+ handle : SENSOR_TYPE_LIGHT,
+ type : SENSOR_TYPE_LIGHT,
+ maxRange : 20,
+ resolution : 0.1,
+ power : 20,
+ };
+ void * new_list = malloc((count+1)*sizeof(sensor_t));
+ new_list = memcpy(new_list, *list, count*sizeof(sensor_t));
+ ((sensor_t *)new_list)[count] = dummy_light;
+ *list = (sensor_t const *)new_list;
+ count++;
+ return count;
+}
+#endif
+
SensorDevice::SensorDevice()
: mSensorDevice(0),
+ mOldSensorsEnabled(0),
+ mOldSensorsCompatMode(false),
mSensorModule(0)
{
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
@@ -109,19 +137,56 @@ SensorDevice::SensorDevice()
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
if (mSensorModule) {
+#ifdef ENABLE_SENSORS_COMPAT
+#ifdef SENSORS_NO_OPEN_CHECK
+ sensors_control_open(&mSensorModule->common, &mSensorControlDevice) ;
+ sensors_data_open(&mSensorModule->common, &mSensorDataDevice) ;
+ mOldSensorsCompatMode = true;
+#else
+ if (!sensors_control_open(&mSensorModule->common, &mSensorControlDevice)) {
+ if (sensors_data_open(&mSensorModule->common, &mSensorDataDevice)) {
+ LOGE("couldn't open data device in backwards-compat mode for module %s (%s)",
+ SENSORS_HARDWARE_MODULE_ID, strerror(-err));
+ } else {
+ LOGD("Opened sensors in backwards compat mode");
+ mOldSensorsCompatMode = true;
+ }
+ } else {
+ LOGE("couldn't open control device in backwards-compat mode for module %s (%s)",
+ SENSORS_HARDWARE_MODULE_ID, strerror(-err));
+ }
+#endif
+#else
err = sensors_open(&mSensorModule->common, &mSensorDevice);
-
LOGE_IF(err, "couldn't open device for module %s (%s)",
SENSORS_HARDWARE_MODULE_ID, strerror(-err));
+#endif
+
- if (mSensorDevice) {
+ if (mSensorDevice || mOldSensorsCompatMode) {
sensor_t const* list;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
+
+#ifdef USE_LGE_ALS_DUMMY
+ count = addDummyLGESensor(&list, count);
+#endif
+
+ if (mOldSensorsCompatMode) {
+ mOldSensorsList = list;
+ mOldSensorsCount = count;
+ mSensorDataDevice->data_open(mSensorDataDevice,
+ mSensorControlDevice->open_data_source(mSensorControlDevice));
+ }
+
mActivationCount.setCapacity(count);
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);
+ if (mOldSensorsCompatMode) {
+ mSensorControlDevice->activate(mSensorControlDevice, list[i].handle, 0);
+ } else {
+ mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
+ }
}
}
}
@@ -157,24 +222,130 @@ void SensorDevice::dump(String8& result, char* buffer, size_t SIZE)
ssize_t SensorDevice::getSensorList(sensor_t const** list) {
if (!mSensorModule) return NO_INIT;
ssize_t count = mSensorModule->get_sensors_list(mSensorModule, list);
+
+#ifdef USE_LGE_ALS_DUMMY
+ return addDummyLGESensor(list, count);
+#endif
return count;
}
status_t SensorDevice::initCheck() const {
- return mSensorDevice && mSensorModule ? NO_ERROR : NO_INIT;
+ return (mSensorDevice || mOldSensorsCompatMode) && mSensorModule ? NO_ERROR : NO_INIT;
}
ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
- if (!mSensorDevice) return NO_INIT;
- return mSensorDevice->poll(mSensorDevice, buffer, count);
+ if (!mSensorDevice && !mOldSensorsCompatMode) return NO_INIT;
+ if (mOldSensorsCompatMode) {
+ size_t pollsDone = 0;
+ //LOGV("%d buffers were requested",count);
+ while (!mOldSensorsEnabled) {
+ sleep(1);
+ LOGV("Waiting...");
+ }
+ while (pollsDone < (size_t)mOldSensorsEnabled && pollsDone < count) {
+ sensors_data_t oldBuffer;
+ long result = mSensorDataDevice->poll(mSensorDataDevice, &oldBuffer);
+ int sensorType = -1;
+ int maxRange = -1;
+
+ if (result == 0x7FFFFFFF) {
+ continue;
+ } else {
+ /* the old data_poll is supposed to return a handle,
+ * which has to be mapped to the type. */
+ for (size_t i=0 ; i<size_t(mOldSensorsCount) && sensorType < 0 ; i++) {
+ if (mOldSensorsList[i].handle == result) {
+ sensorType = mOldSensorsList[i].type;
+ maxRange = mOldSensorsList[i].maxRange;
+ LOGV("mapped sensor type to %d",sensorType);
+ }
+ }
+ }
+ if ( sensorType <= 0 ||
+ sensorType > SENSOR_TYPE_ROTATION_VECTOR) {
+ LOGV("Useless output at round %u from %d",pollsDone, oldBuffer.sensor);
+ count--;
+ continue;
+ }
+ buffer[pollsDone].version = sizeof(struct sensors_event_t);
+ buffer[pollsDone].timestamp = oldBuffer.time;
+ buffer[pollsDone].type = sensorType;
+ buffer[pollsDone].sensor = result;
+ /* This part is a union. Regardless of the sensor type,
+ * we only need to copy a sensors_vec_t and a float */
+ buffer[pollsDone].acceleration = oldBuffer.vector;
+ buffer[pollsDone].temperature = oldBuffer.temperature;
+ LOGV("Adding results for sensor %d", buffer[pollsDone].sensor);
+ /* The ALS and PS sensors only report values on change,
+ * instead of a data "stream" like the others. So don't wait
+ * for the number of requested samples to fill, and deliver
+ * it immediately */
+ if (sensorType == SENSOR_TYPE_PROXIMITY) {
+#ifdef FOXCONN_SENSORS
+ /* Fix ridiculous API breakages from FIH. */
+ /* These idiots are returning -1 for FAR, and 1 for NEAR */
+ if (buffer[pollsDone].distance > 0) {
+ buffer[pollsDone].distance = 0;
+ } else {
+ buffer[pollsDone].distance = 1;
+ }
+#elif defined(PROXIMITY_LIES)
+ if (buffer[pollsDone].distance >= PROXIMITY_LIES)
+ buffer[pollsDone].distance = maxRange;
+#endif
+ return pollsDone+1;
+ } else if (sensorType == SENSOR_TYPE_LIGHT) {
+ return pollsDone+1;
+ }
+ pollsDone++;
+ }
+ return pollsDone;
+ } else {
+ return mSensorDevice->poll(mSensorDevice, buffer, count);
+ }
}
status_t SensorDevice::activate(void* ident, int handle, int enabled)
{
- if (!mSensorDevice) return NO_INIT;
+ if (!mSensorDevice && !mOldSensorsCompatMode) return NO_INIT;
status_t err(NO_ERROR);
bool actuateHardware = false;
+#ifdef USE_LGE_ALS_DUMMY
+
+ if (handle == SENSOR_TYPE_LIGHT) {
+ int nwr, ret, fd;
+ char value[2];
+
+#ifdef USE_LGE_ALS_OMAP3
+ fd = open("/sys/class/leds/lcd-backlight/als", O_RDWR);
+ if(fd < 0)
+ return -ENODEV;
+
+ nwr = sprintf(value, "%s\n", enabled ? "1" : "0");
+ write(fd, value, nwr);
+ close(fd);
+#else
+ fd = open("/sys/devices/platform/star_aat2870.0/lsensor_onoff", O_RDWR);
+ if(fd < 0)
+ return -ENODEV;
+
+ nwr = sprintf(value, "%s\n", enabled ? "1" : "0");
+ write(fd, value, nwr);
+ close(fd);
+ fd = open("/sys/devices/platform/star_aat2870.0/alc", O_RDWR);
+ if(fd < 0)
+ return -ENODEV;
+
+ nwr = sprintf(value, "%s\n", enabled ? "2" : "0");
+ write(fd, value, nwr);
+ close(fd);
+#endif
+
+ return 0;
+
+ }
+#endif
Info& info( mActivationCount.editValueFor(handle) );
@@ -213,7 +384,20 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
if (actuateHardware) {
LOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w");
- err = mSensorDevice->activate(mSensorDevice, handle, enabled);
+ if (mOldSensorsCompatMode) {
+ if (enabled)
+ mOldSensorsEnabled++;
+ else if (mOldSensorsEnabled > 0)
+ mOldSensorsEnabled--;
+ LOGV("Activation for %d (%d)",handle,enabled);
+ if (enabled) {
+ mSensorControlDevice->wake(mSensorControlDevice);
+ }
+ err = mSensorControlDevice->activate(mSensorControlDevice, handle, enabled);
+ err = 0;
+ } else {
+ err = mSensorDevice->activate(mSensorDevice, handle, enabled);
+ }
if (enabled) {
LOGE_IF(err, "Error activating sensor %d (%s)", handle, strerror(-err));
if (err == 0) {
@@ -229,7 +413,11 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
{ // scope for the lock
Mutex::Autolock _l(mLock);
nsecs_t ns = info.selectDelay();
- mSensorDevice->setDelay(mSensorDevice, handle, ns);
+ if (mOldSensorsCompatMode) {
+ mSensorControlDevice->set_delay(mSensorControlDevice, (ns/(1000*1000)));
+ } else {
+ mSensorDevice->setDelay(mSensorDevice, handle, ns);
+ }
}
return err;
@@ -237,13 +425,17 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled)
status_t SensorDevice::setDelay(void* ident, int handle, int64_t ns)
{
- if (!mSensorDevice) return NO_INIT;
+ if (!mSensorDevice && !mOldSensorsCompatMode) return NO_INIT;
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 (mOldSensorsCompatMode) {
+ return mSensorControlDevice->set_delay(mSensorControlDevice, (ns/(1000*1000)));
+ } else {
+ return mSensorDevice->setDelay(mSensorDevice, handle, ns);
+ }
}
// ---------------------------------------------------------------------------
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 728b6cb..919edf9 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -36,6 +36,13 @@ 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;
+ struct sensors_data_device_t* mSensorDataDevice;
+ struct sensors_control_device_t* mSensorControlDevice;
+ int32_t mOldSensorsEnabled;
+ bool mOldSensorsCompatMode;
+ native_handle_t *mOldSensorsDataChannel;
+ sensor_t const* mOldSensorsList;
+ int mOldSensorsCount;
struct sensors_module_t* mSensorModule;
mutable Mutex mLock; // protect mActivationCount[].rates
// fixed-size array after construction
diff --git a/services/sensorservice/sensors_deprecated.h b/services/sensorservice/sensors_deprecated.h
new file mode 100644
index 0000000..efaf6ba
--- /dev/null
+++ b/services/sensorservice/sensors_deprecated.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#define SENSORS_HARDWARE_CONTROL "control"
+#define SENSORS_HARDWARE_DATA "data"
+
+namespace android {
+
+typedef struct {
+ int sensor;
+ union {
+ sensors_vec_t vector;
+ sensors_vec_t orientation;
+ sensors_vec_t acceleration;
+ sensors_vec_t magnetic;
+ float temperature;
+ float distance;
+ float light;
+ };
+ int64_t time;
+ uint32_t reserved;
+} sensors_data_t;
+
+struct sensors_control_device_t {
+ struct hw_device_t common;
+ native_handle_t* (*open_data_source)(struct sensors_control_device_t *dev);
+ int (*close_data_source)(struct sensors_control_device_t *dev);
+ int (*activate)(struct sensors_control_device_t *dev,
+ int handle, int enabled);
+ int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms);
+ int (*wake)(struct sensors_control_device_t *dev);
+};
+
+struct sensors_data_device_t {
+ struct hw_device_t common;
+ int (*data_open)(struct sensors_data_device_t *dev, native_handle_t* nh);
+ int (*data_close)(struct sensors_data_device_t *dev);
+ int (*poll)(struct sensors_data_device_t *dev,
+ sensors_data_t* data);
+};
+
+static inline int sensors_control_open(const struct hw_module_t* module,
+ struct sensors_control_device_t** device) {
+ return module->methods->open(module,
+ SENSORS_HARDWARE_CONTROL, (struct hw_device_t**)device);
+}
+
+static inline int sensors_control_close(struct sensors_control_device_t* device) {
+ return device->common.close(&device->common);
+}
+
+static inline int sensors_data_open(const struct hw_module_t* module,
+ struct sensors_data_device_t** device) {
+ return module->methods->open(module,
+ SENSORS_HARDWARE_DATA, (struct hw_device_t**)device);
+}
+
+static inline int sensors_data_close(struct sensors_data_device_t* device) {
+ return device->common.close(&device->common);
+}
+
+};