summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2021-07-01 12:55:53 +0200
committerIvan Solovev <ivan.solovev@qt.io>2021-07-14 14:58:05 +0200
commitd0351428c74dd9f6d9544ca8bdf442317e1976e8 (patch)
tree02d78dfe282573a084cd4a2acd19b5907c249a6c
parentaa02046dfe9c8c160ab872701aab5c7b768f73c2 (diff)
downloadqtlocation-d0351428c74dd9f6d9544ca8bdf442317e1976e8.tar.gz
QtPositioning: emit missing UpdateTimeoutError during regular updates
The documentation tells that UpdateTimeoutError will be raised if the plugin determines that it fails to provide regular updates. This was not implemented for Android plugin so far. This patch adds such feature. However, there is no straightforward way to find out that the Android OS is not able to provide location updates. For example, analyzing satellite info is not the correct approach, because the OS also uses network information to provide the location. As a result, the only reasonable way is to actually detect that there were no location updates within a certain period of time. This is the approach that is implemented in this patch. The period is calculated based on the selected updateInterval() plus some constant. The constant is large enough for the Android OS to start providing updates under normal conditions. Apart from that, the error is raised immediately when the required location providers are disabled. Fixes: QTBUG-36854 Pick-to: 6.2 Change-Id: I14e8e95e721efd7fbb09d8d9a6e984f80f7249cc Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/plugins/position/android/src/qgeopositioninfosource_android.cpp42
-rw-r--r--src/plugins/position/android/src/qgeopositioninfosource_android_p.h8
2 files changed, 41 insertions, 9 deletions
diff --git a/src/plugins/position/android/src/qgeopositioninfosource_android.cpp b/src/plugins/position/android/src/qgeopositioninfosource_android.cpp
index 1f071e33..b1a41e92 100644
--- a/src/plugins/position/android/src/qgeopositioninfosource_android.cpp
+++ b/src/plugins/position/android/src/qgeopositioninfosource_android.cpp
@@ -39,24 +39,27 @@
#include "qgeopositioninfosource_android_p.h"
#include "jnipositioning.h"
-//#include <QDebug>
#include <QGeoPositionInfo>
-#define UPDATE_FROM_COLD_START 2*60*1000
-
+static constexpr int kUpdateFromColdStart = 2 * 60 * 1000;
+static constexpr int kRegularUpdatesTimerInterval = 30 * 1000;
QGeoPositionInfoSourceAndroid::QGeoPositionInfoSourceAndroid(QObject *parent) :
- QGeoPositionInfoSource(parent), updatesRunning(false), m_error(NoError), m_requestTimer(this)
+ QGeoPositionInfoSource(parent)
{
androidClassKeyForUpdate = AndroidPositioning::registerPositionInfoSource(this);
androidClassKeyForSingleRequest = AndroidPositioning::registerPositionInfoSource(this);
- //qDebug() << "androidClassKey: " << androidClassKeyForUpdate << androidClassKeyForSingleRequest;
//by default use all methods
setPreferredPositioningMethods(AllPositioningMethods);
m_requestTimer.setSingleShot(true);
- QObject::connect(&m_requestTimer, SIGNAL(timeout()), this, SLOT(requestTimeout()));
+ connect(&m_requestTimer, &QTimer::timeout, this,
+ &QGeoPositionInfoSourceAndroid::requestTimeout);
+
+ m_regularUpdatesTimer.setSingleShot(false);
+ connect(&m_regularUpdatesTimer, &QTimer::timeout, this,
+ &QGeoPositionInfoSourceAndroid::regularUpdatesTimeout);
}
QGeoPositionInfoSourceAndroid::~QGeoPositionInfoSourceAndroid()
@@ -137,10 +140,15 @@ void QGeoPositionInfoSourceAndroid::startUpdates()
}
updatesRunning = true;
+ // Start calculating updates from now.
+ m_lastUpdateTime = QDateTime::currentMSecsSinceEpoch();
+ m_regularUpdatesErrorRaised = false;
QGeoPositionInfoSource::Error error = AndroidPositioning::startUpdates(androidClassKeyForUpdate);
if (error != QGeoPositionInfoSource::NoError) {
updatesRunning = false;
setError(error);
+ } else {
+ m_regularUpdatesTimer.start(kRegularUpdatesTimerInterval);
}
}
@@ -150,6 +158,7 @@ void QGeoPositionInfoSourceAndroid::stopUpdates()
return;
updatesRunning = false;
+ m_regularUpdatesTimer.stop();
AndroidPositioning::stopUpdates(androidClassKeyForUpdate);
}
@@ -166,7 +175,7 @@ void QGeoPositionInfoSourceAndroid::requestUpdate(int timeout)
}
if (timeout == 0)
- timeout = UPDATE_FROM_COLD_START;
+ timeout = kUpdateFromColdStart;
m_requestTimer.start(timeout);
@@ -189,6 +198,9 @@ void QGeoPositionInfoSourceAndroid::processPositionUpdate(const QGeoPositionInfo
if (m_requestTimer.isActive())
m_requestTimer.stop();
+ m_lastUpdateTime = QDateTime::currentMSecsSinceEpoch();
+ m_regularUpdatesErrorRaised = false;
+
emit positionUpdated(pInfo);
}
@@ -204,6 +216,11 @@ void QGeoPositionInfoSourceAndroid::processSinglePositionUpdate(const QGeoPositi
void QGeoPositionInfoSourceAndroid::locationProviderDisabled()
{
+ if (updatesRunning && !m_regularUpdatesErrorRaised) {
+ m_regularUpdatesErrorRaised = true;
+ setError(QGeoPositionInfoSource::UpdateTimeoutError);
+ }
+
setError(QGeoPositionInfoSource::ClosedError);
}
@@ -254,6 +271,17 @@ void QGeoPositionInfoSourceAndroid::requestTimeout()
emit positionUpdated(best);
}
+void QGeoPositionInfoSourceAndroid::regularUpdatesTimeout()
+{
+ if (!m_regularUpdatesErrorRaised) {
+ const auto now = QDateTime::currentMSecsSinceEpoch();
+ if ((now - m_lastUpdateTime) > (updateInterval() + kUpdateFromColdStart)) {
+ m_regularUpdatesErrorRaised = true;
+ setError(QGeoPositionInfoSource::UpdateTimeoutError);
+ }
+ }
+}
+
/*
Updates the system assuming that updateInterval
and/or preferredPositioningMethod have changed.
diff --git a/src/plugins/position/android/src/qgeopositioninfosource_android_p.h b/src/plugins/position/android/src/qgeopositioninfosource_android_p.h
index 334b42a8..44cb2799 100644
--- a/src/plugins/position/android/src/qgeopositioninfosource_android_p.h
+++ b/src/plugins/position/android/src/qgeopositioninfosource_android_p.h
@@ -82,17 +82,21 @@ public Q_SLOTS:
void locationProvidersChanged();
private Q_SLOTS:
void requestTimeout();
+ void regularUpdatesTimeout();
private:
void reconfigureRunningSystem();
void setError(Error error);
- bool updatesRunning;
+ bool updatesRunning = false;
int androidClassKeyForUpdate;
int androidClassKeyForSingleRequest;
QList<QGeoPositionInfo> queuedSingleUpdates;
- Error m_error;
+ Error m_error = NoError;
QTimer m_requestTimer;
+ QTimer m_regularUpdatesTimer;
+ qint64 m_lastUpdateTime = 0;
+ bool m_regularUpdatesErrorRaised = false;
};
#endif // QGEOPOSITIONINFOSOURCE_ANDROID_P_H