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
36 QT_USE_NAMESPACE
37
38 class DummySource : public QGeoPositionInfoSource
39 {
40 Q_OBJECT
41
42 public:
43 DummySource(const QVariantMap ¶meters, 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
57 private:
58 QTimer *timer;
59 QTimer *timeoutTimer;
60 QTimer *singleTimer;
61 QGeoPositionInfo lastPosition;
62 QDateTime lastUpdateTime;
63
64 private slots:
65 void updatePosition();
66 void doTimeout();
67 };
68
69 class DummySourcePrivate : public QGeoPositionInfoSourcePrivate
70 {
71 public:
setBackendProperty(const QString & name,const QVariant & value)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 }
backendProperty(const QString & name) const80 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
DummySource(const QVariantMap & parameters,QObject * parent)90 DummySource::DummySource(const QVariantMap ¶meters, 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(*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(timer, SIGNAL(timeout()),
107 this, SLOT(updatePosition()));
108 connect(singleTimer, SIGNAL(timeout()),
109 this, SLOT(updatePosition()));
110 connect(timeoutTimer, SIGNAL(timeout()),
111 this, SLOT(doTimeout()));
112 }
113
error() const114 QGeoPositionInfoSource::Error DummySource::error() const
115 {
116 return QGeoPositionInfoSource::NoError;
117 }
118
119
setUpdateInterval(int msec)120 void 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
minimumUpdateInterval() const134 int DummySource::minimumUpdateInterval() const
135 {
136 return 1000;
137 }
138
lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const139 QGeoPositionInfo DummySource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
140 {
141 Q_UNUSED(fromSatellitePositioningMethodsOnly);
142 return lastPosition;
143 }
144
supportedPositioningMethods() const145 QGeoPositionInfoSource::PositioningMethods DummySource::supportedPositioningMethods() const
146 {
147 return QGeoPositionInfoSource::AllPositioningMethods;
148 }
149
startUpdates()150 void DummySource::startUpdates()
151 {
152 timer->start();
153 }
154
stopUpdates()155 void DummySource::stopUpdates()
156 {
157 timer->stop();
158 }
159
requestUpdate(int timeout)160 void 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
~DummySource()179 DummySource::~DummySource()
180 {}
181
updatePosition()182 void DummySource::updatePosition()
183 {
184 DummySourcePrivate *dd = static_cast<DummySourcePrivate *>(QGeoPositionInfoSourcePrivate::get(*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(QGeoPositionInfo::Direction, lastPosition.coordinate().azimuthTo(coord));
196 if (lastUpdateTime.isValid()) {
197 double speed = lastPosition.coordinate().distanceTo(coord) / lastUpdateTime.msecsTo(now);
198 info.setAttribute(QGeoPositionInfo::GroundSpeed, 1000 * speed);
199 }
200
201 lastUpdateTime = now;
202 lastPosition = info;
203 emit positionUpdated(info);
204 }
205
doTimeout()206 void DummySource::doTimeout()
207 {
208 timeoutTimer->stop();
209 singleTimer->stop();
210 emit updateTimeout();
211 }
212
213
214 class 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
221 public:
222 QGeoPositionInfoSource *positionInfoSource(QObject *parent);
223 QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
224 QGeoAreaMonitorSource *areaMonitor(QObject *parent);
225
226 QGeoPositionInfoSource *positionInfoSourceWithParameters(QObject *parent, const QVariantMap ¶meters);
227 QGeoSatelliteInfoSource *satelliteInfoSourceWithParameters(QObject *parent, const QVariantMap ¶meters);
228 QGeoAreaMonitorSource *areaMonitorWithParameters(QObject *parent, const QVariantMap ¶meters);
229 };
230
positionInfoSource(QObject * parent)231 QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSource(QObject *parent)
232 {
233 return new DummySource(QVariantMap(), parent);
234 }
235
satelliteInfoSource(QObject * parent)236 QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSource(QObject *parent)
237 {
238 return satelliteInfoSourceWithParameters(parent, QVariantMap());
239 }
240
areaMonitor(QObject * parent)241 QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject* parent)
242 {
243 return areaMonitorWithParameters(parent, QVariantMap());
244 }
245
positionInfoSourceWithParameters(QObject * parent,const QVariantMap & parameters)246 QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSourceWithParameters(QObject *parent, const QVariantMap ¶meters)
247 {
248 return new DummySource(parameters, parent);
249 }
250
satelliteInfoSourceWithParameters(QObject * parent,const QVariantMap & parameters)251 QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSourceWithParameters(QObject *parent, const QVariantMap ¶meters)
252 {
253 Q_UNUSED(parent);
254 Q_UNUSED(parameters)
255 return nullptr;
256 }
257
areaMonitorWithParameters(QObject * parent,const QVariantMap & parameters)258 QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitorWithParameters(QObject *parent, const QVariantMap ¶meters)
259 {
260 Q_UNUSED(parent);
261 Q_UNUSED(parameters)
262 return nullptr;
263 }
264
265 #include "plugin.moc"
266