diff options
Diffstat (limited to 'src/plugins/sensors/eandroid/eandroidsensordevice.cpp')
-rw-r--r-- | src/plugins/sensors/eandroid/eandroidsensordevice.cpp | 182 |
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(); +} |