summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qpermissions_android.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qpermissions_android.cpp')
-rw-r--r--src/corelib/kernel/qpermissions_android.cpp56
1 files changed, 50 insertions, 6 deletions
diff --git a/src/corelib/kernel/qpermissions_android.cpp b/src/corelib/kernel/qpermissions_android.cpp
index 25ae111bec..6c21ded72c 100644
--- a/src/corelib/kernel/qpermissions_android.cpp
+++ b/src/corelib/kernel/qpermissions_android.cpp
@@ -49,6 +49,34 @@ static QStringList nativeLocationPermission(const QLocationPermission &permissio
return nativeLocationPermissionList;
}
+static QStringList nativeBluetoothPermission(const QBluetoothPermission &permission)
+{
+ // See https://developer.android.com/guide/topics/connectivity/bluetooth/permissions
+ // for the details.
+
+ // API Level < 31
+ static QString bluetoothGeneral = u"android.permission.BLUETOOTH"_s;
+ // API Level >= 31
+ static QString bluetoothScan = u"android.permission.BLUETOOTH_SCAN"_s;
+ static QString bluetoothAdvertise = u"android.permission.BLUETOOTH_ADVERTISE"_s;
+ static QString bluetoothConnect = u"android.permission.BLUETOOTH_CONNECT"_s;
+ // Fine location is currently required for ALL API levels, but that is not
+ // strictly necessary for API Level >= 31. See QTBUG-112164.
+ static QString fineLocation = u"android.permission.ACCESS_FINE_LOCATION"_s;
+
+ if (QtAndroidPrivate::androidSdkVersion() < 31) {
+ return {bluetoothGeneral, fineLocation};
+ } else {
+ const auto modes = permission.communicationModes();
+ QStringList permissionList;
+ if (modes & QBluetoothPermission::Advertise)
+ permissionList << bluetoothAdvertise;
+ if (modes & QBluetoothPermission::Access)
+ permissionList << bluetoothScan << bluetoothConnect << fineLocation;
+ return permissionList;
+ }
+}
+
static QStringList nativeStringsFromPermission(const QPermission &permission)
{
const auto id = permission.type().id();
@@ -59,8 +87,7 @@ static QStringList nativeStringsFromPermission(const QPermission &permission)
} else if (id == qMetaTypeId<QMicrophonePermission>()) {
return { u"android.permission.RECORD_AUDIO"_s };
} else if (id == qMetaTypeId<QBluetoothPermission>()) {
- // TODO: handle Android 12 new bluetooth permissions
- return { u"android.permission.BLUETOOTH"_s };
+ return nativeBluetoothPermission(*permission.value<QBluetoothPermission>());
} else if (id == qMetaTypeId<QContactsPermission>()) {
const auto readContactsString = u"android.permission.READ_CONTACTS"_s;
switch (permission.value<QContactsPermission>()->accessMode()) {
@@ -104,6 +131,18 @@ Q_GLOBAL_STATIC_WITH_ARGS(PermissionStatusHash, g_permissionStatusHash, ({
{ qMetaTypeId<QLocationPermission>(), Qt::PermissionStatus::Undetermined }
}));
+static Qt::PermissionStatus
+getCombinedStatus(const QList<QtAndroidPrivate::PermissionResult> &androidResults)
+{
+ // Android returns only Denied or Granted
+ for (const auto &result : androidResults) {
+ const auto status = permissionStatusForAndroidResult(result);
+ if (status == Qt::PermissionStatus::Denied)
+ return status;
+ }
+ return Qt::PermissionStatus::Granted;
+}
+
namespace QPermissions::Private
{
Qt::PermissionStatus checkPermission(const QPermission &permission)
@@ -112,8 +151,12 @@ namespace QPermissions::Private
if (nativePermissionList.isEmpty())
return Qt::PermissionStatus::Granted;
- const auto result = QtAndroidPrivate::checkPermission(nativePermissionList.first()).result();
- const auto status = permissionStatusForAndroidResult(result);
+ QList<QtAndroidPrivate::PermissionResult> androidResults;
+ androidResults.reserve(nativePermissionList.size());
+ for (const auto &nativePermission : nativePermissionList)
+ androidResults.push_back(QtAndroidPrivate::checkPermission(nativePermission).result());
+
+ const auto status = getCombinedStatus(androidResults);
const auto it = g_permissionStatusHash->constFind(permission.type().id());
const bool foundStatus = (it != g_permissionStatusHash->constEnd());
const bool itUndetermined = foundStatus && (*it) == Qt::PermissionStatus::Undetermined;
@@ -133,8 +176,9 @@ namespace QPermissions::Private
QtAndroidPrivate::requestPermissions(nativePermissionList).then(qApp,
[callback, permission](QFuture<QtAndroidPrivate::PermissionResult> future) {
- const auto result = future.isValid() ? future.result() : QtAndroidPrivate::Denied;
- const auto status = permissionStatusForAndroidResult(result);
+ const auto androidResults = future.isValid() ? future.results()
+ : QList{QtAndroidPrivate::Denied};
+ const auto status = getCombinedStatus(androidResults);
g_permissionStatusHash->insert(permission.type().id(), status);
callback(status);
}