summaryrefslogtreecommitdiff
path: root/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@qt.io>2019-01-03 08:52:23 +0100
committerOliver Wolff <oliver.wolff@qt.io>2019-01-14 12:43:10 +0000
commited13382f2aa1434ab4c75c6a5dd0896493bc6c69 (patch)
treef3ab7db35ddf5dc681985a50d45ad5011f4cb69f /src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
parent952ab431d7fb9f660438da612d2b00485cce02f3 (diff)
downloadqtlocation-ed13382f2aa1434ab4c75c6a5dd0896493bc6c69.tar.gz
winrt: React on position source status change events
Querying the position source's status is error prone as it is only updated if position tracking is active. Instead we can react on changes for this status and get updated information when it is available. Change-Id: I18d55faf6163568243d2e05d3c63f13e9e45f413 Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io> Reviewed-by: Miguel Costa <miguel.costa@qt.io>
Diffstat (limited to 'src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp')
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp102
1 files changed, 48 insertions, 54 deletions
diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
index b55d2ba3..dcc99e51 100644
--- a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
+++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
@@ -57,11 +57,14 @@ using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
typedef ITypedEventHandler<Geolocator *, PositionChangedEventArgs *> GeoLocatorPositionHandler;
+typedef ITypedEventHandler<Geolocator *, StatusChangedEventArgs *> GeoLocatorStatusHandler;
typedef IAsyncOperationCompletedHandler<Geoposition*> PositionHandler;
typedef IAsyncOperationCompletedHandler<GeolocationAccessStatus> AccessHandler;
Q_DECLARE_LOGGING_CATEGORY(lcPositioningWinRT)
+Q_DECLARE_METATYPE(QGeoPositionInfoSource::Error)
+
QT_BEGIN_NAMESPACE
#ifndef Q_OS_WINRT
@@ -116,33 +119,14 @@ public:
bool updatesOngoing;
int minimumUpdateInterval;
- PositionStatus nativeStatus() const;
+ PositionStatus positionStatus = PositionStatus_NotInitialized;
};
-PositionStatus QGeoPositionInfoSourceWinRTPrivate::nativeStatus() const
-{
-#ifdef Q_OS_WINRT
- qCDebug(lcPositioningWinRT) << __FUNCTION__;
-
- PositionStatus status;
- HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, &status]() {
- return locator->get_LocationStatus(&status);
- });
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Could not query status");
- return PositionStatus_NotAvailable;
- }
- return status;
-#else
- return PositionStatus_Ready;
-#endif
-}
-
-
QGeoPositionInfoSourceWinRT::QGeoPositionInfoSourceWinRT(QObject *parent)
: QGeoPositionInfoSource(parent)
, d_ptr(new QGeoPositionInfoSourceWinRTPrivate)
{
+ qRegisterMetaType<QGeoPositionInfoSource::Error>();
qCDebug(lcPositioningWinRT) << __FUNCTION__;
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
Q_D(QGeoPositionInfoSourceWinRT);
@@ -190,6 +174,7 @@ int QGeoPositionInfoSourceWinRT::init()
}
d->positionToken.value = 0;
+ d->statusToken.value = 0;
d->periodicTimer.setSingleShot(true);
connect(&d->periodicTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::virtualPositionUpdate);
@@ -215,10 +200,9 @@ QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinRT::supporte
{
Q_D(const QGeoPositionInfoSourceWinRT);
- PositionStatus status = d->nativeStatus();
- qCDebug(lcPositioningWinRT) << __FUNCTION__ << status;
+ qCDebug(lcPositioningWinRT) << __FUNCTION__;
- switch (status) {
+ switch (d->positionStatus) {
case PositionStatus::PositionStatus_NoData:
case PositionStatus::PositionStatus_Disabled:
case PositionStatus::PositionStatus_NotAvailable:
@@ -238,7 +222,7 @@ void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInf
if (previousPreferredPositioningMethods == preferredPositioningMethods())
return;
- const bool needsRestart = d->positionToken.value != 0;
+ const bool needsRestart = d->positionToken.value != 0 || d->statusToken.value != 0;
if (needsRestart)
stopHandler();
@@ -266,7 +250,7 @@ void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec)
if (msec != 0 && msec < minimumUpdateInterval())
msec = minimumUpdateInterval();
- const bool needsRestart = d->positionToken.value != 0;
+ const bool needsRestart = d->positionToken.value != 0 || d->statusToken.value != 0;
if (needsRestart)
stopHandler();
@@ -330,7 +314,7 @@ bool QGeoPositionInfoSourceWinRT::startHandler()
return false;
}
- if (!requestAccess() || !checkNativeState())
+ if (!requestAccess())
return false;
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
@@ -348,6 +332,10 @@ bool QGeoPositionInfoSourceWinRT::startHandler()
&d->positionToken);
RETURN_HR_IF_FAILED("Could not add position handler");
+ hr = d->locator->add_StatusChanged(Callback<GeoLocatorStatusHandler>(this,
+ &QGeoPositionInfoSourceWinRT::onStatusChanged).Get(),
+ &d->statusToken);
+ RETURN_HR_IF_FAILED("Could not add status handler");
return hr;
});
if (FAILED(hr)) {
@@ -367,9 +355,11 @@ void QGeoPositionInfoSourceWinRT::stopHandler()
return;
QEventDispatcherWinRT::runOnXamlThread([d]() {
d->locator->remove_PositionChanged(d->positionToken);
+ d->locator->remove_StatusChanged(d->statusToken);
return S_OK;
});
d->positionToken.value = 0;
+ d->statusToken.value = 0;
}
void QGeoPositionInfoSourceWinRT::requestUpdate(int timeout)
@@ -395,12 +385,6 @@ void QGeoPositionInfoSourceWinRT::virtualPositionUpdate()
Q_D(QGeoPositionInfoSourceWinRT);
QMutexLocker locker(&d->mutex);
- // Need to check if services are still running and ok
- if (!checkNativeState()) {
- stopUpdates();
- return;
- }
-
// The operating system did not provide information in time
// Hence we send a virtual position update to keep same behavior
// between backends.
@@ -466,28 +450,10 @@ void QGeoPositionInfoSourceWinRT::setError(QGeoPositionInfoSource::Error positio
emit QGeoPositionInfoSource::error(positionError);
}
-bool QGeoPositionInfoSourceWinRT::checkNativeState()
+void QGeoPositionInfoSourceWinRT::reactOnError(QGeoPositionInfoSource::Error positionError)
{
- Q_D(QGeoPositionInfoSourceWinRT);
- qCDebug(lcPositioningWinRT) << __FUNCTION__;
-
- PositionStatus status = d->nativeStatus();
-
- bool result = false;
- switch (status) {
- case PositionStatus::PositionStatus_NotAvailable:
- setError(QGeoPositionInfoSource::UnknownSourceError);
- break;
- case PositionStatus::PositionStatus_Disabled:
- case PositionStatus::PositionStatus_NoData:
- setError(QGeoPositionInfoSource::ClosedError);
- break;
- default:
- setError(QGeoPositionInfoSource::NoError);
- result = true;
- break;
- }
- return result;
+ setError(positionError);
+ stopUpdates();
}
HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPositionChangedEventArgs *args)
@@ -597,6 +563,34 @@ HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPo
return S_OK;
}
+HRESULT QGeoPositionInfoSourceWinRT::onStatusChanged(IGeolocator *, IStatusChangedEventArgs *args)
+{
+ Q_D(QGeoPositionInfoSourceWinRT);
+
+ HRESULT hr = args->get_Status(&d->positionStatus);
+ RETURN_HR_IF_FAILED("Could not obtain position status");
+ qCDebug(lcPositioningWinRT) << __FUNCTION__ << d->positionStatus;
+ QGeoPositionInfoSource::Error error = QGeoPositionInfoSource::NoError;
+ switch (d->positionStatus) {
+ case PositionStatus::PositionStatus_NotAvailable:
+ error = QGeoPositionInfoSource::UnknownSourceError;
+ break;
+ case PositionStatus::PositionStatus_Disabled:
+ error = QGeoPositionInfoSource::AccessError;
+ break;
+ case PositionStatus::PositionStatus_NoData:
+ error = QGeoPositionInfoSource::ClosedError;
+ break;
+ }
+ if (error != QGeoPositionInfoSource::NoError) {
+ QMetaObject::invokeMethod(this, "reactOnError", Qt::QueuedConnection,
+ Q_ARG(QGeoPositionInfoSource::Error,
+ QGeoPositionInfoSource::UnknownSourceError));
+ }
+
+ return S_OK;
+}
+
bool QGeoPositionInfoSourceWinRT::requestAccess() const
{
qCDebug(lcPositioningWinRT) << __FUNCTION__;