From b17c07dc0b947c979372fbaf558ce9acc07d1837 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 4 Jan 2019 12:20:44 +0100 Subject: winrt: Initialize position source on first usage Loading the plugin without access to the location service will work and not error out. It is still possible to enable location service later and the backend will work as expected. This patch changes the behavior so that the pop up asking for access to the user's location data is no longer shown when the plugin is loaded, but when the backend is actually used for the first time. Change-Id: I23100f7867610c6f23b2d2ea5c15c268468949a9 Reviewed-by: Miguel Costa --- .../winrt/qgeopositioninfosource_winrt.cpp | 72 ++++++++++++++++------ .../winrt/qgeopositioninfosourcefactory_winrt.cpp | 6 -- 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp index 2fedf5b5..fe783bd2 100644 --- a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp +++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp @@ -106,6 +106,12 @@ static inline HRESULT await(const ComPtr locator; @@ -118,6 +124,8 @@ public: QMutex mutex; bool updatesOngoing = false; int minimumUpdateInterval = -1; + int updateInterval = -1; + InitializationState initState = InitializationState::Uninitialized; PositionStatus positionStatus = PositionStatus_NotInitialized; }; @@ -144,9 +152,16 @@ QGeoPositionInfoSourceWinRT::~QGeoPositionInfoSourceWinRT() int QGeoPositionInfoSourceWinRT::init() { - qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); + Q_ASSERT(d->initState != InitializationState::Initializing); + if (d->initState == InitializationState::Initialized) + return 0; + + qCDebug(lcPositioningWinRT) << __FUNCTION__; + d->initState = InitializationState::Initializing; if (!requestAccess()) { + d->initState = InitializationState::Uninitialized; + setError(QGeoPositionInfoSource::AccessError); qWarning ("Location access failed."); return -1; } @@ -155,35 +170,37 @@ int QGeoPositionInfoSourceWinRT::init() &d->locator); RETURN_HR_IF_FAILED("Could not initialize native location services."); - UINT32 interval; - hr = d->locator->get_ReportInterval(&interval); - RETURN_HR_IF_FAILED("Could not retrieve report interval."); - d->minimumUpdateInterval = static_cast(interval); - setUpdateInterval(d->minimumUpdateInterval); + if (d->minimumUpdateInterval == -1) { + UINT32 interval; + hr = d->locator->get_ReportInterval(&interval); + RETURN_HR_IF_FAILED("Could not retrieve report interval."); + d->minimumUpdateInterval = static_cast(interval); + } + if (d->updateInterval == -1) + d->updateInterval = d->minimumUpdateInterval; + setUpdateInterval(d->updateInterval); return hr; }); if (FAILED(hr)) { + d->initState = InitializationState::Uninitialized; setError(QGeoPositionInfoSource::UnknownSourceError); return -1; } - hr = d->locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_Default); - if (FAILED(hr)) { - setError(QGeoPositionInfoSource::UnknownSourceError); - qErrnoWarning(hr, "Could not initialize desired accuracy."); - return -1; - } - d->periodicTimer.setSingleShot(true); connect(&d->periodicTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::virtualPositionUpdate); d->singleUpdateTimer.setSingleShot(true); connect(&d->singleUpdateTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::singleUpdateTimeOut); - setPreferredPositioningMethods(QGeoPositionInfoSource::AllPositioningMethods); + QGeoPositionInfoSource::PositioningMethods preferredMethods = preferredPositioningMethods(); + if (preferredMethods == QGeoPositionInfoSource::NoPositioningMethods) + preferredMethods = QGeoPositionInfoSource::AllPositioningMethods; + setPreferredPositioningMethods(preferredMethods); connect(this, &QGeoPositionInfoSourceWinRT::nativePositionUpdate, this, &QGeoPositionInfoSourceWinRT::updateSynchronized); + d->initState = InitializationState::Initialized; return 0; } @@ -208,9 +225,12 @@ void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInf PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods(); QGeoPositionInfoSource::setPreferredPositioningMethods(methods); - if (previousPreferredPositioningMethods == preferredPositioningMethods()) + if (previousPreferredPositioningMethods == preferredPositioningMethods() + || d->initState != InitializationState::Uninitialized) { return; + } + Q_ASSERT(d->initState != InitializationState::Initializing); const bool needsRestart = d->positionToken.value != 0 || d->statusToken.value != 0; if (needsRestart) @@ -232,6 +252,12 @@ void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec) { qCDebug(lcPositioningWinRT) << __FUNCTION__ << msec; Q_D(QGeoPositionInfoSourceWinRT); + if (d->initState == InitializationState::Uninitialized) { + d->updateInterval = msec; + return; + } + + Q_ASSERT(d->initState != InitializationState::Initializing); // minimumUpdateInterval is initialized to the lowest possible update interval in init(). // Passing 0 will cause an error on Windows 10. // See https://docs.microsoft.com/en-us/uwp/api/windows.devices.geolocation.geolocator.reportinterval @@ -250,9 +276,10 @@ void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec) return; } - d->periodicTimer.setInterval(qMax(msec, minimumUpdateInterval())); + d->updateInterval = msec; + d->periodicTimer.setInterval(d->updateInterval); - QGeoPositionInfoSource::setUpdateInterval(msec); + QGeoPositionInfoSource::setUpdateInterval(d->updateInterval); if (needsRestart) startHandler(); @@ -261,7 +288,7 @@ void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec) int QGeoPositionInfoSourceWinRT::minimumUpdateInterval() const { Q_D(const QGeoPositionInfoSourceWinRT); - return d->minimumUpdateInterval; + return d->minimumUpdateInterval == -1 ? 1000 : d->minimumUpdateInterval; } void QGeoPositionInfoSourceWinRT::startUpdates() @@ -270,6 +297,9 @@ void QGeoPositionInfoSourceWinRT::startUpdates() Q_D(QGeoPositionInfoSourceWinRT); setError(QGeoPositionInfoSource::NoError); + if (init() < 0) + return; + if (d->updatesOngoing) return; @@ -284,6 +314,9 @@ void QGeoPositionInfoSourceWinRT::stopUpdates() qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); + if (init() < 0) + return; + stopHandler(); d->updatesOngoing = false; d->periodicTimer.stop(); @@ -358,6 +391,9 @@ void QGeoPositionInfoSourceWinRT::requestUpdate(int timeout) qCDebug(lcPositioningWinRT) << __FUNCTION__ << timeout; Q_D(QGeoPositionInfoSourceWinRT); + if (init() < 0) + return; + setError(QGeoPositionInfoSource::NoError); if (timeout != 0 && timeout < minimumUpdateInterval()) { emit updateTimeout(); diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp index b1ec6fb3..03b86ca7 100644 --- a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp +++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp @@ -47,12 +47,6 @@ QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryWinRT::positionInfoSource(Q { qCDebug(lcPositioningWinRT) << __FUNCTION__; QGeoPositionInfoSourceWinRT *src = new QGeoPositionInfoSourceWinRT(parent); - if (src->init() < 0) { - qCDebug(lcPositioningWinRT) << __FUNCTION__ << "Source initialization failed."; - delete src; - return nullptr; - } - qCDebug(lcPositioningWinRT) << __FUNCTION__ << "Created position info source."; return src; } -- cgit v1.2.1