summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Wolff <oliver.wolff@qt.io>2019-01-04 12:20:44 +0100
committerOliver Wolff <oliver.wolff@qt.io>2019-01-14 12:43:20 +0000
commitb17c07dc0b947c979372fbaf558ce9acc07d1837 (patch)
treeec81a7f4edb7c0b25c8a42a34a23f9df58a81629
parent379f398ca56458e413cbebbebcbdfa1337cfb6e5 (diff)
downloadqtlocation-b17c07dc0b947c979372fbaf558ce9acc07d1837.tar.gz
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 <miguel.costa@qt.io>
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp72
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp6
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<IAsyncOperation<GeolocationAccessStatus
}
#endif // !Q_OS_WINRT
+enum class InitializationState {
+ Uninitialized,
+ Initializing,
+ Initialized
+};
+
class QGeoPositionInfoSourceWinRTPrivate {
public:
ComPtr<IGeolocator> 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<int>(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<int>(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;
}