diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2021-07-01 12:55:53 +0200 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2021-07-14 14:58:05 +0200 |
commit | d0351428c74dd9f6d9544ca8bdf442317e1976e8 (patch) | |
tree | 02d78dfe282573a084cd4a2acd19b5907c249a6c /src/plugins/position/android/src/qgeopositioninfosource_android.cpp | |
parent | aa02046dfe9c8c160ab872701aab5c7b768f73c2 (diff) | |
download | qtlocation-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>
Diffstat (limited to 'src/plugins/position/android/src/qgeopositioninfosource_android.cpp')
-rw-r--r-- | src/plugins/position/android/src/qgeopositioninfosource_android.cpp | 42 |
1 files changed, 35 insertions, 7 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. |