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 test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtPositioning/qgeopositioninfosource.h>
30#include <QtPositioning/private/qgeopositioninfosource_p.h>
31#include <QtPositioning/qgeopositioninfosourcefactory.h>
32#include <QObject>
33#include <QtPlugin>
34#include <QTimer>
35
36QT_USE_NAMESPACE
37
38class DummySource : public QGeoPositionInfoSource
39{
40 Q_OBJECT
41
42public:
43 DummySource(const QVariantMap &parameters, QObject *parent=0);
44 ~DummySource();
45
46 void startUpdates();
47 void stopUpdates();
48 void requestUpdate(int timeout=5000);
49
50 QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const;
51 PositioningMethods supportedPositioningMethods() const;
52
53 void setUpdateInterval(int msec);
54 int minimumUpdateInterval() const;
55 Error error() const;
56
57private:
58 QTimer *timer;
59 QTimer *timeoutTimer;
60 QTimer *singleTimer;
61 QGeoPositionInfo lastPosition;
62 QDateTime lastUpdateTime;
63
64private slots:
65 void updatePosition();
66 void doTimeout();
67};
68
69class DummySourcePrivate : public QGeoPositionInfoSourcePrivate
70{
71public:
72 bool setBackendProperty(const QString &name, const QVariant &value) override
73 {
74 if (name == QStringLiteral("altitude")) {
75 m_altitude = value.toReal();
76 return true;
77 }
78 return false;
79 }
80 QVariant backendProperty(const QString &name) const override
81 {
82 if (name == QStringLiteral("altitude"))
83 return m_altitude;
84 return QVariant();
85 }
86
87 qreal m_altitude = 0.0;
88};
89
90DummySource::DummySource(const QVariantMap &parameters, QObject *parent) :
91 QGeoPositionInfoSource(*new DummySourcePrivate, parent),
92 timer(new QTimer(this)),
93 timeoutTimer(new QTimer(this)),
94 singleTimer(new QTimer(this)),
95 lastPosition(QGeoCoordinate(0,0), QDateTime::currentDateTime())
96{
97 DummySourcePrivate *dd = static_cast<DummySourcePrivate *>(QGeoPositionInfoSourcePrivate::get(source: *this));
98 if (parameters.contains(QStringLiteral("test.source.altitude"))) {
99 const qreal alti = parameters.value(QStringLiteral("test.source.altitude")).toReal();
100 dd->m_altitude = alti;
101 QGeoCoordinate crd = lastPosition.coordinate();
102 crd.setAltitude(alti);
103 lastPosition.setCoordinate(crd);
104 }
105 timer->setInterval(1000);
106 connect(sender: timer, SIGNAL(timeout()),
107 receiver: this, SLOT(updatePosition()));
108 connect(sender: singleTimer, SIGNAL(timeout()),
109 receiver: this, SLOT(updatePosition()));
110 connect(sender: timeoutTimer, SIGNAL(timeout()),
111 receiver: this, SLOT(doTimeout()));
112}
113
114QGeoPositionInfoSource::Error DummySource::error() const
115{
116 return QGeoPositionInfoSource::NoError;
117}
118
119
120void DummySource::setUpdateInterval(int msec)
121{
122 if (msec == 0) {
123 timer->setInterval(1000);
124 } else if (msec < 1000) {
125 msec = 1000;
126 timer->setInterval(msec);
127 } else {
128 timer->setInterval(msec);
129 }
130
131 QGeoPositionInfoSource::setUpdateInterval(msec);
132}
133
134int DummySource::minimumUpdateInterval() const
135{
136 return 1000;
137}
138
139QGeoPositionInfo DummySource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
140{
141 Q_UNUSED(fromSatellitePositioningMethodsOnly);
142 return lastPosition;
143}
144
145QGeoPositionInfoSource::PositioningMethods DummySource::supportedPositioningMethods() const
146{
147 return QGeoPositionInfoSource::AllPositioningMethods;
148}
149
150void DummySource::startUpdates()
151{
152 timer->start();
153}
154
155void DummySource::stopUpdates()
156{
157 timer->stop();
158}
159
160void DummySource::requestUpdate(int timeout)
161{
162 if (timeout == 0)
163 timeout = 5000;
164 if (timeout < 0)
165 timeout = 0;
166
167 timeoutTimer->setInterval(timeout);
168 timeoutTimer->start();
169
170 if (timer->isActive()) {
171 timer->stop();
172 timer->start();
173 }
174
175 singleTimer->setInterval(1000);
176 singleTimer->start();
177}
178
179DummySource::~DummySource()
180{}
181
182void DummySource::updatePosition()
183{
184 DummySourcePrivate *dd = static_cast<DummySourcePrivate *>(QGeoPositionInfoSourcePrivate::get(source: *this));
185 timeoutTimer->stop();
186 singleTimer->stop();
187
188 const QDateTime now = QDateTime::currentDateTime();
189
190 QGeoCoordinate coord(lastPosition.coordinate().latitude() + 0.1,
191 lastPosition.coordinate().longitude() + 0.1,
192 dd->m_altitude);
193
194 QGeoPositionInfo info(coord, now);
195 info.setAttribute(attribute: QGeoPositionInfo::Direction, value: lastPosition.coordinate().azimuthTo(other: coord));
196 if (lastUpdateTime.isValid()) {
197 double speed = lastPosition.coordinate().distanceTo(other: coord) / lastUpdateTime.msecsTo(now);
198 info.setAttribute(attribute: QGeoPositionInfo::GroundSpeed, value: 1000 * speed);
199 }
200
201 lastUpdateTime = now;
202 lastPosition = info;
203 emit positionUpdated(update: info);
204}
205
206void DummySource::doTimeout()
207{
208 timeoutTimer->stop();
209 singleTimer->stop();
210 emit updateTimeout();
211}
212
213
214class QGeoPositionInfoSourceFactoryTest : public QObject, public QGeoPositionInfoSourceFactoryV2
215{
216 Q_OBJECT
217 Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0"
218 FILE "plugin.json")
219 Q_INTERFACES(QGeoPositionInfoSourceFactoryV2)
220
221public:
222 QGeoPositionInfoSource *positionInfoSource(QObject *parent);
223 QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
224 QGeoAreaMonitorSource *areaMonitor(QObject *parent);
225
226 QGeoPositionInfoSource *positionInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters);
227 QGeoSatelliteInfoSource *satelliteInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters);
228 QGeoAreaMonitorSource *areaMonitorWithParameters(QObject *parent, const QVariantMap &parameters);
229};
230
231QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSource(QObject *parent)
232{
233 return new DummySource(QVariantMap(), parent);
234}
235
236QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSource(QObject *parent)
237{
238 return satelliteInfoSourceWithParameters(parent, parameters: QVariantMap());
239}
240
241QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject* parent)
242{
243 return areaMonitorWithParameters(parent, parameters: QVariantMap());
244}
245
246QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters)
247{
248 return new DummySource(parameters, parent);
249}
250
251QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSourceWithParameters(QObject *parent, const QVariantMap &parameters)
252{
253 Q_UNUSED(parent);
254 Q_UNUSED(parameters)
255 return nullptr;
256}
257
258QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitorWithParameters(QObject *parent, const QVariantMap &parameters)
259{
260 Q_UNUSED(parent);
261 Q_UNUSED(parameters)
262 return nullptr;
263}
264
265#include "plugin.moc"
266

source code of qtlocation/tests/auto/positionplugin/plugin.cpp