diff --git a/adaptors/hybrisaccelerometer/hybrisaccelerometeradaptor.cpp b/adaptors/hybrisaccelerometer/hybrisaccelerometeradaptor.cpp index 23a967d6..6800bc35 100644 --- a/adaptors/hybrisaccelerometer/hybrisaccelerometeradaptor.cpp +++ b/adaptors/hybrisaccelerometer/hybrisaccelerometeradaptor.cpp @@ -21,7 +21,6 @@ #include "hybrisaccelerometeradaptor.h" #include "logging.h" #include "datatypes/utils.h" -#include #include "config.h" #define GRAVITY_RECIPROCAL_THOUSANDS 101.971621298 @@ -66,9 +65,15 @@ void HybrisAccelerometerAdaptor::processSample(const sensors_event_t& data) d->timestamp_ = quint64(data.timestamp * .001); // sensorfw wants milli-G' +#ifdef USE_BINDER + d->x_ = data.u.vec3.x * GRAVITY_RECIPROCAL_THOUSANDS; + d->y_ = data.u.vec3.y * GRAVITY_RECIPROCAL_THOUSANDS; + d->z_ = data.u.vec3.z * GRAVITY_RECIPROCAL_THOUSANDS; +#else d->x_ = data.acceleration.x * GRAVITY_RECIPROCAL_THOUSANDS; d->y_ = data.acceleration.y * GRAVITY_RECIPROCAL_THOUSANDS; d->z_ = data.acceleration.z * GRAVITY_RECIPROCAL_THOUSANDS; +#endif buffer->commit(); buffer->wakeUpReaders(); diff --git a/adaptors/hybrisalsadaptor/hybrisalsadaptor.cpp b/adaptors/hybrisalsadaptor/hybrisalsadaptor.cpp index d3fc997a..c1c3f24c 100644 --- a/adaptors/hybrisalsadaptor/hybrisalsadaptor.cpp +++ b/adaptors/hybrisalsadaptor/hybrisalsadaptor.cpp @@ -24,7 +24,6 @@ #include "hybrisalsadaptor.h" #include "logging.h" #include "datatypes/utils.h" -#include #include "config.h" #include @@ -129,7 +128,11 @@ void HybrisAlsAdaptor::processSample(const sensors_event_t& data) { TimedUnsigned *d = buffer->nextSlot(); d->timestamp_ = quint64(data.timestamp * .001); +#ifdef USE_BINDER + d->value_ = data.u.scalar; +#else d->value_ = data.light; +#endif lastLightValue = d->value_; buffer->commit(); buffer->wakeUpReaders(); diff --git a/adaptors/hybrisgyroscopeadaptor/hybrisgyroscopeadaptor.cpp b/adaptors/hybrisgyroscopeadaptor/hybrisgyroscopeadaptor.cpp index 5e58ad9d..25868e1f 100644 --- a/adaptors/hybrisgyroscopeadaptor/hybrisgyroscopeadaptor.cpp +++ b/adaptors/hybrisgyroscopeadaptor/hybrisgyroscopeadaptor.cpp @@ -21,7 +21,6 @@ #include "hybrisgyroscopeadaptor.h" #include "logging.h" #include "datatypes/utils.h" -#include #include "config.h" #include @@ -73,9 +72,15 @@ void HybrisGyroscopeAdaptor::processSample(const sensors_event_t& data) TimedXyzData *d = buffer->nextSlot(); d->timestamp_ = quint64(data.timestamp * .001); +#ifdef USE_BINDER + d->x_ = (data.u.vec3.x) * RADIANS_TO_DEGREES * 1000; + d->y_ = (data.u.vec3.y) * RADIANS_TO_DEGREES * 1000; + d->z_ = (data.u.vec3.z) * RADIANS_TO_DEGREES * 1000; +#else d->x_ = (data.gyro.x) * RADIANS_TO_DEGREES * 1000; d->y_ = (data.gyro.y) * RADIANS_TO_DEGREES * 1000; d->z_ = (data.gyro.z) * RADIANS_TO_DEGREES * 1000; +#endif buffer->commit(); buffer->wakeUpReaders(); } diff --git a/adaptors/hybrismagnetometeradaptor/hybrismagnetometeradaptor.cpp b/adaptors/hybrismagnetometeradaptor/hybrismagnetometeradaptor.cpp index 0cf3fe77..ac718a2c 100644 --- a/adaptors/hybrismagnetometeradaptor/hybrismagnetometeradaptor.cpp +++ b/adaptors/hybrismagnetometeradaptor/hybrismagnetometeradaptor.cpp @@ -21,7 +21,6 @@ #include "hybrismagnetometeradaptor.h" #include "logging.h" #include "datatypes/utils.h" -#include #include "config.h" HybrisMagnetometerAdaptor::HybrisMagnetometerAdaptor(const QString& id) : @@ -68,6 +67,16 @@ void HybrisMagnetometerAdaptor::processSample(const sensors_event_t& data) { CalibratedMagneticFieldData *d = buffer->nextSlot(); d->timestamp_ = quint64(data.timestamp * .001); + +#ifdef USE_BINDER + d->x_ = data.u.vec3.x * 1000; + d->y_ = data.u.vec3.y * 1000; + d->z_ = data.u.vec3.z * 1000; + d->rx_ = data.u.vec3.x * 1000; + d->ry_ = data.u.vec3.y * 1000; + d->rz_ = data.u.vec3.z * 1000; + d->level_= data.u.vec3.status; +#else //uT d->x_ = (data.magnetic.x * 1000); d->y_ = (data.magnetic.y * 1000); @@ -81,7 +90,7 @@ void HybrisMagnetometerAdaptor::processSample(const sensors_event_t& data) d->rx_ = data.magnetic.x * 1000; d->ry_ = data.magnetic.y * 1000; d->rz_ = data.magnetic.z * 1000; - +#endif #endif buffer->commit(); buffer->wakeUpReaders(); diff --git a/adaptors/hybrisorientationadaptor/hybrisorientationadaptor.cpp b/adaptors/hybrisorientationadaptor/hybrisorientationadaptor.cpp index ede6eb51..95937d76 100644 --- a/adaptors/hybrisorientationadaptor/hybrisorientationadaptor.cpp +++ b/adaptors/hybrisorientationadaptor/hybrisorientationadaptor.cpp @@ -21,7 +21,6 @@ #include "hybrisorientationadaptor.h" #include "logging.h" #include "datatypes/utils.h" -#include #include "config.h" /* @@ -84,9 +83,14 @@ void HybrisOrientationAdaptor::processSample(const sensors_event_t& data) { CompassData *d = buffer->nextSlot(); d->timestamp_ = quint64(data.timestamp * .001); +#ifdef USE_BINDER + d->degrees_ = data.u.vec3.x; //azimuth + d->level_ = data.u.vec3.status; +#else d->degrees_ = data.orientation.azimuth; //azimuth - d->rawDegrees_ = d->degrees_; d->level_ = data.orientation.status; +#endif + d->rawDegrees_ = d->degrees_; buffer->commit(); buffer->wakeUpReaders(); diff --git a/adaptors/hybrispressureadaptor/hybrispressureadaptor.cpp b/adaptors/hybrispressureadaptor/hybrispressureadaptor.cpp index 49831137..fe50d3dd 100644 --- a/adaptors/hybrispressureadaptor/hybrispressureadaptor.cpp +++ b/adaptors/hybrispressureadaptor/hybrispressureadaptor.cpp @@ -26,7 +26,6 @@ #include "hybrispressureadaptor.h" #include "logging.h" #include "datatypes/utils.h" -#include #include "config.h" HybrisPressureAdaptor::HybrisPressureAdaptor(const QString& id) : @@ -70,7 +69,11 @@ void HybrisPressureAdaptor::processSample(const sensors_event_t& data) { TimedUnsigned *d = buffer->nextSlot(); d->timestamp_ = quint64(data.timestamp * .001); +#ifdef USE_BINDER + d->value_ = data.u.scalar * 100;//From hPa to Pa +#else d->value_ = data.pressure * 100;//From hPa to Pa +#endif buffer->commit(); buffer->wakeUpReaders(); } diff --git a/adaptors/hybrisproximityadaptor/hybrisproximityadaptor.cpp b/adaptors/hybrisproximityadaptor/hybrisproximityadaptor.cpp index a64f9f50..c76a7fea 100644 --- a/adaptors/hybrisproximityadaptor/hybrisproximityadaptor.cpp +++ b/adaptors/hybrisproximityadaptor/hybrisproximityadaptor.cpp @@ -25,7 +25,6 @@ #include "hybrisproximityadaptor.h" #include "logging.h" #include "datatypes/utils.h" -#include #include "config.h" #include #include @@ -138,11 +137,18 @@ void HybrisProximityAdaptor::processSample(const sensors_event_t& data) ProximityData *d = buffer->nextSlot(); d->timestamp_ = quint64(data.timestamp * .001); bool near = false; +#ifdef USE_BINDER + if (data.u.scalar < maxRange()) { + near = true; + } + d->value_ = data.u.scalar; +#else if (data.distance < maxRange()) { near = true; } - d->withinProximity_ = near; d->value_ = data.distance; +#endif + d->withinProximity_ = near; lastNearValue = near; buffer->commit(); diff --git a/adaptors/hybrisstepcounteradaptor/hybrisstepcounteradaptor.cpp b/adaptors/hybrisstepcounteradaptor/hybrisstepcounteradaptor.cpp index f32c3edd..f51318e7 100644 --- a/adaptors/hybrisstepcounteradaptor/hybrisstepcounteradaptor.cpp +++ b/adaptors/hybrisstepcounteradaptor/hybrisstepcounteradaptor.cpp @@ -24,7 +24,6 @@ #include "hybrisstepcounteradaptor.h" #include "logging.h" #include "datatypes/utils.h" -#include #include "config.h" #ifndef SENSOR_TYPE_STEP_COUNTER @@ -81,12 +80,16 @@ void HybrisStepCounterAdaptor::processSample(const sensors_event_t& data) { TimedUnsigned *d = buffer->nextSlot(); d->timestamp_ = quint64(data.timestamp * .001); +#ifdef USE_BINDER + d->value_ = data.u.stepCount; +#else #ifdef NO_SENSORS_EVENT_U64 uint64_t value = 0; memcpy(&value, data.data, sizeof value); d->value_ = value; #else d->value_ = data.u64.step_counter; +#endif #endif buffer->commit(); buffer->wakeUpReaders(); diff --git a/common-config.pri b/common-config.pri index 363ec6ac..4275bddb 100644 --- a/common-config.pri +++ b/common-config.pri @@ -38,7 +38,11 @@ OTHER_FILES += \ contains(CONFIG,hybris) { CONFIG += link_pkgconfig - PKGCONFIG += android-headers - PKGCONFIG += libhardware + contains(CONFIG,binder) { + DEFINES += USE_BINDER=1 + PKGCONFIG += libgbinder libglibutil gobject-2.0 glib-2.0 + } else { + PKGCONFIG += android-headers libhardware + } } diff --git a/core/hybris.pro b/core/hybris.pro index c38d89a6..7c377b97 100644 --- a/core/hybris.pro +++ b/core/hybris.pro @@ -5,9 +5,6 @@ TARGET = hybrissensorfw include( ../common-config.pri ) -CONFIG += link_pkgconfig -PKGCONFIG += android-headers - SENSORFW_INCLUDEPATHS = .. \ ../include \ ../filters \ @@ -20,7 +17,11 @@ QMAKE_LIBDIR_FLAGS += -lsensordatatypes-qt5 SOURCES += hybrisadaptor.cpp HEADERS += hybrisadaptor.h -LIBS += -L/usr/lib -lhybris-common -lhardware -L../datatypes +LIBS += -L/usr/lib -L../datatypes + +!contains(CONFIG,binder) { + LIBS += -lhybris-common -lhardware +} include(../common-install.pri) target.path = $$SHAREDLIBPATH diff --git a/core/hybrisadaptor.cpp b/core/hybrisadaptor.cpp index ec818b06..330901ee 100644 --- a/core/hybrisadaptor.cpp +++ b/core/hybrisadaptor.cpp @@ -25,8 +25,9 @@ #include #include +#ifndef USE_BINDER #include -#include +#endif #include #include @@ -34,6 +35,7 @@ #include #include + /* Older devices probably have old android hal and thus do * not define sensor all sensor types that have been added * later on -> In order to both use symbolic names and @@ -125,6 +127,12 @@ #define SENSOR_TYPE_WRIST_TILT_GESTURE (26) #endif +#ifdef USE_BINDER +#define SENSOR_BINDER_SERVICE_DEVICE "/dev/hwbinder" +#define SENSOR_BINDER_SERVICE_IFACE "android.hardware.sensors@1.0::ISensors" +#define SENSOR_BINDER_SERVICE_NAME SENSOR_BINDER_SERVICE_IFACE "/default" +#endif + /* ========================================================================= * * UTILITIES * ========================================================================= */ @@ -217,15 +225,26 @@ HybrisManager::HybrisManager(QObject *parent) : QObject(parent) , m_initialized(false) , m_registeredAdaptors() +#ifdef USE_BINDER + , m_client(NULL) + , m_deathId(0) + , m_pollTransactId(0) + , m_remote(NULL) + , m_serviceManager(NULL) +#else , m_halModule(NULL) , m_halDevice(NULL) - , m_halSensorCount(0) - , m_halSensorArray(NULL) - , m_halSensorState(NULL) - , m_halIndexOfType() - , m_halIndexOfHandle() , m_halEventReaderTid(0) +#endif + , m_sensorArray(NULL) + , m_sensorCount(0) + , m_sensorState(NULL) + , m_indexOfType() + , m_indexOfHandle() { +#ifdef USE_BINDER + startConnect(); +#else int err; /* Open android sensor plugin */ @@ -246,45 +265,60 @@ HybrisManager::HybrisManager(QObject *parent) } /* Get static sensor information */ - m_halSensorCount = m_halModule->get_sensors_list(m_halModule, &m_halSensorArray); + m_sensorCount = m_halModule->get_sensors_list(m_halModule, &m_sensorArray); + + initManager(); +#endif +} +void HybrisManager::initManager() +{ /* Reserve space for sensor state data */ - m_halSensorState = new HybrisSensorState[m_halSensorCount]; + m_sensorState = new HybrisSensorState[m_sensorCount]; /* Select and initialize sensors to be used */ - for (int i = 0 ; i < m_halSensorCount ; i++) { + for (int i = 0 ; i < m_sensorCount ; i++) { /* Always do handle -> index mapping */ - m_halIndexOfHandle.insert(m_halSensorArray[i].handle, i); + m_indexOfHandle.insert(m_sensorArray[i].handle, i); bool use = true; // Assumption: The primary sensor variants that we want to // use are listed before the secondary ones that we want // to ignore -> Use the 1st entry found for each sensor type. - if (m_halIndexOfType.contains(m_halSensorArray[i].type)) { + if (m_indexOfType.contains(m_sensorArray[i].type)) { use = false; } // some devices have compass and compass raw, // ignore compass raw. compass has range 360 - if (m_halSensorArray[i].type == SENSOR_TYPE_ORIENTATION && - m_halSensorArray[i].maxRange != 360) { + if (m_sensorArray[i].type == SENSOR_TYPE_ORIENTATION && + m_sensorArray[i].maxRange != 360) { use = false; } sensordLogD() << Q_FUNC_INFO << (use ? "SELECT" : "IGNORE") - << "type:" << m_halSensorArray[i].type - << "name:" << (m_halSensorArray[i].name ?: "n/a"); + << "type:" << m_sensorArray[i].type +#ifdef USE_BINDER + << "name:" << (m_sensorArray[i].name.data.str ?: "n/a"); +#else + << "name:" << (m_sensorArray[i].name ?: "n/a"); +#endif if (use) { // min/max delay is specified in [us] -> convert to [ms] - int minDelay = (m_halSensorArray[i].minDelay + 999) / 1000; + int minDelay = (m_sensorArray[i].minDelay + 999) / 1000; int maxDelay = -1; // Assume: not defined by hal +#ifdef USE_BINDER + maxDelay = (m_sensorArray[i].maxDelay + 999) / 1000; +#else #ifdef SENSORS_DEVICE_API_VERSION_1_3 if (m_halDevice->common.version >= SENSORS_DEVICE_API_VERSION_1_3) - maxDelay = (m_halSensorArray[i].maxDelay + 999) / 1000; + maxDelay = (m_sensorArray[i].maxDelay + 999) / 1000; #endif +#endif + /* If HAL does not define maximum delay, we need to invent * something that a) allows sensorfwd logic to see a range * instead of a point, b) is unlikely to be wrong enough to @@ -292,6 +326,7 @@ HybrisManager::HybrisManager(QObject *parent) * * For now use: minDelay * 2, but at least 1000 ms. */ + if (maxDelay < 0 && minDelay > 0) { maxDelay = (minDelay < 500) ? 1000 : (minDelay * 2); sensordLogD("hal does not specify maxDelay, fallback: %d ms", @@ -315,35 +350,46 @@ HybrisManager::HybrisManager(QObject *parent) else if (delay > maxDelay ) delay = maxDelay; - m_halSensorState[i].m_minDelay = minDelay; - m_halSensorState[i].m_maxDelay = maxDelay; + m_sensorState[i].m_minDelay = minDelay; + m_sensorState[i].m_maxDelay = maxDelay; - halSetActive(m_halSensorArray[i].handle, true); - halSetDelay(m_halSensorArray[i].handle, delay); + setDelay(m_sensorArray[i].handle, delay, true); + setActive(m_sensorArray[i].handle, true); + setDelay(m_sensorArray[i].handle, delay, false); sensordLogD("delay = %d [%d, %d]", - m_halSensorState[i].m_delay, - m_halSensorState[i].m_minDelay, - m_halSensorState[i].m_maxDelay); + m_sensorState[i].m_delay, + m_sensorState[i].m_minDelay, + m_sensorState[i].m_maxDelay); } - m_halIndexOfType.insert(m_halSensorArray[i].type, i); + m_indexOfType.insert(m_sensorArray[i].type, i); /* Set sane fallback values for select sensors in case the * hal does not report initial values. */ - sensors_event_t *eve = &m_halSensorState[i].m_fallbackEvent; - eve->version = sizeof *eve; - eve->sensor = m_halSensorArray[i].handle; - eve->type = m_halSensorArray[i].type; - switch (m_halSensorArray[i].type) { + sensors_event_t *eve = &m_sensorState[i].m_fallbackEvent; +#ifndef USE_BINDER + eve->version = sizeof *eve; +#endif + eve->sensor = m_sensorArray[i].handle; + eve->type = m_sensorArray[i].type; + switch (m_sensorArray[i].type) { case SENSOR_TYPE_LIGHT: // Roughly indoor lightning +#ifdef USE_BINDER + eve->u.scalar = 400; +#else eve->light = 400; +#endif break; case SENSOR_TYPE_PROXIMITY: // Not-covered - eve->distance = m_halSensorArray[i].maxRange; +#ifdef USE_BINDER + eve->u.scalar = m_sensorArray[i].maxRange; +#else + eve->distance = m_sensorArray[i].maxRange; +#endif break; default: eve->sensor = 0; @@ -353,9 +399,13 @@ HybrisManager::HybrisManager(QObject *parent) } /* Make sure all sensors are initially in stopped state */ - halSetActive(m_halSensorArray[i].handle, false); + setActive(m_sensorArray[i].handle, false); } +#ifdef USE_BINDER + pollEvents(); +#else + int err; /* Start android sensor event reader */ err = pthread_create(&m_halEventReaderTid, 0, halEventReaderThread, this); if (err) { @@ -366,15 +416,56 @@ HybrisManager::HybrisManager(QObject *parent) sensordLogD() << "Hal reader thread started"; m_initialized = true; +#endif } HybrisManager::~HybrisManager() +{ + cleanup(); + +#ifdef USE_BINDER + if (m_serviceManager) { + gbinder_servicemanager_unref(m_serviceManager); + m_serviceManager = NULL; + } +#endif +} + +void HybrisManager::cleanup() { sensordLogD() << "stop all sensors"; foreach (HybrisAdaptor *adaptor, m_registeredAdaptors.values()) { adaptor->stopSensor(); } +#ifdef USE_BINDER + if (m_pollTransactId) { + gbinder_client_cancel(m_client, m_pollTransactId); + m_pollTransactId = 0; + } + + if (m_client) { + gbinder_client_unref(m_client); + m_client = NULL; + } + if (m_remote) { + if (m_deathId) { + gbinder_remote_object_remove_handler(m_remote, m_deathId); + m_deathId = 0; + } + gbinder_remote_object_unref(m_remote); + m_remote = NULL; + } + + for (int i = 0 ; i < m_sensorCount ; i++) { + g_free((void*)m_sensorArray[i].name.data.str); + g_free((void*)m_sensorArray[i].vendor.data.str); + g_free((void*)m_sensorArray[i].typeAsString.data.str); + g_free((void*)m_sensorArray[i].requiredPermission.data.str); + } + delete[] m_sensorArray; + m_sensorArray = NULL; +#else if (m_halDevice) { sensordLogD() << "close sensor device"; int errorCode = sensors_close(m_halDevice); @@ -411,7 +502,11 @@ HybrisManager::~HybrisManager() _exit(EXIT_FAILURE); } } - delete[] m_halSensorState; +#endif + delete[] m_sensorState; + m_sensorState = NULL; + m_sensorCount = 0; + m_initialized = false; } HybrisManager *HybrisManager::instance() @@ -420,33 +515,163 @@ HybrisManager *HybrisManager::instance() return priv; } -int HybrisManager::halHandleForType(int sensorType) const +#ifdef USE_BINDER + +void HybrisManager::getSensorList() +{ + sensordLogD() << "Get sensor list"; + GBinderReader reader; + GBinderRemoteReply *reply; + int status; + + reply = gbinder_client_transact_sync_reply(m_client, GET_SENSORS_LIST, NULL, &status); + + if (status != GBINDER_STATUS_OK) { + sensordLogW() << "Unable to get sensor list: status " << status; + cleanup(); + sleep(1); + startConnect(); + return; + } + + gbinder_remote_reply_init_reader(reply, &reader); + gbinder_reader_read_int32(&reader, &status); + gsize count = 0; + gsize vecSize = 0; + sensor_t *vec = (sensor_t *)gbinder_reader_read_hidl_vec(&reader, &count, &vecSize); + + m_sensorCount = count; + m_sensorArray = new sensor_t[m_sensorCount]; + for (int i = 0 ; i < m_sensorCount ; i++) { + memcpy(&m_sensorArray[i], &vec[i], sizeof(sensor_t)); + + // Read strings + GBinderBuffer *buffer = gbinder_reader_read_buffer(&reader); + m_sensorArray[i].name.data.str = g_strdup((const gchar *)buffer->data); + m_sensorArray[i].name.len = buffer->size; + m_sensorArray[i].name.owns_buffer = true; + gbinder_buffer_free(buffer); + + buffer = gbinder_reader_read_buffer(&reader); + m_sensorArray[i].vendor.data.str = g_strdup((const gchar *)buffer->data); + m_sensorArray[i].vendor.len = buffer->size; + m_sensorArray[i].vendor.owns_buffer = true; + gbinder_buffer_free(buffer); + + buffer = gbinder_reader_read_buffer(&reader); + m_sensorArray[i].typeAsString.data.str = g_strdup((const gchar *)buffer->data); + m_sensorArray[i].typeAsString.len = buffer->size; + m_sensorArray[i].typeAsString.owns_buffer = true; + gbinder_buffer_free(buffer); + + buffer = gbinder_reader_read_buffer(&reader); + m_sensorArray[i].requiredPermission.data.str = g_strdup((const gchar *)buffer->data); + m_sensorArray[i].requiredPermission.len = buffer->size; + m_sensorArray[i].requiredPermission.owns_buffer = true; + gbinder_buffer_free(buffer); + } + gbinder_remote_reply_unref(reply); + + initManager(); + + m_initialized = true; + sensordLogW() << "Hybris sensor manager initialized"; +} + +void HybrisManager::binderDied(GBinderRemoteObject *, void *user_data) +{ + HybrisManager *conn = + static_cast(user_data); + sensordLogW() << "Sensor service died! Trying to reconnect."; + conn->cleanup(); + conn->startConnect(); +} + +void HybrisManager::startConnect() +{ + if (!m_serviceManager) { + m_serviceManager = gbinder_servicemanager_new(SENSOR_BINDER_SERVICE_DEVICE); + } + + if (gbinder_servicemanager_wait(m_serviceManager, -1)) { + finishConnect(); + } else { + sensordLogW() << "Could not get service manager for sensor service"; + cleanup(); + } +} + +void HybrisManager::finishConnect() +{ + m_remote = gbinder_servicemanager_get_service_sync(m_serviceManager, + SENSOR_BINDER_SERVICE_NAME, NULL); + if (!m_remote) { + sensordLogD() << "Could not find remote object for sensor service. Trying to reconnect."; + } else { + gbinder_remote_object_ref(m_remote); + sensordLogD() << "Connected to sensor service"; + m_deathId = gbinder_remote_object_add_death_handler(m_remote, binderDied, + this); + m_client = gbinder_client_new(m_remote, SENSOR_BINDER_SERVICE_IFACE); + if (!m_client) { + sensordLogD() << "Could not create client for sensor service. Trying to reconnect."; + } else { + // Sometimes sensor service has lingering connetion from + // previous client which causes sensor service to restart + // and we need to test with poll if remote is really working. + GBinderRemoteReply *reply; + GBinderLocalRequest *req = gbinder_client_new_request(m_client); + int32_t status; + + // Empty poll to test if remote is working + req = gbinder_local_request_append_int32(req, 0); + + reply = gbinder_client_transact_sync_reply(m_client, POLL, req, &status); + gbinder_local_request_unref(req); + gbinder_remote_reply_unref(reply); + + if (status != GBINDER_STATUS_OK) { + sensordLogW() << "Poll failed with status" << status << ". Trying to reconnect."; + } else { + getSensorList(); + return; + } + } + } + // On failure cleanup and wait before reconnecting + cleanup(); + sleep(1); + startConnect(); +} +#endif //USE_BINDER + +int HybrisManager::handleForType(int sensorType) const { - int index = halIndexForType(sensorType); - return (index < 0) ? -1 : m_halSensorArray[index].handle; + int index = indexForType(sensorType); + return (index < 0) ? -1 : m_sensorArray[index].handle; } -sensors_event_t *HybrisManager::halEventForHandle(int handle) const +sensors_event_t *HybrisManager::eventForHandle(int handle) const { sensors_event_t *event = 0; - int index = halIndexForHandle(handle); + int index = indexForHandle(handle); if (index != -1) { - event = &m_halSensorState[index].m_fallbackEvent; + event = &m_sensorState[index].m_fallbackEvent; } return event; } -int HybrisManager::halIndexForHandle(int handle) const +int HybrisManager::indexForHandle(int handle) const { - int index = m_halIndexOfHandle.value(handle, -1); + int index = m_indexOfHandle.value(handle, -1); if (index == -1) sensordLogW("HYBRIS CTL invalid sensor handle: %d", handle); return index; } -int HybrisManager::halIndexForType(int sensorType) const +int HybrisManager::indexForType(int sensorType) const { - int index = m_halIndexOfType.value(sensorType, -1); + int index = m_indexOfType.value(sensorType, -1); if (index == -1) sensordLogW("HYBRIS CTL invalid sensor type: %d", sensorType); return index; @@ -456,7 +681,7 @@ void HybrisManager::startReader(HybrisAdaptor *adaptor) { if (m_registeredAdaptors.values().contains(adaptor)) { sensordLogD() << "activating " << adaptor->name() << adaptor->m_sensorHandle; - if (!halSetActive(adaptor->m_sensorHandle, true)) { + if (!setActive(adaptor->m_sensorHandle, true)) { sensordLogW() <setValid(false); } @@ -467,7 +692,7 @@ void HybrisManager::stopReader(HybrisAdaptor *adaptor) { if (m_registeredAdaptors.values().contains(adaptor)) { sensordLogD() << "deactivating " << adaptor->name(); - if (!halSetActive(adaptor->m_sensorHandle, false)) { + if (!setActive(adaptor->m_sensorHandle, false)) { sensordLogW() <maxRange; sensordLogT("HYBRIS CTL getMaxRange(%d=%s) -> %g", @@ -505,13 +730,13 @@ float HybrisManager::halGetMaxRange(int handle) const return range; } -float HybrisManager::halGetResolution(int handle) const +float HybrisManager::getResolution(int handle) const { float resolution = 0; - int index = halIndexForHandle(handle); + int index = indexForHandle(handle); if (index != -1) { - const struct sensor_t *sensor = &m_halSensorArray[index]; + const struct sensor_t *sensor = &m_sensorArray[index]; resolution = sensor->resolution; sensordLogT("HYBRIS CTL getResolution(%d=%s) -> %g", @@ -521,14 +746,14 @@ float HybrisManager::halGetResolution(int handle) const return resolution; } -int HybrisManager::halGetMinDelay(int handle) const +int HybrisManager::getMinDelay(int handle) const { int delay = 0; - int index = halIndexForHandle(handle); + int index = indexForHandle(handle); if (index != -1) { - const struct sensor_t *sensor = &m_halSensorArray[index]; - HybrisSensorState *state = &m_halSensorState[index]; + const struct sensor_t *sensor = &m_sensorArray[index]; + HybrisSensorState *state = &m_sensorState[index]; delay = state->m_minDelay; sensordLogT("HYBRIS CTL getMinDelay(%d=%s) -> %d", @@ -538,14 +763,14 @@ int HybrisManager::halGetMinDelay(int handle) const return delay; } -int HybrisManager::halGetMaxDelay(int handle) const +int HybrisManager::getMaxDelay(int handle) const { int delay = 0; - int index = halIndexForHandle(handle); + int index = indexForHandle(handle); if (index != -1) { - const struct sensor_t *sensor = &m_halSensorArray[index]; - HybrisSensorState *state = &m_halSensorState[index]; + const struct sensor_t *sensor = &m_sensorArray[index]; + HybrisSensorState *state = &m_sensorState[index]; delay = state->m_maxDelay; sensordLogT("HYBRIS CTL getMaxDelay(%d=%s) -> %d", @@ -555,14 +780,14 @@ int HybrisManager::halGetMaxDelay(int handle) const return delay; } -int HybrisManager::halGetDelay(int handle) const +int HybrisManager::getDelay(int handle) const { int delay = 0; - int index = halIndexForHandle(handle); + int index = indexForHandle(handle); if (index != -1) { - const struct sensor_t *sensor = &m_halSensorArray[index]; - HybrisSensorState *state = &m_halSensorState[index]; + const struct sensor_t *sensor = &m_sensorArray[index]; + HybrisSensorState *state = &m_sensorState[index]; delay = state->m_delay; sensordLogT("HYBRIS CTL getDelay(%d=%s) -> %d", @@ -572,21 +797,49 @@ int HybrisManager::halGetDelay(int handle) const return delay; } -bool HybrisManager::halSetDelay(int handle, int delay_ms) +bool HybrisManager::setDelay(int handle, int delay_ms, bool force) { bool success = false; - int index = halIndexForHandle(handle); + int index = indexForHandle(handle); if (index != -1) { - const struct sensor_t *sensor = &m_halSensorArray[index]; - HybrisSensorState *state = &m_halSensorState[index]; + const struct sensor_t *sensor = &m_sensorArray[index]; + HybrisSensorState *state = &m_sensorState[index]; - if (state->m_delay == delay_ms) { + if (!force && state->m_delay == delay_ms) { sensordLogT("HYBRIS CTL setDelay(%d=%s, %d) -> no-change", sensor->handle, sensorTypeName(sensor->type), delay_ms); } else { int64_t delay_ns = delay_ms * 1000LL * 1000LL; +#ifdef USE_BINDER + int error; + GBinderLocalRequest *req = gbinder_client_new_request(m_client); + GBinderRemoteReply *reply; + GBinderReader reader; + GBinderWriter writer; + int32_t status; + + gbinder_local_request_init_writer(req, &writer); + + gbinder_writer_append_int32(&writer, sensor->handle); + gbinder_writer_append_int64(&writer, delay_ns); + gbinder_writer_append_int64(&writer, 0); + + reply = gbinder_client_transact_sync_reply(m_client, BATCH, req, &status); + gbinder_local_request_unref(req); + + if (status != GBINDER_STATUS_OK) { + sensordLogW() << "Set delay failed status " << status; + return false; + } + gbinder_remote_reply_init_reader(reply, &reader); + gbinder_reader_read_int32(&reader, &status); + gbinder_reader_read_int32(&reader, &error); + + gbinder_remote_reply_unref(reply); +#else int error = m_halDevice->setDelay(m_halDevice, sensor->handle, delay_ns); +#endif if (error) { sensordLogW("HYBRIS CTL setDelay(%d=%s, %d) -> %d=%s", sensor->handle, sensorTypeName(sensor->type), delay_ms, @@ -603,14 +856,14 @@ bool HybrisManager::halSetDelay(int handle, int delay_ms) return success; } -bool HybrisManager::halGetActive(int handle) const +bool HybrisManager::getActive(int handle) const { bool active = false; - int index = halIndexForHandle(handle); + int index = indexForHandle(handle); if (index != -1) { - const struct sensor_t *sensor = &m_halSensorArray[index]; - HybrisSensorState *state = &m_halSensorState[index]; + const struct sensor_t *sensor = &m_sensorArray[index]; + HybrisSensorState *state = &m_sensorState[index]; active = (state->m_active > 0); sensordLogT("HYBRIS CTL getActive(%d=%s) -> %s", @@ -620,21 +873,54 @@ bool HybrisManager::halGetActive(int handle) const return active; } -bool HybrisManager::halSetActive(int handle, bool active) +bool HybrisManager::setActive(int handle, bool active) { bool success = false; - int index = halIndexForHandle(handle); + int index = indexForHandle(handle); if (index != -1) { - const struct sensor_t *sensor = &m_halSensorArray[index]; - HybrisSensorState *state = &m_halSensorState[index]; + const struct sensor_t *sensor = &m_sensorArray[index]; + HybrisSensorState *state = &m_sensorState[index]; if (state->m_active == active) { sensordLogT("HYBRIS CTL setActive%d=%s, %s) -> no-change", sensor->handle, sensorTypeName(sensor->type), active ? "true" : "false"); success = true; } else { +#ifdef USE_BINDER + if (active && state->m_delay != -1) { + sensordLogD("HYBRIS CTL FORCE PRE UPDATE %i, %s", sensor->handle, sensorTypeName(sensor->type)); + int delay_ms = state->m_delay; + state->m_delay = -1; + setDelay(handle, delay_ms, true); + } + int error; + GBinderLocalRequest *req = gbinder_client_new_request(m_client); + GBinderRemoteReply *reply; + GBinderReader reader; + GBinderWriter writer; + int32_t status; + + gbinder_local_request_init_writer(req, &writer); + + gbinder_writer_append_int32(&writer, sensor->handle); + gbinder_writer_append_int32(&writer, active); + + reply = gbinder_client_transact_sync_reply(m_client, ACTIVATE, req, &status); + gbinder_local_request_unref(req); + + if (status != GBINDER_STATUS_OK) { + sensordLogW() << "Activate failed status " << status; + return false; + } + gbinder_remote_reply_init_reader(reply, &reader); + gbinder_reader_read_int32(&reader, &status); + gbinder_reader_read_int32(&reader, &error); + + gbinder_remote_reply_unref(reply); +#else int error = m_halDevice->activate(m_halDevice, sensor->handle, active); +#endif if (error) { sensordLogW("HYBRIS CTL setActive%d=%s, %s) -> %d=%s", sensor->handle, sensorTypeName(sensor->type), active ? "true" : "false", @@ -645,22 +931,84 @@ bool HybrisManager::halSetActive(int handle, bool active) state->m_active = active; success = true; } +#ifndef USE_BINDER if (state->m_active == true && state->m_delay != -1) { sensordLogD("HYBRIS CTL FORCE DELAY UPDATE"); int delay_ms = state->m_delay; state->m_delay = -1; - halSetDelay(handle, delay_ms); + setDelay(handle, delay_ms, false); } +#endif } } return success; } +#ifdef USE_BINDER +/** + * pollEvents is only called during initialization and after that from pollEventsCallback + * triggered by binder reply so there is only maximum of one active poll at all times + */ +void HybrisManager::pollEvents() +{ + if (m_client) { + GBinderLocalRequest *req = gbinder_client_new_request(m_client); + + req = gbinder_local_request_append_int32(req, 16); // Same number as for HAL + + m_pollTransactId = gbinder_client_transact(m_client, POLL, 0, req, pollEventsCallback, 0, this); + gbinder_local_request_unref(req); + } +} + +void HybrisManager::pollEventsCallback( + GBinderClient* /*client*/, + GBinderRemoteReply* reply, + int status, + void* userData) +{ + HybrisManager *manager = static_cast(userData); + bool blockSuspend = false; + bool errorInInput = false; + GBinderReader reader; + int32_t readerStatus; + int32_t result; + sensors_event_t *buffer; + + manager->m_pollTransactId = 0; + + if (status != GBINDER_STATUS_OK) { + sensordLogW() << "Poll failed status " << status; + // In case of binder failure sleep a little before attempting a new poll + struct timespec ts = { 0, 50 * 1000 * 1000 }; // 50 ms + do { } while (nanosleep(&ts, &ts) == -1 && errno == EINTR); + } else { + // Read sensor events from reply + gbinder_remote_reply_init_reader(reply, &reader); + gbinder_reader_read_int32(&reader, &readerStatus); + gbinder_reader_read_int32(&reader, &result); + gsize structSize = 0; + gsize eventCount = 0; + + buffer = (sensors_event_t *)gbinder_reader_read_hidl_vec(&reader, &eventCount , &structSize); + manager->processEvents(buffer, eventCount, blockSuspend, errorInInput); + + if (blockSuspend) { + ObtainTemporaryWakeLock(); + } + } + // Initiate new poll + manager->pollEvents(); +} + +#else + void *HybrisManager::halEventReaderThread(void *aptr) { HybrisManager *manager = static_cast(aptr); static const size_t numEvents = 16; sensors_event_t buffer[numEvents]; + /* Async cancellation, but disabled */ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); @@ -686,27 +1034,8 @@ void *HybrisManager::halEventReaderThread(void *aptr) /* Process received events */ bool blockSuspend = false; bool errorInInput = false; - for (int i = 0; i < numberOfEvents; i++) { - const sensors_event_t& data = buffer[i]; + manager->processEvents(buffer, numberOfEvents, blockSuspend, errorInInput); - sensordLogT("HYBRIS EVE %s", sensorTypeName(data.type)); - - /* Got data -> Clear the no longer needed fallback event */ - sensors_event_t *fallback = manager->halEventForHandle(data.sensor); - if (fallback && fallback->type == data.type && fallback->sensor == data.sensor) { - fallback->type = fallback->sensor = 0; - } - - if (data.version != sizeof(sensors_event_t)) { - sensordLogW()<< QString("incorrect event version (version=%1, expected=%2").arg(data.version).arg(sizeof(sensors_event_t)); - errorInInput = true; - } - if (data.type == SENSOR_TYPE_PROXIMITY) { - blockSuspend = true; - } - // FIXME: is this thread safe? - manager->processSample(data); - } /* Suspend proof sensor reporting that could occur in display off */ if (blockSuspend) { ObtainTemporaryWakeLock(); @@ -719,6 +1048,37 @@ void *HybrisManager::halEventReaderThread(void *aptr) } return 0; } +#endif + +void HybrisManager::processEvents(const sensors_event_t *buffer, int numberOfEvents, bool &blockSuspend, bool &errorInInput) +{ + for (int i = 0; i < numberOfEvents; i++) { + const sensors_event_t& data = buffer[i]; + + sensordLogT("HYBRIS EVE %s", sensorTypeName(data.type)); + + /* Got data -> Clear the no longer needed fallback event */ + sensors_event_t *fallback = eventForHandle(data.sensor); + if (fallback && fallback->type == data.type && fallback->sensor == data.sensor) { + fallback->type = fallback->sensor = 0; + } + +#ifdef USE_BINDER + Q_UNUSED(errorInInput); +#else + if (data.version != sizeof(sensors_event_t)) { + sensordLogW()<< QString("incorrect event version (version=%1, expected=%2").arg(data.version).arg(sizeof(sensors_event_t)); + errorInInput = true; + } +#endif + + if (data.type == SENSOR_TYPE_PROXIMITY) { + blockSuspend = true; + } + // FIXME: is this thread safe? + processSample(data); + } +} /* ========================================================================= * * HybrisAdaptor @@ -732,7 +1092,7 @@ HybrisAdaptor::HybrisAdaptor(const QString& id, int type) , m_sensorHandle(-1) , m_sensorType(type) { - m_sensorHandle = hybrisManager()->halHandleForType(m_sensorType); + m_sensorHandle = hybrisManager()->handleForType(m_sensorType); if (m_sensorHandle == -1) { sensordLogW() << Q_FUNC_INFO <<"no such sensor" << id; setValid(false); @@ -789,12 +1149,12 @@ qreal HybrisAdaptor::minRange() const qreal HybrisAdaptor::maxRange() const { - return hybrisManager()->halGetMaxRange(m_sensorHandle); + return hybrisManager()->getMaxRange(m_sensorHandle); } qreal HybrisAdaptor::resolution() const { - return hybrisManager()->halGetResolution(m_sensorHandle); + return hybrisManager()->getResolution(m_sensorHandle); } /* ------------------------------------------------------------------------- * @@ -803,30 +1163,30 @@ qreal HybrisAdaptor::resolution() const unsigned int HybrisAdaptor::minInterval() const { - return hybrisManager()->halGetMinDelay(m_sensorHandle); + return hybrisManager()->getMinDelay(m_sensorHandle); } unsigned int HybrisAdaptor::maxInterval() const { - return hybrisManager()->halGetMaxDelay(m_sensorHandle); + return hybrisManager()->getMaxDelay(m_sensorHandle); } unsigned int HybrisAdaptor::interval() const { - return hybrisManager()->halGetDelay(m_sensorHandle); + return hybrisManager()->getDelay(m_sensorHandle); } bool HybrisAdaptor::setInterval(const unsigned int value, const int sessionId) { Q_UNUSED(sessionId); - bool ok = hybrisManager()->halSetDelay(m_sensorHandle, value); + bool ok = hybrisManager()->setDelay(m_sensorHandle, value, false); if (!ok) { sensordLogW() << Q_FUNC_INFO << "setInterval not ok"; } else { /* If we have not yet received sensor data, apply fallback value */ - sensors_event_t *fallback = hybrisManager()->halEventForHandle(m_sensorHandle); + sensors_event_t *fallback = hybrisManager()->eventForHandle(m_sensorHandle); if (fallback && fallback->sensor == m_sensorHandle && fallback->type == m_sensorType) { sensordLogT("HYBRIS FALLBACK type:%s sensor:%d", sensorTypeName(fallback->type), @@ -913,7 +1273,7 @@ void HybrisAdaptor::evaluateSensor() } /* If we have not yet received sensor data, apply fallback value */ - sensors_event_t *fallback = hybrisManager()->halEventForHandle(m_sensorHandle); + sensors_event_t *fallback = hybrisManager()->eventForHandle(m_sensorHandle); if (fallback && fallback->sensor == m_sensorHandle && fallback->type == m_sensorType) { sensordLogT("HYBRIS FALLBACK type:%s sensor:%d", sensorTypeName(fallback->type), diff --git a/core/hybrisadaptor.h b/core/hybrisadaptor.h index 82843450..9a04eba7 100644 --- a/core/hybrisadaptor.h +++ b/core/hybrisadaptor.h @@ -26,10 +26,16 @@ #include #include -#include - #include "deviceadaptor.h" + +#ifdef USE_BINDER +#include +#include "hybrisbindertypes.h" +#else #include +#include +#endif + #define SENSORFW_MCE_WATCHER class HybrisAdaptor; @@ -54,23 +60,25 @@ class HybrisManager : public QObject explicit HybrisManager(QObject *parent = 0); virtual ~HybrisManager(); + void cleanup(); + void initManager(); /* - - - - - - - - - - - - - - - - - - - * - * android sensor hal functions + * android sensor functions * - - - - - - - - - - - - - - - - - - - */ - sensors_event_t *halEventForHandle(int handle) const; - int halIndexForHandle(int handle) const; - int halIndexForType (int sensorType) const; - int halHandleForType (int sensorType) const; - float halGetMaxRange (int handle) const; - float halGetResolution (int handle) const; - int halGetMinDelay (int handle) const; - int halGetMaxDelay (int handle) const; - int halGetDelay (int handle) const; - bool halSetDelay (int handle, int delay_ms); - bool halGetActive (int handle) const; - bool halSetActive (int handle, bool active); + sensors_event_t *eventForHandle(int handle) const; + int indexForHandle(int handle) const; + int indexForType (int sensorType) const; + int handleForType (int sensorType) const; + float getMaxRange (int handle) const; + float getResolution (int handle) const; + int getMinDelay (int handle) const; + int getMaxDelay (int handle) const; + int getDelay (int handle) const; + bool setDelay (int handle, int delay_ms, bool force); + bool getActive (int handle) const; + bool setActive (int handle, bool active); /* - - - - - - - - - - - - - - - - - - - * * HybrisManager <--> sensorfwd @@ -85,19 +93,46 @@ class HybrisManager : public QObject // fields bool m_initialized; QMap m_registeredAdaptors; // type -> obj + +#ifdef USE_BINDER + // Binder backend + GBinderClient *m_client; + gulong m_deathId; + gulong m_pollTransactId; + GBinderRemoteObject *m_remote; + GBinderServiceManager *m_serviceManager; + struct sensor_t *m_sensorArray; // [m_sensorCount] +#else + // HAL backend struct sensors_module_t *m_halModule; struct sensors_poll_device_t *m_halDevice; - int m_halSensorCount; - const struct sensor_t *m_halSensorArray; // [m_halSensorCount] - HybrisSensorState *m_halSensorState; // [m_halSensorCount] - QMap m_halIndexOfType; // type -> index - QMap m_halIndexOfHandle; // handle -> index pthread_t m_halEventReaderTid; + const struct sensor_t *m_sensorArray; // [m_sensorCount] +#endif + int m_sensorCount; + HybrisSensorState *m_sensorState; // [m_sensorCount] + QMap m_indexOfType; // type -> index + QMap m_indexOfHandle; // handle -> index + +#ifdef USE_BINDER + void getSensorList(); + void startConnect(); + void finishConnect(); + static void binderDied(GBinderRemoteObject *, void *user_data); + void pollEvents(); + static void pollEventsCallback( + GBinderClient* /*client*/, GBinderRemoteReply* reply, + int status, void* userData); +#endif friend class HybrisAdaptorReader; +#ifndef USE_BINDER private: static void *halEventReaderThread(void *aptr); +#endif + void processEvents(const sensors_event_t *buffer, + int numberOfEvents, bool &blockSuspend, bool &errorInInput); }; class HybrisAdaptor : public DeviceAdaptor diff --git a/core/hybrisbindertypes.h b/core/hybrisbindertypes.h new file mode 100644 index 00000000..83612d1b --- /dev/null +++ b/core/hybrisbindertypes.h @@ -0,0 +1,278 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Jolla Ltd +** Contact: matti.lehtimaki@jolla.com +** +** +** $QT_BEGIN_LICENSE:LGPL$ +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef HYBRIS_BINDER_TYPES_H +#define HYBRIS_BINDER_TYPES_H + +#include +#include +#include + +#define STATUS_OK 0 + +#define ALIGNED(x) __attribute__ ((aligned(x))) + +enum binder_calls { + // MUST be in the same order as the interfaces in ISensors.hidl + GET_SENSORS_LIST = GBINDER_FIRST_CALL_TRANSACTION, + SET_OPERATION_MODE, + ACTIVATE, + POLL, + BATCH, + FLUSH, + INJECT_SENSOR_DATA, + REGISTER_DIRECT_CHANNEL, + UNREGISTER_DIRECT_CHANNEL, + CONFIG_DIRECT_REPORT, +}; + +enum { + RESULT_OK = 0, + RESULT_PERMISSION_DENIED = -1, + RESULT_NO_MEMORY = -12, + RESULT_BAD_VALUE = -22, + RESULT_INVALID_OPERATION = -38, +}; + +enum { + OPERATION_MODE_NORMAL = 0, + OPERATION_MODE_DATA_INJECTION = 1, +}; + +enum { + SENSOR_TYPE_META_DATA = 0, + SENSOR_TYPE_ACCELEROMETER = 1, + SENSOR_TYPE_MAGNETIC_FIELD = 2, + SENSOR_TYPE_ORIENTATION = 3, + SENSOR_TYPE_GYROSCOPE = 4, + SENSOR_TYPE_LIGHT = 5, + SENSOR_TYPE_PRESSURE = 6, + SENSOR_TYPE_TEMPERATURE = 7, + SENSOR_TYPE_PROXIMITY = 8, + SENSOR_TYPE_GRAVITY = 9, + SENSOR_TYPE_LINEAR_ACCELERATION = 10, + SENSOR_TYPE_ROTATION_VECTOR = 11, + SENSOR_TYPE_RELATIVE_HUMIDITY = 12, + SENSOR_TYPE_AMBIENT_TEMPERATURE = 13, + SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14, + SENSOR_TYPE_GAME_ROTATION_VECTOR = 15, + SENSOR_TYPE_GYROSCOPE_UNCALIBRATED = 16, + SENSOR_TYPE_SIGNIFICANT_MOTION = 17, + SENSOR_TYPE_STEP_DETECTOR = 18, + SENSOR_TYPE_STEP_COUNTER = 19, + SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR = 20, + SENSOR_TYPE_HEART_RATE = 21, + SENSOR_TYPE_TILT_DETECTOR = 22, + SENSOR_TYPE_WAKE_GESTURE = 23, + SENSOR_TYPE_GLANCE_GESTURE = 24, + SENSOR_TYPE_PICK_UP_GESTURE = 25, + SENSOR_TYPE_WRIST_TILT_GESTURE = 26, + SENSOR_TYPE_DEVICE_ORIENTATION = 27, + SENSOR_TYPE_POSE_6DOF = 28, + SENSOR_TYPE_STATIONARY_DETECT = 29, + SENSOR_TYPE_MOTION_DETECT = 30, + SENSOR_TYPE_HEART_BEAT = 31, + SENSOR_TYPE_DYNAMIC_SENSOR_META = 32, + SENSOR_TYPE_ADDITIONAL_INFO = 33, + SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT = 34, + SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED = 35, + SENSOR_TYPE_DEVICE_PRIVATE_BASE = 65536, // 0x10000 +}; + +enum { + SENSOR_FLAG_WAKE_UP = 1u, // 1 + SENSOR_FLAG_CONTINUOUS_MODE = 0u, // 0 + SENSOR_FLAG_ON_CHANGE_MODE = 2u, // 2 + SENSOR_FLAG_ONE_SHOT_MODE = 4u, // 4 + SENSOR_FLAG_SPECIAL_REPORTING_MODE = 6u, // 6 + SENSOR_FLAG_DATA_INJECTION = 16u, // 0x10 + SENSOR_FLAG_DYNAMIC_SENSOR = 32u, // 0x20 + SENSOR_FLAG_ADDITIONAL_INFO = 64u, // 0x40 + SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM = 1024u, // 0x400 + SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC = 2048u, // 0x800 + SENSOR_FLAG_MASK_REPORTING_MODE = 14u, // 0xE + SENSOR_FLAG_MASK_DIRECT_REPORT = 896u, // 0x380 + SENSOR_FLAG_MASK_DIRECT_CHANNEL = 3072u, // 0xC00 +}; + +struct sensor_t { + int32_t handle ALIGNED(4); + gbinder_hidl_string name ALIGNED(8); + gbinder_hidl_string vendor ALIGNED(8); + int32_t version ALIGNED(4); + int32_t type ALIGNED(4); + gbinder_hidl_string typeAsString ALIGNED(8); + float maxRange ALIGNED(4); + float resolution ALIGNED(4); + float power ALIGNED(4); + int32_t minDelay ALIGNED(4); + uint32_t fifoReservedEventCount ALIGNED(4); + uint32_t fifoMaxEventCount ALIGNED(4); + gbinder_hidl_string requiredPermission ALIGNED(8); + int32_t maxDelay ALIGNED(4); + uint32_t flags ALIGNED(4); +} ALIGNED(8); + +static_assert(sizeof(sensor_t) == 112, "wrong size"); + +enum { + NO_CONTACT = -1, // (-1) + UNRELIABLE = 0, + ACCURACY_LOW = 1, + ACCURACY_MEDIUM = 2, + ACCURACY_HIGH = 3, +}; + +struct Vec3 { + float x ALIGNED(4); + float y ALIGNED(4); + float z ALIGNED(4); + int8_t status ALIGNED(1); +} ALIGNED(4); + +static_assert(sizeof(Vec3) == 16, "wrong size"); + +struct Vec4 { + float x ALIGNED(4); + float y ALIGNED(4); + float z ALIGNED(4); + float w ALIGNED(4); +} ALIGNED(4); + +static_assert(sizeof(Vec4) == 16, "wrong size"); + +struct Uncal { + float x ALIGNED(4); + float y ALIGNED(4); + float z ALIGNED(4); + float x_bias ALIGNED(4); + float y_bias ALIGNED(4); + float z_bias ALIGNED(4); +} ALIGNED(4); + +static_assert(sizeof(Uncal) == 24, "wrong size"); + +struct HeartRate { + float bpm ALIGNED(4); + int8_t status ALIGNED(1); +} ALIGNED(4); + +static_assert(sizeof(HeartRate) == 8, "wrong size"); + +enum { + META_DATA_FLUSH_COMPLETE = 1u, // 1 +}; + +struct MetaData { + uint32_t what ALIGNED(4); +} ALIGNED(4); + +static_assert(sizeof(MetaData) == 4, "wrong size"); + +struct Dynamicsensor_t { + bool connected ALIGNED(1); + int32_t handle ALIGNED(4); + uint8_t uuid[16] ALIGNED(1); +} ALIGNED(4); + +static_assert(sizeof(Dynamicsensor_t) == 24, "wrong size"); + +enum class AdditionalInfoType : uint32_t { + AINFO_BEGIN = 0u, // 0 + AINFO_END = 1u, // 1 + AINFO_UNTRACKED_DELAY = 65536u, // 0x10000 + AINFO_INTERNAL_TEMPERATURE = 65537u, // 65537 + AINFO_VEC3_CALIBRATION = 65538u, // 65538 + AINFO_SENSOR_PLACEMENT = 65539u, // 65539 + AINFO_SAMPLING = 65540u, // 65540 + AINFO_CHANNEL_NOISE = 131072u, // 0x20000 + AINFO_CHANNEL_SAMPLER = 131073u, // 131073 + AINFO_CHANNEL_FILTER = 131074u, // 131074 + AINFO_CHANNEL_LINEAR_TRANSFORM = 131075u, // 131075 + AINFO_CHANNEL_NONLINEAR_MAP = 131076u, // 131076 + AINFO_CHANNEL_RESAMPLER = 131077u, // 131077 + AINFO_LOCAL_GEOMAGNETIC_FIELD = 196608u, // 0x30000 + AINFO_LOCAL_GRAVITY = 196609u, // 196609 + AINFO_DOCK_STATE = 196610u, // 196610 + AINFO_HIGH_PERFORMANCE_MODE = 196611u, // 196611 + AINFO_MAGNETIC_FIELD_CALIBRATION = 196612u, // 196612 + AINFO_CUSTOM_START = 268435456u, // 0x10000000 + AINFO_DEBUGGING_START = 1073741824u, // 0x40000000 +}; + +struct AdditionalInfo { + union Payload { + int32_t data_int32[14] ALIGNED(4); + float data_float[14] ALIGNED(4); + } ALIGNED(4); + + static_assert(sizeof(AdditionalInfo::Payload) == 56, "wrong size"); + + AdditionalInfoType type ALIGNED(4); + int32_t serial ALIGNED(4); + AdditionalInfo::Payload u ALIGNED(4); +} ALIGNED(4); + +static_assert(sizeof(AdditionalInfo) == 64, "wrong size"); + +union SensorEventPayload { + Vec3 vec3 ALIGNED(4); + Vec4 vec4 ALIGNED(4); + Uncal uncal ALIGNED(4); + MetaData meta ALIGNED(4); + float scalar ALIGNED(4); + uint64_t stepCount ALIGNED(8); + HeartRate heartRate ALIGNED(4); + float pose6DOF[15] ALIGNED(4); + Dynamicsensor_t dynamic ALIGNED(4); + AdditionalInfo additional ALIGNED(4); + float data[16] ALIGNED(4); +} ALIGNED(8); + +static_assert(sizeof(SensorEventPayload) == 64, "wrong size"); + +struct sensors_event_t { + int64_t timestamp ALIGNED(8); + int32_t sensor ALIGNED(4); + int32_t type ALIGNED(4); + SensorEventPayload u ALIGNED(8); +} ALIGNED(8); + +static_assert(sizeof(sensors_event_t) == 80, "wrong size"); + +enum class RateLevel : int32_t { + STOP = 0, + NORMAL = 1, + FAST = 2, + VERY_FAST = 3, +}; + +enum class SensorsEventFormatOffset : uint16_t { + SIZE_FIELD = 0, // 0x0 + REPORT_TOKEN = 4, // 0x4 + SENSOR_TYPE = 8, // 0x8 + ATOMIC_COUNTER = 12, // 0xC + TIMESTAMP = 16, // 0x10 + DATA = 24, // 0x18 + RESERVED = 88, // 0x58 + TOTAL_LENGTH = 104, // 0x68 +}; + +#endif // HYBRIS_BINDER_TYPES_H diff --git a/filters/declinationfilter/declinationfilter.cpp b/filters/declinationfilter/declinationfilter.cpp index cc44c282..bcb8ccd5 100644 --- a/filters/declinationfilter/declinationfilter.cpp +++ b/filters/declinationfilter/declinationfilter.cpp @@ -35,7 +35,8 @@ const char* DeclinationFilter::declinationKey = "/system/osso/location/settings/ DeclinationFilter::DeclinationFilter() : Filter(this, &DeclinationFilter::correct), - declinationCorrection_(0) + declinationCorrection_(0), + lastUpdate_(0) { updateInterval_ = SensorFrameworkConfig::configuration()->value("compass/declination_update_interval", 1000 * 60 * 60) * 1000; loadSettings(); diff --git a/rpm/sensorfw-qt5-binder.spec b/rpm/sensorfw-qt5-binder.spec new file mode 100644 index 00000000..a92454a4 --- /dev/null +++ b/rpm/sensorfw-qt5-binder.spec @@ -0,0 +1,11 @@ +Name: hybris-libsensorfw-qt5-binder +Provides: hybris-libsensorfw-qt5 = %{version}-%{release} +Conflicts: hybris-libsensorfw-qt5-hal +Obsoletes: hybris-libsensorfw-qt5 < %{version}-%{release} + +BuildRequires: pkgconfig(libgbinder) + +# additional parameters for qmake +%define qmake_extra_parameters CONFIG+=binder + +%include rpm/sensorfw-qt5-hybris.inc diff --git a/rpm/sensorfw-qt5-hybris.inc b/rpm/sensorfw-qt5-hybris.inc new file mode 100644 index 00000000..548aa7da --- /dev/null +++ b/rpm/sensorfw-qt5-hybris.inc @@ -0,0 +1,67 @@ +Summary: Sensor Framework Qt5 +Version: 0.10.9 +Release: 0 +Group: System/Sensor Framework +License: LGPLv2+ +URL: http://gitorious.org/sensorfw +Source0: %{name}-%{version}.tar.bz2 +# Eventhough this is not really needed we have this here +# as this is added to packaging dir by tar_git. +Source2: sensorfwd.service +Requires: sensord-qt5 +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +BuildRequires: pkgconfig(Qt5Core) +BuildRequires: pkgconfig(Qt5DBus) +BuildRequires: pkgconfig(Qt5Network) +BuildRequires: pkgconfig(Qt5Test) +BuildRequires: pkgconfig(mlite5) +BuildRequires: pkgconfig(sensord-qt5) +Obsoletes: %{name}-configs <= 0.8.17 + +%description +Sensor Framework provides an interface to hardware sensor drivers through logical sensors. This package contains sensor framework daemon and required libraries. + +%package devel +Summary: Sensor framework daemon libraries development headers +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: qt5-qtcore-devel +Requires: qt5-qtdbus-devel +Requires: qt5-qtnetwork-devel + +%description devel +Development headers for sensor framework daemon and libraries. + +%prep +%setup -q -n %{name}-%{version} + +%build +unset LD_AS_NEEDED +export LD_RUN_PATH=/usr/lib/sensord-qt5/ +export QT_SELECT=5 + +%qmake5 CONFIG+=hybris %{qmake_extra_parameters} PC_VERSION=`echo %{version} | sed 's/+.*//'` + +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} +export QT_SELECT=5 +%qmake5_install + +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + +%files +%defattr(-,root,root,-) +%{_libdir}/libhybrissensorfw*.so.* +%{_libdir}/libhybrissensorfw*.so +%{_libdir}/sensord-qt5/*.so + +%files devel +%defattr(-,root,root,-) +%{_includedir}/sensord-qt5/* diff --git a/rpm/sensorfw-qt5-hybris.spec b/rpm/sensorfw-qt5-hybris.spec index 8ff0c948..83cb846b 100644 --- a/rpm/sensorfw-qt5-hybris.spec +++ b/rpm/sensorfw-qt5-hybris.spec @@ -1,70 +1,12 @@ -Name: hybris-libsensorfw-qt5 -Summary: Sensor Framework Qt5 -Version: 0.10.9 -Release: 0 -Group: System/Sensor Framework -License: LGPLv2+ -URL: http://gitorious.org/sensorfw -Source0: %{name}-%{version}.tar.bz2 -# Eventhough these are really needed we have these here -# as those are added to packaging dir by tar_git. -Source2: sensorfwd.service -Requires: sensord-qt5 -Requires(post): /sbin/ldconfig -Requires(postun): /sbin/ldconfig -BuildRequires: pkgconfig(Qt5Core) -BuildRequires: pkgconfig(Qt5DBus) -BuildRequires: pkgconfig(Qt5Network) -BuildRequires: pkgconfig(Qt5Test) -BuildRequires: pkgconfig(mlite5) -BuildRequires: pkgconfig(sensord-qt5) +Name: hybris-libsensorfw-qt5-hal +Provides: hybris-libsensorfw-qt5 = %{version}-%{release} +Conflicts: hybris-libsensorfw-qt5-binder +Obsoletes: hybris-libsensorfw-qt5 < %{version}-%{release} + BuildRequires: pkgconfig(libhardware) BuildRequires: pkgconfig(android-headers) -Obsoletes: %{name}-configs <= 0.8.17 - -%description -Sensor Framework provides an interface to hardware sensor drivers through logical sensors. This package contains sensor framework daemon and required libraries. - -%package devel -Summary: Sensor framework daemon libraries development headers -Group: Development/Libraries -Requires: %{name} = %{version}-%{release} -Requires: qt5-qtcore-devel -Requires: qt5-qtdbus-devel -Requires: qt5-qtnetwork-devel - -%description devel -Development headers for sensor framework daemon and libraries. - -%prep -%setup -q -n %{name}-%{version} - -%build -unset LD_AS_NEEDED -export LD_RUN_PATH=/usr/lib/sensord-qt5/ -export QT_SELECT=5 - -%qmake5 CONFIG+=hybris PC_VERSION=`echo %{version} | sed 's/+.*//'` - -make %{?_smp_mflags} - -%install -rm -rf %{buildroot} -export QT_SELECT=5 -%qmake5_install - -%post -/sbin/ldconfig - -%postun -/sbin/ldconfig -%files -%defattr(-,root,root,-) -%{_libdir}/libhybrissensorfw*.so.* -%{_libdir}/libhybrissensorfw*.so -%{_libdir}/sensord-qt5/*.so +# additional parameters for qmake +%define qmake_extra_parameters %{nil} -%files devel -%defattr(-,root,root,-) -%{_includedir}/sensord-qt5/* +%include rpm/sensorfw-qt5-hybris.inc