summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron McCarthy <aaron.mccarthy@jollamobile.com>2013-09-06 15:46:27 +1000
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-21 11:13:34 +0100
commitf8323499944e5f6a44516d96cea5f824f5a7a4b9 (patch)
treecb552e8c135b9c325ed82a139a6705d355d91763
parent7d3d2498ae79b96f53fd960532ae81bfedf088c1 (diff)
downloadqtlocation-f8323499944e5f6a44516d96cea5f824f5a7a4b9.tar.gz
Don't require a position fix before reporting Geoclue satellite info.
The Geoclue plugin uses the Geoclue master provider to select the most appropriate position provider. However, it doesn't select a provider unless it is in the available state. For satellite information a position fix is not required. If the Geoclue master provider doesn't return a valid provider the plugin will now listen for all SatelliteChanged signals from any org.freedesktop.Geoclue.Satellite interface. This means that if multiple satellite based providers are active at the same time QGeoSatelliteInfoSource will include satellite information from both providers. Change-Id: I257b56dc03fed51a5c4ba0023862708b9618be05 Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
-rw-r--r--src/plugins/position/geoclue/geoclue.pro4
-rw-r--r--src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp109
-rw-r--r--src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h5
3 files changed, 111 insertions, 7 deletions
diff --git a/src/plugins/position/geoclue/geoclue.pro b/src/plugins/position/geoclue/geoclue.pro
index 81e39d8a..5c318645 100644
--- a/src/plugins/position/geoclue/geoclue.pro
+++ b/src/plugins/position/geoclue/geoclue.pro
@@ -14,9 +14,11 @@ SOURCES += \
qgeopositioninfosourcefactory_geoclue.cpp \
qgeocluemaster.cpp
-config_geoclue-satellite {
+qtHaveModule(dbus):config_geoclue-satellite {
DEFINES += HAS_SATELLITE
+ QT *= dbus
+
HEADERS += qgeosatelliteinfosource_geocluemaster.h
SOURCES += qgeosatelliteinfosource_geocluemaster.cpp
}
diff --git a/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp b/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp
index 35901d10..6dcedeec 100644
--- a/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp
+++ b/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp
@@ -41,6 +41,10 @@
#include "qgeosatelliteinfosource_geocluemaster.h"
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusArgument>
+
#define MINIMUM_UPDATE_INTERVAL 1000
QT_BEGIN_NAMESPACE
@@ -117,8 +121,41 @@ void satellite_callback(GeoclueSatellite *satellite, int timestamp, int satellit
}
+const QDBusArgument &operator>>(const QDBusArgument &argument, QGeoSatelliteInfo &si)
+{
+ int a;
+
+ argument.beginStructure();
+ argument >> a;
+ si.setSatelliteIdentifier(a);
+ argument >> a;
+ si.setAttribute(QGeoSatelliteInfo::Elevation, a);
+ argument >> a;
+ si.setAttribute(QGeoSatelliteInfo::Azimuth, a);
+ argument >> a;
+ si.setSignalStrength(a);
+ argument.endStructure();
+ return argument;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument, QList<QGeoSatelliteInfo> &sis)
+{
+ sis.clear();
+
+ argument.beginArray();
+ while (!argument.atEnd()) {
+ QGeoSatelliteInfo si;
+ argument >> si;
+ sis.append(si);
+ }
+ argument.endArray();
+
+ return argument;
+}
+
QGeoSatelliteInfoSourceGeoclueMaster::QGeoSatelliteInfoSourceGeoclueMaster(QObject *parent)
-: QGeoSatelliteInfoSource(parent), QGeoclueMaster(this), m_sat(0)
+: QGeoSatelliteInfoSource(parent), QGeoclueMaster(this), m_sat(0), m_error(NoError),
+ m_satellitesChangedConnected(false)
{
m_requestTimer.setSingleShot(true);
connect(&m_requestTimer, SIGNAL(timeout()), this, SIGNAL(requestTimeout()));
@@ -143,7 +180,7 @@ int QGeoSatelliteInfoSourceGeoclueMaster::minimumUpdateInterval() const
QGeoSatelliteInfoSource::Error QGeoSatelliteInfoSourceGeoclueMaster::error() const
{
- return NoError;
+ return m_error;
}
void QGeoSatelliteInfoSourceGeoclueMaster::startUpdates()
@@ -220,11 +257,71 @@ void QGeoSatelliteInfoSourceGeoclueMaster::positionProviderChanged(const QByteAr
if (m_sat)
cleanupSatelliteSource();
- m_sat = geoclue_satellite_new(service.constData(), path.constData());
- if (m_sat) {
- g_signal_connect(G_OBJECT(m_sat), "satellite-changed",
- G_CALLBACK(satellite_changed), this);
+ QByteArray providerService;
+ QByteArray providerPath;
+
+ if (service.isEmpty() || path.isEmpty()) {
+ // No valid position provider has been selected. This probably means that the GPS provider
+ // has not yet obtained a position fix. It can still provide satellite information though.
+ if (!m_satellitesChangedConnected) {
+ QDBusConnection conn = QDBusConnection::sessionBus();
+ conn.connect(QString(), QString(), QStringLiteral("org.freedesktop.Geoclue.Satellite"),
+ QStringLiteral("SatelliteChanged"), this,
+ SLOT(satellitesChanged(QDBusMessage)));
+ m_satellitesChangedConnected = true;
+ return;
+ }
+ } else {
+ if (m_satellitesChangedConnected) {
+ QDBusConnection conn = QDBusConnection::sessionBus();
+ conn.disconnect(QString(), QString(),
+ QStringLiteral("org.freedesktop.Geoclue.Satellite"),
+ QStringLiteral("SatelliteChanged"), this,
+ SLOT(satellitesChanged(QDBusMessage)));
+ m_satellitesChangedConnected = false;
+ }
+
+ providerService = service;
+ providerPath = path;
}
+
+ if (providerService.isEmpty() || providerPath.isEmpty()) {
+ m_error = AccessError;
+ emit QGeoSatelliteInfoSource::error(m_error);
+ return;
+ }
+
+ m_sat = geoclue_satellite_new(providerService.constData(), providerPath.constData());
+ if (!m_sat) {
+ m_error = AccessError;
+ emit QGeoSatelliteInfoSource::error(m_error);
+ return;
+ }
+
+ g_signal_connect(G_OBJECT(m_sat), "satellite-changed", G_CALLBACK(satellite_changed), this);
+}
+
+void QGeoSatelliteInfoSourceGeoclueMaster::satellitesChanged(const QDBusMessage &message)
+{
+ QVariantList arguments = message.arguments();
+ if (arguments.length() != 5)
+ return;
+
+ int timestamp = arguments.at(0).toInt();
+ int usedSatellites = arguments.at(1).toInt();
+ int visibleSatellites = arguments.at(2).toInt();
+
+ QDBusArgument dbusArgument = arguments.at(3).value<QDBusArgument>();
+
+ QList<int> usedPrn;
+ dbusArgument >> usedPrn;
+
+ dbusArgument = arguments.at(4).value<QDBusArgument>();
+
+ QList<QGeoSatelliteInfo> satelliteInfos;
+ dbusArgument >> satelliteInfos;
+
+ satelliteChanged(timestamp, usedSatellites, visibleSatellites, usedPrn, satelliteInfos);
}
bool QGeoSatelliteInfoSourceGeoclueMaster::configureSatelliteSource()
diff --git a/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h b/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h
index 1448f827..52cbb316 100644
--- a/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h
+++ b/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h
@@ -52,6 +52,8 @@
QT_BEGIN_NAMESPACE
+class QDBusMessage;
+
class QGeoSatelliteInfoSourceGeoclueMaster : public QGeoSatelliteInfoSource, public QGeoclueMaster
{
Q_OBJECT
@@ -77,6 +79,7 @@ public:
private slots:
void positionProviderChanged(const QByteArray &service, const QByteArray &path);
+ void satellitesChanged(const QDBusMessage &message);
private:
bool configureSatelliteSource();
@@ -86,6 +89,8 @@ private:
QTimer m_requestTimer;
QList<QGeoSatelliteInfo> m_inView;
QList<QGeoSatelliteInfo> m_inUse;
+ Error m_error;
+ bool m_satellitesChangedConnected;
};
QT_END_NAMESPACE