From 7477dec2d46655fbb2bc42f29bb7405ef4425bc3 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Thu, 30 Mar 2023 18:01:05 +0200 Subject: [PATCH] QBluetoothPermission: support new Android permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Teach QBluetoothPermission to understand new fine-grained Bluetooth permissions, which were introduced for Android 12. Also request the ACCESS_FINE_LOCATION permission together with Bluetooth permissions, because it is required for Bluetooth to work properly. At this point QBluetoothPermission simply requests all Bluetooth permissions, because we do not (yet) have a public API to distinguish between them. Task-number: QTBUG-109964 Change-Id: I98d304eb59c238656d6a92917f611c3b3ba9e760 Reviewed-by: Tor Arne Vestbø Reviewed-by: Juha Vuolle --- src/corelib/kernel/qpermissions.cpp | 21 +++++++++++++++++- src/corelib/kernel/qpermissions_android.cpp | 24 +++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qpermissions.cpp b/src/corelib/kernel/qpermissions.cpp index 588ad0b132b..35c72900de8 100644 --- a/src/corelib/kernel/qpermissions.cpp +++ b/src/corelib/kernel/qpermissions.cpp @@ -358,9 +358,28 @@ QT_PERMISSION_IMPL_COMMON(QMicrophonePermission) \row \li Android \li \l{android-uses-permission}{\c{uses-permission}} - \li \c android.permission.BLUETOOTH + \li Up to Android 11 (API Level < 31): + \list + \li \c android.permission.BLUETOOTH + \li \c android.permission.ACCESS_FINE_LOCATION + \endlist + + Starting from Android 12 (API Level >= 31): + \list + \li \c android.permission.BLUETOOTH_ADVERTISE + \li \c android.permission.BLUETOOTH_CONNECT + \li \c android.permission.BLUETOOTH_SCAN + \li \c android.permission.ACCESS_FINE_LOCATION + \endlist \include permissions.qdocinc end-usage-declarations + \note Currently on Android the \c android.permission.ACCESS_FINE_LOCATION + permission is requested together with Bluetooth permissions. This is + required for Bluetooth to work properly, unless the application provides a + strong assertion in the application manifest that it does not use Bluetooth + to derive a physical location. This permission coupling may change in + future. + \include permissions.qdocinc permission-metadata */ diff --git a/src/corelib/kernel/qpermissions_android.cpp b/src/corelib/kernel/qpermissions_android.cpp index 25ae111bec9..1def982f29c 100644 --- a/src/corelib/kernel/qpermissions_android.cpp +++ b/src/corelib/kernel/qpermissions_android.cpp @@ -49,6 +49,27 @@ static QStringList nativeLocationPermission(const QLocationPermission &permissio return nativeLocationPermissionList; } +static QStringList nativeBluetoothPermission() +{ + // 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 + return {bluetoothScan, bluetoothAdvertise, bluetoothConnect, fineLocation}; +} + static QStringList nativeStringsFromPermission(const QPermission &permission) { const auto id = permission.type().id(); @@ -59,8 +80,7 @@ static QStringList nativeStringsFromPermission(const QPermission &permission) } else if (id == qMetaTypeId()) { return { u"android.permission.RECORD_AUDIO"_s }; } else if (id == qMetaTypeId()) { - // TODO: handle Android 12 new bluetooth permissions - return { u"android.permission.BLUETOOTH"_s }; + return nativeBluetoothPermission(); } else if (id == qMetaTypeId()) { const auto readContactsString = u"android.permission.READ_CONTACTS"_s; switch (permission.value()->accessMode()) {