summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@digia.com>2013-08-26 09:35:01 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-17 11:38:14 +0200
commit0ed9f7496656fa0ea52d703c7fddff26c2192857 (patch)
treeec0d4d7dc638e8018a8896a0b62cc91840c9c23d
parent87ce030b7b7336e561779dc9516d5ae2242a5d5f (diff)
Improve area monitoring API.
1.) QGeoAreaMonitor renamed to QGeoAreaMonitorSource 2.) Add new QGeoAreaMonitorInfo data type encpsulating individual areas to be monitored 3.) Port positionpoll plug-in to new features 4.) Make positionpoll monitor thread safe 4.) Extend and fix the QGeoAreaMonitor unit test 5.) Fix documentation. Task-number: QTBUG-31711 Change-Id: Icfc982de4753d2f43cb4d15c234eb7b7c039a0c4 Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
-rw-r--r--src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp2
-rw-r--r--src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h2
-rw-r--r--src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.cpp2
-rw-r--r--src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.h2
-rw-r--r--src/plugins/position/positionpoll/positionpollfactory.cpp5
-rw-r--r--src/plugins/position/positionpoll/positionpollfactory.h2
-rw-r--r--src/plugins/position/positionpoll/qgeoareamonitor_polling.cpp480
-rw-r--r--src/plugins/position/positionpoll/qgeoareamonitor_polling.h42
-rw-r--r--src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.cpp2
-rw-r--r--src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.h2
-rw-r--r--src/positioning/doc/snippets/cpp/cppqml.cpp40
-rw-r--r--src/positioning/doc/src/cpp-position.qdoc4
-rw-r--r--src/positioning/doc/src/qtpositioning-plugins.qdoc2
-rw-r--r--src/positioning/positioning.pro6
-rw-r--r--src/positioning/qgeoareamonitor.cpp256
-rw-r--r--src/positioning/qgeoareamonitorinfo.cpp379
-rw-r--r--src/positioning/qgeoareamonitorinfo.h105
-rw-r--r--src/positioning/qgeoareamonitorsource.cpp390
-rw-r--r--src/positioning/qgeoareamonitorsource.h109
-rw-r--r--src/positioning/qgeopositioninfosourcefactory.cpp4
-rw-r--r--src/positioning/qgeopositioninfosourcefactory.h4
-rw-r--r--src/positioning/qgeosatelliteinfosource.cpp17
-rw-r--r--src/positioning/qgeosatelliteinfosource.h4
-rw-r--r--tests/auto/positionplugin/plugin.cpp4
-rw-r--r--tests/auto/positionplugintest/tst_positionplugin.cpp4
-rw-r--r--tests/auto/qgeoareamonitor/logfilepositionsource.cpp125
-rw-r--r--tests/auto/qgeoareamonitor/logfilepositionsource.h (renamed from src/positioning/qgeoareamonitor.h)52
-rw-r--r--tests/auto/qgeoareamonitor/qgeoareamonitor.pro7
-rw-r--r--tests/auto/qgeoareamonitor/simplelog.txt87
-rw-r--r--tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp734
30 files changed, 2355 insertions, 519 deletions
diff --git a/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp b/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp
index 5f243d89..9be36053 100644
--- a/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp
+++ b/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.cpp
@@ -73,7 +73,7 @@ QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryGeoclue::satelliteInfoSour
#endif
}
-QGeoAreaMonitor *QGeoPositionInfoSourceFactoryGeoclue::areaMonitor(QObject *parent)
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryGeoclue::areaMonitor(QObject *parent)
{
Q_UNUSED(parent);
return 0;
diff --git a/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h b/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h
index 0fa95d72..3de93bbf 100644
--- a/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h
+++ b/src/plugins/position/geoclue/qgeopositioninfosourcefactory_geoclue.h
@@ -65,7 +65,7 @@ class QGeoPositionInfoSourceFactoryGeoclue : public QObject, public QGeoPosition
public:
QGeoPositionInfoSource *positionInfoSource(QObject *parent);
QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
- QGeoAreaMonitor *areaMonitor(QObject *parent);
+ QGeoAreaMonitorSource *areaMonitor(QObject *parent);
};
#endif
diff --git a/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.cpp b/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.cpp
index dee265de..3e8b93a3 100644
--- a/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.cpp
+++ b/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.cpp
@@ -58,7 +58,7 @@ QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryGypsy::satelliteInfoSource
return src;
}
-QGeoAreaMonitor *QGeoPositionInfoSourceFactoryGypsy::areaMonitor(QObject *parent)
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryGypsy::areaMonitor(QObject *parent)
{
Q_UNUSED(parent);
return 0;
diff --git a/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.h b/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.h
index 6cd145ca..dab3cc71 100644
--- a/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.h
+++ b/src/plugins/position/gypsy/qgeopositioninfosourcefactory_gypsy.h
@@ -55,7 +55,7 @@ class QGeoPositionInfoSourceFactoryGypsy : public QObject, public QGeoPositionIn
public:
QGeoPositionInfoSource *positionInfoSource(QObject *parent);
QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
- QGeoAreaMonitor *areaMonitor(QObject *parent);
+ QGeoAreaMonitorSource *areaMonitor(QObject *parent);
};
#endif
diff --git a/src/plugins/position/positionpoll/positionpollfactory.cpp b/src/plugins/position/positionpoll/positionpollfactory.cpp
index a3ec6527..0f02bff1 100644
--- a/src/plugins/position/positionpoll/positionpollfactory.cpp
+++ b/src/plugins/position/positionpoll/positionpollfactory.cpp
@@ -54,10 +54,9 @@ QGeoSatelliteInfoSource *PositionPollFactory::satelliteInfoSource(QObject *paren
return 0;
}
-QGeoAreaMonitor *PositionPollFactory::areaMonitor(QObject *parent)
+QGeoAreaMonitorSource *PositionPollFactory::areaMonitor(QObject *parent)
{
- QGeoAreaMonitorPolling *ret = 0;
- ret = new QGeoAreaMonitorPolling(parent);
+ QGeoAreaMonitorPolling *ret = new QGeoAreaMonitorPolling(parent);
if (ret && ret->isValid())
return ret;
delete ret;
diff --git a/src/plugins/position/positionpoll/positionpollfactory.h b/src/plugins/position/positionpoll/positionpollfactory.h
index 73a4d60a..79ad85eb 100644
--- a/src/plugins/position/positionpoll/positionpollfactory.h
+++ b/src/plugins/position/positionpoll/positionpollfactory.h
@@ -54,7 +54,7 @@ class PositionPollFactory : public QObject, public QGeoPositionInfoSourceFactory
public:
QGeoPositionInfoSource *positionInfoSource(QObject *parent);
QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
- QGeoAreaMonitor *areaMonitor(QObject *parent);
+ QGeoAreaMonitorSource *areaMonitor(QObject *parent);
};
#endif // POSITIONPOLLFACTORY_H
diff --git a/src/plugins/position/positionpoll/qgeoareamonitor_polling.cpp b/src/plugins/position/positionpoll/qgeoareamonitor_polling.cpp
index 784c9fad..55d66993 100644
--- a/src/plugins/position/positionpoll/qgeoareamonitor_polling.cpp
+++ b/src/plugins/position/positionpoll/qgeoareamonitor_polling.cpp
@@ -41,94 +41,476 @@
#include "qgeoareamonitor_polling.h"
#include <qgeocoordinate.h>
+#include <qgeorectangle.h>
+#include <qgeocircle.h>
#include <QtCore/qmetaobject.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qmutex.h>
#define UPDATE_INTERVAL_5S 5000
-QGeoAreaMonitorPolling::QGeoAreaMonitorPolling(QObject *parent) : QGeoAreaMonitor(parent)
+typedef QHash<QString, QGeoAreaMonitorInfo> MonitorTable;
+
+
+static QMetaMethod areaEnteredSignal()
{
- insideArea = false;
- location = QGeoPositionInfoSource::createDefaultSource(this);
- if (location) {
- location->setUpdateInterval(UPDATE_INTERVAL_5S);
- connect(location, SIGNAL(positionUpdated(QGeoPositionInfo)),
- this, SLOT(positionUpdated(QGeoPositionInfo)));
- }
+ static QMetaMethod signal = QMetaMethod::fromSignal(&QGeoAreaMonitorPolling::areaEntered);
+ return signal;
}
-QGeoAreaMonitorPolling::~QGeoAreaMonitorPolling()
+static QMetaMethod areaExitedSignal()
{
- if (location)
- location->stopUpdates();
+ static QMetaMethod signal = QMetaMethod::fromSignal(&QGeoAreaMonitorPolling::areaExited);
+ return signal;
+}
+
+static QMetaMethod monitorExpiredSignal()
+{
+ static QMetaMethod signal = QMetaMethod::fromSignal(&QGeoAreaMonitorPolling::monitorExpired);
+ return signal;
}
-void QGeoAreaMonitorPolling::setCenter(const QGeoCoordinate &coordinate)
+class QGeoAreaMonitorPollingPrivate : public QObject
{
- if (coordinate.isValid()) {
- QGeoAreaMonitor::setCenter(coordinate);
+ Q_OBJECT
+public:
+ QGeoAreaMonitorPollingPrivate() : source(0), mutex(QMutex::Recursive)
+ {
+ nextExpiryTimer = new QTimer(this);
+ nextExpiryTimer->setSingleShot(true);
+ connect(nextExpiryTimer, SIGNAL(timeout()),
+ this, SLOT(timeout()));
+ }
+
+ void startMonitoring(const QGeoAreaMonitorInfo &monitor)
+ {
+ QMutexLocker locker(&mutex);
+
+ activeMonitorAreas.insert(monitor.identifier(), monitor);
+ singleShotTrigger.remove(monitor.identifier());
+
+ checkStartStop();
+ setupNextExpiryTimeout();
+ }
+
+ void requestUpdate(const QGeoAreaMonitorInfo &monitor, int signalId)
+ {
+ QMutexLocker locker(&mutex);
+
+ activeMonitorAreas.insert(monitor.identifier(), monitor);
+ singleShotTrigger.insert(monitor.identifier(), signalId);
+
+ checkStartStop();
+ setupNextExpiryTimeout();
+ }
+
+ QGeoAreaMonitorInfo stopMonitoring(const QGeoAreaMonitorInfo &monitor)
+ {
+ QMutexLocker locker(&mutex);
+
+ QGeoAreaMonitorInfo mon = activeMonitorAreas.take(monitor.identifier());
+
checkStartStop();
+ setupNextExpiryTimeout();
+
+ return mon;
}
+
+ void registerClient(QGeoAreaMonitorPolling *client)
+ {
+ QMutexLocker locker(&mutex);
+
+ connect(this, SIGNAL(timeout(QGeoAreaMonitorInfo)),
+ client, SLOT(timeout(QGeoAreaMonitorInfo)));
+
+ connect(this, SIGNAL(positionError(QGeoPositionInfoSource::Error)),
+ client, SLOT(positionError(QGeoPositionInfoSource::Error)));
+
+ connect(this, SIGNAL(areaEventDetected(QGeoAreaMonitorInfo,QGeoPositionInfo,bool)),
+ client, SLOT(processAreaEvent(QGeoAreaMonitorInfo,QGeoPositionInfo,bool)));
+
+ registeredClients.append(client);
+ }
+
+ void deregisterClient(QGeoAreaMonitorPolling *client)
+ {
+ QMutexLocker locker(&mutex);
+
+ registeredClients.removeAll(client);
+ if (registeredClients.isEmpty())
+ checkStartStop();
+ }
+
+ void setPositionSource(QGeoPositionInfoSource *newSource)
+ {
+ QMutexLocker locker(&mutex);
+
+ if (newSource == source)
+ return;
+
+ if (source)
+ delete source;
+
+ source = newSource;
+
+ if (source) {
+ source->setParent(this);
+ source->moveToThread(this->thread());
+ if (source->updateInterval() == 0)
+ source->setUpdateInterval(UPDATE_INTERVAL_5S);
+ disconnect(source, 0, 0, 0); //disconnect all
+ connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
+ this, SLOT(positionUpdated(QGeoPositionInfo)));
+ connect(source, SIGNAL(error(QGeoPositionInfoSource::Error)),
+ this, SIGNAL(positionError(QGeoPositionInfoSource::Error)));
+ checkStartStop();
+ }
+ }
+
+ QGeoPositionInfoSource* positionSource() const
+ {
+ QMutexLocker locker(&mutex);
+ return source;
+ }
+
+ MonitorTable activeMonitors() const
+ {
+ QMutexLocker locker(&mutex);
+
+ return activeMonitorAreas;
+ }
+
+ void checkStartStop()
+ {
+ QMutexLocker locker(&mutex);
+
+ bool signalsConnected = false;
+ foreach (const QGeoAreaMonitorPolling *client, registeredClients) {
+ if (client->signalsAreConnected) {
+ signalsConnected = true;
+ break;
+ }
+ }
+
+ if (signalsConnected && !activeMonitorAreas.isEmpty()) {
+ if (source)
+ source->startUpdates();
+ else
+ //translated to InsufficientPositionInfo
+ emit positionError(QGeoPositionInfoSource::ClosedError);
+ } else {
+ if (source)
+ source->stopUpdates();
+ }
+ }
+
+private:
+ void setupNextExpiryTimeout()
+ {
+ nextExpiryTimer->stop();
+ activeExpiry.first = QDateTime();
+ activeExpiry.second = QString();
+
+ foreach (const QGeoAreaMonitorInfo &info, activeMonitors()) {
+ if (info.expiration().isValid()) {
+ if (!activeExpiry.first.isValid()) {
+ activeExpiry.first = info.expiration();
+ activeExpiry.second = info.identifier();
+ continue;
+ }
+ if (info.expiration() < activeExpiry.first) {
+ activeExpiry.first = info.expiration();
+ activeExpiry.second = info.identifier();
+ }
+ }
+ }
+
+ if (activeExpiry.first.isValid())
+ nextExpiryTimer->start(QDateTime::currentDateTime().msecsTo(activeExpiry.first));
+ }
+
+
+ //returns true if areaEntered should be emitted
+ bool processInsideArea(const QString &monitorIdent)
+ {
+ if (!insideArea.contains(monitorIdent)) {
+ if (singleShotTrigger.value(monitorIdent, -1) == areaEnteredSignal().methodIndex()) {
+ //this is the finishing singleshot event
+ singleShotTrigger.remove(monitorIdent);
+ activeMonitorAreas.remove(monitorIdent);
+ setupNextExpiryTimeout();
+ } else {
+ insideArea.insert(monitorIdent);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ //returns true if areaExited should be emitted
+ bool processOutsideArea(const QString &monitorIdent)
+ {
+ if (insideArea.contains(monitorIdent)) {
+ if (singleShotTrigger.value(monitorIdent, -1) == areaExitedSignal().methodIndex()) {
+ //this is the finishing singleShot event
+ singleShotTrigger.remove(monitorIdent);
+ activeMonitorAreas.remove(monitorIdent);
+ setupNextExpiryTimeout();
+ } else {
+ insideArea.remove(monitorIdent);
+ }
+ return true;
+ }
+ return false;
+ }
+
+
+
+Q_SIGNALS:
+ void timeout(const QGeoAreaMonitorInfo &info);
+ void positionError(const QGeoPositionInfoSource::Error error);
+ void areaEventDetected(const QGeoAreaMonitorInfo &minfo,
+ const QGeoPositionInfo &pinfo, bool isEnteredEvent);
+private Q_SLOTS:
+ void timeout()
+ {
+ /*
+ * Don't block timer firing even if monitorExpiredSignal is not connected.
+ * This allows us to continue to remove the existing monitors as they expire.
+ **/
+ const QGeoAreaMonitorInfo info = activeMonitorAreas.take(activeExpiry.second);
+ setupNextExpiryTimeout();
+ emit timeout(info);
+
+ }
+
+ void positionUpdated(const QGeoPositionInfo &info)
+ {
+ foreach (const QGeoAreaMonitorInfo &monInfo, activeMonitors()) {
+ const QString identifier = monInfo.identifier();
+ if (monInfo.area().contains(info.coordinate())) {
+ if (processInsideArea(identifier))
+ emit areaEventDetected(monInfo, info, true);
+ } else {
+ if (processOutsideArea(identifier))
+ emit areaEventDetected(monInfo, info, false);
+ }
+ }
+ }
+
+private:
+ QPair<QDateTime, QString> activeExpiry;
+ QHash<QString, int> singleShotTrigger;
+ QTimer* nextExpiryTimer;
+ QSet<QString> insideArea;
+
+ MonitorTable activeMonitorAreas;
+
+ QGeoPositionInfoSource* source;
+ QList<QGeoAreaMonitorPolling*> registeredClients;
+ mutable QMutex mutex;
+};
+
+Q_GLOBAL_STATIC(QGeoAreaMonitorPollingPrivate, pollingPrivate)
+
+
+QGeoAreaMonitorPolling::QGeoAreaMonitorPolling(QObject *parent)
+ : QGeoAreaMonitorSource(parent), signalsAreConnected(false)
+{
+ d = pollingPrivate();
+ lastError = QGeoAreaMonitorSource::UnknownSourceError;
+ d->registerClient(this);
+ //hookup to default source if existing
+ if (!positionInfoSource())
+ setPositionInfoSource(QGeoPositionInfoSource::createDefaultSource(this));
}
-void QGeoAreaMonitorPolling::setRadius(qreal radius)
+QGeoAreaMonitorPolling::~QGeoAreaMonitorPolling()
{
- QGeoAreaMonitor::setRadius(radius);
- checkStartStop();
+ d->deregisterClient(this);
}
-static QMetaMethod areaEnteredSignal()
+QGeoPositionInfoSource* QGeoAreaMonitorPolling::positionInfoSource() const
{
- static QMetaMethod signal = QMetaMethod::fromSignal(&QGeoAreaMonitorPolling::areaEntered);
- return signal;
+ return d->positionSource();
}
-static QMetaMethod areaExitedSignal()
+void QGeoAreaMonitorPolling::setPositionInfoSource(QGeoPositionInfoSource *source)
{
- static QMetaMethod signal = QMetaMethod::fromSignal(&QGeoAreaMonitorPolling::areaExited);
- return signal;
+ d->setPositionSource(source);
}
-void QGeoAreaMonitorPolling::connectNotify(const QMetaMethod &signal)
+QGeoAreaMonitorSource::Error QGeoAreaMonitorPolling::error() const
{
- if (signal == areaEnteredSignal() ||
- signal == areaExitedSignal())
- checkStartStop();
+ return lastError;
}
-void QGeoAreaMonitorPolling::disconnectNotify(const QMetaMethod &signal)
+bool QGeoAreaMonitorPolling::startMonitoring(const QGeoAreaMonitorInfo &monitor)
{
- if (signal == areaEnteredSignal() ||
- signal == areaExitedSignal())
- checkStartStop();
+ if (!monitor.isValid())
+ return false;
+
+ //reject an expiry in the past
+ if (monitor.expiration().isValid() &&
+ (monitor.expiration() < QDateTime::currentDateTime()))
+ return false;
+
+ //don't accept persistent monitor since we don't support it
+ if (monitor.isPersistent())
+ return false;
+
+ //update or insert
+ d->startMonitoring(monitor);
+
+ return true;
+}
+
+int QGeoAreaMonitorPolling::idForSignal(const char *signal)
+{
+ const QByteArray sig = QMetaObject::normalizedSignature(signal + 1);
+ const QMetaObject * const mo = metaObject();
+
+ return mo->indexOfSignal(sig.constData());
+}
+
+bool QGeoAreaMonitorPolling::requestUpdate(const QGeoAreaMonitorInfo &monitor, const char *signal)
+{
+ if (!monitor.isValid())
+ return false;
+ //reject an expiry in the past
+ if (monitor.expiration().isValid() &&
+ (monitor.expiration() < QDateTime::currentDateTime()))
+ return false;
+
+ //don't accept persistent monitor since we don't support it
+ if (monitor.isPersistent())
+ return false;
+
+ if (!signal)
+ return false;
+
+ const int signalId = idForSignal(signal);
+ if (signalId < 0)
+ return false;
+
+ //only accept area entered or exit signal
+ if (signalId != areaEnteredSignal().methodIndex() &&
+ signalId != areaExitedSignal().methodIndex())
+ {
+ return false;
+ }
+
+ d->requestUpdate(monitor, signalId);
+
+ return true;
+}
+
+bool QGeoAreaMonitorPolling::stopMonitoring(const QGeoAreaMonitorInfo &monitor)
+{
+ QGeoAreaMonitorInfo info = d->stopMonitoring(monitor);
+
+ return info.isValid();
+}
+
+QList<QGeoAreaMonitorInfo> QGeoAreaMonitorPolling::activeMonitors() const
+{
+ return d->activeMonitors().values();
+}
+
+QList<QGeoAreaMonitorInfo> QGeoAreaMonitorPolling::activeMonitors(const QGeoShape &region) const
+{
+ QList<QGeoAreaMonitorInfo> results;
+ if (region.isEmpty())
+ return results;
+
+ const MonitorTable list = d->activeMonitors();
+ foreach (const QGeoAreaMonitorInfo &monitor, list) {
+ QGeoCoordinate center;
+ switch (monitor.area().type()) {
+ case QGeoShape::CircleType:
+ {
+ QGeoCircle circle(monitor.area());
+ center = circle.center();
+ break;
+ }
+ case QGeoShape::RectangleType:
+ {
+ QGeoRectangle rectangle(monitor.area());
+ center = rectangle.center();
+ break;
+ }
+ case QGeoShape::UnknownType:
+ {
+ break;
+ }
+ }
+ if (region.contains(center))
+ results.append(monitor);
+ }
+
+ return results;
}
-void QGeoAreaMonitorPolling::checkStartStop()
+QGeoAreaMonitorSource::AreaMonitorFeatures QGeoAreaMonitorPolling::supportedAreaMonitorFeatures() const
{
- if (!location) return;
+ return 0;
+}
- if ((isSignalConnected(areaEnteredSignal()) ||
- isSignalConnected(areaExitedSignal())) &&
- QGeoAreaMonitor::center().isValid() &&
- QGeoAreaMonitor::radius() > qreal(0.0)) {
- location->startUpdates();
- } else {
- location->stopUpdates();
+void QGeoAreaMonitorPolling::connectNotify(const QMetaMethod &/*signal*/)
+{
+ if (!signalsAreConnected &&
+ (isSignalConnected(areaEnteredSignal()) ||
+ isSignalConnected(areaExitedSignal())) )
+ {
+ signalsAreConnected = true;
+ d->checkStartStop();
}
}
-void QGeoAreaMonitorPolling::positionUpdated(const QGeoPositionInfo &info)
+void QGeoAreaMonitorPolling::disconnectNotify(const QMetaMethod &/*signal*/)
{
- double distance = info.coordinate().distanceTo(QGeoAreaMonitor::center());
+ if (!isSignalConnected(areaEnteredSignal()) &&
+ !isSignalConnected(areaExitedSignal()))
+ {
+ signalsAreConnected = false;
+ d->checkStartStop();
+ }
+}
- if (distance <= QGeoAreaMonitor::radius()) {
- if (!insideArea)
- emit areaEntered(info);
- insideArea = true;
- } else if (insideArea) {
- emit areaExited(info);
- insideArea = false;
+void QGeoAreaMonitorPolling::positionError(const QGeoPositionInfoSource::Error error)
+{
+ switch (error) {
+ case QGeoPositionInfoSource::AccessError:
+ lastError = QGeoAreaMonitorSource::AccessError;
+ break;
+ case QGeoPositionInfoSource::UnknownSourceError:
+ lastError = QGeoAreaMonitorSource::UnknownSourceError;
+ break;
+ case QGeoPositionInfoSource::ClosedError:
+ lastError = QGeoAreaMonitorSource::InsufficientPositionInfo;
+ break;
}
+
+ emit QGeoAreaMonitorSource::error(lastError);
+}
+
+void QGeoAreaMonitorPolling::timeout(const QGeoAreaMonitorInfo& monitor)
+{
+ if (isSignalConnected(monitorExpiredSignal()))
+ emit monitorExpired(monitor);
+}
+
+void QGeoAreaMonitorPolling::processAreaEvent(const QGeoAreaMonitorInfo &minfo,
+ const QGeoPositionInfo &pinfo, bool isEnteredEvent)
+{
+ if (isEnteredEvent)
+ emit areaEntered(minfo, pinfo);
+ else
+ emit areaExited(minfo, pinfo);
}
+#include "qgeoareamonitor_polling.moc"
#include "moc_qgeoareamonitor_polling.cpp"
diff --git a/src/plugins/position/positionpoll/qgeoareamonitor_polling.h b/src/plugins/position/positionpoll/qgeoareamonitor_polling.h
index a94e4e40..f25cd685 100644
--- a/src/plugins/position/positionpoll/qgeoareamonitor_polling.h
+++ b/src/plugins/position/positionpoll/qgeoareamonitor_polling.h
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
@@ -42,37 +42,55 @@
#ifndef QGEOAREAMONITORPOLLING_H
#define QGEOAREAMONITORPOLLING_H
-#include "qgeoareamonitor.h"
-#include "qgeopositioninfosource.h"
+#include <qgeoareamonitorsource.h>
+#include <qgeopositioninfosource.h>
/**
* QGeoAreaMonitorPolling
*
*/
-class QGeoAreaMonitorPolling : public QGeoAreaMonitor
+
+class QGeoAreaMonitorPollingPrivate;
+class QGeoAreaMonitorPolling : public QGeoAreaMonitorSource
{
Q_OBJECT
-
public :
explicit QGeoAreaMonitorPolling(QObject *parent = 0);
~QGeoAreaMonitorPolling();
- void setCenter(const QGeoCoordinate &coordinate);
- void setRadius(qreal radius);
- inline bool isValid() { return location; }
+ void setPositionInfoSource(QGeoPositionInfoSource *source) Q_DECL_OVERRIDE;
+ QGeoPositionInfoSource* positionInfoSource() const Q_DECL_OVERRIDE;
+
+ Error error() const Q_DECL_OVERRIDE;
+
+ bool startMonitoring(const QGeoAreaMonitorInfo &monitor) Q_DECL_OVERRIDE;
+ bool requestUpdate(const QGeoAreaMonitorInfo &monitor,
+ const char *signal) Q_DECL_OVERRIDE;
+ bool stopMonitoring(const QGeoAreaMonitorInfo &monitor) Q_DECL_OVERRIDE;
+
+ QList<QGeoAreaMonitorInfo> activeMonitors() const Q_DECL_OVERRIDE;
+ QList<QGeoAreaMonitorInfo> activeMonitors(const QGeoShape &region) const Q_DECL_OVERRIDE;
+
+ QGeoAreaMonitorSource::AreaMonitorFeatures supportedAreaMonitorFeatures() const Q_DECL_OVERRIDE;
+
+ inline bool isValid() { return positionInfoSource(); }
+
+ bool signalsAreConnected;
private Q_SLOTS:
- void positionUpdated(const QGeoPositionInfo &info);
+ void positionError(QGeoPositionInfoSource::Error error);
+ void timeout(const QGeoAreaMonitorInfo &monitor);
+ void processAreaEvent(const QGeoAreaMonitorInfo &minfo, const QGeoPositionInfo &pinfo, bool isEnteredEvent);
private:
- bool insideArea;
- QGeoPositionInfoSource *location;
+ QGeoAreaMonitorPollingPrivate* d;
+ QGeoAreaMonitorSource::Error lastError;
void connectNotify(const QMetaMethod &signal);
void disconnectNotify(const QMetaMethod &signal);
- void checkStartStop();
+ int idForSignal(const char *signal);
};
#endif // QGEOAREAMONITORPOLLING_H
diff --git a/src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.cpp b/src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.cpp
index efdb65b4..1d737e24 100644
--- a/src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.cpp
+++ b/src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.cpp
@@ -56,7 +56,7 @@ QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactorySimulator::satelliteInfoSo
return src;
}
-QGeoAreaMonitor *QGeoPositionInfoSourceFactorySimulator::areaMonitor(QObject *parent)
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactorySimulator::areaMonitor(QObject *parent)
{
Q_UNUSED(parent);
return 0;
diff --git a/src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.h b/src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.h
index 42dadf77..e31a7e01 100644
--- a/src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.h
+++ b/src/plugins/position/simulator/qgeopositioninfosourcefactory_simulator.h
@@ -57,7 +57,7 @@ class QGeoPositionInfoSourceFactorySimulator : public QObject, public QGeoPositi
public:
QGeoPositionInfoSource *positionInfoSource(QObject *parent);
QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
- QGeoAreaMonitor *areaMonitor(QObject *parent);
+ QGeoAreaMonitorSource *areaMonitor(QObject *parent);
};
#endif // QGEOPOSITIONINFOSOURCEFACTORY_SIMULATOR_H
diff --git a/src/positioning/doc/snippets/cpp/cppqml.cpp b/src/positioning/doc/snippets/cpp/cppqml.cpp
index 5ab23513..95d34b7c 100644
--- a/src/positioning/doc/snippets/cpp/cppqml.cpp
+++ b/src/positioning/doc/snippets/cpp/cppqml.cpp
@@ -39,9 +39,12 @@
****************************************************************************/
#include <QtCore/QObject>
+#include <QtCore/QDebug>
#include <QtCore/QVariant>
#include <QtPositioning/QGeoAddress>
#include <QtPositioning/QGeoLocation>
+#include <QtPositioning/QGeoCircle>
+#include <QtPositioning/QGeoAreaMonitorSource>
void cppQmlInterface(QObject *qmlObject)
{
@@ -62,3 +65,40 @@ void cppQmlInterface(QObject *qmlObject)
//! [Location set]
}
+class MyClass : public QObject
+{
+ Q_OBJECT
+//! [BigBen]
+public:
+ MyClass() : QObject()
+ {
+ QGeoAreaMonitorSource *monitor = QGeoAreaMonitorSource::createDefaultMonitorSource(this);
+ if (monitor) {
+ connect(monitor, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)),
+ this, SLOT(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo));
+ connect(monitor, SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo)),
+ this, SLOT(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo)));
+
+ QGeoAreaMonitorInfo bigBen("Big Ben");
+ QGeoCoordinate position(51.50104, -0.124632);
+ bigBen.setMonitoredArea(QGeoCircle(position, 100));
+
+ monitor->startMonitoring(bigBen);
+
+ } else {
+ qDebug() << "Could not create default area monitor";
+ }
+ }
+
+public Q_SLOTS:
+ void areaEntered(const QGeoAreaMonitorInfo &mon, const QGeoPositionInfo &update)
+ {
+ qDebug() << "Now within 100 meters, current position is" << update.coordinate();
+ }
+
+ void areaExited(const QGeoAreaMonitorInfo &mon, const QGeoPositionInfo &update)
+ {
+ qDebug() << "No longer within 100 meters, current position is" << update.coordinate();
+ }
+//! [BigBen]
+};
diff --git a/src/positioning/doc/src/cpp-position.qdoc b/src/positioning/doc/src/cpp-position.qdoc
index 75c2e30e..16fceea5 100644
--- a/src/positioning/doc/src/cpp-position.qdoc
+++ b/src/positioning/doc/src/cpp-position.qdoc
@@ -84,10 +84,10 @@ the platform.
If a problem occurs with access to the information source then an
\l {QGeoPositionInfoSource::error()}{error()} signal is emitted.
-The QGeoAreaMonitor class enables client applications to be notified when
+The QGeoAreaMonitorSource class enables client applications to be notified when
the receiving device has moved in or out of a particular area, as specified
by a coordinate and radius. If the platform provides built-in support for
-area monitoring, QGeoAreaMonitor::createDefaultMonitor() returns an instance of
+area monitoring, QGeoAreaMonitorSource::createDefaultMonitor() returns an instance of
the default area monitor.
Satellite information can also be distributed through the
diff --git a/src/positioning/doc/src/qtpositioning-plugins.qdoc b/src/positioning/doc/src/qtpositioning-plugins.qdoc
index 1ed1be1a..5873aadd 100644
--- a/src/positioning/doc/src/qtpositioning-plugins.qdoc
+++ b/src/positioning/doc/src/qtpositioning-plugins.qdoc
@@ -61,7 +61,7 @@ The entries have the following meaning:
\li Set to \c true if the plugin implements a \l QGeoSatelliteInfoSource.
\row
\li Monitor
- \li Set to \c true if the plugin implements a \l QGeoAreaMonitor.
+ \li Set to \c true if the plugin implements a \l QGeoAreaMonitorSource.
\row
\li Priority
\li The plugin priority. If multiple plugins have the same provider name, the plugin
diff --git a/src/positioning/positioning.pro b/src/positioning/positioning.pro
index da1186bf..296356d0 100644
--- a/src/positioning/positioning.pro
+++ b/src/positioning/positioning.pro
@@ -8,7 +8,8 @@ OTHER_FILES += doc/src/*.qdoc # show .qdoc files in Qt Creator
PUBLIC_HEADERS += \
qgeoaddress.h \
- qgeoareamonitor.h \
+ qgeoareamonitorinfo.h \
+ qgeoareamonitorsource.h \
qgeoshape.h \
qgeorectangle.h \
qgeocircle.h \
@@ -37,7 +38,8 @@ PRIVATE_HEADERS += \
SOURCES += \
qgeoaddress.cpp \
- qgeoareamonitor.cpp \
+ qgeoareamonitorsource.cpp \
+ qgeoareamonitorinfo.cpp \
qgeoshape.cpp \
qgeorectangle.cpp \
qgeocircle.cpp \
diff --git a/src/positioning/qgeoareamonitor.cpp b/src/positioning/qgeoareamonitor.cpp
deleted file mode 100644
index 5ad69e9a..00000000
--- a/src/positioning/qgeoareamonitor.cpp
+++ /dev/null
@@ -1,256 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtPositioning module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/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 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qgeoareamonitor.h>
-#include "qgeopositioninfosourcefactory.h"
-#include "qgeopositioninfosource_p.h"
-
-/*!
- \class QGeoAreaMonitor
- \inmodule QtPositioning
- \ingroup QtPositioning-positioning
- \since Qt Positioning 5.0
-
- \brief The QGeoAreaMonitor class enables the detection of proximity
- changes for a specified set of coordinates.
-
- A QGeoAreaMonitor emits signals when the current position is in
- range, or has moved out of range, of a specified circular area.
- The area is specified by a coordinate (the center point) and a
- radius (in meters).
-
- For example:
-
- \code
- public:
- MyClass::MyClass()
- {
- QGeoAreaMonitor *monitor = QGeoAreaMonitor::createDefaultMonitor();
- if (monitor) {
- connect(monitor, SIGNAL(areaEntered(QGeoPositionInfo)),
- this, SLOT(areaEntered(QGeoPositionInfo)));
- connect(monitor, SIGNAL(areaExited(QGeoPositionInfo)),
- this, SLOT(areaExited(QGeoPositionInfo)));
-
- QGeoCoordinate bigBenLocation(51.50104, -0.124632);
- monitor->setCenter(bigBenLocation);
- monitor->setRadius(100);
- } else {
- qDebug() << "Could not create default area monitor";
- }
- }
-
- public Q_SLOTS:
- void areaEntered(const QGeoPositionInfo &update)
- {
- qDebug() << "Now within 100 meters, current position is" << update.coordinate();
- }
-
- void areaExited(const QGeoPositionInfo &update)
- {
- qDebug() << "No longer within 100 meters, current position is" << update.coordinate();
- }
- \endcode
-*/
-
-QT_BEGIN_NAMESPACE
-
-class QGeoAreaMonitorPrivate
-{
-public:
- QGeoCoordinate coord;
- qreal radius;
-};
-
-
-/*!
- Creates a monitor with the given \a parent.
-*/
-QGeoAreaMonitor::QGeoAreaMonitor(QObject *parent)
- : QObject(parent),
- d(new QGeoAreaMonitorPrivate)
-{
- d->radius = qreal(0.0);
-}
-
-/*!
- Destroys the monitor.
-*/
-QGeoAreaMonitor::~QGeoAreaMonitor()
-{
- delete d;
-}
-
-/*!
- \property QGeoAreaMonitor::center
- \brief holds the center of the area to be monitored.
-
- When the center is set, if the radius has already been set and
- the current position is within the monitored area, areaEntered()
- is emitted immediately.
-
- By default, contains an invalid coordinate.
-
- Note: Subclass implementations must call the base implementation of
- setCenter() so that center() returns the correct value.
-*/
-void QGeoAreaMonitor::setCenter(const QGeoCoordinate &coordinate)
-{
- d->coord = coordinate;
-}
-
-QGeoCoordinate QGeoAreaMonitor::center() const
-{
- return d->coord;
-}
-
-/*!
- \property QGeoAreaMonitor::radius
- \brief holds the radius of the area to be monitored, in meters.
-
- If the specified radius is less than the minimum supported radius, the
- radius is set to the minimum radius.
-
- When this property is set, if the center coordinate has already been set and
- the current position is within the monitored area, areaEntered()
- is emitted immediately.
-
- By default, this property is 0.
-
- Note: Subclass implementations must call the base implementation of
- setRadius() so that radius() returns the correct value.
-*/
-void QGeoAreaMonitor::setRadius(qreal radius)
-{
- d->radius = radius;
-}
-
-qreal QGeoAreaMonitor::radius() const
-{
- return d->radius;
-}
-
-/*!
- Creates and returns a monitor with the given \a parent that
- monitors areas using resources on the underlying system.
-
- Returns 0 if the system has no support for position monitoring.
-*/
-QGeoAreaMonitor *QGeoAreaMonitor::createDefaultMonitor(QObject *parent)
-{
- QList<QJsonObject> plugins = QGeoPositionInfoSourcePrivate::pluginsSorted();
- foreach (const QJsonObject &obj, plugins) {
- if (obj.value(QStringLiteral("Monitor")).isBool()
- && obj.value(QStringLiteral("Monitor")).toBool())
- {
- QGeoPositionInfoSourcePrivate d;
- d.metaData = obj;
- d.loadPlugin();
- QGeoAreaMonitor *s = 0;
- if (d.factory)
- s = d.factory->areaMonitor(parent);
- return s;
- }
- }
-
- return 0;
-}
-
-/*!
- Creates and returns a monitor with the given \a parent,
- by loading the plugin named \a sourceName.
-
- Returns 0 if the plugin cannot be found.
-*/
-QGeoAreaMonitor *QGeoAreaMonitor::createMonitor(const QString &sourceName, QObject *parent)
-{
- QHash<QString, QJsonObject> plugins = QGeoPositionInfoSourcePrivate::plugins();
- if (plugins.contains(sourceName)) {
- QGeoPositionInfoSourcePrivate d;
- d.metaData = plugins.value(sourceName);
- d.loadPlugin();
- QGeoAreaMonitor *s = 0;
- if (d.factory)
- s = d.factory->areaMonitor(parent);
- return s;
- }
-
- return 0;
-}
-
-/*!
- Returns a list of available monitor plugins, including the default system
- backend if one is available.
-*/
-QStringList QGeoAreaMonitor::availableMonitors()
-{
- QStringList plugins;
- QHash<QString, QJsonObject> meta = QGeoPositionInfoSourcePrivate::plugins();
- foreach (const QString &name, meta.keys()) {
- if (meta.value(name).value(QStringLiteral("Monitor")).isBool()
- && meta.value(name).value(QStringLiteral("Monitor")).toBool()) {
- plugins << name;
- }
- }
-
- return plugins;
-}
-
-
-
-/*!
- \fn void QGeoAreaMonitor::areaEntered(const QGeoPositionInfo &update);
-
- Emitted when the current position has moved from a position outside the
- monitored area to a position within the monitored area.
-
- The \a update holds the new position.
-*/
-
-/*!
- \fn void QGeoAreaMonitor::areaExited(const QGeoPositionInfo &update);
-
- Emitted when the current position has moved from a position within the
- monitored area to a position outside the monitored area.
-
- The \a update holds the new position.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/positioning/qgeoareamonitorinfo.cpp b/src/positioning/qgeoareamonitorinfo.cpp
new file mode 100644
index 00000000..b4e0d179
--- /dev/null
+++ b/src/positioning/qgeoareamonitorinfo.cpp
@@ -0,0 +1,379 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPositioning module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGeoAreaMonitorInfo>
+#include <QDateTime>
+#include <QSharedData>
+#include <QUuid>
+
+#ifndef QT_NO_DEBUG_STREAM
+#include <QDebug>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGeoAreaMonitorInfo
+ \inmodule QtPositioning
+ \since Qt Positioning 5.2
+ \ingroup QtPositioning-positioning
+
+ \brief The QGeoAreaMonitorInfo class describes the parameters of an area or region
+ to be monitored for proximity.
+
+ The purpose of area monitoring is to inform a user when he/she comes close to an area of
+ interest. In general such an area is described by a \l QGeoCircle. The circle's center
+ represents the place of interest and the area around it identifies the geographical region
+ within which notifications are sent.
+
+ A QGeoAreaMonitorInfo object is valid if it has a non-empty name and a valid \l area().
+ Such objects must be registered with a \l QGeoAreaMonitorSource to start and stop the
+ monitoring process. Note that extensive monitoring can be very resource consuming
+ because the positioning engine must remain active and has to match the current position
+ with each QGeoAreaMonitorInfo instance.
+
+ To further reduce the burden on the system there are optional attributes which can
+ set. Each monitored area can have an expiry date which automatically removes the
+ to-be-monitored area from the monitoring source once the expiry date has been reached.
+ Another option is to adjust the persistence of a monitored area. A QGeoAreaMonitorInfo
+ that \l isPersistent() will remain active beyond
+ the current applications lifetime. If an area is entered while the monitoring
+ application is not running the application will be started. Note that this feature is
+ not available on all platforms. Its availability can be checked via
+ \l QGeoAreaMonitorSource::supportedAreaMonitorFeatures().
+
+ \sa QGeoAreaMonitorSource
+
+ */
+
+class QGeoAreaMonitorInfoPrivate : public QSharedData
+{
+public:
+ QGeoAreaMonitorInfoPrivate() : QSharedData(), persistent(false) {}
+ QGeoAreaMonitorInfoPrivate(const QGeoAreaMonitorInfoPrivate &other)
+ : QSharedData(other)
+ {
+ uid = other.uid;
+ name = other.name;
+ shape = other.shape;
+ persistent = other.persistent;
+ notificationParameters = other.notificationParameters;
+ expiry = other.expiry;
+ }
+ ~QGeoAreaMonitorInfoPrivate() {}
+
+ QUuid uid;
+ QString name;
+ QGeoShape shape;
+ bool persistent;
+ QVariantMap notificationParameters;
+ QDateTime expiry;
+};
+
+/*!
+ Constructs a QGeoAreaMonitorInfo object with the specified \a name.
+
+ \sa name()
+ */
+QGeoAreaMonitorInfo::QGeoAreaMonitorInfo(const QString &name)
+{
+ d = new QGeoAreaMonitorInfoPrivate;
+ d->name = name;
+ d->uid = QUuid::createUuid();
+}
+
+/*!
+ Constructs a QGeoAreaMonitorInfo object as a copy of \a other.
+ */
+QGeoAreaMonitorInfo::QGeoAreaMonitorInfo(const QGeoAreaMonitorInfo &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Destructor
+ */
+QGeoAreaMonitorInfo::~QGeoAreaMonitorInfo()
+{
+}
+
+/*!
+ Assigns \a other to this QGeoAreaMonitorInfo object and returns a reference
+ to this QGeoAreaMonitorInfo object.
+ */
+QGeoAreaMonitorInfo &QGeoAreaMonitorInfo::operator=(const QGeoAreaMonitorInfo &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Returns true if all of this object's values are the same as those of
+ \a other.
+*/
+bool QGeoAreaMonitorInfo::operator==(const QGeoAreaMonitorInfo &other) const
+{
+ return (d->name == other.d->name &&
+ d->uid == other.d->uid &&
+ d->shape == other.d->shape &&
+ d->persistent == other.d->persistent &&
+ d->expiry == other.d->expiry &&
+ d->notificationParameters == other.d->notificationParameters);
+}
+
+/*!
+ Returns true if any of this object's values are not the same as those of
+ \a other.
+*/
+bool QGeoAreaMonitorInfo::operator!=(const QGeoAreaMonitorInfo &other) const
+{
+ return !QGeoAreaMonitorInfo::operator ==(other);
+}
+
+/*!
+ Returns the name of the QGeoAreaMonitorInfo object. The name should be used to
+ for user-visibility purposes.
+ */
+QString QGeoAreaMonitorInfo::name() const
+{
+ return d->name;
+}
+
+/*!
+ Sets the user visibile \a name.
+ */
+void QGeoAreaMonitorInfo::setName(const QString &name)
+{
+ if (d->name != name)
+ d->name = name;
+}
+
+/*!
+ Returns the identifier of the QGeoAreaMonitorInfo object.
+ The identifier is automatically generated upon construction of a new
+ QGeoAreaMonitorInfo object.
+*/
+
+QString QGeoAreaMonitorInfo::identifier() const
+{
+ return d->uid.toString();
+}
+
+/*!
+ Returns true, if the monitor is valid. A valid QGeoAreaMonitorInfo has a non-empty name()
+ and the monitored area is not \l {QGeoShape::isEmpty()}{empty()}.
+ Otherwise this function returns false.
+ */
+bool QGeoAreaMonitorInfo::isValid() const
+{
+ return (!d->name.isEmpty() && !d->shape.isEmpty());
+}
+
+/*!
+ Returns the boundaries of the to-be-monitored area. This area must not be empty.
+
+ \sa setArea()
+ */
+QGeoShape QGeoAreaMonitorInfo::area() const
+{
+ return d->shape;
+}
+
+/*!
+ Sets the to-be-monitored area to \a newShape.
+
+ \sa area()
+ */
+void QGeoAreaMonitorInfo::setArea(const QGeoShape &newShape)
+{
+ d->shape = newShape;
+}
+
+/*!
+ Returns the expiry date.
+
+ After an active QGeoAreaMonitorInfo has expired the region is no longer monitored
+ and the QGeoAreaMonitorInfo object is removed from the list of
+ \l {QGeoAreaMonitorSource::activeMonitors()}{active monitors}.
+
+ If the expiry \l QDateTime is invalid the QGeoAreaMonitorInfo object is treated as not having
+ an expiry date. This implies an indefinite monitoring period if the object is persistent or
+ until the current application closes if the object is non-persistent.
+
+ \sa QGeoAreaMonitorSource::activeMonitors()
+ */
+QDateTime QGeoAreaMonitorInfo::expiration() const
+{
+ return d->expiry;
+}
+
+/*!
+ Sets the expiry date and time to \a expiry.
+ */
+void QGeoAreaMonitorInfo::setExpiration(const QDateTime &expiry)
+{
+ d->expiry = expiry;
+}
+
+/*!
+ Returns true if the QGeoAreaMonitorInfo is persistent.
+ The default value for this property is false.
+
+ A non-persistent QGeoAreaMonitorInfo will be removed by the system once
+ the application owning the monitor object stops. Persistent objects remain
+ active and can be retrieved once the application restarts.
+
+ If the system triggers an event associated to a persistent QGeoAreaMonitorInfo
+ the relevant application will be re-started and the appropriate signal emitted.
+
+ \sa setPersistent()
+ */
+bool QGeoAreaMonitorInfo::isPersistent() const
+{
+ return d->persistent;
+}
+
+/*!
+ Sets the QGeoAreaMonitorInfo objects persistence to \a isPersistent.
+
+ Note that setting this flag does not imply that QGeoAreaMonitorInfoSource supports persistent
+ monitoring. \l QGeoAreaMonitorSource::supportedAreaMonitorFeatures() can be used to
+ check for this feature's availability.
+
+ \sa isPersistent()
+ */
+void QGeoAreaMonitorInfo::setPersistent(bool isPersistent)
+{
+ d->persistent = isPersistent;
+}
+
+
+/*!
+ Returns the set of platform specific paraemters used by this QGeoAreaMonitorInfo.
+
+ \sa setNotificationParameters()
+ */
+QVariantMap QGeoAreaMonitorInfo::notificationParameters() const
+{
+ return d->notificationParameters;
+}
+
+/*!
+ Sets the set of platform specific \a parameters used by QGeoAreaMonitorInfo.
+
+ \sa notificationParameters()
+ */
+void QGeoAreaMonitorInfo::setNotificationParameters(const QVariantMap &parameters)
+{
+ d->notificationParameters = parameters;
+}
+
+#ifndef QT_NO_DATASTREAM
+
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QGeoAreaMonitorInfo &monitor)
+ \relates QGeoAreaMonitorInfo
+
+ Writes the given \a monitor to the specified \a stream.
+
+ \sa {Serializing Qt Data Types}
+*/
+QDataStream &operator<<(QDataStream &ds, const QGeoAreaMonitorInfo &monitor)
+{
+ ds << monitor.name() << monitor.d->uid << monitor.area()
+ << monitor.isPersistent() << monitor.notificationParameters() << monitor.expiration();
+ return ds;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QGeoAreaMonitorInfo &monitor)
+ \relates QGeoAreaMonitorInfo
+
+ Reads a area monitoring data from the specified \a stream into the given
+ \a monitor.
+
+ \sa {Serializing Qt Data Types}
+*/
+
+QDataStream &operator>>(QDataStream &ds, QGeoAreaMonitorInfo &monitor)
+{
+ QString s;
+ ds >> s;
+ monitor = QGeoAreaMonitorInfo(s);
+
+ QUuid id;
+ ds >> id;
+ monitor.d->uid = id;
+
+ QGeoShape shape;
+ ds >> shape;
+ monitor.setArea(shape);
+
+ bool persistent;
+ ds >> persistent;
+ monitor.setPersistent(persistent);
+
+ QVariantMap map;
+ ds >> map;
+ monitor.setNotificationParameters(map);
+
+ QDateTime dt;
+ ds >> dt;
+ monitor.setExpiration(dt);
+
+ return ds;
+}
+
+#endif
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QGeoAreaMonitorInfo &monitor)
+{
+ dbg.nospace() << "QGeoAreaMonitorInfo(\"" << qPrintable(monitor.name())
+ << "\", " << monitor.area()
+ << ", persistent: " << monitor.isPersistent()
+ << ", expiry: " << monitor.expiration() << ")";
+ return dbg.space();
+}
+
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/positioning/qgeoareamonitorinfo.h b/src/positioning/qgeoareamonitorinfo.h
new file mode 100644
index 00000000..938671df
--- /dev/null
+++ b/src/positioning/qgeoareamonitorinfo.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPositioning module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGEOAREAMONITORINFO_H
+#define QGEOAREAMONITORINFO_H
+
+#include <QtPositioning/QGeoCoordinate>
+#include <QtPositioning/QGeoShape>
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QVariantMap>
+
+QT_BEGIN_NAMESPACE
+
+class QDataStream;
+class QGeoAreaMonitorInfo;
+
+#ifndef QT_NO_DATASTREAM
+Q_POSITIONING_EXPORT QDataStream &operator<<(QDataStream &, const QGeoAreaMonitorInfo &);
+Q_POSITIONING_EXPORT QDataStream &operator>>(QDataStream &, QGeoAreaMonitorInfo &);
+#endif
+
+class QGeoAreaMonitorInfoPrivate;
+class Q_POSITIONING_EXPORT QGeoAreaMonitorInfo
+{
+public:
+ explicit QGeoAreaMonitorInfo(const QString &name = QString());
+ QGeoAreaMonitorInfo(const QGeoAreaMonitorInfo &other);
+ ~QGeoAreaMonitorInfo();
+
+ QGeoAreaMonitorInfo &operator=(const QGeoAreaMonitorInfo &other);
+
+ bool operator==(const QGeoAreaMonitorInfo &other) const;
+ bool operator!=(const QGeoAreaMonitorInfo &other) const;
+
+ QString name() const;
+ void setName(const QString &name);
+
+ QString identifier() const;
+ bool isValid() const;
+
+ QGeoShape area() const;
+ void setArea(const QGeoShape &newShape);
+
+ QDateTime expiration() const;
+ void setExpiration(const QDateTime &expiry);
+
+ bool isPersistent() const;
+ void setPersistent(bool isPersistent);
+
+ QVariantMap notificationParameters() const;
+ void setNotificationParameters(const QVariantMap &parameters);
+private:
+ QSharedDataPointer<QGeoAreaMonitorInfoPrivate> d;
+
+#ifndef QT_NO_DATASTREAM
+ friend Q_POSITIONING_EXPORT QDataStream &operator<<(QDataStream &, const QGeoAreaMonitorInfo &);
+ friend Q_POSITIONING_EXPORT QDataStream &operator>>(QDataStream &, QGeoAreaMonitorInfo &);
+#endif
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_POSITIONING_EXPORT QDebug operator<<(QDebug, const QGeoAreaMonitorInfo &);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QGEOAREAMONITORINFO_H
diff --git a/src/positioning/qgeoareamonitorsource.cpp b/src/positioning/qgeoareamonitorsource.cpp
new file mode 100644
index 00000000..2f23d942
--- /dev/null
+++ b/src/positioning/qgeoareamonitorsource.cpp
@@ -0,0 +1,390 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPositioning module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGeoAreaMonitorSource>
+#include "qgeopositioninfosourcefactory.h"
+#include "qgeopositioninfosource_p.h"
+
+/*!
+ \class QGeoAreaMonitorSource
+ \inmodule QtPositioning
+ \ingroup QtPositioning-positioning
+ \since Qt Positioning 5.0
+
+ \brief The QGeoAreaMonitorSource class enables the detection of proximity
+ changes for a specified set of coordinates.
+
+ A QGeoAreaMonitorSource emits signals when the current position is in
+ range, or has moved out of range, of a specified area.
+ Each area is specified by a \l QGeoAreaMonitorInfo object.
+ For example:
+
+ \snippet cpp/cppqml.cpp BigBen
+
+ \c QGeoAreaMonitorSource follows a singleton pattern. Each instance of
+ the class with the same \l sourceName() shares the same area monitoring backend.
+ If a new \l QGeoAreaMonitorInfo object is added via \l startMonitoring()
+ or \l requestUpdate() it can be retrieved by another instance of this class
+ (provided that they are sourced from the same area monitor provider plug-in).
+ The same singleton pattern applies to the \l QGeoPositionInfoSource instance
+ used by this class. The following code snippet emphasizes the behavior:
+
+ \code
+ QGeoAreaMonitorSource *s1 = QGeoAreaMonitorSource::createSource("blah", this);
+ QGeoAreaMonitorSource *s2 = QGeoAreaMonitorSource::createSource("blah", this);
+ QVERIFY(s1->positionInfoSource() == s2->positionInfoSource);
+ \endcode
+*/
+
+QT_BEGIN_NAMESPACE
+
+
+
+class QGeoAreaMonitorSourcePrivate
+{
+public:
+ QGeoPositionInfoSource *source;
+ QString providerName;
+};
+
+/*!
+ \enum QGeoAreaMonitorSource::Error
+ Defines the types of positioning methods.
+
+ The Error enumeration represents the errors which can occur.
+
+ \value AccessError The connection setup to the remote area monitoring backend failed because the
+ application lacked the required privileges.
+ \value InsufficientPositionInfo The area monitoring source could not retrieve a location fix or
+ the accuracy of the fix is not high enough to provide an effective area monitoring.
+ \value UnknownSourceError An unidentified error occurred.
+*/
+
+/*!
+ \enum QGeoAreaMonitorSource::AreaMonitorFeature
+ Defines the types of area monitoring capabilities.
+
+ \value PersistentAreaMonitorFeature QGeoAreaMonitorInfo instances can be made persistent.
+ A persistent monitor continues to be active even when the application managing the monitor is
+ not running.
+ \value AnyAreaMonitorFeature Matches all possible area monitoring features.
+*/
+
+/*!
+ \fn virtual AreaMonitoringFeatures QGeoAreaMonitorSource::supportedAreaMonitorFeatures() const = 0;
+
+ Returns the area monitoring features available to this source.
+*/
+
+/*!
+ \fn virtual QGeoAreaMonitorSource::Error QGeoAreaMonitorSource::error() const
+
+ Returns the type of error that last occurred.
+*/
+
+/*!
+ Creates a monitor with the given \a parent.
+*/
+QGeoAreaMonitorSource::QGeoAreaMonitorSource(QObject *parent)
+ : QObject(parent),
+ d(new QGeoAreaMonitorSourcePrivate)
+{
+ d->source = 0;
+}
+
+/*!
+ Destroys the monitor.
+*/
+QGeoAreaMonitorSource::~QGeoAreaMonitorSource()
+{
+ delete d;
+}
+
+/*!
+ Creates and returns a monitor with the given \a parent that
+ monitors areas using resources on the underlying system.
+
+ Returns 0 if the system has no support for position monitoring.
+*/
+QGeoAreaMonitorSource *QGeoAreaMonitorSource::createDefaultSource(QObject *parent)
+{
+ QList<QJsonObject> plugins = QGeoPositionInfoSourcePrivate::pluginsSorted();
+ foreach (const QJsonObject &obj, plugins) {
+ if (obj.value(QStringLiteral("Monitor")).isBool()
+ && obj.value(QStringLiteral("Monitor")).toBool())
+ {
+ QGeoPositionInfoSourcePrivate d;
+ d.metaData = obj;
+ d.loadPlugin();
+ QGeoAreaMonitorSource *s = 0;
+ if (d.factory)
+ s = d.factory->areaMonitor(parent);
+ if (s)
+ s->d->providerName = d.metaData.value(QStringLiteral("Provider")).toString();
+ return s;
+ }
+ }
+
+ return 0;
+}
+
+/*!
+ Creates and returns a monitor with the given \a parent,
+ by loading the plugin named \a sourceName.
+
+ Returns 0 if the plugin cannot be found.
+*/
+QGeoAreaMonitorSource *QGeoAreaMonitorSource::createSource(const QString &sourceName, QObject *parent)
+{
+ QHash<QString, QJsonObject> plugins = QGeoPositionInfoSourcePrivate::plugins();
+ if (plugins.contains(sourceName)) {
+ QGeoPositionInfoSourcePrivate d;
+ d.metaData = plugins.value(sourceName);
+ d.loadPlugin();
+ QGeoAreaMonitorSource *s = 0;
+ if (d.factory)
+ s = d.factory->areaMonitor(parent);
+ if (s)
+ s->d->providerName = d.metaData.value(QStringLiteral("Provider")).toString();
+ return s;
+ }
+
+ return 0;
+}
+
+/*!
+ Returns a list of available monitor plugins, including the default system
+ backend if one is available.
+*/
+QStringList QGeoAreaMonitorSource::availableSources()
+{
+ QStringList plugins;
+ QHash<QString, QJsonObject> meta = QGeoPositionInfoSourcePrivate::plugins();
+ foreach (const QString &name, meta.keys()) {
+ if (meta.value(name).value(QStringLiteral("Monitor")).isBool()
+ && meta.value(name).value(QStringLiteral("Monitor")).toBool()) {
+ plugins << name;
+ }
+ }
+
+ return plugins;
+}
+
+/*!
+ Returns the unique name of the area monitor source implementation in use.
+
+ This is the same name that can be passed to createSource() in order to
+ create a new instance of a particular area monitor source implementation.
+*/
+QString QGeoAreaMonitorSource::sourceName() const
+{
+ return d->providerName;
+}
+
+/*!
+ Returns the current QGeoPositionInfoSource used by this QGeoAreaMonitorSource
+ object. The function will return \l QGeoPositionInfoSource::createDefaultSource()
+ if no other object has been set.
+
+ The function returns 0 if not even a default QGeoPositionInfoSource exists.
+
+ Any usage of the returned \l QGeoPositionInfoSource instance should account
+ for the fact that it may reside in a different thread.
+
+ \sa QGeoPositionInfoSource, setPositionInfoSource()
+*/
+QGeoPositionInfoSource* QGeoAreaMonitorSource::positionInfoSource() const
+{
+ return d->source;
+}
+
+/*!
+ Sets the new \l QGeoPositionInfoSource to be used by this QGeoAreaMonitorSource object.
+ The area monitoring backend becomes the new QObject parent for \a newSource.
+ The previous \l QGeoPositionInfoSource object will be deleted. All QGeoAreaMonitorSource
+ instances based on the same \l sourceName() share the same QGeoPositionInfoSource
+ instance.
+
+ This may be useful when it is desirable to manipulate the positioning system
+ used by the area monitoring engine.
+
+ Note that ownership must be taken care of by subclasses of QGeoAreaMonitorSource.
+ Due to the singleton pattern behind this class \a newSource may be moved to a
+ new thread.
+
+ \sa positionInfoSource()
+ */
+void QGeoAreaMonitorSource::setPositionInfoSource(QGeoPositionInfoSource *newSource)
+{
+ d->source = newSource;
+}
+
+
+/*!
+ \fn virtual bool QGeoAreaMonitorSource::startMonitoring(const QGeoAreaMonitorInfo &monitor)
+
+ Returns \c true if the monitoring of \a monitor could be successfully started; otherwise
+ returns false. A reason for not being able to start monitoring could be the unavailability
+ of an appropriate default position info source while no alternative QGeoPositionInfoSource
+ has been set via \l setPositionInfoSource().
+
+ If \a monitor is already active the existing monitor object will be replaced by the new \a monitor reference.
+ The identification of QGeoAreaMonitorInfo instances happens via \l QGeoAreaMonitorInfo::identifier().
+ Therefore this function can also be used to update active monitors.
+
+ If \a monitor has an expiry date that has been passed this function returns false. Calling
+ this function for an already via \l requestUpdate() registered single shot monitor
+ switches the monitor to a permanent monitoring mode.
+
+ Requesting persistent monitoring on a QGeoAreaMonitorSource instance fails if the area monitoring
+ backend doesn't support \l QGeoAreaMonitorSource::PersistentAreaMonitorFeature.
+
+ \sa stopMonitoring()
+*/
+
+/*!
+ \fn virtual bool QGeoAreaMonitorSource::requestUpdate(const QGeoAreaMonitorInfo &monitor, const char *signal)
+
+ Enables single shot area monitoring. Area monitoring for \a monitor will be performed
+ until this QGeoAreaMonitorSource instance emits \a signal for the first time. Once
+ the signal was emitted, \a monitor is automatically removed from the list of \l activeMonitors().
+ If \a monitor is invalid or has an expiry date that has been passed this function returns false.
+
+ \code
+ QGeoAreaMonitor singleShotMonitor;
+ QGeoAreaMonitorSource * source = QGeoAreaMonitorSource::createDefaultSource(this);
+ //...
+ bool ret = source->requestUpdate(singleShotMonitor,
+ SIGNAL(areaExited(QGeoAreaMonitor,QGeoPositionInfo)));
+ \endcode
+
+ The above \c singleShotMonitor object will cease to send updates once the \l areaExited() signal
+ was emitted for the first time. Until this point in time any other signal may be emitted
+ zero or more times depending on the area context.
+
+ It is not possible to simultanously request updates for more than one signal of the same monitor object.
+ The last call to this function determines the signal upon which the updates cease to continue.
+ At this stage only the \l areaEntered() and \l areaExited() signals can be used to
+ terminate the monitoring process.
+
+ Requesting persistent monitoring on a QGeoAreaMonitorSource instance fails if the area monitoring
+ backend doesn't support \l QGeoAreaMonitorSource::PersistentAreaMonitorFeature.
+
+ If \a monitor was already registered via \l startMonitoring() it is converted to a single
+ shot behavior.
+
+ \sa startMonitoring(), stopMonitoring()
+ */
+
+/*!
+ \fn virtual bool QGeoAreaMonitorSource::stopMonitoring(const QGeoAreaMonitorInfo &monitor)
+
+ Returns true if \a monitor was successfully removed from the list of \l activeMonitors();
+ otherwise returns false. This behavior is independent on whether \a monitor was registered
+ via \l startMonitoring() or \l requestUpdate().
+*/
+
+/*!
+ \fn virtual QList<QGeoAreaMonitorInfo> QGeoAreaMonitorSource::activeMonitors() const
+
+ Returns the list of all active monitors known to the QGeoAreaMonitorSource object.
+
+ An active monitor was started via startMonitoring() the source object will emit
+ the required signals such as areaEntered() or areaExited(). Multiple \l QGeoAreaMonitorSource
+ instances within the same application share the same active monitor objects.
+
+ Unless an active QGeoAreaMonitorInfo \l {QGeoAreaMonitorInfo::isPersistent()}{isPersistent()} an active QGeoAreaMonitorInfo
+ will be stopped once the current application terminates.
+*/
+
+/*!
+ \fn virtual QList<QGeoAreaMonitorInfo> QGeoAreaMonitorSource::activeMonitors(const QGeoShape &lookupArea) const
+
+ Returns the list of all active monitors known to the QGeoAreaMonitorSource object whose
+ center lies within \a lookupArea. If \a lookupArea is empty the returned list will be empty.
+
+ An active monitor was started via startMonitoring() and the source object will emit
+ the required signals such as areaEntered() or areaExited(). Multiple QGeoAreaMonitorSource
+ instances within the same application share the same monitor objects.
+
+ Unless an active QGeoAreaMonitorInfo \l {QGeoAreaMonitorInfo::isPersistent()}{isPersistent()} an active QGeoAreaMonitorInfo
+ will be stopped once the current application terminates.
+
+ \sa QGeoShape
+*/
+
+
+/*!
+ \fn void QGeoAreaMonitorSource::monitorExpired(const QGeoAreaMonitorInfo &monitor)
+
+ Emitted when \a monitor has expired. An expired area monitor is automatically
+ removed from the list of \l activeMonitors().
+
+ \sa activeMonitors()
+*/
+
+/*!
+ \fn void QGeoAreaMonitorSource::areaEntered(const QGeoAreaMonitorInfo &monitor, const QGeoPositionInfo &update)
+
+ Emitted when the current position has moved from a position outside of the active \a monitor
+ to a position within the monitored area.
+
+ The \a update holds the new position.
+*/
+
+/*!
+ \fn void QGeoAreaMonitorSource::areaExited(const QGeoAreaMonitorInfo &monitor, const QGeoPositionInfo &update)
+
+ Emitted when the current position has moved from a position within the active \a monitor
+ to a position outside the monitored area.
+
+ The \a update holds the new position.
+*/
+
+/*!
+ \fn void QGeoAreaMonitorSource::error(QGeoAreaMonitorSource::Error areaMonitoringError)
+
+ This signal is emitted after an error occurred. The \a areaMonitoringError
+ parameter describes the type of error that occurred.
+
+*/
+
+QT_END_NAMESPACE
diff --git a/src/positioning/qgeoareamonitorsource.h b/src/positioning/qgeoareamonitorsource.h
new file mode 100644
index 00000000..03c98874
--- /dev/null
+++ b/src/positioning/qgeoareamonitorsource.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPositioning module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QGEOAREAMONITORSOURCE_H
+#define QGEOAREAMONITORSOURCE_H
+
+#include <QtPositioning/QGeoCoordinate>
+#include <QtPositioning/QGeoAreaMonitorInfo>
+#include <QtPositioning/QGeoPositionInfoSource>
+
+#include <QObject>
+#include <QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QGeoPositionInfo;
+class QGeoAreaMonitorSourcePrivate;
+class Q_POSITIONING_EXPORT QGeoAreaMonitorSource : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum Error {
+ AccessError = 0,
+ InsufficientPositionInfo,
+ UnknownSourceError
+ };
+ Q_ENUMS(Error)
+
+ enum AreaMonitorFeature {
+ PersistentAreaMonitorFeature = 0x00000001,
+ AnyAreaMonitorFeature = 0xffffffff
+ };
+ Q_DECLARE_FLAGS(AreaMonitorFeatures, AreaMonitorFeature)
+
+ explicit QGeoAreaMonitorSource(QObject *parent);
+ virtual ~QGeoAreaMonitorSource();
+
+ static QGeoAreaMonitorSource *createDefaultSource(QObject *parent);
+ static QGeoAreaMonitorSource *createSource(const QString& sourceName, QObject *parent);
+ static QStringList availableSources();
+
+ virtual void setPositionInfoSource(QGeoPositionInfoSource *source);
+ virtual QGeoPositionInfoSource* positionInfoSource() const;
+
+ QString sourceName() const;
+
+ virtual Error error() const = 0;
+ virtual AreaMonitorFeatures supportedAreaMonitorFeatures() const = 0;
+
+ virtual bool startMonitoring(const QGeoAreaMonitorInfo &monitor) = 0;
+ virtual bool stopMonitoring(const QGeoAreaMonitorInfo &monitor) = 0;
+ virtual bool requestUpdate(const QGeoAreaMonitorInfo &monitor, const char *signal) = 0;
+
+ virtual QList<QGeoAreaMonitorInfo> activeMonitors() const = 0;
+ virtual QList<QGeoAreaMonitorInfo> activeMonitors(const QGeoShape &lookupArea) const = 0;
+
+Q_SIGNALS:
+ void areaEntered(const QGeoAreaMonitorInfo &monitor, const QGeoPositionInfo &update);
+ void areaExited(const QGeoAreaMonitorInfo &monitor, const QGeoPositionInfo &update);
+ void monitorExpired(const QGeoAreaMonitorInfo &monitor);
+ void error(QGeoAreaMonitorSource::Error error);
+
+private:
+ Q_DISABLE_COPY(QGeoAreaMonitorSource)
+ QGeoAreaMonitorSourcePrivate *d;
+};
+
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/positioning/qgeopositioninfosourcefactory.cpp b/src/positioning/qgeopositioninfosourcefactory.cpp
index a113a4aa..bebbe20e 100644
--- a/src/positioning/qgeopositioninfosourcefactory.cpp
+++ b/src/positioning/qgeopositioninfosourcefactory.cpp
@@ -73,9 +73,9 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QGeoAreaMonitor *QGeoPositionInfoSourceFactory::areaMonitor(QObject *parent);
+ \fn QGeoAreaMonitorSource *QGeoPositionInfoSourceFactory::areaMonitor(QObject *parent);
- Returns a new QGeoAreaMonitor associated with this plugin with parent \a parent.
+ Returns a new QGeoAreaMonitorSource associated with this plugin with parent \a parent.
Can also return 0, in which case the plugin loader will use the factory with the
next highest priority.
*/
diff --git a/src/positioning/qgeopositioninfosourcefactory.h b/src/positioning/qgeopositioninfosourcefactory.h
index 32e0bc00..5704c2dc 100644
--- a/src/positioning/qgeopositioninfosourcefactory.h
+++ b/src/positioning/qgeopositioninfosourcefactory.h
@@ -44,7 +44,7 @@
#include <QtPositioning/QGeoPositionInfoSource>
#include <QtPositioning/QGeoSatelliteInfoSource>
-#include <QtPositioning/QGeoAreaMonitor>
+#include <QtPositioning/QGeoAreaMonitorSource>
#include <QList>
QT_BEGIN_NAMESPACE
@@ -56,7 +56,7 @@ public:
virtual QGeoPositionInfoSource *positionInfoSource(QObject *parent) = 0;
virtual QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent) = 0;
- virtual QGeoAreaMonitor *areaMonitor(QObject *parent) = 0;
+ virtual QGeoAreaMonitorSource *areaMonitor(QObject *parent) = 0;
};
#define QT_POSITION_SOURCE_INTERFACE
diff --git a/src/positioning/qgeosatelliteinfosource.cpp b/src/positioning/qgeosatelliteinfosource.cpp
index faf8dad8..ee1b316a 100644
--- a/src/positioning/qgeosatelliteinfosource.cpp
+++ b/src/positioning/qgeosatelliteinfosource.cpp
@@ -93,6 +93,7 @@ class QGeoSatelliteInfoSourcePrivate
{
public:
int interval;
+ QString providerName;
};
/*!
@@ -114,6 +115,18 @@ QGeoSatelliteInfoSource::~QGeoSatelliteInfoSource()
}
/*!
+ Returns the unique name of the satellite source implementation in use.
+
+ This is the same name that can be passed to createSource() in order to
+ create a new instance of a particular satellite source implementation.
+*/
+QString QGeoSatelliteInfoSource::sourceName() const
+{
+ return d->providerName;
+}
+
+
+/*!
\property QGeoSatelliteInfoSource::updateInterval
\brief This property holds the requested interval in milliseconds between each update.
@@ -168,6 +181,8 @@ QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createDefaultSource(QObject *p
QGeoSatelliteInfoSource *s = 0;
if (d.factory)
s = d.factory->satelliteInfoSource(parent);
+ if (s)
+ s->d->providerName = d.metaData.value(QStringLiteral("Provider")).toString();
return s;
}
}
@@ -191,6 +206,8 @@ QGeoSatelliteInfoSource *QGeoSatelliteInfoSource::createSource(const QString &so
QGeoSatelliteInfoSource *src = 0;
if (d.factory)
src = d.factory->satelliteInfoSource(parent);
+ if (src)
+ src->d->providerName = d.metaData.value(QStringLiteral("Provider")).toString();
return src;
}
diff --git a/src/positioning/qgeosatelliteinfosource.h b/src/positioning/qgeosatelliteinfosource.h
index 35aa2b33..2b25aec7 100644
--- a/src/positioning/qgeosatelliteinfosource.h
+++ b/src/positioning/qgeosatelliteinfosource.h
@@ -57,7 +57,7 @@ class Q_POSITIONING_EXPORT QGeoSatelliteInfoSource : public QObject
public:
enum Error {
- AccessError,
+ AccessError = 0,
ClosedError, /* 1 */
UnknownSourceError = -1
};
@@ -70,6 +70,8 @@ public:
static QGeoSatelliteInfoSource *createSource(const QString &sourceName, QObject *parent);
static QStringList availableSources();
+ QString sourceName() const;
+
virtual void setUpdateInterval(int msec);
int updateInterval() const;
virtual int minimumUpdateInterval() const = 0;
diff --git a/tests/auto/positionplugin/plugin.cpp b/tests/auto/positionplugin/plugin.cpp
index 26f8ed34..bfc4880b 100644
--- a/tests/auto/positionplugin/plugin.cpp
+++ b/tests/auto/positionplugin/plugin.cpp
@@ -190,7 +190,7 @@ class QGeoPositionInfoSourceFactoryTest : public QObject, public QGeoPositionInf
public:
QGeoPositionInfoSource *positionInfoSource(QObject *parent);
QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent);
- QGeoAreaMonitor *areaMonitor(QObject *parent);
+ QGeoAreaMonitorSource *areaMonitor(QObject *parent);
};
QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSource(QObject *parent)
@@ -205,7 +205,7 @@ QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSource(
return 0;
}
-QGeoAreaMonitor *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject* parent)
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject* parent)
{
Q_UNUSED(parent)
return 0;
diff --git a/tests/auto/positionplugintest/tst_positionplugin.cpp b/tests/auto/positionplugintest/tst_positionplugin.cpp
index 384f7a80..f152e762 100644
--- a/tests/auto/positionplugintest/tst_positionplugin.cpp
+++ b/tests/auto/positionplugintest/tst_positionplugin.cpp
@@ -45,7 +45,7 @@
#include <QSignalSpy>
#include <qgeopositioninfosource.h>
#include <qgeosatelliteinfosource.h>
-#include <qgeoareamonitor.h>
+#include <qgeoareamonitorsource.h>
#include <qgeocoordinate.h>
QT_USE_NAMESPACE
@@ -78,7 +78,7 @@ void tst_PositionPlugin::availableSources()
{
QVERIFY(QGeoPositionInfoSource::availableSources().contains("test.source"));
QVERIFY(!QGeoSatelliteInfoSource::availableSources().contains("test.source"));
- QVERIFY(!QGeoAreaMonitor::availableMonitors().contains("test.source"));
+ QVERIFY(!QGeoAreaMonitorSource::availableSources().contains("test.source"));
}
void tst_PositionPlugin::create()
diff --git a/tests/auto/qgeoareamonitor/logfilepositionsource.cpp b/tests/auto/qgeoareamonitor/logfilepositionsource.cpp
new file mode 100644
index 00000000..fcfb7e0d
--- /dev/null
+++ b/tests/auto/qgeoareamonitor/logfilepositionsource.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore>
+#include <QtTest>
+
+#include "logfilepositionsource.h"
+
+LogFilePositionSource::LogFilePositionSource(QObject *parent)
+ : QGeoPositionInfoSource(parent),
+ logFile(new QFile(this)),
+ timer(new QTimer(this))
+{
+ connect(timer, SIGNAL(timeout()), this, SLOT(readNextPosition()));
+
+ logFile->setFileName(QFINDTESTDATA("simplelog.txt"));
+ if (!logFile->open(QIODevice::ReadOnly))
+ qWarning() << "Error: cannot open source file" << logFile->fileName();
+}
+
+QGeoPositionInfo LogFilePositionSource::lastKnownPosition(bool /*fromSatellitePositioningMethodsOnly*/) const
+{
+ return lastPosition;
+}
+
+LogFilePositionSource::PositioningMethods LogFilePositionSource::supportedPositioningMethods() const
+{
+ return AllPositioningMethods;
+}
+
+int LogFilePositionSource::minimumUpdateInterval() const
+{
+ return 200;
+}
+
+void LogFilePositionSource::startUpdates()
+{
+ int interval = updateInterval();
+ if (interval < minimumUpdateInterval())
+ interval = minimumUpdateInterval();
+
+ timer->start(interval);
+}
+
+void LogFilePositionSource::stopUpdates()
+{
+ timer->stop();
+}
+
+void LogFilePositionSource::requestUpdate(int /*timeout*/)
+{
+ // For simplicity, ignore timeout - assume that if data is not available
+ // now, no data will be added to the file later
+ if (logFile->canReadLine())
+ readNextPosition();
+ else
+ emit updateTimeout();
+}
+
+void LogFilePositionSource::readNextPosition()
+{
+ QByteArray line = logFile->readLine().trimmed();
+ if (!line.isEmpty()) {
+ QList<QByteArray> data = line.split(' ');
+ double latitude;
+ double longitude;
+ bool hasLatitude = false;
+ bool hasLongitude = false;
+ QDateTime timestamp = QDateTime::fromString(QString(data.value(0)), Qt::ISODate);
+ latitude = data.value(1).toDouble(&hasLatitude);
+ longitude = data.value(2).toDouble(&hasLongitude);
+
+ if (hasLatitude && hasLongitude && timestamp.isValid()) {
+ QGeoCoordinate coordinate(latitude, longitude);
+ QGeoPositionInfo info(coordinate, timestamp);
+ if (info.isValid()) {
+ lastPosition = info;
+ emit positionUpdated(info);
+ }
+ }
+ }
+}
+
+QGeoPositionInfoSource::Error LogFilePositionSource::error() const
+{
+ return QGeoPositionInfoSource::UnknownSourceError;
+}
diff --git a/src/positioning/qgeoareamonitor.h b/tests/auto/qgeoareamonitor/logfilepositionsource.h
index 1aed8b6b..966b2540 100644
--- a/src/positioning/qgeoareamonitor.h
+++ b/tests/auto/qgeoareamonitor/logfilepositionsource.h
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtPositioning module of the Qt Toolkit.
+** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -38,48 +38,42 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef QGEOAREAMONITOR_H
-#define QGEOAREAMONITOR_H
-#include <QtPositioning/QGeoCoordinate>
+#ifndef LOGFILEPOSITIONSOURCE_H
+#define LOGFILEPOSITIONSOURCE_H
-#include <QObject>
-#include <QStringList>
+#include <qgeopositioninfosource.h>
QT_BEGIN_NAMESPACE
+class QFile;
+class QTimer;
+QT_END_NAMESPACE
-class QGeoPositionInfo;
-class QGeoAreaMonitorPrivate;
-class Q_POSITIONING_EXPORT QGeoAreaMonitor : public QObject
+class LogFilePositionSource : public QGeoPositionInfoSource
{
Q_OBJECT
- Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter)
- Q_PROPERTY(qreal radius READ radius WRITE setRadius)
-
public:
- explicit QGeoAreaMonitor(QObject *parent);
- virtual ~QGeoAreaMonitor() = 0;
+ LogFilePositionSource(QObject *parent = 0);
+
+ QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const;
- virtual void setCenter(const QGeoCoordinate &coordinate);
- QGeoCoordinate center() const;
+ PositioningMethods supportedPositioningMethods() const;
+ int minimumUpdateInterval() const;
+ Error error() const;
- virtual void setRadius(qreal radius);
- qreal radius() const;
+public slots:
+ virtual void startUpdates();
+ virtual void stopUpdates();
- static QGeoAreaMonitor *createDefaultMonitor(QObject *parent);
- static QGeoAreaMonitor *createMonitor(const QString& sourceName, QObject *parent);
- static QStringList availableMonitors();
+ virtual void requestUpdate(int timeout = 5000);
-Q_SIGNALS:
- void areaEntered(const QGeoPositionInfo &update);
- void areaExited(const QGeoPositionInfo &update);
+private slots:
+ void readNextPosition();
private:
- Q_DISABLE_COPY(QGeoAreaMonitor)
- QGeoAreaMonitorPrivate *d;
+ QFile *logFile;
+ QTimer *timer;
+ QGeoPositionInfo lastPosition;
};
-
-QT_END_NAMESPACE
-
#endif
diff --git a/tests/auto/qgeoareamonitor/qgeoareamonitor.pro b/tests/auto/qgeoareamonitor/qgeoareamonitor.pro
index 05cc5ef5..35581bca 100644
--- a/tests/auto/qgeoareamonitor/qgeoareamonitor.pro
+++ b/tests/auto/qgeoareamonitor/qgeoareamonitor.pro
@@ -2,7 +2,12 @@ TEMPLATE = app
CONFIG+=testcase
TARGET=tst_qgeoareamonitor
-SOURCES += tst_qgeoareamonitor.cpp
+SOURCES += tst_qgeoareamonitor.cpp \
+ logfilepositionsource.cpp
+
+HEADERS += logfilepositionsource.h
+
+OTHER_FILES += *.txt
QT += positioning testlib
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qgeoareamonitor/simplelog.txt b/tests/auto/qgeoareamonitor/simplelog.txt
new file mode 100644
index 00000000..5a14fb80
--- /dev/null
+++ b/tests/auto/qgeoareamonitor/simplelog.txt
@@ -0,0 +1,87 @@
+2009-08-24T22:24:34 -27.54 153.090718
+2009-08-24T22:24:35 -27.55 153.090718
+2009-08-24T22:24:36 -27.56 153.090718
+2009-08-24T22:24:37 -27.57 153.090718
+2009-08-24T22:24:38 -27.58 153.090783
+2009-08-24T22:24:39 -27.59 153.090845
+2009-08-24T22:24:40 -27.60 153.090908
+2009-08-24T22:24:41 -27.61 153.090971
+2009-08-24T22:24:42 -27.62 153.091036
+2009-08-24T22:24:43 -27.63 153.091102
+2009-08-24T22:24:44 -27.64 153.091167
+2009-08-24T22:24:45 -27.65 153.091232
+2009-08-24T22:24:46 -27.65 153.091298
+2009-08-24T22:24:47 -27.65 153.091366
+2009-08-24T22:24:48 -27.65 153.091435
+2009-08-24T22:24:49 -27.66 153.091507
+2009-08-24T22:24:50 -27.67 153.091581
+2009-08-24T22:24:51 -27.68 153.091654
+2009-08-24T22:24:52 -27.69 153.091729
+2009-08-24T22:24:53 -27.70 153.091800
+2009-08-24T22:24:54 -27.71 153.091870
+2009-08-24T22:24:55 -27.72 153.091940
+2009-08-24T22:24:56 -27.73 153.092010
+2009-08-24T22:24:57 -27.74 153.092078
+2009-08-24T22:24:58 -27.75 153.092144
+2009-08-24T22:24:59 -27.78 153.092218
+2009-08-24T22:25:00 -27.79 153.092308
+2009-08-24T22:25:01 -27.80 153.092415
+2009-08-24T22:25:02 -27.81 153.092530
+2009-08-24T22:25:03 -27.82 153.092648
+2009-08-24T22:25:04 -27.83 153.092763
+2009-08-24T22:25:05 -27.84 153.092879
+2009-08-24T22:25:06 -27.85 153.092990
+2009-08-24T22:25:07 -27.84 153.093099
+2009-08-24T22:25:08 -27.83 153.093204
+2009-08-24T22:25:09 -27.82 153.093303
+2009-08-24T22:25:10 -27.81 153.093396
+2009-08-24T22:25:11 -27.80 153.093484
+2009-08-24T22:25:12 -27.79 153.093568
+2009-08-24T22:25:13 -27.78 153.093647
+2009-08-24T22:25:14 -27.77 153.093727
+2009-08-24T22:25:15 -27.76 153.093810
+2009-08-24T22:25:16 -27.75 153.093896
+2009-08-24T22:25:17 -27.74 153.093984
+2009-08-24T22:25:18 -27.72 153.094074
+2009-08-24T22:25:19 -27.70 153.094168
+2009-08-24T22:25:20 -27.71 153.094267
+2009-08-24T22:25:21 -27.69 153.094370
+2009-08-24T22:25:22 -27.68 153.094474
+2009-08-24T22:25:23 -27.67 153.094581
+2009-08-24T22:25:24 -27.66 153.094688
+2009-08-24T22:25:25 -27.65 153.094796
+2009-08-24T22:25:26 -27.64 153.094905
+2009-08-24T22:25:27 -27.63 153.095012
+2009-08-24T22:25:28 -27.62 153.095121
+2009-08-24T22:25:29 -27.61 153.095231
+2009-08-24T22:25:30 -27.60 153.095340
+2009-08-24T22:25:31 -27.59 153.095449
+2009-08-24T22:25:32 -27.58 153.095558
+2009-08-24T22:25:33 -27.57 153.095667
+2009-08-24T22:25:34 -27.56 153.095776
+2009-08-24T22:25:35 -27.55 153.095885
+2009-08-24T22:25:36 -27.54 153.095995
+2009-08-24T22:25:37 -27.53 153.096109
+2009-08-24T22:25:38 -27.52 153.096226
+2009-08-24T22:25:39 -27.51 153.096337
+2009-08-24T22:25:40 -27.50 153.096441
+2009-08-24T22:25:41 -27.49 153.096537
+2009-08-24T22:25:42 -27.48 153.096628
+2009-08-24T22:25:43 -27.47 153.096714
+2009-08-24T22:25:44 -27.46 153.096795
+2009-08-24T22:25:45 -27.45 153.096847
+2009-08-24T22:25:46 -27.44 153.096855
+2009-08-24T22:25:47 -27.43 153.096873
+2009-08-24T22:25:48 -27.42 153.096875
+2009-08-24T22:25:49 -27.41 153.096878
+2009-08-24T22:25:50 -27.40 153.096880
+2009-08-24T22:25:51 -27.39 153.096880
+2009-08-24T22:25:52 -27.38 153.096881
+2009-08-24T22:25:53 -27.37 153.096882
+2009-08-24T22:25:54 -27.36 153.096883
+2009-08-24T22:25:55 -27.35 153.096883
+2009-08-24T22:25:56 -27.34 153.096883
+2009-08-24T22:25:57 -27.33 153.096890
+2009-08-24T22:25:58 -27.32 153.096919
+2009-08-24T22:25:59 -27.31 153.096985
+2009-08-24T22:26:00 -27.30 153.097060
diff --git a/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp b/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp
index 347fca19..cd9894e5 100644
--- a/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp
+++ b/tests/auto/qgeoareamonitor/tst_qgeoareamonitor.cpp
@@ -48,41 +48,30 @@
#include <limits.h>
#include <float.h>
-#include <qgeoareamonitor.h>
+#include <QDebug>
+#include <QDataStream>
+
+#include <qgeoareamonitorinfo.h>
+#include <qgeoareamonitorsource.h>
#include <qgeopositioninfo.h>
#include <qgeopositioninfosource.h>
+#include <qnmeapositioninfosource.h>
+#include <qgeocircle.h>
+#include <qgeorectangle.h>
+
+#include "logfilepositionsource.h"
QT_USE_NAMESPACE
-#define MINIMUM_TIMEOUT 5000
+#define UPDATE_INTERVAL 200
Q_DECLARE_METATYPE(QGeoPositionInfo)
+Q_DECLARE_METATYPE(QGeoAreaMonitorInfo)
-
-class MyPositionAreaMonitor : public QGeoAreaMonitor
-{
- Q_OBJECT
-public:
- MyPositionAreaMonitor(QObject* parent = 0) : QGeoAreaMonitor(parent) {}
- ~MyPositionAreaMonitor() {}
-};
-
-
-static qreal tst_qgeoareamonitor_minimumRadius()
-{
- // tests should not be run with minimum radius in this case
- return 0;
-}
-
-
-class tst_QGeoAreaMonitor : public QObject
+class tst_QGeoAreaMonitorSource : public QObject
{
Q_OBJECT
-private:
- QGeoAreaMonitor* monitor;
-
-
private slots:
void initTestCase()
{
@@ -92,179 +81,628 @@ private slots:
QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath()
+ QStringLiteral("/../../../plugins"));
qRegisterMetaType<QGeoPositionInfo>();
+ qRegisterMetaType<QGeoAreaMonitorInfo>();
}
void init()
{
- monitor = 0;
}
void cleanup()
{
- delete monitor;
- monitor = 0;
+ QGeoAreaMonitorSource *obj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll"));
+
+ QList<QGeoAreaMonitorInfo> list = obj->activeMonitors();
+ if (list.count() > 0) {
+ //cleanup installed monitors
+ foreach (const QGeoAreaMonitorInfo& info, list) {
+ QVERIFY(obj->stopMonitoring(info));
+ }
+ }
+ QVERIFY(obj->activeMonitors().count() == 0);
}
void cleanupTestCase()
{
}
- void coordinate()
+ void tst_monitor()
{
- MyPositionAreaMonitor mon;
- QCOMPARE(mon.center(), QGeoCoordinate());
+ QGeoAreaMonitorInfo defaultMonitor;
+ QVERIFY(defaultMonitor.name().isEmpty());
+ QVERIFY(!defaultMonitor.identifier().isEmpty());
+ QCOMPARE(defaultMonitor.isPersistent(), false);
+ QVERIFY(!defaultMonitor.area().isValid());
+ QVERIFY(!defaultMonitor.isValid());
+ QCOMPARE(defaultMonitor.expiration(), QDateTime());
+ QCOMPARE(defaultMonitor.notificationParameters(), QVariantMap());
+
+ QGeoAreaMonitorSource *obj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll"));
+ QVERIFY(!obj->startMonitoring(defaultMonitor));
+ QCOMPARE(obj->activeMonitors().count(), 0);
+ QVERIFY(!obj->requestUpdate(defaultMonitor,
+ SIGNAL(areaEntered(QGeoMonitorInfo,QGeoAreaPositionInfo))));
+ delete obj;
+
+ //copy constructor based
+ QGeoAreaMonitorInfo copy(defaultMonitor);
+ QVERIFY(copy.name().isEmpty());
+ QCOMPARE(copy.identifier(), defaultMonitor.identifier());
+ QVERIFY(copy == defaultMonitor);
+ QVERIFY(!(copy != defaultMonitor));
+ QCOMPARE(copy.isPersistent(), false);
+
+ copy.setName(QString("my name"));
+ QCOMPARE(copy.name(), QString("my name"));
+
+
+ QDateTime now = QDateTime::currentDateTime().addSecs(1000); //little bit in the future
+ copy.setExpiration(now);
+ QVERIFY(copy != defaultMonitor);
+ QCOMPARE(copy.expiration(), now);
+
+ QCOMPARE(copy.isPersistent(), defaultMonitor.isPersistent());
+ copy.setPersistent(true);
+ QCOMPARE(copy.isPersistent(), true);
+ QCOMPARE(defaultMonitor.isPersistent(), false);
+ copy.setPersistent(false);
+
+ QVERIFY(copy.area() == defaultMonitor.area());
+ QVERIFY(!copy.area().isValid());
+ copy.setArea(QGeoCircle(QGeoCoordinate(1, 2), 4));
+ QVERIFY(copy.area().isValid());
+ QVERIFY(copy.area() != defaultMonitor.area());
+ QVERIFY(copy.area().contains(QGeoCoordinate(1, 2)));
+
+ QVERIFY(copy.notificationParameters().isEmpty());
+ QVariantMap map;
+ map.insert(QString("MyKey"), QVariant(123));
+ copy.setNotificationParameters(map);
+ QVERIFY(!copy.notificationParameters().isEmpty());
+ QCOMPARE(copy.notificationParameters().value(QString("MyKey")).toInt(), 123);
+ QCOMPARE(defaultMonitor.notificationParameters().value(QString("MyKey")).toInt(), 0);
+
+ QCOMPARE(defaultMonitor.identifier(), copy.identifier());
+
+ //assignment operator based
+ QGeoAreaMonitorInfo assignmentCopy;
+ assignmentCopy = copy;
+ QVERIFY(copy == assignmentCopy);
+ QVERIFY(assignmentCopy != defaultMonitor);
+
+ QVERIFY(assignmentCopy.area().contains(QGeoCoordinate(1, 2)));
+ QCOMPARE(assignmentCopy.expiration(), now);
+ QCOMPARE(assignmentCopy.isPersistent(), false);
+ QCOMPARE(assignmentCopy.notificationParameters().value(QString("MyKey")).toInt(), 123);
+ QCOMPARE(defaultMonitor.identifier(), assignmentCopy.identifier());
+ QCOMPARE(assignmentCopy.name(), QString("my name"));
+
+ //validity checks for requestUpdate()
+ obj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll"));
+ QCOMPARE(obj->activeMonitors().count(), 0);
+ //reference -> should work
+ QVERIFY(obj->requestUpdate(copy, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo))));
+ QCOMPARE(obj->activeMonitors().count(), 1);
+ //replaces areaEntered single shot
+ QVERIFY(obj->requestUpdate(copy, SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo))));
+ QCOMPARE(obj->activeMonitors().count(), 1);
+ //replaces areaExited single shot
+ QVERIFY(obj->startMonitoring(copy));
+ QCOMPARE(obj->activeMonitors().count(), 1);
+
+
+ //invalid signal
+ QVERIFY(!obj->requestUpdate(copy, 0));
+ QCOMPARE(obj->activeMonitors().count(), 1);
+
+ //signal that doesn't exist
+ QVERIFY(!obj->requestUpdate(copy, SIGNAL(areaEntered(QGeoMonitor))));
+ QCOMPARE(obj->activeMonitors().count(), 1);
+
+ QVERIFY(!obj->requestUpdate(copy, "SIGNAL(areaEntered(QGeoMonitor))"));
+ QCOMPARE(obj->activeMonitors().count(), 1);
+
+ //ensure that we cannot add a persistent monitor to a source
+ //that doesn't support persistence
+ QGeoAreaMonitorInfo persistenceMonitor(copy);
+ persistenceMonitor.setPersistent(obj->supportedAreaMonitorFeatures() & QGeoAreaMonitorSource::PersistentAreaMonitorFeature);
+ persistenceMonitor.setPersistent(!persistenceMonitor.isPersistent());
+
+ QVERIFY(!obj->requestUpdate(persistenceMonitor, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo))));
+ QCOMPARE(obj->activeMonitors().count(), 1);
+ QVERIFY(!obj->startMonitoring(persistenceMonitor));
+ QCOMPARE(obj->activeMonitors().count(), 1);
+
+ //ensure that persistence was only reason for rejection
+ persistenceMonitor.setPersistent(!persistenceMonitor.isPersistent());
+ QVERIFY(obj->startMonitoring(persistenceMonitor));
+ //persistenceMonitor is copy of already added monitor
+ //the last call was an update
+ QCOMPARE(obj->activeMonitors().count(), 1);
+
+ delete obj;
}
- void radius()
+ void tst_monitorValid()
{
- MyPositionAreaMonitor mon;
- qFuzzyCompare(mon.radius(), qreal(0.0));
+ QGeoAreaMonitorInfo mon;
+ QVERIFY(!mon.isValid());
+ QCOMPARE(mon.name(), QString());
+ QCOMPARE(mon.area().isValid(), false);
+
+ QGeoAreaMonitorInfo mon2 = mon;
+ QVERIFY(!mon2.isValid());
+
+ QGeoShape invalidShape;
+ QGeoCircle emptyCircle(QGeoCoordinate(0,1), 0);
+ QGeoCircle validCircle(QGeoCoordinate(0,1), 1);
+
+ //all invalid since no name set yet
+ mon2.setArea(invalidShape);
+ QVERIFY(mon2.area() == invalidShape);
+ QVERIFY(!mon2.isValid());
+
+ mon2.setArea(emptyCircle);
+ QVERIFY(mon2.area() == emptyCircle);
+ QVERIFY(!mon2.isValid());
+
+ mon2.setArea(validCircle);
+ QVERIFY(mon2.area() == validCircle);
+ QVERIFY(!mon2.isValid());
+
+ //valid since name and non-empy shape has been set
+ QGeoAreaMonitorInfo validMonitor("TestMonitor");
+ QVERIFY(validMonitor.name() == QString("TestMonitor"));
+ QVERIFY(!validMonitor.isValid());
+
+ validMonitor.setArea(invalidShape);
+ QVERIFY(validMonitor.area() == invalidShape);
+ QVERIFY(!validMonitor.isValid());
+
+ validMonitor.setArea(emptyCircle);
+ QVERIFY(validMonitor.area() == emptyCircle);
+ QVERIFY(!validMonitor.isValid());
+
+ validMonitor.setArea(validCircle);
+ QVERIFY(validCircle == validMonitor.area());
+ QVERIFY(validMonitor.isValid());
}
- void constructor_withoutParent()
+ void tst_monitorStreaming()
{
- MyPositionAreaMonitor *myMonitor = new MyPositionAreaMonitor();
- delete myMonitor;
- }
+ QByteArray container;
+ QDataStream stream(&container, QIODevice::ReadWrite);
- void constructor_withParent()
- {
- QObject* parent = new QObject;
- new MyPositionAreaMonitor(parent);
- delete parent;
+ QGeoAreaMonitorInfo monitor("someName");
+ monitor.setArea(QGeoCircle(QGeoCoordinate(1,3), 5.4));
+ QVERIFY(monitor.isValid());
+ QCOMPARE(monitor.name(), QString("someName"));
+
+ QGeoAreaMonitorInfo target;
+ QVERIFY(!target.isValid());
+ QVERIFY(target.name().isEmpty());
+
+ QVERIFY(target != monitor);
+
+ stream << monitor;
+ stream.device()->seek(0);
+ stream >> target;
+
+ QVERIFY(target == monitor);
+ QVERIFY(target.isValid());
+ QCOMPARE(target.name(), QString("someName"));
+ QVERIFY(target.area() == QGeoCircle(QGeoCoordinate(1,3), 5.4));
}
- void createDefaultMonitor()
+ void tst_createDefaultSource()
{
QObject* parent = new QObject;
- QGeoAreaMonitor* obj = QGeoAreaMonitor::createDefaultMonitor(parent);
+ QGeoAreaMonitorSource* obj = QGeoAreaMonitorSource::createDefaultSource(parent);
QVERIFY(obj != 0);
- delete parent;
+ QVERIFY(obj->parent() == parent);
+ delete obj;
- const QStringList monitors = QGeoAreaMonitor::availableMonitors();
+ const QStringList monitors = QGeoAreaMonitorSource::availableSources();
QVERIFY(!monitors.isEmpty());
QVERIFY(monitors.contains(QStringLiteral("positionpoll")));
- parent = new QObject;
- obj = QGeoAreaMonitor::createMonitor(QStringLiteral("positionpoll"), parent);
+ obj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), parent);
QVERIFY(obj != 0);
+ QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll"));
delete parent;
- obj = QGeoAreaMonitor::createMonitor(QStringLiteral("randomNonExistingName"), 0);
+ obj = QGeoAreaMonitorSource::createSource(QStringLiteral("randomNonExistingName"), 0);
QVERIFY(obj == 0);
}
- //TC_ID_4_x_1
- void center_createDefaultMonitor()
+ void tst_activeMonitors()
{
- monitor = QGeoAreaMonitor::createDefaultMonitor(0);
- QVERIFY(monitor != 0);
- QVERIFY(monitor->center().isValid() == false);
- }
-
- //TC_ID_4_x_1
- void radius_createDefaultMonitor()
- {
- monitor = QGeoAreaMonitor::createDefaultMonitor(0);
- QVERIFY(monitor != 0);
- qFuzzyCompare(monitor->radius(), qreal(0.0));
- }
-
- void setCenter()
- {
- QFETCH(QGeoCoordinate, coord);
- QFETCH(bool, validity);
-
- monitor = QGeoAreaMonitor::createDefaultMonitor(0);
- QVERIFY(monitor != 0);
-
- monitor->setCenter(coord);
- QCOMPARE(monitor->center().isValid(), validity);
- if (validity)
- QCOMPARE(monitor->center(), coord);
- }
-
- void setCenter_data()
- {
- QTest::addColumn<QGeoCoordinate>("coord");
- QTest::addColumn<bool>("validity");
-
- QTest::newRow("valid coordinate") << QGeoCoordinate(34.56, -12.4, 56) << true; //TC_ID_4_x_1
- QTest::newRow("invalid coordinate") << QGeoCoordinate(173.2, -195.8) << false; //TC_ID_4_x_2
- QTest::newRow("uninitialised coordinate") << QGeoCoordinate() << false; //TC_ID_4_x_3
- }
-
- void setCenter_twice()
- {
- QFETCH(QGeoCoordinate, first_coord);
- QFETCH(QGeoCoordinate, second_coord);
- QFETCH(QGeoCoordinate, expected_coord);
-
- monitor = QGeoAreaMonitor::createDefaultMonitor(0);
- QVERIFY(monitor != 0);
-
- monitor->setCenter(first_coord);
- monitor->setCenter(second_coord);
- QCOMPARE(monitor->center(), expected_coord);
- }
-
- void setCenter_twice_data()
- {
- QTest::addColumn<QGeoCoordinate>("first_coord");
- QTest::addColumn<QGeoCoordinate>("second_coord");
- QTest::addColumn<QGeoCoordinate>("expected_coord");
-
- //TC_ID_4_x_4
- QTest::newRow("setting first valid then invalid coordinate")
- << QGeoCoordinate(34.56, -12.4, 56) << QGeoCoordinate(173.2, -195.8)
- << QGeoCoordinate(34.56, -12.4, 56);
- //TC_ID_4_x_5
- QTest::newRow("setting first invalid then valid coordinate")
- << QGeoCoordinate(173.2, -195.8) << QGeoCoordinate(34.56, -12.4, 56)
- << QGeoCoordinate(34.56, -12.4, 56);
- //TC_ID_4_x_6
- QTest::newRow("setting first valid then valid coordinate")
- << QGeoCoordinate(-12.56, 101.4, 56) << QGeoCoordinate(34.56, -12.4, 56)
- << QGeoCoordinate(34.56, -12.4, 56);
+ QGeoAreaMonitorSource *obj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll"));
+
+ LogFilePositionSource *source = new LogFilePositionSource(this);
+ source->setUpdateInterval(UPDATE_INTERVAL);
+ obj->setPositionInfoSource(source);
+ QCOMPARE(obj->positionInfoSource(), source);
+
+
+ QVERIFY(obj->activeMonitors().isEmpty());
+
+ QGeoAreaMonitorInfo mon("Monitor_Circle");
+ mon.setArea(QGeoCircle(QGeoCoordinate(1,1), 1000));
+ QVERIFY(obj->startMonitoring(mon));
+
+ QGeoAreaMonitorInfo mon2("Monitor_rectangle_below");
+ QGeoRectangle r_below(QGeoCoordinate(1,1),2,2);
+ mon2.setArea(r_below);
+ QVERIFY(obj->startMonitoring(mon2));
+
+ QGeoAreaMonitorInfo mon3("Monitor_rectangle_above");
+ QGeoRectangle r_above(QGeoCoordinate(2,1),2,2);
+ mon3.setArea(r_above);
+ QVERIFY(obj->startMonitoring(mon3));
+
+ QList<QGeoAreaMonitorInfo> results = obj->activeMonitors();
+ QCOMPARE(results.count(), 3);
+ foreach (const QGeoAreaMonitorInfo& info, results) {
+ QVERIFY(info == mon || info == mon2 || info == mon3);
+ }
+
+ results = obj->activeMonitors(QGeoShape());
+ QCOMPARE(results.count(), 0);
+
+ results = obj->activeMonitors(QGeoRectangle(QGeoCoordinate(1,1),0.2, 0.2));
+ QCOMPARE(results.count(), 2);
+ foreach (const QGeoAreaMonitorInfo& info, results) {
+ QVERIFY(info == mon || info == mon2);
+ }
+
+ results = obj->activeMonitors(QGeoCircle(QGeoCoordinate(1,1),1000));
+ QCOMPARE(results.count(), 2);
+ foreach (const QGeoAreaMonitorInfo& info, results) {
+ QVERIFY(info == mon || info == mon2);
+ }
+
+ results = obj->activeMonitors(QGeoCircle(QGeoCoordinate(2,1),1000));
+ QCOMPARE(results.count(), 1);
+ foreach (const QGeoAreaMonitorInfo& info, results) {
+ QVERIFY(info == mon3);
+ }
+
+ //same as above except that we use a different monitor source object instance
+ //all monitor objects of same type share same active monitors
+ QGeoAreaMonitorSource *secondObj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(secondObj != 0);
+ QCOMPARE(secondObj->sourceName(), QStringLiteral("positionpoll"));
+
+ results = secondObj->activeMonitors();
+ QCOMPARE(results.count(), 3);
+ foreach (const QGeoAreaMonitorInfo& info, results) {
+ QVERIFY(info == mon || info == mon2 || info == mon3);
+ }
+
+ results = secondObj->activeMonitors(QGeoShape());
+ QCOMPARE(results.count(), 0);
+
+ results = secondObj->activeMonitors(QGeoRectangle(QGeoCoordinate(1,1),0.2, 0.2));
+ QCOMPARE(results.count(), 2);
+ foreach (const QGeoAreaMonitorInfo& info, results) {
+ QVERIFY(info == mon || info == mon2);
+ }
+
+ results = secondObj->activeMonitors(QGeoCircle(QGeoCoordinate(1,1),1000));
+ QCOMPARE(results.count(), 2);
+ foreach (const QGeoAreaMonitorInfo& info, results) {
+ QVERIFY(info == mon || info == mon2);
+ }
+
+ results = secondObj->activeMonitors(QGeoCircle(QGeoCoordinate(2,1),1000));
+ QCOMPARE(results.count(), 1);
+ foreach (const QGeoAreaMonitorInfo& info, results) {
+ QVERIFY(info == mon3);
+ }
+
+ delete obj;
+ delete secondObj;
}
- void setRadius()
+ void tst_testExpiryTimeout()
{
- QFETCH(qreal, radius);
- QFETCH(qreal, expected_radius);
-
- monitor = QGeoAreaMonitor::createDefaultMonitor(0);
- QVERIFY(monitor != 0);
-
- monitor->setRadius(radius);
- qFuzzyCompare(monitor->radius(), expected_radius);
+ QGeoAreaMonitorSource *obj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll"));
+
+ QGeoAreaMonitorSource *secondObj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(secondObj != 0);
+ QCOMPARE(secondObj->sourceName(), QStringLiteral("positionpoll"));
+
+ LogFilePositionSource *source = new LogFilePositionSource(this);
+ source->setUpdateInterval(UPDATE_INTERVAL);
+ obj->setPositionInfoSource(source);
+
+ //Singleton pattern behind QGeoAreaMonitorSource ensures same position info source
+ QCOMPARE(obj->positionInfoSource(), source);
+ QCOMPARE(secondObj->positionInfoSource(), source);
+
+ QSignalSpy expirySpy(obj, SIGNAL(monitorExpired(QGeoAreaMonitorInfo)));
+ QSignalSpy expirySpy2(secondObj, SIGNAL(monitorExpired(QGeoAreaMonitorInfo)));
+
+ QDateTime now = QDateTime::currentDateTime();
+
+ const int monitorCount = 4;
+ for (int i = 1; i <= monitorCount; i++) {
+ QGeoAreaMonitorInfo mon(QString::number(i));
+ mon.setArea(QGeoRectangle(QGeoCoordinate(i,i), i, i));
+ mon.setExpiration(now.addSecs(i*5));
+ QVERIFY(mon.isValid());
+ QVERIFY(obj->startMonitoring(mon));
+ }
+
+
+
+ QCOMPARE(obj->activeMonitors().count(), monitorCount);
+ QCOMPARE(secondObj->activeMonitors().count(), monitorCount);
+
+ QGeoAreaMonitorInfo info("InvalidExpiry");
+ info.setArea(QGeoRectangle(QGeoCoordinate(10,10), 1, 1 ));
+ QVERIFY(info.isValid());
+ info.setExpiration(now.addSecs(-1000));
+ QVERIFY(info.expiration() < now);
+ QVERIFY(!obj->startMonitoring(info));
+ QCOMPARE(obj->activeMonitors().count(), monitorCount);
+ QVERIFY(!obj->requestUpdate(info, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo))));
+ QCOMPARE(obj->activeMonitors().count(), monitorCount);
+
+ for (int i = 1; i <= monitorCount; i++) {
+ QTRY_VERIFY_WITH_TIMEOUT(expirySpy.count() == 1, 7000); //each expiry within 5 s
+ QGeoAreaMonitorInfo mon = expirySpy.takeFirst().at(0).value<QGeoAreaMonitorInfo>();
+ QCOMPARE(obj->activeMonitors().count(), monitorCount-i);
+ QCOMPARE(mon.name(), QString::number(i));
+ }
+
+ QCOMPARE(expirySpy2.count(), monitorCount);
+ QCOMPARE(secondObj->activeMonitors().count(), 0); //all monitors expired
+ for (int i = 1; i <= monitorCount; i++) {
+ QGeoAreaMonitorInfo mon = expirySpy2.takeFirst().at(0).value<QGeoAreaMonitorInfo>();
+ QCOMPARE(mon.name(), QString::number(i));
+ }
+
+ delete obj;
+ delete secondObj;
}
- void setRadius_data()
+ void tst_enteredExitedSignal()
{
- QTest::addColumn<qreal>("radius");
- QTest::addColumn<qreal>("expected_radius");
-
- QTest::newRow("zero radius") << qreal(0.0) << tst_qgeoareamonitor_minimumRadius(); //TC_ID_4_x_1
- QTest::newRow("radius ok") << qreal(1000.58) << qreal(1000.58); //TC_ID_4_x_2
- QTest::newRow("negative radius") << qreal(-876.58) << tst_qgeoareamonitor_minimumRadius(); //TC_ID_4_x_3
- QTest::newRow("float min") << qreal(FLT_MIN) << tst_qgeoareamonitor_minimumRadius(); //TC_ID_4
- QTest::newRow("float max") << qreal(FLT_MAX) << qreal(FLT_MAX); //TC_ID_4_x_4_x_5
+ QGeoAreaMonitorSource *obj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll"));
+ obj->setObjectName("firstObject");
+ QSignalSpy enteredSpy(obj, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)));
+ QSignalSpy exitedSpy(obj, SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo)));
+
+ LogFilePositionSource *source = new LogFilePositionSource(this);
+ source->setUpdateInterval(UPDATE_INTERVAL);
+ obj->setPositionInfoSource(source);
+ QCOMPARE(obj->positionInfoSource(), source);
+
+ QGeoAreaMonitorSource *secondObj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(secondObj != 0);
+ QCOMPARE(secondObj->sourceName(), QStringLiteral("positionpoll"));
+ QSignalSpy enteredSpy2(secondObj, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)));
+ QSignalSpy exitedSpy2(secondObj, SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo)));
+ secondObj->setObjectName("secondObject");
+
+ QGeoAreaMonitorInfo infoRectangle("Rectangle");
+ infoRectangle.setArea(QGeoRectangle(QGeoCoordinate(-27.65, 153.093), 0.2, 0.2));
+ QVERIFY(infoRectangle.isValid());
+ QVERIFY(obj->startMonitoring(infoRectangle));
+
+ QGeoAreaMonitorInfo infoCircle("Circle");
+ infoCircle.setArea(QGeoCircle(QGeoCoordinate(-27.70, 153.093),10000));
+ QVERIFY(infoCircle.isValid());
+ QVERIFY(obj->startMonitoring(infoCircle));
+
+ QGeoAreaMonitorInfo singleShot_enter("SingleShot_on_Entered");
+ singleShot_enter.setArea(QGeoRectangle(QGeoCoordinate(-27.67, 153.093), 0.2, 0.2));
+ QVERIFY(singleShot_enter.isValid());
+ QVERIFY(obj->requestUpdate(singleShot_enter,
+ SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo))));
+
+ QGeoAreaMonitorInfo singleShot_exit("SingleShot_on_Exited");
+ singleShot_exit.setArea(QGeoRectangle(QGeoCoordinate(-27.70, 153.093), 0.2, 0.2));
+ QVERIFY(singleShot_exit.isValid());
+ QVERIFY(obj->requestUpdate(singleShot_exit,
+ SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo))));
+
+ QVERIFY(obj->activeMonitors().count() == 4); //all monitors active
+ QVERIFY(secondObj->activeMonitors().count() == 4); //all monitors active
+
+ static const int Number_Of_Entered_Events = 6;
+ static const int Number_Of_Exited_Events = 5;
+ //takes 87 (lines)*200(timeout)/1000 seconds to finish
+ QTRY_VERIFY_WITH_TIMEOUT(enteredSpy.count() == Number_Of_Entered_Events, 20000);
+ QTRY_VERIFY_WITH_TIMEOUT(exitedSpy.count() == Number_Of_Exited_Events, 20000);
+ QCOMPARE(enteredSpy.count(), Number_Of_Entered_Events);
+ QCOMPARE(exitedSpy.count(), Number_Of_Exited_Events);
+
+ QList<QGeoAreaMonitorInfo> monitorsInExpectedEnteredEventOrder;
+ monitorsInExpectedEnteredEventOrder << infoRectangle << singleShot_enter << singleShot_exit
+ << infoCircle << infoCircle << infoRectangle;
+
+ QList<QGeoAreaMonitorInfo> monitorsInExpectedExitedEventOrder;
+ monitorsInExpectedExitedEventOrder << infoRectangle << infoCircle
+ << singleShot_exit << infoCircle << infoRectangle;
+
+ QList<QGeoCoordinate> enteredEventCoordinateOrder;
+ enteredEventCoordinateOrder << QGeoCoordinate(-27.55, 153.090718) //infoRectangle
+ << QGeoCoordinate(-27.57, 153.090718) //singleshot_enter
+ << QGeoCoordinate(-27.60, 153.090908) //singleshot_exit
+ << QGeoCoordinate(-27.62, 153.091036) //infoCircle
+ << QGeoCoordinate(-27.78, 153.093647) //infoCircle
+ << QGeoCoordinate(-27.75, 153.093896);//infoRectangle
+ QCOMPARE(enteredEventCoordinateOrder.count(), Number_Of_Entered_Events);
+ QCOMPARE(monitorsInExpectedEnteredEventOrder.count(), Number_Of_Entered_Events);
+
+ QList<QGeoCoordinate> exitedEventCoordinateOrder;
+ exitedEventCoordinateOrder << QGeoCoordinate(-27.78, 153.092218) //infoRectangle
+ << QGeoCoordinate(-27.79, 153.092308) //infoCircle
+ << QGeoCoordinate(-27.81, 153.092530) //singleshot_exit
+ << QGeoCoordinate(-27.61, 153.095231) //infoCircle
+ << QGeoCoordinate(-27.54, 153.095995);//infoCircle
+ QCOMPARE(exitedEventCoordinateOrder.count(), Number_Of_Exited_Events);
+ QCOMPARE(monitorsInExpectedExitedEventOrder.count(), Number_Of_Exited_Events);
+
+ //verify that both sources got the same signals
+ for (int i = 0; i < Number_Of_Entered_Events; i++) {
+ //first source
+ QGeoAreaMonitorInfo monInfo = enteredSpy.first().at(0).value<QGeoAreaMonitorInfo>();
+ QGeoPositionInfo posInfo = enteredSpy.takeFirst().at(1).value<QGeoPositionInfo>();
+ QVERIFY2(monInfo == monitorsInExpectedEnteredEventOrder.at(i),
+ qPrintable(QString::number(i) + ": " + monInfo.name()));
+ QVERIFY2(posInfo.coordinate() == enteredEventCoordinateOrder.at(i),
+ qPrintable(QString::number(i) + ". posInfo"));
+
+ //reset info objects to avoid comparing the same
+ monInfo = QGeoAreaMonitorInfo();
+ posInfo = QGeoPositionInfo();
+
+ //second source
+ monInfo = enteredSpy2.first().at(0).value<QGeoAreaMonitorInfo>();
+ posInfo = enteredSpy2.takeFirst().at(1).value<QGeoPositionInfo>();
+ QVERIFY2(monInfo == monitorsInExpectedEnteredEventOrder.at(i),
+ qPrintable(QString::number(i) + ": " + monInfo.name()));
+ QVERIFY2(posInfo.coordinate() == enteredEventCoordinateOrder.at(i),
+ qPrintable(QString::number(i) + ". posInfo"));
+ }
+
+ for (int i = 0; i < Number_Of_Exited_Events; i++) {
+ //first source
+ QGeoAreaMonitorInfo monInfo = exitedSpy.first().at(0).value<QGeoAreaMonitorInfo>();
+ QGeoPositionInfo posInfo = exitedSpy.takeFirst().at(1).value<QGeoPositionInfo>();
+ QVERIFY2(monInfo == monitorsInExpectedExitedEventOrder.at(i),
+ qPrintable(QString::number(i) + ": " + monInfo.name()));
+ QVERIFY2(posInfo.coordinate() == exitedEventCoordinateOrder.at(i),
+ qPrintable(QString::number(i) + ". posInfo"));
+
+ //reset info objects to avoid comparing the same
+ monInfo = QGeoAreaMonitorInfo();
+ posInfo = QGeoPositionInfo();
+
+ //second source
+ monInfo = exitedSpy2.first().at(0).value<QGeoAreaMonitorInfo>();
+ posInfo = exitedSpy2.takeFirst().at(1).value<QGeoPositionInfo>();
+ QVERIFY2(monInfo == monitorsInExpectedExitedEventOrder.at(i),
+ qPrintable(QString::number(i) + ": " + monInfo.name()));
+ QVERIFY2(posInfo.coordinate() == exitedEventCoordinateOrder.at(i),
+ qPrintable(QString::number(i) + ". posInfo"));
+ }
+
+ QCOMPARE(obj->activeMonitors().count(), 2); //single shot monitors have been removed
+ QCOMPARE(secondObj->activeMonitors().count(), 2);
+
+ delete obj;
+ delete secondObj;
}
- //TC_ID_4_x_6
- void setRadius_twice()
+ void tst_swapOfPositionSource()
{
- monitor = QGeoAreaMonitor::createDefaultMonitor(0);
- QVERIFY(monitor != 0);
-
- monitor->setRadius(qreal(1235.985));
- monitor->setRadius(qreal(6754.075));
-
- qFuzzyCompare(monitor->radius(), qreal(6754.075f));
+ QGeoAreaMonitorSource *obj = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->sourceName(), QStringLiteral("positionpoll"));
+ obj->setObjectName("firstObject");
+ QSignalSpy enteredSpy(obj, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)));
+ QSignalSpy exitedSpy(obj, SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo)));
+
+ QGeoAreaMonitorSource *obj2 = QGeoAreaMonitorSource::createSource(QStringLiteral("positionpoll"), 0);
+ QVERIFY(obj2 != 0);
+ QCOMPARE(obj2->sourceName(), QStringLiteral("positionpoll"));
+ obj2->setObjectName("secondObject");
+ QSignalSpy enteredSpy2(obj2, SIGNAL(areaEntered(QGeoAreaMonitorInfo,QGeoPositionInfo)));
+ QSignalSpy exitedSpy2(obj2, SIGNAL(areaExited(QGeoAreaMonitorInfo,QGeoPositionInfo)));
+
+ LogFilePositionSource *source = new LogFilePositionSource(this);
+ source->setUpdateInterval(UPDATE_INTERVAL);
+ source->setObjectName("FirstLogFileSource");
+
+ LogFilePositionSource *source2 = new LogFilePositionSource(this);
+ source2->setUpdateInterval(UPDATE_INTERVAL);
+ source2->setObjectName("SecondLogFileSource");
+
+ obj->setPositionInfoSource(source);
+ QCOMPARE(obj->positionInfoSource(), obj2->positionInfoSource());
+ QCOMPARE(obj2->positionInfoSource(), source);
+
+ QGeoAreaMonitorInfo infoRectangle("Rectangle");
+ infoRectangle.setArea(QGeoRectangle(QGeoCoordinate(-27.70, 153.092), 0.2, 0.2));
+ QVERIFY(infoRectangle.isValid());
+ QVERIFY(obj->startMonitoring(infoRectangle));
+
+ QCOMPARE(obj->activeMonitors().count(), 1);
+ QCOMPARE(obj2->activeMonitors().count(), 1);
+
+ QGeoCoordinate firstBorder(-27.6, 153.090908);
+ QGeoCoordinate secondBorder(-27.81, 153.092530);
+
+ /***********************************/
+ //1. trigger events on source (until areaExit
+ QTRY_VERIFY_WITH_TIMEOUT(exitedSpy.count() == 1, 20000);
+ QCOMPARE(enteredSpy.count(), enteredSpy2.count());
+ QCOMPARE(exitedSpy.count(), exitedSpy2.count());
+
+ //compare entered event
+ QVERIFY(enteredSpy.first().at(0).value<QGeoAreaMonitorInfo>() ==
+ enteredSpy2.first().at(0).value<QGeoAreaMonitorInfo>());
+ QGeoPositionInfo info = enteredSpy.takeFirst().at(1).value<QGeoPositionInfo>();
+ QVERIFY(info == enteredSpy2.takeFirst().at(1).value<QGeoPositionInfo>());
+ QVERIFY(info.coordinate() == firstBorder);
+ //compare exit event
+ QVERIFY(exitedSpy.first().at(0).value<QGeoAreaMonitorInfo>() ==
+ exitedSpy2.first().at(0).value<QGeoAreaMonitorInfo>());
+ info = exitedSpy.takeFirst().at(1).value<QGeoPositionInfo>();
+ QVERIFY(info == exitedSpy2.takeFirst().at(1).value<QGeoPositionInfo>());
+ QVERIFY(info.coordinate() == secondBorder);
+
+ QCOMPARE(exitedSpy.count(), 0);
+ QCOMPARE(enteredSpy.count(), 0);
+ QCOMPARE(exitedSpy2.count(), 0);
+ QCOMPARE(enteredSpy2.count(), 0);
+
+ /***********************************/
+ //2. change position source -> which restarts at beginning again
+ obj2->setPositionInfoSource(source2);
+ QCOMPARE(obj->positionInfoSource(), obj2->positionInfoSource());
+ QCOMPARE(obj2->positionInfoSource(), source2);
+
+ QTRY_VERIFY_WITH_TIMEOUT(exitedSpy.count() == 1, 20000);
+ QCOMPARE(enteredSpy.count(), enteredSpy2.count());
+ QCOMPARE(exitedSpy.count(), exitedSpy2.count());
+
+ //compare entered event
+ QVERIFY(enteredSpy.first().at(0).value<QGeoAreaMonitorInfo>() ==
+ enteredSpy2.first().at(0).value<QGeoAreaMonitorInfo>());
+ info = enteredSpy.takeFirst().at(1).value<QGeoPositionInfo>();
+ QVERIFY(info == enteredSpy2.takeFirst().at(1).value<QGeoPositionInfo>());
+ QVERIFY(info.coordinate() == firstBorder);
+ //compare exit event
+ QVERIFY(exitedSpy.first().at(0).value<QGeoAreaMonitorInfo>() ==
+ exitedSpy2.first().at(0).value<QGeoAreaMonitorInfo>());
+ info = exitedSpy.takeFirst().at(1).value<QGeoPositionInfo>();
+ QVERIFY(info == exitedSpy2.takeFirst().at(1).value<QGeoPositionInfo>());
+ QVERIFY(info.coordinate() == secondBorder);
+
+
+ //obj was deleted when setting new source
+ delete obj2;
}
};
-QTEST_GUILESS_MAIN(tst_QGeoAreaMonitor)
+QTEST_GUILESS_MAIN(tst_QGeoAreaMonitorSource)
#include "tst_qgeoareamonitor.moc"