summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2023-04-21 16:17:36 +0200
committerIvan Solovev <ivan.solovev@qt.io>2023-05-10 09:58:54 +0200
commit697f2dbb559966a0f7aeccdb5a905da39ebcfab6 (patch)
tree6ddc82c8a72fa9a47e6dd96f986cc48d68eed181
parentf5ca6f089ff19906184d788e78aecbf52de6ac8b (diff)
CoreLocation plugin: introduce RequestAlwaysPermission parameter
Previously we were using NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription to distinguish the level of permission that we want to request. However, Apple now always requires *both* entries to present in the Info.plist file. [ChangeLog][Important Behavior Changes][Apple] Introduce an explicit RequestAlwaysPermission parameter to the corelocation plugin. When specified and set to true, this parameters enables the "Always" location request. When not specified or set to false, only the "When In Use" location permission is requested. By default this parameter is not specified. This patch is only applicable to Qt 6.5 and earlier versions, because starting from Qt 6.6 the Qt Positioning library will no longer request the permissions. Instead the new QPermission API must be used at the user application level. Fixes: QTBUG-109359 Pick-to: 6.2 5.15 Change-Id: Ib35f578a6459e84d2ff29c79416ae5ee9f104cc8 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Juha Vuolle <juha.vuolle@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/plugins/position/corelocation/qgeopositioninfosource_cl.mm33
-rw-r--r--src/plugins/position/corelocation/qgeopositioninfosource_cl_p.h3
-rw-r--r--src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.mm3
-rw-r--r--src/positioning/doc/src/plugins/corelocation.qdoc93
-rw-r--r--src/positioning/doc/src/qtpositioning-plugins.qdoc4
5 files changed, 123 insertions, 13 deletions
diff --git a/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm b/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm
index 173fdf2e..87972dfc 100644
--- a/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm
+++ b/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm
@@ -7,6 +7,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/private/qglobal_p.h>
#include <QtCore/qtimezone.h>
+#include <QtCore/qvariantmap.h>
#include "qgeopositioninfosource_cl_p.h"
@@ -82,7 +83,9 @@
QT_BEGIN_NAMESPACE
-QGeoPositionInfoSourceCL::QGeoPositionInfoSourceCL(QObject *parent)
+static const auto alwaysPermissionKey = QStringLiteral("RequestAlwaysPermission");
+
+QGeoPositionInfoSourceCL::QGeoPositionInfoSourceCL(const QVariantMap &parameters, QObject *parent)
: QGeoPositionInfoSource(parent),
m_locationManager(0),
m_updatesWanted(false),
@@ -90,6 +93,7 @@ QGeoPositionInfoSourceCL::QGeoPositionInfoSourceCL(QObject *parent)
m_updateTimeout(0),
m_positionError(QGeoPositionInfoSource::NoError)
{
+ m_requestAlwaysPermission = parameters.value(alwaysPermissionKey, false).toBool();
}
QGeoPositionInfoSourceCL::~QGeoPositionInfoSourceCL()
@@ -137,19 +141,30 @@ bool QGeoPositionInfoSourceCL::enableLocationManager()
m_locationManager.delegate = [[PositionLocationDelegate alloc] initWithInfoSource:this];
}
- // -requestAlwaysAuthorization requires both NSLocationAlwaysAndWhenInUseUsageDescription and
- // NSLocationWhenInUseUsageDescription entries present in Info.plist (otherwise,
- // while probably a noop, the call generates a warning).
- // -requestWhenInUseAuthorization only requires NSLocationWhenInUseUsageDescription
- // entry in Info.plist
+ // According to QTBUG-109359, Apple now requires both NSLocationWhenInUseUsageDescription
+ // and NSLocationAlwaysAndWhenInUseUsageDescription entries to present in Info.plist
+ // if the binary has capabilities to request both (symbols for that are present).
+ // This means that we cannot use the presence of permission keys to decide
+ // which authorization type to request (as both need to be present).
+ // Use an explicit plugin parameter instead.
#ifdef Q_OS_IOS
NSDictionary<NSString *, id> *infoDict = NSBundle.mainBundle.infoDictionary;
const bool hasAlwaysUseUsage = !![infoDict objectForKey:@"NSLocationAlwaysAndWhenInUseUsageDescription"];
const bool hasWhenInUseUsage = !![infoDict objectForKey:@"NSLocationWhenInUseUsageDescription"];
- if (hasAlwaysUseUsage && hasWhenInUseUsage)
- [m_locationManager requestAlwaysAuthorization];
- else if (hasWhenInUseUsage)
+ if (hasAlwaysUseUsage && hasWhenInUseUsage) {
+ if (m_requestAlwaysPermission)
+ [m_locationManager requestAlwaysAuthorization];
+ else
+ [m_locationManager requestWhenInUseAuthorization];
+ } else if (hasWhenInUseUsage) {
+ qWarning("Requesting \"When In Use\" location permission in fallback mode. "
+ "Your application is missing the NSLocationAlwaysAndWhenInUseUsageDescription "
+ "entry in the Info.plist file. It will be impossible to publish the application "
+ "into App Store without this entry. Please add both "
+ "NSLocationWhenInUseUsageDescription and "
+ "NSLocationAlwaysAndWhenInUseUsageDescription to your Info.plist file.");
[m_locationManager requestWhenInUseAuthorization];
+ }
#endif // Q_OS_IOS
return (m_locationManager != nullptr);
diff --git a/src/plugins/position/corelocation/qgeopositioninfosource_cl_p.h b/src/plugins/position/corelocation/qgeopositioninfosource_cl_p.h
index f49951d5..7e9774be 100644
--- a/src/plugins/position/corelocation/qgeopositioninfosource_cl_p.h
+++ b/src/plugins/position/corelocation/qgeopositioninfosource_cl_p.h
@@ -26,7 +26,7 @@ class QGeoPositionInfoSourceCL : public QGeoPositionInfoSource
{
Q_OBJECT
public:
- QGeoPositionInfoSourceCL(QObject *parent = 0);
+ QGeoPositionInfoSourceCL(const QVariantMap &parameters, QObject *parent = 0);
~QGeoPositionInfoSourceCL();
QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override;
@@ -57,6 +57,7 @@ private:
Q_DISABLE_COPY(QGeoPositionInfoSourceCL);
CLLocationManager *m_locationManager;
bool m_updatesWanted;
+ bool m_requestAlwaysPermission = false;
QGeoPositionInfo m_lastUpdate;
diff --git a/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.mm b/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.mm
index 0979422c..49d2c977 100644
--- a/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.mm
+++ b/src/plugins/position/corelocation/qgeopositioninfosourcefactory_cl.mm
@@ -6,8 +6,7 @@
QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryCL::positionInfoSource(QObject *parent, const QVariantMap &parameters)
{
- Q_UNUSED(parameters)
- return new QGeoPositionInfoSourceCL(parent);
+ return new QGeoPositionInfoSourceCL(parameters, parent);
}
QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryCL::satelliteInfoSource(QObject *parent, const QVariantMap &parameters)
diff --git a/src/positioning/doc/src/plugins/corelocation.qdoc b/src/positioning/doc/src/plugins/corelocation.qdoc
new file mode 100644
index 00000000..32e44382
--- /dev/null
+++ b/src/positioning/doc/src/plugins/corelocation.qdoc
@@ -0,0 +1,93 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+\page position-plugin-corelocation.html
+\title Qt Positioning Core Location plugin
+\ingroup QtPositioning-plugins
+
+\brief Provides positioning information on Apple platforms
+
+\section1 Overview
+
+The plugin wraps iOS and macOS positioning subsystems. It is only available
+on Apple platforms that support corelocation. The plugin provides only
+positioning information.
+
+This plugin can be loaded by using the provider name \b corelocation.
+
+\section1 Parameters
+
+The following table lists parameters that \e can be passed to the corelocation
+plugin.
+
+\table
+\header
+ \li Parameter
+ \li Description
+\row
+ \li RequestAlwaysPermission
+ \li Ask permissions for using location not only while using the
+ application, but also in background. The parameter is a \c bool, so
+ it accepts either \c {true} or \c {false}. If the parameter is not
+ specified, it is considered to be \c {false}.
+\endtable
+
+On iOS, the application can ask for two levels of location permissions:
+
+\list
+ \li \b {When In Use} - makes location updates available only when someone
+ uses your app.
+ \li \b {Always} - makes location updates available at any time, and lets
+ the system launch your app quietly to handle some updates.
+\endlist
+
+By default, only the \b {When In Use} permission is requested.
+The \c RequestAlwaysPermission parameter is used to explicitly reqeust for
+\b {Always} permission.
+
+\section1 Position source usage example
+
+The following examples show how to create a \b corelocation PositionSource
+using different permission levels.
+
+\section2 QML
+
+\code
+// default - When In Use permission.
+PositionSource {
+ name: "corelocation"
+}
+
+// RequestAlwaysPermission = false. Same as default.
+PositionSource {
+ name: "corelocation"
+ PluginParameter { name: "RequestAlwaysPermission"; value: false }
+}
+
+// RequestAlwaysPermission = true. Request Always permission.
+PositionSource {
+ name: "corelocation"
+ PluginParameter { name: "RequestAlwaysPermission"; value: true }
+}
+\endcode
+
+\section2 C++
+
+\code
+// default - When In Use permission.
+QGeoPositionInfoSource *defaultSource
+ = QGeoPositionInfoSource::createSource("corelocation", this);
+
+// RequestAlwaysPermission = false. Same as default.
+params["RequestAlwaysPermission"] = false;
+QGeoPositionInfoSource *whenInUseSource
+ = QGeoPositionInfoSource::createSource("corelocation", params, this);
+
+// RequestAlwaysPermission = true. Request Always permission.
+params["RequestAlwaysPermission"] = true;
+QGeoPositionInfoSource *alwaysSource
+ = QGeoPositionInfoSource::createSource("corelocation", params, this);
+\endcode
+
+*/
diff --git a/src/positioning/doc/src/qtpositioning-plugins.qdoc b/src/positioning/doc/src/qtpositioning-plugins.qdoc
index f650e3c3..24c62afb 100644
--- a/src/positioning/doc/src/qtpositioning-plugins.qdoc
+++ b/src/positioning/doc/src/qtpositioning-plugins.qdoc
@@ -18,7 +18,9 @@ Some plugins already ship with Qt. These are:
\li Wraps Android positioning subsystem. Available only on Android.
\row
\li \b corelocation
- \li Wraps iOS and macOS positioning subsystems. Available only on Apple platforms supporting corelocation.
+ \li A \l {Qt Positioning Core Location plugin}{Core Location} backend
+ wraps iOS and macOS positioning subsystems. Available only on Apple
+ platforms supporting corelocation.
\row
\li \b geoclue2
\li A \l {Qt Positioning GeoClue v2 plugin}{GeoClue v2} backend that