6#include <QtCore/QLoggingCategory>
7#include <QtCore/QSaveFile>
8#include <QtCore/QScopedPointer>
9#include <QtCore/QTimer>
10#include <QtDBus/QDBusPendingCallWatcher>
13#include <client_interface.h>
14#include "moc_client_interface.cpp"
15#include <location_interface.h>
16#include "moc_location_interface.cpp"
17#include "moc_manager_interface.cpp"
57 parseParameters(parameters);
59 qDBusRegisterMetaType<Timestamp>();
61 restoreLastPosition();
65 this, &QGeoPositionInfoSourceGeoclue2::requestUpdateTimeout);
81 if (fromSatellitePositioningMethodsOnly && !m_lastPositionFromSatellite)
83 return m_lastPosition;
89 const auto accuracy = m_manager.property(
"AvailableAccuracyLevel").toUInt(&
ok);
96 case GCLUE_ACCURACY_LEVEL_COUNTRY:
97 case GCLUE_ACCURACY_LEVEL_CITY:
98 case GCLUE_ACCURACY_LEVEL_NEIGHBORHOOD:
99 case GCLUE_ACCURACY_LEVEL_STREET:
101 case GCLUE_ACCURACY_LEVEL_EXACT:
103 case GCLUE_ACCURACY_LEVEL_NONE:
128 qCWarning(lcPositioningGeoclue2) <<
"Already running";
132 qCDebug(lcPositioningGeoclue2) <<
"Starting updates";
140 if (m_lastPosition.
isValid()) {
149 qCWarning(lcPositioningGeoclue2) <<
"Already stopped";
153 qCDebug(lcPositioningGeoclue2) <<
"Stopping updates";
162 qCDebug(lcPositioningGeoclue2) <<
"Request timer was active, ignoring startUpdates";
184void QGeoPositionInfoSourceGeoclue2::restoreLastPosition()
186#if !defined(QT_NO_DATASTREAM)
191 out >> m_lastPosition;
196void QGeoPositionInfoSourceGeoclue2::saveLastPosition()
198#if !defined(QT_NO_DATASTREAM) && QT_CONFIG(temporaryfile)
203 QSaveFile
file(filePath);
213void QGeoPositionInfoSourceGeoclue2::createClient()
215 const QDBusPendingReply<QDBusObjectPath>
reply = m_manager.GetClient();
220 const QDBusPendingReply<QDBusObjectPath>
reply = *
watcher;
221 if (
reply.isError()) {
222 const auto error = reply.error();
223 qCWarning(lcPositioningGeoclue2) <<
"Unable to obtain the client:"
224 << error.name() << error.message();
225 setError(AccessError);
227 const QString clientPath = reply.value().path();
228 qCDebug(lcPositioningGeoclue2) <<
"Client path is:"
231 m_client = new OrgFreedesktopGeoClue2ClientInterface(
232 QLatin1String(GEOCLUE2_SERVICE_NAME),
234 QDBusConnection::systemBus(),
236 if (!m_client->isValid()) {
237 const auto error = m_client->lastError();
238 qCCritical(lcPositioningGeoclue2) <<
"Unable to create the client object:"
239 << error.name() << error.message();
241 setError(AccessError);
243 connect(m_client.data(), &OrgFreedesktopGeoClue2ClientInterface::LocationUpdated,
244 this, &QGeoPositionInfoSourceGeoclue2::handleNewLocation);
246 if (configureClient())
253void QGeoPositionInfoSourceGeoclue2::startClient()
256 if (!m_running && !m_requestTimer->
isActive())
270 if (
reply.isError()) {
271 const auto error = reply.error();
272 qCCritical(lcPositioningGeoclue2) <<
"Unable to start the client:"
273 << error.name() << error.message();
277 setError(AccessError);
279 qCDebug(lcPositioningGeoclue2) <<
"Client successfully started";
281 const QDBusObjectPath location = m_client->location();
282 const QString path = location.path();
283 if (path.isEmpty() || path == QLatin1String(
"/"))
291void QGeoPositionInfoSourceGeoclue2::stopClient()
294 if (m_requestTimer->
isActive() || m_running || !m_client)
303 if (
reply.isError()) {
304 const auto error = reply.error();
305 qCCritical(lcPositioningGeoclue2) <<
"Unable to stop the client:"
306 << error.name() << error.message();
307 setError(AccessError);
309 qCDebug(lcPositioningGeoclue2) <<
"Client successfully stopped";
315bool QGeoPositionInfoSourceGeoclue2::configureClient()
322 <<
"Unable to configure the client due to the desktop id is not set via"
328 m_client->setDesktopId(m_desktopId);
332 m_client->setTimeThreshold(secs);
337 m_client->setRequestedAccuracyLevel(GCLUE_ACCURACY_LEVEL_EXACT);
340 m_client->setRequestedAccuracyLevel(GCLUE_ACCURACY_LEVEL_STREET);
343 m_client->setRequestedAccuracyLevel(GCLUE_ACCURACY_LEVEL_EXACT);
346 m_client->setRequestedAccuracyLevel(GCLUE_ACCURACY_LEVEL_NONE);
353void QGeoPositionInfoSourceGeoclue2::requestUpdateTimeout()
355 qCDebug(lcPositioningGeoclue2) <<
"Request update timeout occurred";
362void QGeoPositionInfoSourceGeoclue2::handleNewLocation(
const QDBusObjectPath &oldLocation,
366 m_requestTimer->
stop();
368 const auto oldPath = oldLocation.path();
369 const auto newPath = newLocation.path();
370 qCDebug(lcPositioningGeoclue2) <<
"Old location object path:" << oldPath;
371 qCDebug(lcPositioningGeoclue2) <<
"New location object path:" << newPath;
373 OrgFreedesktopGeoClue2LocationInterface
location(
380 qCCritical(lcPositioningGeoclue2) <<
"Unable to create the location object:"
385 const auto altitude =
location.altitude();
386 if (altitude > std::numeric_limits<double>::lowest())
387 coordinate.setAltitude(altitude);
399 const auto accuracy =
location.accuracy();
404 const auto speed =
location.speed();
407 const auto heading =
location.heading();
412 qCDebug(lcPositioningGeoclue2) <<
"New position:" << m_lastPosition;
418void QGeoPositionInfoSourceGeoclue2::parseParameters(
const QVariantMap ¶meters)
420 if (parameters.
contains(desktopIdParameter))
421 m_desktopId = parameters.
value(desktopIdParameter).
toString();
429#include "moc_qgeopositioninfosource_geoclue2_p.cpp"
static JNINativeMethod methods[]
QString applicationName
the name of this application
static QDBusConnection systemBus()
Returns a QDBusConnection object opened with the system bus.
void finished(QDBusPendingCallWatcher *self=nullptr)
This signal is emitted when the pending call has finished and its reply is available.
\inmodule QtCore\reentrant
static QDateTime currentDateTime()
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QDateTime fromSecsSinceEpoch(qint64 secs, const QTimeZone &timeZone)
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
void startUpdates() override
Starts emitting updates at regular intervals as specified by setUpdateInterval().
~QGeoPositionInfoSourceGeoclue2()
PositioningMethods supportedPositioningMethods() const override
Returns the positioning methods available to this source.
Error error() const override
Returns the type of error that last occurred.
void requestUpdate(int timeout=5000) override
Attempts to get the current position and emit positionUpdated() with this information.
QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly=false) const override
Returns an update containing the last known position, or a null update if none is available.
void stopUpdates() override
Stops emitting updates at regular intervals.
int minimumUpdateInterval() const override
void setPreferredPositioningMethods(PositioningMethods methods) override
void setUpdateInterval(int msec) override
QGeoPositionInfoSourceGeoclue2(const QVariantMap ¶meters, QObject *parent=nullptr)
int updateInterval
This property holds the requested interval in milliseconds between each update.
void positionUpdated(const QGeoPositionInfo &update)
If startUpdates() or requestUpdate() is called, this signal is emitted when an update becomes availab...
@ SatellitePositioningMethods
@ NonSatellitePositioningMethods
void errorOccurred(QGeoPositionInfoSource::Error)
This signal is emitted after an error occurred.
virtual void setPreferredPositioningMethods(PositioningMethods methods)
Error
The Error enumeration represents the errors which can occur.
virtual void setUpdateInterval(int msec)
PositioningMethods preferredPositioningMethods
Sets the preferred positioning methods for this source.
bool isValid() const
Returns true if the timestamp() and coordinate() values are both valid.
QGeoCoordinate coordinate() const
Returns the coordinate for this position.
void setAttribute(Attribute attribute, qreal value)
Sets the value for attribute to value.
QDateTime timestamp() const
Returns the date and time at which this position was reported, in UTC time.
T value(const Key &key, const T &defaultValue=T()) const
bool contains(const Key &key) const
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static QString writableLocation(StandardLocation type)
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
void setSingleShot(bool singleShot)
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
bool isActive() const
Returns true if the timer is running (pending); otherwise returns false.
void stop()
Stops the timer.
void timeout(QPrivateSignal)
This signal is emitted when the timer times out.
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
Combined button and popup list for selecting options.
static const auto desktopIdParameter
static QString lastPositionFilePath()
@ GCLUE_ACCURACY_LEVEL_COUNTRY
@ GCLUE_ACCURACY_LEVEL_NONE
@ GCLUE_ACCURACY_LEVEL_EXACT
@ GCLUE_ACCURACY_LEVEL_NEIGHBORHOOD
@ GCLUE_ACCURACY_LEVEL_CITY
@ GCLUE_ACCURACY_LEVEL_STREET
const char GEOCLUE2_SERVICE_NAME[]
DBusConnection const char DBusError * error
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
#define MINIMUM_UPDATE_INTERVAL
#define UPDATE_TIMEOUT_COLD_START
#define qCCritical(category,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
constexpr const T & qMax(const T &a, const T &b)
#define Q_ARG(Type, data)
GLbitfield GLuint64 timeout
[4]
QLatin1StringView QLatin1String
#define QStringLiteral(str)
QFutureWatcher< int > watcher
QTextStream out(stdout)
[7]