summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAaron McCarthy <mccarthy.aaron@gmail.com>2015-01-20 11:48:16 +1000
committerAaron McCarthy <mccarthy.aaron@gmail.com>2015-09-10 07:46:11 +0000
commita3cb74a7ce3d4d138deb2e895288a36a1b3ce3ce (patch)
treeea69a2d563be4dee567be5bde8de0ddcadcf7074 /src
parentf6a48c06d3090e553867db327665b3cc44d9b21a (diff)
downloadqtlocation-a3cb74a7ce3d4d138deb2e895288a36a1b3ce3ce.tar.gz
Remove dependency on libgeoclue.
Re-implement Geoclue plugin using only Qt DBus dropping both the build-time and run-time dependency on libgeoclue. Allowing the Geoclue plugin to be build on all platforms that support Qt DBus. The priority of the Geoclue plugin has been lowered slightly so that the native position plugin, if available, has precedence. [ChangeLog][QtPositioning][Position] The Geoclue plugin has been re-implemented using Qt DBus. Task-number: QTBUG-40702 Change-Id: Ia06d089bfb46c10769ccffd765c044c361a9b484 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/position/geoclue/geoclue.pro37
-rw-r--r--src/plugins/position/geoclue/geocluetypes.cpp99
-rw-r--r--src/plugins/position/geoclue/geocluetypes.h87
-rw-r--r--src/plugins/position/geoclue/org.freedesktop.Geoclue.Master.xml10
-rw-r--r--src/plugins/position/geoclue/org.freedesktop.Geoclue.MasterClient.xml41
-rw-r--r--src/plugins/position/geoclue/org.freedesktop.Geoclue.Position.xml25
-rw-r--r--src/plugins/position/geoclue/org.freedesktop.Geoclue.Satellite.xml33
-rw-r--r--src/plugins/position/geoclue/org.freedesktop.Geoclue.Velocity.xml20
-rw-r--r--src/plugins/position/geoclue/org.freedesktop.Geoclue.xml24
-rw-r--r--src/plugins/position/geoclue/plugin-satellite.json8
-rw-r--r--src/plugins/position/geoclue/plugin.json4
-rw-r--r--src/plugins/position/geoclue/qgeocluemaster.cpp121
-rw-r--r--src/plugins/position/geoclue/qgeocluemaster.h40
-rw-r--r--src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.cpp374
-rw-r--r--src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.h (renamed from src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster_p.h)87
-rw-r--r--src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp16
-rw-r--r--src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h23
-rw-r--r--src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp254
-rw-r--r--src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h37
-rw-r--r--src/plugins/position/position.pro2
-rw-r--r--src/positioning/doc/src/qtpositioning.qdoc8
21 files changed, 800 insertions, 550 deletions
diff --git a/src/plugins/position/geoclue/geoclue.pro b/src/plugins/position/geoclue/geoclue.pro
index a3c34ece..0d9aab7d 100644
--- a/src/plugins/position/geoclue/geoclue.pro
+++ b/src/plugins/position/geoclue/geoclue.pro
@@ -1,32 +1,37 @@
TARGET = qtposition_geoclue
-QT = core positioning
+QT = core positioning dbus
PLUGIN_TYPE = position
PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryGeoclue
load(qt_plugin)
HEADERS += \
- qgeopositioninfosource_geocluemaster_p.h \
+ qgeopositioninfosource_geocluemaster.h \
+ qgeosatelliteinfosource_geocluemaster.h \
qgeopositioninfosourcefactory_geoclue.h \
- qgeocluemaster.h
+ qgeocluemaster.h \
+ geocluetypes.h
SOURCES += \
qgeopositioninfosource_geocluemaster.cpp \
+ qgeosatelliteinfosource_geocluemaster.cpp \
qgeopositioninfosourcefactory_geoclue.cpp \
- qgeocluemaster.cpp
+ qgeocluemaster.cpp \
+ geocluetypes.cpp
+
+QDBUSXML2CPP_INTERFACE_HEADER_FLAGS += "-N -i geocluetypes.h"
+DBUS_INTERFACES += \
+ org.freedesktop.Geoclue.MasterClient.xml \
+ org.freedesktop.Geoclue.Master.xml \
+ org.freedesktop.Geoclue.Position.xml \
+ org.freedesktop.Geoclue.Velocity.xml \
+ org.freedesktop.Geoclue.Satellite.xml \
+ org.freedesktop.Geoclue.xml
-qtHaveModule(dbus):config_geoclue-satellite {
- DEFINES += HAS_SATELLITE
-
- QT *= dbus
-
- HEADERS += qgeosatelliteinfosource_geocluemaster.h
- SOURCES += qgeosatelliteinfosource_geocluemaster.cpp
-}
+OTHER_FILES += \
+ $$DBUS_INTERFACES
-CONFIG += link_pkgconfig
-PKGCONFIG += geoclue
+INCLUDEPATH += $$QT.location.includes $$OUT_PWD
OTHER_FILES += \
- plugin.json \
- plugin-satellite.json
+ plugin.json
diff --git a/src/plugins/position/geoclue/geocluetypes.cpp b/src/plugins/position/geoclue/geocluetypes.cpp
new file mode 100644
index 00000000..ece3d113
--- /dev/null
+++ b/src/plugins/position/geoclue/geocluetypes.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Aaron McCarthy <mccarthy.aaron@gmail.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPositioning module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "geocluetypes.h"
+
+const QDBusArgument &dbus_argument_helper(const QDBusArgument &arg, Accuracy &accuracy)
+{
+ arg.beginStructure();
+ qint32 level;
+ arg >> level;
+ accuracy.m_level = static_cast<Accuracy::Level>(level);
+ arg >> accuracy.m_horizontal;
+ arg >> accuracy.m_vertical;
+ arg.endStructure();
+
+ return arg;
+}
+
+QT_BEGIN_NAMESPACE
+
+QDBusArgument &operator<<(QDBusArgument &arg, const Accuracy &accuracy)
+{
+ arg.beginStructure();
+ arg << qint32(accuracy.level());
+ arg << accuracy.horizontal();
+ arg << accuracy.vertical();
+ arg.endStructure();
+
+ return arg;
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &arg, Accuracy &accuracy)
+{
+ return dbus_argument_helper(arg, accuracy);
+}
+
+const QDBusArgument &operator>>(const QDBusArgument &argument, QGeoSatelliteInfo &si)
+{
+ qint32 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;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/position/geoclue/geocluetypes.h b/src/plugins/position/geoclue/geocluetypes.h
new file mode 100644
index 00000000..ff748b13
--- /dev/null
+++ b/src/plugins/position/geoclue/geocluetypes.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Aaron McCarthy <mccarthy.aaron@gmail.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPositioning module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GEOCLUETYPES_H
+#define GEOCLUETYPES_H
+
+#include <QtDBus/QDBusArgument>
+#include <QtPositioning/QGeoSatelliteInfo>
+
+class Accuracy
+{
+public:
+ enum Level {
+ None = 0,
+ Country,
+ Region,
+ Locality,
+ PostalCode,
+ Street,
+ Detailed
+ };
+
+ Accuracy()
+ : m_level(None), m_horizontal(0), m_vertical(0)
+ {
+ }
+
+ inline Level level() const { return m_level; }
+ inline double horizontal() const { return m_horizontal; }
+ inline double vertical() const { return m_vertical; }
+
+private:
+ Level m_level;
+ double m_horizontal;
+ double m_vertical;
+
+ friend const QDBusArgument &dbus_argument_helper(const QDBusArgument &arg, Accuracy &accuracy);
+};
+
+Q_DECLARE_METATYPE(Accuracy)
+Q_DECLARE_METATYPE(QList<QGeoSatelliteInfo>)
+
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_TYPEINFO(Accuracy, Q_MOVABLE_TYPE);
+
+QDBusArgument &operator<<(QDBusArgument &arg, const Accuracy &accuracy);
+const QDBusArgument &operator>>(const QDBusArgument &arg, Accuracy &accuracy);
+
+const QDBusArgument &operator>>(const QDBusArgument &arg, QGeoSatelliteInfo &si);
+const QDBusArgument &operator>>(const QDBusArgument &arg, QList<QGeoSatelliteInfo> &sis);
+
+QT_END_NAMESPACE
+
+#endif // GEOCLUETYPES_H
+
diff --git a/src/plugins/position/geoclue/org.freedesktop.Geoclue.Master.xml b/src/plugins/position/geoclue/org.freedesktop.Geoclue.Master.xml
new file mode 100644
index 00000000..e7df140c
--- /dev/null
+++ b/src/plugins/position/geoclue/org.freedesktop.Geoclue.Master.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.Geoclue.Master">
+ <method name="Create">
+ <arg name="path" type="o" direction="out"/>
+ </method>
+ </interface>
+</node>
+
diff --git a/src/plugins/position/geoclue/org.freedesktop.Geoclue.MasterClient.xml b/src/plugins/position/geoclue/org.freedesktop.Geoclue.MasterClient.xml
new file mode 100644
index 00000000..29c95885
--- /dev/null
+++ b/src/plugins/position/geoclue/org.freedesktop.Geoclue.MasterClient.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.Geoclue.MasterClient">
+ <method name="GetPositionProvider">
+ <arg name="name" type="s" direction="out"/>
+ <arg name="description" type="s" direction="out"/>
+ <arg name="service" type="s" direction="out"/>
+ <arg name="path" type="s" direction="out"/>
+ </method>
+ <method name="GetAddressProvider">
+ <arg name="name" type="s" direction="out"/>
+ <arg name="description" type="s" direction="out"/>
+ <arg name="service" type="s" direction="out"/>
+ <arg name="path" type="s" direction="out"/>
+ </method>
+ <method name="PositionStart">
+ </method>
+ <method name="AddressStart">
+ </method>
+ <method name="SetRequirements">
+ <arg name="accuracyLevel" type="i" direction="in"/>
+ <arg name="time" type="i" direction="in"/>
+ <arg name="requireUpdates" type="b" direction="in"/>
+ <arg name="allowedResources" type="i" direction="in"/>
+ </method>
+ <signal name="PositionProviderChanged">
+ <arg name="name" type="s"/>
+ <arg name="description" type="s"/>
+ <arg name="service" type="s"/>
+ <arg name="path" type="s"/>
+ </signal>
+ <signal name="AddressProviderChanged">
+ <arg name="name" type="s"/>
+ <arg name="description" type="s"/>
+ <arg name="service" type="s"/>
+ <arg name="path" type="s"/>
+ </signal>
+ </interface>
+</node>
+
diff --git a/src/plugins/position/geoclue/org.freedesktop.Geoclue.Position.xml b/src/plugins/position/geoclue/org.freedesktop.Geoclue.Position.xml
new file mode 100644
index 00000000..ce5c80de
--- /dev/null
+++ b/src/plugins/position/geoclue/org.freedesktop.Geoclue.Position.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.Geoclue.Position">
+ <method name="GetPosition">
+ <arg name="fields" type="i" direction="out"/>
+ <arg name="timestamp" type="i" direction="out"/>
+ <arg name="latitude" type="d" direction="out"/>
+ <arg name="longitude" type="d" direction="out"/>
+ <arg name="altitude" type="d" direction="out"/>
+ <arg name="accuracy" type="(idd)" direction="out"/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.Out5" value="Accuracy"/>
+ </method>
+ <signal name="PositionChanged">
+ <arg name="fields" type="i"/>
+ <arg name="timestamp" type="i"/>
+ <arg name="latitude" type="d"/>
+ <arg name="longitude" type="d"/>
+ <arg name="altitude" type="d"/>
+ <arg name="accuracy" type="(idd)"/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In5" value="Accuracy"/>
+ </signal>
+ </interface>
+</node>
+
diff --git a/src/plugins/position/geoclue/org.freedesktop.Geoclue.Satellite.xml b/src/plugins/position/geoclue/org.freedesktop.Geoclue.Satellite.xml
new file mode 100644
index 00000000..2ed112c9
--- /dev/null
+++ b/src/plugins/position/geoclue/org.freedesktop.Geoclue.Satellite.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.Satellite">
+ <method name="GetSatellite">
+ <arg name="timestamp" type="i" direction="out" />
+ <arg name="satelliteUsed" type="i" direction="out" />
+ <arg name="satelliteVisible" type="i" direction="out" />
+ <arg name="usedPrn" type="ai" direction="out" />
+ <arg name="satInfo" type="a(iiii)" direction="out" />
+ <annotation name="org.qtproject.QtDBus.QtTypeName.Out3" value="QList&lt;qint32&gt;"/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.Out4" value="QList&lt;QGeoSatelliteInfo&gt;"/>
+ </method>
+ <method name="GetLastSatellite">
+ <arg name="timestamp" type="i" direction="out" />
+ <arg name="satelliteUsed" type="i" direction="out" />
+ <arg name="satelliteVisible" type="i" direction="out" />
+ <arg name="usedPrn" type="ai" direction="out" />
+ <arg name="satInfo" type="a(iiii)" direction="out" />
+ <annotation name="org.qtproject.QtDBus.QtTypeName.Out3" value="QList&lt;qint32&gt;"/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.Out4" value="QList&lt;QGeoSatelliteInfo&gt;"/>
+ </method>
+ <signal name="SatelliteChanged">
+ <arg name="timestamp" type="i" />
+ <arg name="satelliteUsed" type="i" />
+ <arg name="satelliteVisible" type="i" />
+ <arg name="usedPrn" type="ai" />
+ <arg name="satInfo" type="a(iiii)" />'
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In3" value="QList&lt;qint32&gt;"/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In4" value="QList&lt;QGeoSatelliteInfo&gt;"/>
+ </signal>
+ </interface>
+</node>
diff --git a/src/plugins/position/geoclue/org.freedesktop.Geoclue.Velocity.xml b/src/plugins/position/geoclue/org.freedesktop.Geoclue.Velocity.xml
new file mode 100644
index 00000000..a1be122a
--- /dev/null
+++ b/src/plugins/position/geoclue/org.freedesktop.Geoclue.Velocity.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/">
+ <interface name="org.freedesktop.Geoclue.Velocity">
+ <method name="GetVelocity">
+ <arg name="fields" type="i" direction="out" />
+ <arg name="timestamp" type="i" direction="out" />
+ <arg name="speed" type="d" direction="out" />
+ <arg name="direction" type="d" direction="out" />
+ <arg name="climb" type="d" direction="out" />
+ </method>
+ <signal name="VelocityChanged">
+ <arg name="fields" type="i" />
+ <arg name="timestamp" type="i" />
+ <arg name="speed" type="d" />
+ <arg name="direction" type="d" />
+ <arg name="climb" type="d" />
+ </signal>
+ </interface>
+</node>
diff --git a/src/plugins/position/geoclue/org.freedesktop.Geoclue.xml b/src/plugins/position/geoclue/org.freedesktop.Geoclue.xml
new file mode 100644
index 00000000..c9b6f635
--- /dev/null
+++ b/src/plugins/position/geoclue/org.freedesktop.Geoclue.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.freedesktop.Geoclue">
+ <method name="RemoveReference">
+ </method>
+ <method name="AddReference">
+ </method>
+ <method name="SetOptions">
+ <arg name="options" type="a{sv}" direction="in"/>
+ <annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
+ </method>
+ <method name="GetStatus">
+ <arg name="status" type="i" direction="out"/>
+ </method>
+ <method name="GetProviderInfo">
+ <arg name="name" type="s" direction="out"/>
+ <arg name="description" type="s" direction="out"/>
+ </method>
+ <signal name="StatusChanged">
+ <arg name="status" type="i"/>
+ </signal>
+ </interface>
+</node>
diff --git a/src/plugins/position/geoclue/plugin-satellite.json b/src/plugins/position/geoclue/plugin-satellite.json
deleted file mode 100644
index cf03d6ed..00000000
--- a/src/plugins/position/geoclue/plugin-satellite.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "Keys": ["geoclue"],
- "Provider": "geoclue",
- "Position": true,
- "Satellite": true,
- "Priority": 1000,
- "Testable": false
-}
diff --git a/src/plugins/position/geoclue/plugin.json b/src/plugins/position/geoclue/plugin.json
index f11d27cb..82f8afc6 100644
--- a/src/plugins/position/geoclue/plugin.json
+++ b/src/plugins/position/geoclue/plugin.json
@@ -2,8 +2,8 @@
"Keys": ["geoclue"],
"Provider": "geoclue",
"Position": true,
- "Satellite": false,
+ "Satellite": true,
"Monitor": false,
- "Priority": 1000,
+ "Priority": 999,
"Testable": false
}
diff --git a/src/plugins/position/geoclue/qgeocluemaster.cpp b/src/plugins/position/geoclue/qgeocluemaster.cpp
index 7c340ba7..db074f59 100644
--- a/src/plugins/position/geoclue/qgeocluemaster.cpp
+++ b/src/plugins/position/geoclue/qgeocluemaster.cpp
@@ -33,94 +33,79 @@
#include "qgeocluemaster.h"
-#include <QtCore/QByteArray>
-#include <QtCore/QMetaMethod>
+#include <master_interface.h>
+#include <geoclue_interface.h>
+#include <masterclient_interface.h>
QT_BEGIN_NAMESPACE
-namespace
+QGeoclueMaster::QGeoclueMaster(QObject *parent)
+: QObject(parent), m_master(0), m_provider(0), m_client(0)
{
-
-void position_provider_changed(GeoclueMasterClient *client, char *name, char *description,
- char *service, char *path, QObject *handler)
-{
- Q_UNUSED(client)
- Q_UNUSED(name)
- Q_UNUSED(description)
-
- const QByteArray pService = QByteArray(service);
- const QByteArray pPath = QByteArray(path);
-
- QMetaObject::invokeMethod(handler, "positionProviderChanged", Qt::QueuedConnection,
- Q_ARG(QByteArray, pService), Q_ARG(QByteArray, pPath));
-}
-
-}
-
-QGeoclueMaster::QGeoclueMaster(QObject *handler)
-: m_client(0), m_masterPosition(0), m_handler(handler)
-{
-#if !defined(GLIB_VERSION_2_36)
- g_type_init();
-#endif
}
QGeoclueMaster::~QGeoclueMaster()
{
releaseMasterClient();
+
+ delete m_master;
}
bool QGeoclueMaster::hasMasterClient() const
{
- return m_client && m_masterPosition;
+ return m_client;
}
-bool QGeoclueMaster::createMasterClient(GeoclueAccuracyLevel accuracy, GeoclueResourceFlags resourceFlags)
+bool QGeoclueMaster::createMasterClient(Accuracy::Level accuracyLevel, ResourceFlags resourceFlags)
{
- Q_ASSERT(!m_client && !m_masterPosition);
+ Q_ASSERT(!m_provider || !m_client);
- GeoclueMaster *master = geoclue_master_get_default();
- if (!master) {
- qCritical("QGeoclueMaster error creating GeoclueMaster");
+ if (!m_master) {
+ m_master = new OrgFreedesktopGeoclueMasterInterface(QStringLiteral("org.freedesktop.Geoclue.Master"),
+ QStringLiteral("/org/freedesktop/Geoclue/Master"),
+ QDBusConnection::sessionBus());
+ }
+
+ QDBusPendingReply<QDBusObjectPath> client = m_master->Create();
+ if (client.isError()) {
+ QDBusError e = client.error();
+ qCritical("Failed to create Geoclue client interface. Geoclue error: %s",
+ qPrintable(e.errorString(e.type())));
return false;
}
- GError *error = 0;
+ qDebug() << "Geoclue client path:" << client.value().path();
- m_client = geoclue_master_create_client(master, 0, &error);
- g_object_unref (master);
+ m_provider = new OrgFreedesktopGeoclueInterface(QStringLiteral("org.freedesktop.Geoclue.Master"),
+ client.value().path(), QDBusConnection::sessionBus());
+ m_provider->AddReference();
- if (!m_client) {
- qCritical("QGeoclueMaster error creating GeoclueMasterClient.");
- if (error) {
- qCritical("Geoclue error: %s", error->message);
- g_error_free(error);
- }
- return false;
- }
+ m_client = new OrgFreedesktopGeoclueMasterClientInterface(QStringLiteral("org.freedesktop.Geoclue.Master"),
+ client.value().path(),
+ QDBusConnection::sessionBus());
+
+ connect(m_client, SIGNAL(PositionProviderChanged(QString,QString,QString,QString)),
+ this, SIGNAL(positionProviderChanged(QString,QString,QString,QString)));
- g_signal_connect(G_OBJECT(m_client), "position-provider-changed",
- G_CALLBACK(position_provider_changed), m_handler);
-
- if (!geoclue_master_client_set_requirements(m_client, accuracy, 0, true,
- resourceFlags, &error)) {
- qCritical("QGeoclueMaster geoclue set_requirements failed.");
- if (error) {
- qCritical ("Geoclue error: %s", error->message);
- g_error_free (error);
- }
- g_object_unref(m_client);
- m_client = 0;
+ QDBusPendingReply<> reply = m_client->SetRequirements(accuracyLevel, 0, true, resourceFlags);
+ if (reply.isError()) {
+ QDBusError e = reply.error();
+ qCritical("Failed to set Geoclue positioning requirements. Geoclue error: %s",
+ qPrintable(e.errorString(e.type())));
+
+ releaseMasterClient();
return false;
}
// Need to create the master position interface even though it will not be used, otherwise
// GetPositionProvider always returns empty strings.
- m_masterPosition = geoclue_master_client_create_position(m_client, 0);
- if (!m_masterPosition) {
- qCritical("QGeoclueMaster failed to get master position object");
- g_object_unref(m_client);
- m_client = 0;
+ reply = m_client->PositionStart();
+ if (reply.isError()) {
+ QDBusError e = reply.error();
+ qCritical("Failed to start positioning. Geoclue error: %s",
+ qPrintable(e.errorString(e.type())));
+
+ releaseMasterClient();
return false;
}
@@ -129,16 +114,12 @@ bool QGeoclueMaster::createMasterClient(GeoclueAccuracyLevel accuracy, GeoclueRe
void QGeoclueMaster::releaseMasterClient()
{
- if (m_masterPosition) {
- g_object_unref(m_masterPosition);
- m_masterPosition = 0;
- }
- if (m_client) {
- g_signal_handlers_disconnect_by_func(G_OBJECT(m_client), (void *)position_provider_changed,
- m_handler);
- g_object_unref(m_client);
- m_client = 0;
- }
+ if (m_provider)
+ m_provider->RemoveReference();
+ delete m_provider;
+ m_provider = 0;
+ delete m_client;
+ m_client = 0;
}
QT_END_NAMESPACE
diff --git a/src/plugins/position/geoclue/qgeocluemaster.h b/src/plugins/position/geoclue/qgeocluemaster.h
index 0451f812..83c1eb94 100644
--- a/src/plugins/position/geoclue/qgeocluemaster.h
+++ b/src/plugins/position/geoclue/qgeocluemaster.h
@@ -34,29 +34,51 @@
#ifndef QGEOCLUEMASTER_H
#define QGEOCLUEMASTER_H
+#include "geocluetypes.h"
+
#include <QtCore/QObject>
-#include <geoclue/geoclue-master.h>
+class OrgFreedesktopGeoclueMasterInterface;
+class OrgFreedesktopGeoclueInterface;
+class OrgFreedesktopGeoclueMasterClientInterface;
QT_BEGIN_NAMESPACE
-class QGeoclueMaster
+class QGeoclueMaster : public QObject
{
+ Q_OBJECT
+
public:
- QGeoclueMaster(QObject *handler);
- virtual ~QGeoclueMaster();
+ QGeoclueMaster(QObject *parent = 0);
+ ~QGeoclueMaster();
+
+ enum ResourceFlag
+ {
+ ResourceNone = 0,
+ ResourceNetwork = 1 << 0,
+ ResourceCell = 1 << 1,
+ ResourceGps = 1 << 2,
+ ResourceAll = (1 << 10) - 1
+ };
+
+ Q_DECLARE_FLAGS(ResourceFlags, ResourceFlag)
bool hasMasterClient() const;
- bool createMasterClient(GeoclueAccuracyLevel accuracy, GeoclueResourceFlags resourceFlags);
+ bool createMasterClient(Accuracy::Level accuracyLevel, ResourceFlags resourceFlags);
void releaseMasterClient();
-private:
- GeoclueMasterClient *m_client;
- GeocluePosition *m_masterPosition;
+signals:
+ void positionProviderChanged(const QString &name, const QString &description,
+ const QString &service, const QString &path);
- QObject *m_handler;
+private:
+ OrgFreedesktopGeoclueMasterInterface *m_master;
+ OrgFreedesktopGeoclueInterface *m_provider;
+ OrgFreedesktopGeoclueMasterClientInterface *m_client;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGeoclueMaster::ResourceFlags)
+
QT_END_NAMESPACE
#endif // QGEOCLUEMASTER_H
diff --git a/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.cpp b/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.cpp
index fe5b048e..cc0a8119 100644
--- a/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.cpp
+++ b/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.cpp
@@ -33,7 +33,11 @@
**
****************************************************************************/
-#include "qgeopositioninfosource_geocluemaster_p.h"
+#include "qgeopositioninfosource_geocluemaster.h"
+
+#include <geoclue_interface.h>
+#include <position_interface.h>
+#include <velocity_interface.h>
#include <QtCore/QDateTime>
#include <QtCore/QFile>
@@ -41,64 +45,23 @@
#include <QtCore/QStandardPaths>
#include <QtCore/QVariantMap>
#include <QtCore/QtNumeric>
+#include <QtDBus/QDBusMetaType>
#ifdef Q_LOCATION_GEOCLUE_DEBUG
#include <QDebug>
#endif
-#include <dbus/dbus-glib.h>
-
#ifndef QT_NO_DATASTREAM
#include <QtCore/QDataStream>
#endif
-QT_BEGIN_NAMESPACE
-
#define MINIMUM_UPDATE_INTERVAL 1000
#define UPDATE_TIMEOUT_COLD_START 120000
-namespace
-{
-
-void position_changed(GeocluePosition *position, GeocluePositionFields fields, int timestamp,
- double latitude, double longitude, double altitude,
- GeoclueAccuracy *accuracy, QGeoPositionInfoSourceGeoclueMaster *master)
-{
- Q_UNUSED(position)
-
- if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE && fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)
- master->updatePosition(fields, timestamp, latitude, longitude, altitude, accuracy);
- else
- master->regularUpdateFailed();
-}
-
-void velocity_changed(GeoclueVelocity *velocity, GeoclueVelocityFields fields, int timestamp,
- double speed, double direction, double climb,
- QGeoPositionInfoSourceGeoclueMaster *master)
-{
- Q_UNUSED(velocity)
-
- if (fields == GEOCLUE_VELOCITY_FIELDS_NONE)
- master->velocityUpdateFailed();
- else
- master->velocityUpdateSucceeded(fields, timestamp, speed, direction, climb);
-}
+QT_BEGIN_NAMESPACE
-void position_callback(GeocluePosition *pos, GeocluePositionFields fields, int timestamp,
- double latitude, double longitude, double altitude,
- GeoclueAccuracy *accuracy, GError *error, gpointer userdata)
+namespace
{
- Q_UNUSED(pos)
-
- if (error)
- g_error_free(error);
-
- QGeoPositionInfoSourceGeoclueMaster *master =
- static_cast<QGeoPositionInfoSourceGeoclueMaster *>(userdata);
-
- if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE && fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)
- master->updatePosition(fields, timestamp, latitude, longitude, altitude, accuracy);
-}
double knotsToMetersPerSecond(double knots)
{
@@ -108,11 +71,13 @@ double knotsToMetersPerSecond(double knots)
}
QGeoPositionInfoSourceGeoclueMaster::QGeoPositionInfoSourceGeoclueMaster(QObject *parent)
-: QGeoPositionInfoSource(parent), QGeoclueMaster(this), m_pos(0), m_vel(0),
- m_lastVelocityIsFresh(false), m_regularUpdateTimedOut(false), m_lastVelocity(qQNaN()),
+: QGeoPositionInfoSource(parent), m_master(new QGeoclueMaster(this)), m_provider(0), m_pos(0),
+ m_vel(0), m_lastVelocityIsFresh(false), m_regularUpdateTimedOut(false), m_lastVelocity(qQNaN()),
m_lastDirection(qQNaN()), m_lastClimb(qQNaN()), m_lastPositionFromSatellite(false),
- m_methods(AllPositioningMethods), m_running(false), m_error(NoError)
+ m_running(false), m_error(NoError)
{
+ qDBusRegisterMetaType<Accuracy>();
+
#ifndef QT_NO_DATASTREAM
// Load the last known location
QFile file(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) +
@@ -123,8 +88,11 @@ QGeoPositionInfoSourceGeoclueMaster::QGeoPositionInfoSourceGeoclueMaster(QObject
}
#endif
+ connect(m_master, SIGNAL(positionProviderChanged(QString,QString,QString,QString)),
+ this, SLOT(positionProviderChanged(QString,QString,QString,QString)));
+
m_requestTimer.setSingleShot(true);
- QObject::connect(&m_requestTimer, SIGNAL(timeout()), this, SLOT(requestUpdateTimeout()));
+ connect(&m_requestTimer, SIGNAL(timeout()), this, SLOT(requestUpdateTimeout()));
setPreferredPositioningMethods(AllPositioningMethods);
}
@@ -144,50 +112,10 @@ QGeoPositionInfoSourceGeoclueMaster::~QGeoPositionInfoSourceGeoclueMaster()
}
#endif
- if (m_pos)
- g_object_unref (m_pos);
- if (m_vel)
- g_object_unref(m_vel);
-}
-
-void QGeoPositionInfoSourceGeoclueMaster::velocityUpdateFailed()
-{
-#ifdef Q_LOCATION_GEOCLUE_DEBUG
- qDebug() << "QGeoPositionInfoSourceGeoclueMaster velocity update failed.";
-#endif
- // Set the velocitydata non-fresh.
- m_lastVelocityIsFresh = false;
-}
-
-void QGeoPositionInfoSourceGeoclueMaster::velocityUpdateSucceeded(GeoclueVelocityFields fields,
- int timestamp, double speed,
- double direction, double climb)
-{
- Q_UNUSED(timestamp);
-
-#ifdef Q_LOCATION_GEOCLUE_DEBUG
- qDebug() << "QGeoPositionInfoSourceGeoclueMaster velocity update succeeded, speed: " << speed;
-#endif
- // Store the velocity and mark it as fresh. Simple but hopefully adequate.
- if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED)
- m_lastVelocity = knotsToMetersPerSecond(speed);
- else
- m_lastVelocity = qQNaN();
-
- if (fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION)
- m_lastDirection = direction;
- else
- m_lastDirection = qQNaN();
-
- if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB)
- m_lastClimb = climb;
- else
- m_lastClimb = qQNaN();
-
- m_lastVelocityIsFresh = true;
+ cleanupPositionSource();
}
-void QGeoPositionInfoSourceGeoclueMaster::regularUpdateFailed()
+void QGeoPositionInfoSourceGeoclueMaster::positionUpdateFailed()
{
#ifdef Q_LOCATION_GEOCLUE_DEBUG
qDebug() << "QGeoPositionInfoSourceGeoclueMaster regular update failed.";
@@ -200,33 +128,25 @@ void QGeoPositionInfoSourceGeoclueMaster::regularUpdateFailed()
}
}
-void QGeoPositionInfoSourceGeoclueMaster::updatePosition(GeocluePositionFields fields,
- int timestamp, double latitude,
- double longitude, double altitude,
- GeoclueAccuracy *accuracy)
+void QGeoPositionInfoSourceGeoclueMaster::updatePosition(PositionFields fields, int timestamp,
+ double latitude, double longitude,
+ double altitude, Accuracy accuracy)
{
if (m_requestTimer.isActive())
m_requestTimer.stop();
QGeoCoordinate coordinate(latitude, longitude);
- if (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)
+ if (fields & Altitude)
coordinate.setAltitude(altitude);
m_lastPosition = QGeoPositionInfo(coordinate, QDateTime::fromTime_t(timestamp));
- if (accuracy) {
- double horizontalAccuracy = qQNaN();
- double verticalAccuracy = qQNaN();
- GeoclueAccuracyLevel accuracyLevel = GEOCLUE_ACCURACY_LEVEL_NONE;
- geoclue_accuracy_get_details(accuracy, &accuracyLevel, &horizontalAccuracy, &verticalAccuracy);
+ m_lastPositionFromSatellite = accuracy.level() == Accuracy::Detailed;
- m_lastPositionFromSatellite = accuracyLevel & GEOCLUE_ACCURACY_LEVEL_DETAILED;
-
- if (!qIsNaN(horizontalAccuracy))
- m_lastPosition.setAttribute(QGeoPositionInfo::HorizontalAccuracy, horizontalAccuracy);
- if (!qIsNaN(verticalAccuracy))
- m_lastPosition.setAttribute(QGeoPositionInfo::VerticalAccuracy, verticalAccuracy);
- }
+ if (!qIsNaN(accuracy.horizontal()))
+ m_lastPosition.setAttribute(QGeoPositionInfo::HorizontalAccuracy, accuracy.horizontal());
+ if (!qIsNaN(accuracy.vertical()))
+ m_lastPosition.setAttribute(QGeoPositionInfo::VerticalAccuracy, accuracy.vertical());
if (m_lastVelocityIsFresh) {
if (!qIsNaN(m_lastVelocity))
@@ -253,69 +173,50 @@ void QGeoPositionInfoSourceGeoclueMaster::updatePosition(GeocluePositionFields f
// Only stop positioning if regular updates not active.
if (!m_running) {
cleanupPositionSource();
- releaseMasterClient();
+ m_master->releaseMasterClient();
}
}
+void QGeoPositionInfoSourceGeoclueMaster::velocityUpdateFailed()
+{
+ // Set the velocitydata non-fresh.
+ m_lastVelocityIsFresh = false;
+}
+
+void QGeoPositionInfoSourceGeoclueMaster::updateVelocity(VelocityFields fields, int timestamp,
+ double speed, double direction,
+ double climb)
+{
+ Q_UNUSED(timestamp)
+
+ // Store the velocity and mark it as fresh. Simple but hopefully adequate.
+ m_lastVelocity = (fields & Speed) ? knotsToMetersPerSecond(speed) : qQNaN();
+ m_lastDirection = (fields & Direction) ? direction : qQNaN();
+ m_lastClimb = (fields & Climb) ? climb : qQNaN();
+ m_lastVelocityIsFresh = true;
+}
+
void QGeoPositionInfoSourceGeoclueMaster::cleanupPositionSource()
{
- if (m_pos) {
- g_object_unref(m_pos);
- m_pos = 0;
- }
- if (m_vel) {
- g_object_unref(m_vel);
- m_vel = 0;
- }
+ if (m_provider)
+ m_provider->RemoveReference();
+ delete m_provider;
+ m_provider = 0;
+ delete m_pos;
+ m_pos = 0;
+ delete m_vel;
+ m_vel = 0;
}
void QGeoPositionInfoSourceGeoclueMaster::setOptions()
{
- if (!m_pos)
+ if (!m_provider)
return;
QVariantMap options;
options.insert(QStringLiteral("UpdateInterval"), updateInterval());
- GHashTable *gOptions = g_hash_table_new(g_str_hash, g_str_equal);
-
- for (QVariantMap::ConstIterator i = options.constBegin(); i != options.constEnd(); ++i) {
- char *key = qstrdup(i.key().toUtf8().constData());
-
- const QVariant v = i.value();
-
- GValue *value = new GValue;
- memset(value, 0, sizeof(*value));
-
- switch (v.userType()) {
- case QMetaType::QString:
- g_value_init(value, G_TYPE_STRING);
- g_value_set_string(value, v.toString().toUtf8().constData());
- break;
- case QMetaType::Int:
- g_value_init(value, G_TYPE_INT);
- g_value_set_int(value, v.toInt());
- break;
- default:
- qWarning("Unexpected type %d %s", v.userType(), v.typeName());
- }
-
- g_hash_table_insert(gOptions, key, value);
- }
-
- geoclue_provider_set_options(GEOCLUE_PROVIDER(m_pos), gOptions, 0);
-
- GHashTableIter iter;
- char *key;
- GValue *value;
-
- g_hash_table_iter_init(&iter, gOptions);
- while (g_hash_table_iter_next(&iter, reinterpret_cast<void **>(&key), reinterpret_cast<void **>(&value))) {
- delete[] key;
- delete value;
- }
-
- g_hash_table_destroy(gOptions);
+ m_provider->SetOptions(options);
}
void QGeoPositionInfoSourceGeoclueMaster::setUpdateInterval(int msec)
@@ -341,13 +242,13 @@ void QGeoPositionInfoSourceGeoclueMaster::setPreferredPositioningMethods(Positio
// Don't start Geoclue provider until necessary. Don't currently have a master client, no need
// no recreate one.
- if (!hasMasterClient())
+ if (!m_master->hasMasterClient())
return;
// Free potential previous sources, because new requirements can't be set for the client
// (creating a position object after changing requirements seems to fail).
cleanupPositionSource();
- releaseMasterClient();
+ m_master->releaseMasterClient();
// Restart Geoclue provider with new requirements.
configurePositionSource();
@@ -356,18 +257,14 @@ void QGeoPositionInfoSourceGeoclueMaster::setPreferredPositioningMethods(Positio
QGeoPositionInfo QGeoPositionInfoSourceGeoclueMaster::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
{
- if (fromSatellitePositioningMethodsOnly) {
- if (m_lastPositionFromSatellite)
- return m_lastPosition;
- else
- return QGeoPositionInfo();
- }
+ if (fromSatellitePositioningMethodsOnly && !m_lastPositionFromSatellite)
+ return QGeoPositionInfo();
+
return m_lastPosition;
}
QGeoPositionInfoSourceGeoclueMaster::PositioningMethods QGeoPositionInfoSourceGeoclueMaster::supportedPositioningMethods() const
{
- // There is no really knowing which methods the GeoClue master supports.
return AllPositioningMethods;
}
@@ -383,7 +280,7 @@ void QGeoPositionInfoSourceGeoclueMaster::startUpdates()
m_running = true;
// Start Geoclue provider.
- if (!hasMasterClient()) {
+ if (!m_master->hasMasterClient()) {
configurePositionSource();
setOptions();
}
@@ -405,17 +302,22 @@ void QGeoPositionInfoSourceGeoclueMaster::stopUpdates()
if (!m_running)
return;
- if (m_pos)
- g_signal_handlers_disconnect_by_func(G_OBJECT(m_pos), (void *)position_changed, this);
- if (m_vel)
- g_signal_handlers_disconnect_by_func(G_OBJECT(m_vel), (void *)velocity_changed, this);
+ if (m_pos) {
+ disconnect(m_pos, SIGNAL(PositionChanged(qint32,qint32,double,double,double,Accuracy)),
+ this, SLOT(positionChanged(qint32,qint32,double,double,double,Accuracy)));
+ }
+
+ if (m_vel) {
+ disconnect(m_vel, SIGNAL(VelocityChanged(qint32,qint32,double,double,double)),
+ this, SLOT(velocityChanged(qint32,qint32,double,double,double)));
+ }
m_running = false;
// Only stop positioning if single update not requested.
if (!m_requestTimer.isActive()) {
cleanupPositionSource();
- releaseMasterClient();
+ m_master->releaseMasterClient();
}
}
@@ -432,7 +334,7 @@ void QGeoPositionInfoSourceGeoclueMaster::requestUpdate(int timeout)
return;
}
- if (!hasMasterClient()) {
+ if (!m_master->hasMasterClient()) {
configurePositionSource();
setOptions();
}
@@ -442,8 +344,55 @@ void QGeoPositionInfoSourceGeoclueMaster::requestUpdate(int timeout)
// for whole cold start time.
m_requestTimer.start(timeout ? timeout : UPDATE_TIMEOUT_COLD_START);
- if (m_pos)
- geoclue_position_get_position_async(m_pos, position_callback, this);
+ if (m_pos) {
+ QDBusPendingReply<qint32, qint32, double, double, double, Accuracy> reply = m_pos->GetPosition();
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(getPositionFinished(QDBusPendingCallWatcher*)));
+ }
+}
+
+void QGeoPositionInfoSourceGeoclueMaster::positionProviderChanged(const QString &name,
+ const QString &description,
+ const QString &service,
+ const QString &path)
+{
+ Q_UNUSED(name)
+ Q_UNUSED(description)
+
+ cleanupPositionSource();
+
+ if (service.isEmpty() || path.isEmpty()) {
+ if (!m_regularUpdateTimedOut) {
+ m_regularUpdateTimedOut = true;
+ emit updateTimeout();
+ }
+ return;
+ }
+
+ m_provider = new OrgFreedesktopGeoclueInterface(service, path, QDBusConnection::sessionBus());
+ m_provider->AddReference();
+
+ m_pos = new OrgFreedesktopGeocluePositionInterface(service, path, QDBusConnection::sessionBus());
+
+ if (m_running) {
+ connect(m_pos, SIGNAL(PositionChanged(qint32,qint32,double,double,double,Accuracy)),
+ this, SLOT(positionChanged(qint32,qint32,double,double,double,Accuracy)));
+ }
+
+ // Get the current position immediately.
+ QDBusPendingReply<qint32, qint32, double, double, double, Accuracy> reply = m_pos->GetPosition();
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(getPositionFinished(QDBusPendingCallWatcher*)));
+
+ setOptions();
+
+ m_vel = new OrgFreedesktopGeoclueVelocityInterface(service, path, QDBusConnection::sessionBus());
+ if (m_vel->isValid() && m_running) {
+ connect(m_vel, SIGNAL(VelocityChanged(qint32,qint32,double,double,double)),
+ this, SLOT(velocityChanged(qint32,qint32,double,double,double)));
+ }
}
void QGeoPositionInfoSourceGeoclueMaster::requestUpdateTimeout()
@@ -457,70 +406,71 @@ void QGeoPositionInfoSourceGeoclueMaster::requestUpdateTimeout()
// Only stop positioning if regular updates not active.
if (!m_running) {
cleanupPositionSource();
- releaseMasterClient();
+ m_master->releaseMasterClient();
}
}
-void QGeoPositionInfoSourceGeoclueMaster::positionProviderChanged(const QByteArray &service, const QByteArray &path)
+void QGeoPositionInfoSourceGeoclueMaster::getPositionFinished(QDBusPendingCallWatcher *watcher)
{
- if (m_pos)
- cleanupPositionSource();
+ QDBusPendingReply<qint32, qint32, double, double, double, Accuracy> reply = *watcher;
+ watcher->deleteLater();
- if (service.isEmpty() || path.isEmpty()) {
- if (!m_regularUpdateTimedOut) {
- m_regularUpdateTimedOut = true;
- emit updateTimeout();
- }
+ if (reply.isError())
return;
+
+ PositionFields fields = static_cast<PositionFields>(reply.argumentAt<0>());
+ if (fields & Latitude && fields & Longitude) {
+ qint32 timestamp = reply.argumentAt<1>();
+ double latitude = reply.argumentAt<2>();
+ double longitude = reply.argumentAt<3>();
+ double altitude = reply.argumentAt<4>();
+ Accuracy accuracy = reply.argumentAt<5>();
+ updatePosition(fields, timestamp, latitude, longitude, altitude, accuracy);
}
+}
- m_pos = geoclue_position_new(service.constData(), path.constData());
- if (m_pos) {
- if (m_running) {
- g_signal_connect(G_OBJECT(m_pos), "position-changed",
- G_CALLBACK(position_changed), this);
- }
+void QGeoPositionInfoSourceGeoclueMaster::positionChanged(qint32 fields, qint32 timestamp, double latitude, double longitude, double altitude, const Accuracy &accuracy)
+{
+ PositionFields pFields = static_cast<PositionFields>(fields);
- // Get the current position immediately.
- geoclue_position_get_position_async(m_pos, position_callback, this);
- setOptions();
+ if (pFields & Latitude && pFields & Longitude)
+ updatePosition(pFields, timestamp, latitude, longitude, altitude, accuracy);
+ else
+ positionUpdateFailed();
+}
- m_vel = geoclue_velocity_new(service.constData(), path.constData());
- if (m_vel && m_running) {
- g_signal_connect(G_OBJECT(m_vel), "velocity-changed",
- G_CALLBACK(velocity_changed), this);
- }
- }
+void QGeoPositionInfoSourceGeoclueMaster::velocityChanged(qint32 fields, qint32 timestamp, double speed, double direction, double climb)
+{
+ VelocityFields vFields = static_cast<VelocityFields>(fields);
+
+ if (vFields == NoVelocityFields)
+ velocityUpdateFailed();
+ else
+ updateVelocity(vFields, timestamp, speed, direction, climb);
}
void QGeoPositionInfoSourceGeoclueMaster::configurePositionSource()
{
- GeoclueAccuracyLevel accuracy;
- GeoclueResourceFlags resourceFlags;
+ bool created = false;
switch (preferredPositioningMethods()) {
case SatellitePositioningMethods:
- accuracy = GEOCLUE_ACCURACY_LEVEL_DETAILED;
- resourceFlags = GEOCLUE_RESOURCE_GPS;
+ created = m_master->createMasterClient(Accuracy::Detailed, QGeoclueMaster::ResourceGps);
break;
case NonSatellitePositioningMethods:
- accuracy = GEOCLUE_ACCURACY_LEVEL_NONE;
- resourceFlags = GeoclueResourceFlags(GEOCLUE_RESOURCE_CELL | GEOCLUE_RESOURCE_NETWORK);
+ created = m_master->createMasterClient(Accuracy::None, QGeoclueMaster::ResourceCell | QGeoclueMaster::ResourceNetwork);
break;
case AllPositioningMethods:
- accuracy = GEOCLUE_ACCURACY_LEVEL_NONE;
- resourceFlags = GEOCLUE_RESOURCE_ALL;
+ created = m_master->createMasterClient(Accuracy::None, QGeoclueMaster::ResourceAll);
break;
default:
- qWarning("GeoPositionInfoSourceGeoClueMaster unknown preferred method.");
+ qWarning("QGeoPositionInfoSourceGeoclueMaster unknown preferred method.");
m_error = UnknownSourceError;
emit QGeoPositionInfoSource::error(m_error);
return;
}
- if (createMasterClient(accuracy, resourceFlags)) {
- m_error = NoError;
- } else {
+ if (!created) {
m_error = UnknownSourceError;
emit QGeoPositionInfoSource::error(m_error);
}
@@ -531,6 +481,4 @@ QGeoPositionInfoSource::Error QGeoPositionInfoSourceGeoclueMaster::error() const
return m_error;
}
-#include "moc_qgeopositioninfosource_geocluemaster_p.cpp"
-
QT_END_NAMESPACE
diff --git a/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster_p.h b/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.h
index 2dcd3824..09f6812c 100644
--- a/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster_p.h
+++ b/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.h
@@ -36,33 +36,26 @@
#ifndef QGEOPOSITIONINFOSOURCE_GEOCLUEMASTER_H
#define QGEOPOSITIONINFOSOURCE_GEOCLUEMASTER_H
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
#include "qgeocluemaster.h"
+#include "geocluetypes.h"
-#include <qgeopositioninfosource.h>
-#include <geoclue/geoclue-velocity.h>
-#include <QTimer>
+#include <QtCore/QTimer>
+#include <QtPositioning/QGeoPositionInfoSource>
-//#define Q_LOCATION_GEOCLUE_DEBUG
+class OrgFreedesktopGeoclueInterface;
+class OrgFreedesktopGeocluePositionInterface;
+class OrgFreedesktopGeoclueVelocityInterface;
QT_BEGIN_NAMESPACE
-class QGeoPositionInfoSourceGeoclueMaster : public QGeoPositionInfoSource, public QGeoclueMaster
+class QDBusPendingCallWatcher;
+
+class QGeoPositionInfoSourceGeoclueMaster : public QGeoPositionInfoSource
{
Q_OBJECT
public:
- QGeoPositionInfoSourceGeoclueMaster(QObject *parent = 0);
+ explicit QGeoPositionInfoSourceGeoclueMaster(QObject *parent = 0);
~QGeoPositionInfoSourceGeoclueMaster();
// From QGeoPositionInfoSource
@@ -72,34 +65,61 @@ public:
void setPreferredPositioningMethods(PositioningMethods methods);
int minimumUpdateInterval() const;
- void updatePosition(GeocluePositionFields fields, int timestamp, double latitude,
- double longitude, double altitude, GeoclueAccuracy *accuracy);
-
- void regularUpdateFailed();
-
- void velocityUpdateFailed();
- void velocityUpdateSucceeded(GeoclueVelocityFields fields, int timestamp, double speed,
- double direction, double climb);
-
Error error() const;
-public slots:
- virtual void startUpdates();
- virtual void stopUpdates();
- virtual void requestUpdate(int timeout = 5000);
+ virtual void startUpdates() Q_DECL_OVERRIDE;
+ virtual void stopUpdates() Q_DECL_OVERRIDE;
+ virtual void requestUpdate(int timeout = 5000) Q_DECL_OVERRIDE;
private slots:
+ void positionProviderChanged(const QString &name, const QString &description,
+ const QString &service, const QString &path);
void requestUpdateTimeout();
- void positionProviderChanged(const QByteArray &service, const QByteArray &path);
+
+ void getPositionFinished(QDBusPendingCallWatcher *watcher);
+ void positionChanged(qint32 fields, qint32 timestamp, double latitude, double longitude,
+ double altitude, const Accuracy &accuracy);
+ void velocityChanged(qint32 fields, qint32 timestamp, double speed, double direction,
+ double climb);
private:
void configurePositionSource();
void cleanupPositionSource();
void setOptions();
+ enum PositionField
+ {
+ NoPositionFields = 0,
+ Latitude = 1 << 0,
+ Longitude = 1 << 1,
+ Altitude = 1 << 2
+ };
+ Q_DECLARE_FLAGS(PositionFields, PositionField)
+
+ void updatePosition(PositionFields fields, int timestamp, double latitude,
+ double longitude, double altitude, Accuracy accuracy);
+ void positionUpdateFailed();
+
+ enum VelocityField
+ {
+ NoVelocityFields = 0,
+ Speed = 1 << 0,
+ Direction = 1 << 1,
+ Climb = 1 << 2
+ };
+ Q_DECLARE_FLAGS(VelocityFields, VelocityField)
+
+ void updateVelocity(VelocityFields fields, int timestamp, double speed, double direction,
+ double climb);
+ void velocityUpdateFailed();
+
private:
- GeocluePosition *m_pos;
- GeoclueVelocity *m_vel;
+ QGeoclueMaster *m_master;
+
+ OrgFreedesktopGeoclueInterface *m_provider;
+ OrgFreedesktopGeocluePositionInterface *m_pos;
+ OrgFreedesktopGeoclueVelocityInterface *m_vel;
+
QTimer m_requestTimer;
bool m_lastVelocityIsFresh;
bool m_regularUpdateTimedOut;
@@ -108,7 +128,6 @@ private:
double m_lastClimb;
bool m_lastPositionFromSatellite;
QGeoPositionInfo m_lastPosition;
- PositioningMethods m_methods;
bool m_running;
QGeoPositionInfoSource::Error m_error;
};
diff --git a/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp b/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp
index a7c92678..18f90fbf 100644
--- a/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp
+++ b/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp
@@ -34,13 +34,13 @@
****************************************************************************/
#include "qgeopositioninfosourcefactory_geoclue.h"
-#include "qgeopositioninfosource_geocluemaster_p.h"
-#ifdef HAS_SATELLITE
+#include "qgeopositioninfosource_geocluemaster.h"
#include "qgeosatelliteinfosource_geocluemaster.h"
-#endif
Q_DECLARE_METATYPE(QGeoPositionInfo)
+QT_BEGIN_NAMESPACE
+
QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryGeoclue::positionInfoSource(QObject *parent)
{
qRegisterMetaType<QGeoPositionInfo>();
@@ -49,17 +49,13 @@ QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryGeoclue::positionInfoSource
QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryGeoclue::satelliteInfoSource(QObject *parent)
{
-#ifdef HAS_SATELLITE
return new QGeoSatelliteInfoSourceGeoclueMaster(parent);
-#else
- Q_UNUSED(parent)
-
- return 0;
-#endif
}
QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryGeoclue::areaMonitor(QObject *parent)
{
- Q_UNUSED(parent);
+ Q_UNUSED(parent)
return 0;
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h b/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h
index fdd0675f..17da509e 100644
--- a/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h
+++ b/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h
@@ -36,28 +36,29 @@
#ifndef QGEOPOSITIONINFOSOURCEFACTORY_GEOCLUE_H
#define QGEOPOSITIONINFOSOURCEFACTORY_GEOCLUE_H
-#include <QObject>
-#include <qgeopositioninfosourcefactory.h>
+#include <QtCore/QObject>
+#include <QtPositioning/QGeoPositionInfoSourceFactory>
-#ifdef HAS_SATELLITE
-#define PLUGIN_JSON "plugin-satellite.json"
-#else
-#define PLUGIN_JSON "plugin.json"
-#endif
+QT_BEGIN_NAMESPACE
+/*
+ Qt Positioning plugin for Geoclue. This plugin supports Geoclue version 0.12.99.
+*/
class QGeoPositionInfoSourceFactoryGeoclue : public QObject, public QGeoPositionInfoSourceFactory
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0"
- FILE PLUGIN_JSON)
+ FILE "plugin.json")
Q_INTERFACES(QGeoPositionInfoSourceFactory)
public:
- QGeoPositionInfoSource *positionInfoSource(QObject *parent);
- QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
- QGeoAreaMonitorSource *areaMonitor(QObject *parent);
+ QGeoPositionInfoSource *positionInfoSource(QObject *parent) Q_DECL_OVERRIDE;
+ QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent) Q_DECL_OVERRIDE;
+ QGeoAreaMonitorSource *areaMonitor(QObject *parent) Q_DECL_OVERRIDE;
};
+QT_END_NAMESPACE
+
#endif
diff --git a/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp b/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp
index 501a983c..47b60b95 100644
--- a/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp
+++ b/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.cpp
@@ -33,122 +33,22 @@
#include "qgeosatelliteinfosource_geocluemaster.h"
-#include <QtDBus/QDBusConnection>
-#include <QtDBus/QDBusMessage>
-#include <QtDBus/QDBusArgument>
+#include <geoclue_interface.h>
+#include <satellite_interface.h>
+
+#include <QtDBus/QDBusPendingCallWatcher>
#define MINIMUM_UPDATE_INTERVAL 1000
QT_BEGIN_NAMESPACE
-namespace
-{
-
-void satellite_changed(GeoclueSatellite *satellite, int timestamp, int satellite_used,
- int satellite_visible, GArray *used_prn, GPtrArray *sat_info,
- gpointer userdata)
-{
- Q_UNUSED(satellite)
-
- QGeoSatelliteInfoSourceGeoclueMaster *source =
- static_cast<QGeoSatelliteInfoSourceGeoclueMaster *>(userdata);
-
- QList<int> usedPrns;
- for (unsigned int i = 0; i < used_prn->len; ++i)
- usedPrns.append(g_array_index(used_prn, int, i));
-
- QList<QGeoSatelliteInfo> satInfos;
- for (unsigned int i = 0; i < sat_info->len; ++i) {
- GValueArray *a = static_cast<GValueArray *>(g_ptr_array_index(sat_info, i));
-
- QGeoSatelliteInfo satInfo;
-
- satInfo.setSatelliteIdentifier(g_value_get_int(g_value_array_get_nth(a, 0)));
- satInfo.setAttribute(QGeoSatelliteInfo::Elevation,
- g_value_get_int(g_value_array_get_nth(a, 1)));
- satInfo.setAttribute(QGeoSatelliteInfo::Azimuth,
- g_value_get_int(g_value_array_get_nth(a, 2)));
- satInfo.setSignalStrength(g_value_get_int(g_value_array_get_nth(a, 3)));
-
- satInfos.append(satInfo);
- }
-
- source->satelliteChanged(timestamp, satellite_used, satellite_visible, usedPrns, satInfos);
-}
-
-void satellite_callback(GeoclueSatellite *satellite, int timestamp, int satellite_used,
- int satellite_visible, GArray *used_prn, GPtrArray *sat_info,
- GError *error, gpointer userdata)
-{
- Q_UNUSED(satellite)
-
- if (error)
- g_error_free(error);
-
- QGeoSatelliteInfoSourceGeoclueMaster *source =
- static_cast<QGeoSatelliteInfoSourceGeoclueMaster *>(userdata);
-
- QList<int> usedPrns;
- for (unsigned int i = 0; i < used_prn->len; ++i)
- usedPrns.append(g_array_index(used_prn, int, i));
-
- QList<QGeoSatelliteInfo> satInfos;
- for (unsigned int i = 0; i < sat_info->len; ++i) {
- GValueArray *a = static_cast<GValueArray *>(g_ptr_array_index(sat_info, i));
-
- QGeoSatelliteInfo satInfo;
-
- satInfo.setSatelliteIdentifier(g_value_get_int(g_value_array_get_nth(a, 0)));
- satInfo.setAttribute(QGeoSatelliteInfo::Elevation,
- g_value_get_int(g_value_array_get_nth(a, 1)));
- satInfo.setAttribute(QGeoSatelliteInfo::Azimuth,
- g_value_get_int(g_value_array_get_nth(a, 2)));
- satInfo.setSignalStrength(g_value_get_int(g_value_array_get_nth(a, 3)));
-
- satInfos.append(satInfo);
- }
-
- source->requestUpdateFinished(timestamp, satellite_used, satellite_visible, usedPrns, satInfos);
-}
-
-}
-
-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), m_error(NoError),
- m_satellitesChangedConnected(false), m_running(false)
+: QGeoSatelliteInfoSource(parent), m_master(new QGeoclueMaster(this)), m_provider(0), m_sat(0),
+ m_error(NoError), m_satellitesChangedConnected(false), m_running(false)
{
+ connect(m_master, SIGNAL(positionProviderChanged(QString,QString,QString,QString)),
+ this, SLOT(positionProviderChanged(QString,QString,QString,QString)));
+
m_requestTimer.setSingleShot(true);
connect(&m_requestTimer, SIGNAL(timeout()), this, SLOT(requestUpdateTimeout()));
}
@@ -163,6 +63,14 @@ int QGeoSatelliteInfoSourceGeoclueMaster::minimumUpdateInterval() const
return MINIMUM_UPDATE_INTERVAL;
}
+void QGeoSatelliteInfoSourceGeoclueMaster::setUpdateInterval(int msec)
+{
+ if (msec < 0 || (msec > 0 && msec < MINIMUM_UPDATE_INTERVAL))
+ msec = MINIMUM_UPDATE_INTERVAL;
+
+ QGeoSatelliteInfoSource::setUpdateInterval(msec);
+}
+
QGeoSatelliteInfoSource::Error QGeoSatelliteInfoSourceGeoclueMaster::error() const
{
return m_error;
@@ -176,14 +84,10 @@ void QGeoSatelliteInfoSourceGeoclueMaster::startUpdates()
m_running = true;
// Start Geoclue provider.
- if (!hasMasterClient())
+ if (!m_master->hasMasterClient())
configureSatelliteSource();
- // m_sat is likely to be invalid until Geoclue master selects a position provider.
- if (!m_sat)
- return;
-
- g_signal_connect(G_OBJECT(m_sat), "satellite-changed", G_CALLBACK(satellite_changed), this);
+ m_requestTimer.start(updateInterval());
}
void QGeoSatelliteInfoSourceGeoclueMaster::stopUpdates()
@@ -191,15 +95,17 @@ void QGeoSatelliteInfoSourceGeoclueMaster::stopUpdates()
if (!m_running)
return;
- if (m_sat)
- g_signal_handlers_disconnect_by_func(G_OBJECT(m_sat), gpointer(satellite_changed), this);
+ if (m_sat) {
+ disconnect(m_sat, SIGNAL(SatelliteChanged(qint32,qint32,qint32,QList<qint32>,QList<QGeoSatelliteInfo>)),
+ this, SLOT(satelliteChanged(qint32,qint32,qint32,QList<qint32>,QList<QGeoSatelliteInfo>)));
+ }
m_running = false;
// Only stop positioning if single update not requested.
if (!m_requestTimer.isActive()) {
cleanupSatelliteSource();
- releaseMasterClient();
+ m_master->releaseMasterClient();
}
}
@@ -213,19 +119,24 @@ void QGeoSatelliteInfoSourceGeoclueMaster::requestUpdate(int timeout)
if (m_requestTimer.isActive())
return;
- if (!hasMasterClient())
+ if (!m_master->hasMasterClient())
configureSatelliteSource();
m_requestTimer.start(qMax(timeout, minimumUpdateInterval()));
- if (m_sat)
- geoclue_satellite_get_satellite_async(m_sat, satellite_callback, this);
+ if (m_sat) {
+ QDBusPendingReply<qint32, qint32, qint32, QList<qint32>, QList<QGeoSatelliteInfo> > reply =
+ m_sat->GetSatellite();
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(getSatelliteFinished(QDBusPendingCallWatcher*)));
+ }
}
-void QGeoSatelliteInfoSourceGeoclueMaster::satelliteChanged(int timestamp, int satellitesUsed,
- int satellitesVisible,
- const QList<int> &usedPrn,
- const QList<QGeoSatelliteInfo> &satInfos)
+void QGeoSatelliteInfoSourceGeoclueMaster::updateSatelliteInfo(int timestamp, int satellitesUsed,
+ int satellitesVisible,
+ const QList<int> &usedPrn,
+ const QList<QGeoSatelliteInfo> &satInfos)
{
Q_UNUSED(timestamp)
@@ -252,36 +163,57 @@ void QGeoSatelliteInfoSourceGeoclueMaster::satelliteChanged(int timestamp, int s
m_inUse = inUse;
emit satellitesInUseUpdated(m_inUse);
-}
-void QGeoSatelliteInfoSourceGeoclueMaster::requestUpdateFinished(int timestamp, int satellitesUsed,
- int satellitesVisible,
- const QList<int> &usedPrn,
- const QList<QGeoSatelliteInfo> &satInfos)
-{
- m_requestTimer.stop();
- satelliteChanged(timestamp, satellitesUsed, satellitesVisible, usedPrn, satInfos);
+ m_requestTimer.start(updateInterval());
}
void QGeoSatelliteInfoSourceGeoclueMaster::requestUpdateTimeout()
{
// If we end up here, there has not been a valid satellite info update.
- emit requestTimeout();
+ if (m_running) {
+ m_inView.clear();
+ m_inUse.clear();
+ emit satellitesInViewUpdated(m_inView);
+ emit satellitesInUseUpdated(m_inUse);
+ } else {
+ emit requestTimeout();
- // Only stop satellite info if regular updates not active.
- if (!m_running) {
+ // Only stop satellite info if regular updates not active.
cleanupSatelliteSource();
- releaseMasterClient();
+ m_master->releaseMasterClient();
}
}
-void QGeoSatelliteInfoSourceGeoclueMaster::positionProviderChanged(const QByteArray &service, const QByteArray &path)
+void QGeoSatelliteInfoSourceGeoclueMaster::getSatelliteFinished(QDBusPendingCallWatcher *watcher)
{
- if (m_sat)
- cleanupSatelliteSource();
+ QDBusPendingReply<qint32, qint32, qint32, QList<qint32>, QList<QGeoSatelliteInfo> > reply = *watcher;
+ watcher->deleteLater();
+
+ if (reply.isError())
+ return;
+
+ m_requestTimer.stop();
+ updateSatelliteInfo(reply.argumentAt<0>(), reply.argumentAt<1>(), reply.argumentAt<2>(),
+ reply.argumentAt<3>(), reply.argumentAt<4>());
+}
+
+void QGeoSatelliteInfoSourceGeoclueMaster::satelliteChanged(int timestamp, int satellitesUsed, int satellitesVisible, const QList<int> &usedPrn, const QList<QGeoSatelliteInfo> &satInfos)
+{
+ updateSatelliteInfo(timestamp, satellitesUsed, satellitesVisible, usedPrn, satInfos);
+}
- QByteArray providerService;
- QByteArray providerPath;
+void QGeoSatelliteInfoSourceGeoclueMaster::positionProviderChanged(const QString &name,
+ const QString &description,
+ const QString &service,
+ const QString &path)
+{
+ Q_UNUSED(name)
+ Q_UNUSED(description)
+
+ cleanupSatelliteSource();
+
+ QString providerService;
+ QString providerPath;
if (service.isEmpty() || path.isEmpty()) {
// No valid position provider has been selected. This probably means that the GPS provider
@@ -290,7 +222,7 @@ void QGeoSatelliteInfoSourceGeoclueMaster::positionProviderChanged(const QByteAr
QDBusConnection conn = QDBusConnection::sessionBus();
conn.connect(QString(), QString(), QStringLiteral("org.freedesktop.Geoclue.Satellite"),
QStringLiteral("SatelliteChanged"), this,
- SLOT(satellitesChanged(QDBusMessage)));
+ SLOT(satelliteChanged(QDBusMessage)));
m_satellitesChangedConnected = true;
return;
}
@@ -300,7 +232,7 @@ void QGeoSatelliteInfoSourceGeoclueMaster::positionProviderChanged(const QByteAr
conn.disconnect(QString(), QString(),
QStringLiteral("org.freedesktop.Geoclue.Satellite"),
QStringLiteral("SatelliteChanged"), this,
- SLOT(satellitesChanged(QDBusMessage)));
+ SLOT(satelliteChanged(QDBusMessage)));
m_satellitesChangedConnected = false;
}
@@ -314,17 +246,18 @@ void QGeoSatelliteInfoSourceGeoclueMaster::positionProviderChanged(const QByteAr
return;
}
- m_sat = geoclue_satellite_new(providerService.constData(), providerPath.constData());
- if (!m_sat) {
- m_error = AccessError;
- emit QGeoSatelliteInfoSource::error(m_error);
- return;
- }
+ m_provider = new OrgFreedesktopGeoclueInterface(providerService, providerPath, QDBusConnection::sessionBus());
+ m_provider->AddReference();
- g_signal_connect(G_OBJECT(m_sat), "satellite-changed", G_CALLBACK(satellite_changed), this);
+ m_sat = new OrgFreedesktopGeoclueSatelliteInterface(providerService, providerPath, QDBusConnection::sessionBus());
+
+ if (m_running) {
+ connect(m_sat, SIGNAL(SatelliteChanged(qint32,qint32,qint32,QList<qint32>,QList<QGeoSatelliteInfo>)),
+ this, SLOT(satelliteChanged(qint32,qint32,qint32,QList<qint32>,QList<QGeoSatelliteInfo>)));
+ }
}
-void QGeoSatelliteInfoSourceGeoclueMaster::satellitesChanged(const QDBusMessage &message)
+void QGeoSatelliteInfoSourceGeoclueMaster::satelliteChanged(const QDBusMessage &message)
{
QVariantList arguments = message.arguments();
if (arguments.length() != 5)
@@ -347,17 +280,22 @@ void QGeoSatelliteInfoSourceGeoclueMaster::satellitesChanged(const QDBusMessage
satelliteChanged(timestamp, usedSatellites, visibleSatellites, usedPrn, satelliteInfos);
}
-bool QGeoSatelliteInfoSourceGeoclueMaster::configureSatelliteSource()
+void QGeoSatelliteInfoSourceGeoclueMaster::configureSatelliteSource()
{
- return createMasterClient(GEOCLUE_ACCURACY_LEVEL_DETAILED, GEOCLUE_RESOURCE_GPS);
+ if (!m_master->createMasterClient(Accuracy::Detailed, QGeoclueMaster::ResourceGps)) {
+ m_error = UnknownSourceError;
+ emit QGeoSatelliteInfoSource::error(m_error);
+ }
}
void QGeoSatelliteInfoSourceGeoclueMaster::cleanupSatelliteSource()
{
- if (m_sat) {
- g_object_unref(m_sat);
- m_sat = 0;
- }
+ if (m_provider)
+ m_provider->RemoveReference();
+ delete m_provider;
+ m_provider = 0;
+ delete m_sat;
+ m_sat = 0;
}
QT_END_NAMESPACE
diff --git a/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h b/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h
index 3269a423..e840e8a3 100644
--- a/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h
+++ b/src/plugins/position/geoclue/qgeosatelliteinfosource_geocluemaster.h
@@ -36,17 +36,18 @@
#include "qgeocluemaster.h"
-#include <geoclue/geoclue-satellite.h>
-
-#include <QtCore/qcompilerdetection.h>
#include <QtCore/QTimer>
#include <QtPositioning/QGeoSatelliteInfoSource>
+class OrgFreedesktopGeoclueInterface;
+class OrgFreedesktopGeoclueSatelliteInterface;
+
QT_BEGIN_NAMESPACE
class QDBusMessage;
+class QDBusPendingCallWatcher;
-class QGeoSatelliteInfoSourceGeoclueMaster : public QGeoSatelliteInfoSource, public QGeoclueMaster
+class QGeoSatelliteInfoSourceGeoclueMaster : public QGeoSatelliteInfoSource
{
Q_OBJECT
@@ -55,28 +56,36 @@ public:
~QGeoSatelliteInfoSourceGeoclueMaster();
int minimumUpdateInterval() const Q_DECL_OVERRIDE;
+ void setUpdateInterval(int msec) Q_DECL_OVERRIDE;
+
Error error() const Q_DECL_OVERRIDE;
void startUpdates() Q_DECL_OVERRIDE;
void stopUpdates() Q_DECL_OVERRIDE;
void requestUpdate(int timeout = 0) Q_DECL_OVERRIDE;
- void satelliteChanged(int timestamp, int satellitesUsed, int satellitesVisible,
- const QList<int> &usedPrn, const QList<QGeoSatelliteInfo> &satInfos);
-
- void requestUpdateFinished(int timestamp, int satellitesUsed, int satellitesVisible,
- const QList<int> &usedPrn, const QList<QGeoSatelliteInfo> &satInfos);
-
private slots:
+ void positionProviderChanged(const QString &name, const QString &description,
+ const QString &service, const QString &path);
void requestUpdateTimeout();
- void positionProviderChanged(const QByteArray &service, const QByteArray &path);
- void satellitesChanged(const QDBusMessage &message);
+
+ void getSatelliteFinished(QDBusPendingCallWatcher *watcher);
+ void satelliteChanged(int timestamp, int satellitesUsed, int satellitesVisible,
+ const QList<int> &usedPrn, const QList<QGeoSatelliteInfo> &satInfos);
+ void satelliteChanged(const QDBusMessage &message);
private:
- bool configureSatelliteSource();
+ void configureSatelliteSource();
void cleanupSatelliteSource();
- GeoclueSatellite *m_sat;
+ void updateSatelliteInfo(int timestamp, int satellitesUsed, int satellitesVisible,
+ const QList<int> &usedPrn, const QList<QGeoSatelliteInfo> &satInfos);
+
+ QGeoclueMaster *m_master;
+
+ OrgFreedesktopGeoclueInterface *m_provider;
+ OrgFreedesktopGeoclueSatelliteInterface *m_sat;
+
QTimer m_requestTimer;
QList<QGeoSatelliteInfo> m_inView;
QList<QGeoSatelliteInfo> m_inUse;
diff --git a/src/plugins/position/position.pro b/src/plugins/position/position.pro
index 8374a489..6a6264e2 100644
--- a/src/plugins/position/position.pro
+++ b/src/plugins/position/position.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
-config_geoclue:SUBDIRS += geoclue
+qtHaveModule(dbus):SUBDIRS += geoclue
config_gypsy:SUBDIRS += gypsy
qtHaveModule(simulator):SUBDIRS += simulator
ios:SUBDIRS += corelocation
diff --git a/src/positioning/doc/src/qtpositioning.qdoc b/src/positioning/doc/src/qtpositioning.qdoc
index c2d6912d..95a267ab 100644
--- a/src/positioning/doc/src/qtpositioning.qdoc
+++ b/src/positioning/doc/src/qtpositioning.qdoc
@@ -61,10 +61,10 @@
The Qt Positioning API provides positioning information via QML and C++ interfaces.
-Currently the API is supported on \l{Qt for Android}{Android},
-\l{Qt for iOS}{iOS},
-\l{Qt for Linux/X11}{Linux} (using \l{http://www.freedesktop.org/wiki/Software/GeoClue}{GeoClue})
-and \l {Qt for WinRT} {WinRT}.
+Currently the API is supported on \l {Qt for Android}{Android}, \l {Qt for iOS}{iOS},
+\l {Qt for Linux/X11}{Linux} (using
+\l {http://www.freedesktop.org/wiki/Software/GeoClue}{GeoClue version 0.12.99})
+and \l {Qt for WinRT}{WinRT}.
\section1 Overview