summaryrefslogtreecommitdiffstats
path: root/src/plugins/sensors/eandroid/eandroidsensordevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/sensors/eandroid/eandroidsensordevice.cpp')
-rw-r--r--src/plugins/sensors/eandroid/eandroidsensordevice.cpp182
1 files changed, 182 insertions, 0 deletions
diff --git a/src/plugins/sensors/eandroid/eandroidsensordevice.cpp b/src/plugins/sensors/eandroid/eandroidsensordevice.cpp
new file mode 100644
index 0000000..178ef8f
--- /dev/null
+++ b/src/plugins/sensors/eandroid/eandroidsensordevice.cpp
@@ -0,0 +1,182 @@
+#include <eandroidsensordevice.h>
+
+EventReaderThread::EventReaderThread(EAndroidSensorDevice *device) :
+ m_device(device)
+{
+}
+
+SensorEventArray* EventReaderThread::lock()
+{
+ m_mutex.lock();
+ return &m_events;
+}
+
+void EventReaderThread::run()
+{
+ static const size_t numEvents = 16;
+ sensors_event_t buffer[numEvents];
+ int err = 0;
+ int n;
+ do {
+ n = m_device->m_sensorDevice->poll(m_device->m_sensorDevice, buffer, numEvents);
+ if (n < 0) {
+ qWarning("poll() failed (%s)\n", strerror(-err));
+ break;
+ }
+ m_mutex.lock();
+ for (int i = 0 ; i < n ; i++) {
+ sensors_event_t& event = buffer[i];
+ if (event.version != sizeof(sensors_event_t)) {
+ qWarning("incorrect event version (version=%d, expected=%d",
+ event.version, sizeof(sensors_event_t));
+ break;
+ }
+ m_events.append(event);
+ }
+ m_mutex.unlock();
+ eventPending();
+ } while (true);
+}
+
+EAndroidSensorDevice::EAndroidSensorDevice()
+ : m_eventThread(0),
+ m_sensorModule(0),
+ m_availableSensorsList(0)
+{
+ initSensorDevice();
+ m_eventThread = new EventReaderThread(this);
+ connect(m_eventThread, SIGNAL(eventPending()), this,
+ SLOT(processSensorEvents()), Qt::QueuedConnection);
+}
+
+EAndroidSensorDevice* EAndroidSensorDevice::m_instance = 0;
+EAndroidSensorDevice* EAndroidSensorDevice::instance()
+{
+ if (!m_instance)
+ m_instance = new EAndroidSensorDevice();
+ return m_instance;
+}
+
+void EAndroidSensorDevice::registerListener(int type, EAndroidBaseSensor *sensor, int dataRateHz)
+{
+ bool startReaderThread = m_listenersHash.isEmpty();
+ bool enableSensor = m_listenersHash[type].isEmpty();
+ m_listenersHash[type].push_back(sensor);
+ if (startReaderThread)
+ m_eventThread->start();
+ if (enableSensor) {
+ setActive(type, true);
+ setDelay(type, dataRateHz);
+ }
+}
+
+void EAndroidSensorDevice::unregisterListener(int type, EAndroidBaseSensor *sensor)
+{
+ m_listenersHash[type].removeOne(sensor);
+ bool disableSensor = m_listenersHash[type].isEmpty();
+ if (disableSensor)
+ m_listenersHash.remove(type);
+ bool stopReaderThread = m_listenersHash.isEmpty();
+ if (stopReaderThread)
+ m_eventThread->quit();
+ if (disableSensor)
+ setActive(type, false);
+}
+
+int EAndroidSensorDevice::indexForType(int type) const
+{
+ for (int i = 0; i < m_availableSensors; ++i)
+ if (m_availableSensorsList[i].type == type)
+ return i;
+ qWarning() << "invalid sensor type: " << type;
+ return -1;
+}
+
+void EAndroidSensorDevice::setActive(int type, bool enable)
+{
+ for (int i = 0; i < m_availableSensors; i++) {
+ if (m_availableSensorsList[i].type == type) {
+ int err = m_sensorDevice->activate(m_sensorDevice,
+ m_availableSensorsList[i].handle, enable);
+ if (err != 0)
+ qWarning("activate() for '%s'failed (%s)\n",
+ m_availableSensorsList[i].name, strerror(-err));
+ }
+ }
+}
+
+void EAndroidSensorDevice::setDelay(int type, int dataRateHz) const
+{
+ qint64 ns;
+ // convert microseconds to nanoseconds
+ qint32 maxRateNs = maxDataRate(type) * 1000;
+ if (dataRateHz == 0) {
+ // if dataRateHz is not set, then we use maxRateNs
+ ns = maxRateNs;
+ } else {
+ // convert Hz to nanoseconds
+ ns = 1000000000LL / dataRateHz;
+ if (ns > maxRateNs)
+ ns = maxRateNs;
+ }
+ int index = indexForType(type);
+ if (index != -1)
+ m_sensorDevice->setDelay(m_sensorDevice,
+ m_availableSensorsList[index].handle, ns);
+
+}
+
+qint32 EAndroidSensorDevice::maxDataRate(int type) const
+{
+ // minDelay - minimum delay allowed between events in microseconds
+ int index = indexForType(type);
+ if (index != -1)
+ return m_availableSensorsList[index].minDelay;
+ return 0;
+}
+
+QString EAndroidSensorDevice::description(int type) const
+{
+ int index = indexForType(type);
+ if (index != -1) {
+ QString desc;
+ desc.append(m_availableSensorsList[index].name);
+ desc.append(QString(" (Vendor:%1) ").arg(m_availableSensorsList[index].vendor));
+ return desc;
+ }
+ return QString();
+}
+
+int EAndroidSensorDevice::availableSensors(sensor_t const** list) const
+{
+ return m_sensorModule->get_sensors_list(m_sensorModule, list);
+}
+
+void EAndroidSensorDevice::initSensorDevice()
+{
+ int err = 0;
+ err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
+ (hw_module_t const**)&m_sensorModule);
+ if (err != 0)
+ qWarning("hw_get_module() failed (%s)\n", strerror(-err));
+
+ if (m_sensorModule) {
+ err = sensors_open(&m_sensorModule->common, &m_sensorDevice);
+ if (err != 0)
+ qWarning("sensors_open() failed (%s)\n", strerror(-err));
+ }
+ m_availableSensors = m_sensorModule->get_sensors_list(m_sensorModule,
+ &m_availableSensorsList);
+}
+
+void EAndroidSensorDevice::processSensorEvents() const
+{
+ SensorEventArray *eventqueue = m_eventThread->lock();
+ for (int i = 0; i < eventqueue->size(); i++) {
+ sensors_event_t event = eventqueue->at(i);
+ foreach (EAndroidBaseSensor *sensorListener, m_listenersHash[event.type])
+ sensorListener->processEvent(event);
+ }
+ eventqueue->clear();
+ m_eventThread->unlock();
+}