1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtPositioning module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39#include <qgeosatelliteinfosource.h>
40#include <qgeosatelliteinfosource_p.h>
41#include "qgeopositioninfosourcefactory.h"
42#include "qgeopositioninfosource_p.h"
43#include <QPluginLoader>
44#include <QStringList>
45#include <QCryptographicHash>
46#include <QtCore/private/qfactoryloader_p.h>
47#include <QFile>
48
49QT_BEGIN_NAMESPACE
50
51/*!
52 \class QGeoSatelliteInfoSource
53 \inmodule QtPositioning
54 \ingroup QtPositioning-positioning
55 \since 5.2
56
57 \brief The QGeoSatelliteInfoSource class is an abstract base class for the distribution of satellite information updates.
58
59 The static function QGeoSatelliteInfoSource::createDefaultSource() creates a default
60 satellite data source that is appropriate for the platform, if one is
61 available. Otherwise, available QGeoPositionInfoSourceFactory plugins will
62 be checked for one that has a satellite data source available.
63
64 Call startUpdates() and stopUpdates() to start and stop regular updates,
65 or requestUpdate() to request a single update.
66 When an update is available, satellitesInViewUpdated() and/or
67 satellitesInUseUpdated() will be emitted.
68
69 If regular satellite updates are required, setUpdateInterval() can be used
70 to specify how often these updates should be emitted. If no interval is
71 specified, updates are simply provided whenever they are available.
72 For example:
73
74 \code
75 // Emit updates every 10 seconds if available
76 QGeoSatelliteInfoSource *source = QGeoSatelliteInfoSource::createDefaultSource(0);
77 if (source)
78 source->setUpdateInterval(10000);
79 \endcode
80
81 To remove an update interval that was previously set, call
82 setUpdateInterval() with a value of 0.
83
84 Note that the satellite source may have a minimum value requirement for
85 update intervals, as returned by minimumUpdateInterval().
86*/
87
88/*!
89 Creates a satellite source with the specified \a parent.
90*/
91
92QGeoSatelliteInfoSourcePrivate::~QGeoSatelliteInfoSourcePrivate()
93{
94
95}
96
97QGeoSatelliteInfoSourcePrivate *QGeoSatelliteInfoSourcePrivate::get(QGeoSatelliteInfoSource &source)
98{
99 return source.d;
100}
101
102QGeoSatelliteInfoSource::QGeoSatelliteInfoSource(QObject *parent)
103 : QObject(parent),
104 d(new QGeoSatelliteInfoSourcePrivate)
105{
106 d->interval = 0;
107}
108
109QGeoSatelliteInfoSource::QGeoSatelliteInfoSource(QGeoSatelliteInfoSourcePrivate &dd, QObject *parent)
110: QObject(parent),
111 d(&dd)
112{
113
114}
115
116/*!
117 Destroys the satellite source.
118*/
119QGeoSatelliteInfoSource::~QGeoSatelliteInfoSource()
120{
121 delete d;
122}
123
124/*!
125 Returns the unique name of the satellite source implementation in use.
126
127 This is the same name that can be passed to createSource() in order to
128 create a new instance of a particular satellite source implementation.
129*/
130QString QGeoSatelliteInfoSource::sourceName() const
131{
132 return d->providerName;
133}
134
135
136/*!
137 \property QGeoSatelliteInfoSource::updateInterval
138 \brief This property holds the requested interval in milliseconds between each update.
139
140 If the update interval is not set (or is set to 0) the
141 source will provide updates as often as necessary.
142
143 If the update interval is set, the source will provide updates at an
144 interval as close to the requested interval as possible. If the requested
145 interval is less than the minimumUpdateInterval(),
146 the minimum interval is used instead.
147
148 Changes to the update interval will happen as soon as is practical, however the
149 time the change takes may vary between implementations. Whether or not the elapsed
150 time from the previous interval is counted as part of the new interval is also
151 implementation dependent.
152
153 The default value for this property is 0.
154
155 Note: Subclass implementations must call the base implementation of
156 setUpdateInterval() so that updateInterval() returns the correct value.
157*/
158void QGeoSatelliteInfoSource::setUpdateInterval(int msec)
159{
160 d->interval = msec;
161}
162
163int QGeoSatelliteInfoSource::updateInterval() const
164{
165 return d->interval;
166}
167
168static QGeoSatelliteInfoSource* createSource_real(const QJsonObject &meta, const QVariantMap &parameters, QObject *parent)
169{
170 QGeoPositionInfoSourcePrivate d;
171 d.metaData = meta;
172 d.loadPlugin();
173 QGeoSatelliteInfoSource *s = nullptr;
174 if (!parameters.isEmpty() && d.factoryV2)
175 s = d.factoryV2->satelliteInfoSourceWithParameters(parent, parameters);
176 else if (d.factory)
177 s = d.factory->satelliteInfoSource(parent);
178 if (s)
179 QGeoSatelliteInfoSourcePrivate::get(source&: *s)->providerName = d.metaData.value(QStringLiteral("Provider")).toString();
180
181 return s;
182}
183
184/*!
185 Creates and returns a source with the specified \a parent that reads
186 from the system's default source of satellite update information, or the
187 highest priority available plugin.
188
189 Returns 0 if the system has no default satellite source, no valid plugins
190 could be found or the user does not have the permission to access the satellite data.
191*/
192QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createDefaultSource(QObject *parent)
193{
194 return createDefaultSource(parameters: QVariantMap(), parent);
195}
196
197/*!
198 Creates and returns a source with the given \a parent,
199 by loading the plugin named \a sourceName.
200
201 Returns 0 if the plugin cannot be found.
202*/
203QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createSource(const QString &sourceName, QObject *parent)
204{
205 return createSource(sourceName, parameters: QVariantMap(), parent);
206}
207
208/*!
209 Creates and returns a satellite source with the given \a parent that
210 reads from the system's default sources of satellite data, or the plugin
211 with the highest available priority.
212
213 Returns nullptr if the system has no default satellite source, no valid plugins
214 could be found or the user does not have the permission to access the satellite information.
215
216 This method passes \a parameters to the factory to configure the source.
217
218 \since Qt 5.14
219*/
220QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createDefaultSource(const QVariantMap &parameters, QObject *parent)
221{
222 QList<QJsonObject> plugins = QGeoPositionInfoSourcePrivate::pluginsSorted();
223 foreach (const QJsonObject &obj, plugins) {
224 if (obj.value(QStringLiteral("Satellite")).isBool()
225 && obj.value(QStringLiteral("Satellite")).toBool())
226 {
227 const QString testableKey = QStringLiteral("Testable");
228 if (obj.contains(key: testableKey) && !obj.value(key: testableKey).toBool()) {
229 static bool inTest = qEnvironmentVariableIsSet(varName: "QT_QTESTLIB_RUNNING");
230 if (inTest)
231 continue;
232 }
233 return createSource_real(meta: obj, parameters, parent);
234 }
235 }
236
237 return nullptr;
238}
239
240/*!
241 Creates and returns a satellite source with the given \a parent,
242 by loading the plugin named \a sourceName.
243
244 Returns nullptr if the plugin cannot be found.
245
246 This method passes \a parameters to the factory to configure the source.
247
248 \since Qt 5.14
249*/
250QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createSource(const QString &sourceName, const QVariantMap &parameters, QObject *parent)
251{
252 QHash<QString, QJsonObject> plugins = QGeoPositionInfoSourcePrivate::plugins();
253 if (plugins.contains(akey: sourceName))
254 return createSource_real(meta: plugins.value(akey: sourceName), parameters, parent);
255 return nullptr;
256}
257
258/*!
259 Returns a list of available source plugins, including the default system
260 backend if one is available.
261*/
262QStringList QGeoSatelliteInfoSource::availableSources()
263{
264 QStringList plugins;
265 const QHash<QString, QJsonObject> meta = QGeoPositionInfoSourcePrivate::plugins();
266 for (auto it = meta.cbegin(), end = meta.cend(); it != end; ++it) {
267 if (it.value().value(QStringLiteral("Satellite")).isBool()
268 && it.value().value(QStringLiteral("Satellite")).toBool()) {
269 plugins << it.key();
270 }
271 }
272
273 return plugins;
274}
275
276/*!
277 \fn void QGeoSatelliteInfoSource::satellitesInViewUpdated(const QList<QGeoSatelliteInfo> &satellites);
278
279 If startUpdates() or requestUpdate() is called, this signal is emitted
280 when an update is available on the satellites that are
281 currently in view.
282
283 The \a satellites parameter holds the satellites currently in view.
284*/
285
286/*!
287 \fn void QGeoSatelliteInfoSource::satellitesInUseUpdated(const QList<QGeoSatelliteInfo> &satellites);
288
289 If startUpdates() or requestUpdate() is called, this signal is emitted
290 when an update is available on the number of satellites that are
291 currently in use.
292
293 These are the satellites that are used to get a "fix" - that
294 is, those used to determine the current position.
295
296 The \a satellites parameter holds the satellites currently in use.
297*/
298
299/*!
300 \property QGeoSatelliteInfoSource::minimumUpdateInterval
301 \brief This property holds the minimum time (in milliseconds) required to retrieve a satellite update.
302
303 This is the minimum value accepted by setUpdateInterval() and
304 requestUpdate().
305*/
306
307
308/*!
309 \fn virtual void QGeoSatelliteInfoSource::startUpdates() = 0;
310
311 Starts emitting updates at regular intervals. The updates will be
312 provided whenever new satellite information becomes available.
313
314 If satellite information cannot be retrieved or some other
315 form of timeout has occurred the satellitesInViewUpdated()
316 and satellitesInUseUpdated() signals may be emitted with
317 empty parameter lists.
318
319 \sa satellitesInViewUpdated(), satellitesInUseUpdated()
320*/
321
322/*!
323 \fn virtual void QGeoSatelliteInfoSource::stopUpdates() = 0;
324
325 Stops emitting updates at regular intervals.
326*/
327
328/*!
329 \fn virtual void QGeoSatelliteInfoSource::requestUpdate(int timeout = 0);
330
331 Attempts to get the current satellite information and emit
332 satellitesInViewUpdated() and satellitesInUseUpdated() with this
333 information. If the current satellite information cannot be found
334 within the given \a timeout (in milliseconds) or if \a timeout is less than the value returned by
335 minimumUpdateInterval(), requestTimeout() is
336 emitted.
337
338 If the timeout is zero, the timeout defaults to a reasonable timeout
339 period as appropriate for the source.
340
341 This does nothing if another update request is in progress. However
342 it can be called even if startUpdates() has already been called and
343 regular updates are in progress.
344*/
345
346/*!
347 \fn void QGeoSatelliteInfoSource::requestTimeout();
348
349 Emitted if requestUpdate() was called and the current satellite
350 information could not be retrieved within the specified timeout.
351
352 While the triggering of this signal may be considered an error condition,
353 it does not imply the emission of the \c error() signal. Only the emission of
354 \c requestTimeout() is required to indicate a timeout.
355*/
356
357/*!
358 \fn QGeoSatelliteInfoSource::Error QGeoSatelliteInfoSource::error() const = 0
359
360 Returns the last error that occurred.
361
362 This signal is not emitted when a requestTimeout() has occurred.
363*/
364
365/*!
366 \fn void QGeoSatelliteInfoSource::error(QGeoSatelliteInfoSource::Error satelliteError)
367
368 This signal is emitted after an error occurred. The \a satelliteError
369 parameter describes the type of error that occurred.
370
371*/
372
373/*!
374 \enum QGeoSatelliteInfoSource::Error
375
376 The Error enumeration represents the errors which can occur.
377
378 \value AccessError The connection setup to the satellite backend failed because the
379 application lacked the required privileges.
380 \value ClosedError The satellite backend closed the connection, which happens for example in case
381 the user is switching location services to off. This object becomes invalid and should be deleted.
382 A new satellite source can be created by calling createDefaultSource() later on.
383 \value NoError No error has occurred.
384 \value UnknownSourceError An unidentified error occurred.
385 */
386
387
388QT_END_NAMESPACE
389

source code of qtlocation/src/positioning/qgeosatelliteinfosource.cpp