From 06d37147d1b59ca8cb5ce526a96b4ba59e44e0fa Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Wed, 5 Apr 2023 17:30:03 +0200 Subject: QtBluetooth: use public QPermission API to check for permissions on Android MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now when we have the fine-grained public QBluetoothPermission API, we can use it to check for permissions in the Android implementation. Adapt QtBluetooth examples to use only the minimal required set of permissions. As a drive-by: fix a couple of qCWarning() strings. Task-number: QTBUG-109964 Change-Id: I55c67bcae27926e76bf9c1a8a9367af2b58883ff Reviewed-by: Tor Arne Vestbø --- .../bluetooth/heartrate-game/connectionhandler.cpp | 1 + examples/bluetooth/heartrate-game/devicefinder.cpp | 1 + examples/bluetooth/lowenergyscanner/device.cpp | 6 ++-- src/bluetooth/android/androidutils.cpp | 32 ++++++---------------- src/bluetooth/android/androidutils_p.h | 13 ++------- .../qbluetoothdevicediscoveryagent_android.cpp | 22 ++++----------- src/bluetooth/qbluetoothlocaldevice_android.cpp | 11 ++++---- src/bluetooth/qbluetoothserver_android.cpp | 2 +- .../qbluetoothservicediscoveryagent_android.cpp | 2 +- src/bluetooth/qbluetoothserviceinfo_android.cpp | 2 +- src/bluetooth/qbluetoothsocket_android.cpp | 6 ++-- src/bluetooth/qlowenergycontroller.cpp | 2 +- src/bluetooth/qlowenergycontroller_android.cpp | 5 ++-- 13 files changed, 36 insertions(+), 69 deletions(-) diff --git a/examples/bluetooth/heartrate-game/connectionhandler.cpp b/examples/bluetooth/heartrate-game/connectionhandler.cpp index 0b86ed5f..1394b057 100644 --- a/examples/bluetooth/heartrate-game/connectionhandler.cpp +++ b/examples/bluetooth/heartrate-game/connectionhandler.cpp @@ -65,6 +65,7 @@ void ConnectionHandler::initLocalDevice() { #if QT_CONFIG(permissions) QBluetoothPermission permission{}; + permission.setCommunicationModes(QBluetoothPermission::Access); switch (qApp->checkPermission(permission)) { case Qt::PermissionStatus::Undetermined: qApp->requestPermission(permission, this, &ConnectionHandler::initLocalDevice); diff --git a/examples/bluetooth/heartrate-game/devicefinder.cpp b/examples/bluetooth/heartrate-game/devicefinder.cpp index cdaa83d4..a73f89c0 100644 --- a/examples/bluetooth/heartrate-game/devicefinder.cpp +++ b/examples/bluetooth/heartrate-game/devicefinder.cpp @@ -51,6 +51,7 @@ void DeviceFinder::startSearch() #if QT_CONFIG(permissions) //! [permissions] QBluetoothPermission permission{}; + permission.setCommunicationModes(QBluetoothPermission::Access); switch (qApp->checkPermission(permission)) { case Qt::PermissionStatus::Undetermined: qApp->requestPermission(permission, this, &DeviceFinder::startSearch); diff --git a/examples/bluetooth/lowenergyscanner/device.cpp b/examples/bluetooth/lowenergyscanner/device.cpp index a3c6e106..ae74d54c 100644 --- a/examples/bluetooth/lowenergyscanner/device.cpp +++ b/examples/bluetooth/lowenergyscanner/device.cpp @@ -50,9 +50,11 @@ void Device::startDeviceDiscovery() { #if QT_CONFIG(permissions) //! [les-bluetooth-permission] - const auto permissionStatus = qApp->checkPermission(QBluetoothPermission{}); + QBluetoothPermission permission; + permission.setCommunicationModes(QBluetoothPermission::Access); + const auto permissionStatus = qApp->checkPermission(permission); if (permissionStatus == Qt::PermissionStatus::Undetermined) { - qApp->requestPermission(QBluetoothPermission{}, this, &Device::startDeviceDiscovery); + qApp->requestPermission(permission, this, &Device::startDeviceDiscovery); return; } if (permissionStatus == Qt::PermissionStatus::Denied) { diff --git a/src/bluetooth/android/androidutils.cpp b/src/bluetooth/android/androidutils.cpp index 7c99bad3..22160ab7 100644 --- a/src/bluetooth/android/androidutils.cpp +++ b/src/bluetooth/android/androidutils.cpp @@ -4,40 +4,24 @@ #include "androidutils_p.h" #include "jni_android_p.h" -#include +#include +#include #include QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID) -static QString androidPermissionString(BluetoothPermission permission) +bool ensureAndroidPermission(QBluetoothPermission::CommunicationModes modes) { - switch (permission) { - case BluetoothPermission::Scan: - return {QStringLiteral("android.permission.BLUETOOTH_SCAN")}; - case BluetoothPermission::Advertise: - return {QStringLiteral("android.permission.BLUETOOTH_ADVERTISE")}; - case BluetoothPermission::Connect: - return {QStringLiteral("android.permission.BLUETOOTH_CONNECT")}; - } - return {}; -} - -bool ensureAndroidPermission(BluetoothPermission permission) -{ - // The current set of permissions are only applicable with 31+ - if (QNativeInterface::QAndroidApplication::sdkVersion() < 31) - return true; - - const auto permString = androidPermissionString(permission); + QBluetoothPermission permission; + permission.setCommunicationModes(modes); - // First check if we have the permission already - if (QtAndroidPrivate::checkPermission(permString).result() == QtAndroidPrivate::Authorized) + if (qApp->checkPermission(permission) == Qt::PermissionStatus::Granted) return true; - qCWarning(QT_BT_ANDROID) << "Permission not authorized:" << permString; - return false; + qCWarning(QT_BT_ANDROID) << "Permissions not authorized for a specified mode:" << modes; + return false; } QJniObject getDefaultBluetoothAdapter() diff --git a/src/bluetooth/android/androidutils_p.h b/src/bluetooth/android/androidutils_p.h index 9912ad38..5c83fc61 100644 --- a/src/bluetooth/android/androidutils_p.h +++ b/src/bluetooth/android/androidutils_p.h @@ -17,19 +17,12 @@ #include #include -#include +#include QT_BEGIN_NAMESPACE -enum class BluetoothPermission { - Scan, - Advertise, - Connect -}; - -// Checks if a permssion is already authorized and requests if not. -// Returns true if permission is successfully authorized -bool ensureAndroidPermission(BluetoothPermission permission); +// Checks if a permssion is already authorized or not +bool ensureAndroidPermission(QBluetoothPermission::CommunicationModes modes); // Returns the default bluetooth adapter, or an invalid object if not available QJniObject getDefaultBluetoothAdapter(); diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp index 54d0cdae..1971a945 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp @@ -133,18 +133,16 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent if (setErrorIfPowerOff()) return; - auto precisePermission = QStringLiteral("android.permission.ACCESS_FINE_LOCATION"); - auto preciseCheckRes = QtAndroidPrivate::checkPermission(precisePermission).result(); - if (preciseCheckRes != QtAndroidPrivate::Authorized) { - qCWarning(QT_BT_ANDROID) << - "Search not possible due to missing permission (ACCESS_FINE_LOCATION)"; + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { + qCWarning(QT_BT_ANDROID) + << "Search not possible due to missing QBluetoothPermission::Access permission"; errorString = QBluetoothDeviceDiscoveryAgent::tr( - "Missing Location permission. Search is not possible."); + "Failed to start device discovery due to missing permissions."); lastError = QBluetoothDeviceDiscoveryAgent::MissingPermissionsError; emit q->errorOccurred(lastError); return; } - qCDebug(QT_BT_ANDROID) << "ACCESS_FINE_LOCATION permission available"; + qCDebug(QT_BT_ANDROID) << "QBluetoothPermission::Access permission available"; // Double check Location service is turned on bool locationTurnedOn = true; // backwards compatible behavior to previous Qt versions @@ -182,16 +180,6 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent qCDebug(QT_BT_ANDROID) << "Location turned on"; - if (!(ensureAndroidPermission(BluetoothPermission::Scan) && - ensureAndroidPermission(BluetoothPermission::Connect))) { - qCWarning(QT_BT_ANDROID) << "Device discovery start() failed due to missing permissions"; - errorString = QBluetoothDeviceDiscoveryAgent::tr( - "Failed to start device discovery due to missing permissions."); - lastError = QBluetoothDeviceDiscoveryAgent::MissingPermissionsError; - emit q->errorOccurred(lastError); - return; - } - // install Java BroadcastReceiver if (!receiver) { // SDP based device discovery diff --git a/src/bluetooth/qbluetoothlocaldevice_android.cpp b/src/bluetooth/qbluetoothlocaldevice_android.cpp index ca7faed0..381f3c15 100644 --- a/src/bluetooth/qbluetoothlocaldevice_android.cpp +++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp @@ -55,8 +55,7 @@ void QBluetoothLocalDevicePrivate::initialize(const QBluetoothAddress &address) return; } - if (!(ensureAndroidPermission(BluetoothPermission::Scan) && - ensureAndroidPermission(BluetoothPermission::Connect))) { + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { qCWarning(QT_BT_ANDROID) << "Local device initialize() failed due to missing permissions"; return; } @@ -244,8 +243,8 @@ void QBluetoothLocalDevice::setHostMode(QBluetoothLocalDevice::HostMode requeste } case QBluetoothLocalDevice::HostDiscoverable: { - if (!ensureAndroidPermission(BluetoothPermission::Advertise)) { - qCWarning(QT_BT_ANDROID) << "Local device setHostMode() failed due to" + if (!ensureAndroidPermission(QBluetoothPermission::Advertise)) { + qCWarning(QT_BT_ANDROID) << "Local device setHostMode() failed due to " "missing permissions"; emit errorOccurred(QBluetoothLocalDevice::MissingPermissionsError); return; @@ -288,8 +287,8 @@ QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const QList QBluetoothLocalDevice::allDevices() { // As a static class function we need to ensure permissions here (in addition to initialize()) - if (!ensureAndroidPermission(BluetoothPermission::Connect)) { - qCWarning(QT_BT_ANDROID) << "Local device allDevices() failed due to" + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { + qCWarning(QT_BT_ANDROID) << "Local device allDevices() failed due to " "missing permissions"; return {}; } diff --git a/src/bluetooth/qbluetoothserver_android.cpp b/src/bluetooth/qbluetoothserver_android.cpp index 3449542b..df26daed 100644 --- a/src/bluetooth/qbluetoothserver_android.cpp +++ b/src/bluetooth/qbluetoothserver_android.cpp @@ -98,7 +98,7 @@ bool QBluetoothServer::listen(const QBluetoothAddress &localAdapter, quint16 por return false; } - if (!ensureAndroidPermission(BluetoothPermission::Connect)) { + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { qCWarning(QT_BT_ANDROID) << "Bluetooth server listen() failed due to missing permissions"; d->m_lastError = QBluetoothServer::MissingPermissionsError; emit errorOccurred(d->m_lastError); diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp index 8ac1abd0..952ba3dd 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp @@ -83,7 +83,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr { Q_Q(QBluetoothServiceDiscoveryAgent); - if (!ensureAndroidPermission(BluetoothPermission::Connect)) { + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { qCWarning(QT_BT_ANDROID) << "Service discovery start() failed due to missing permissions"; error = QBluetoothServiceDiscoveryAgent::MissingPermissionsError; errorString = QBluetoothServiceDiscoveryAgent::tr( diff --git a/src/bluetooth/qbluetoothserviceinfo_android.cpp b/src/bluetooth/qbluetoothserviceinfo_android.cpp index 11f76f9f..33ca7d52 100644 --- a/src/bluetooth/qbluetoothserviceinfo_android.cpp +++ b/src/bluetooth/qbluetoothserviceinfo_android.cpp @@ -55,7 +55,7 @@ bool QBluetoothServiceInfoPrivate::unregisterService() bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress& localAdapter) { - if (!ensureAndroidPermission(BluetoothPermission::Connect)) { + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { qCWarning(QT_BT_ANDROID) << "Serviceinfo registerService() failed due to" "missing permissions"; return false; diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp index a9eed7a4..619cf451 100644 --- a/src/bluetooth/qbluetoothsocket_android.cpp +++ b/src/bluetooth/qbluetoothsocket_android.cpp @@ -236,7 +236,7 @@ void QBluetoothSocketPrivateAndroid::connectToServiceHelper(const QBluetoothAddr qCDebug(QT_BT_ANDROID) << "connectToServiceHelper()" << address.toString() << uuid.toString(); - if (!ensureAndroidPermission(BluetoothPermission::Connect)) { + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { qCWarning(QT_BT_ANDROID) << "Bluetooth socket connect failed due to missing permissions"; errorString = QBluetoothSocket::tr( "Bluetooth socket connect failed due to missing permissions."); @@ -543,7 +543,7 @@ void QBluetoothSocketPrivateAndroid::abort() QString QBluetoothSocketPrivateAndroid::localName() const { - if (!ensureAndroidPermission(BluetoothPermission::Connect)) { + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { qCWarning(QT_BT_ANDROID) << "Bluetooth socket localName() failed due to" "missing permissions"; } else if (adapter.isValid()) { @@ -557,7 +557,7 @@ QBluetoothAddress QBluetoothSocketPrivateAndroid::localAddress() const { QString result; - if (!ensureAndroidPermission(BluetoothPermission::Connect)) { + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { qCWarning(QT_BT_ANDROID) << "Bluetooth socket localAddress() failed due to" "missing permissions"; } else if (adapter.isValid()) { diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp index 1cdf03bb..bfa8a832 100644 --- a/src/bluetooth/qlowenergycontroller.cpp +++ b/src/bluetooth/qlowenergycontroller.cpp @@ -840,7 +840,7 @@ QLowEnergyService *QLowEnergyController::addService(const QLowEnergyServiceData } #if defined(QT_ANDROID_BLUETOOTH) - if (!ensureAndroidPermission(BluetoothPermission::Connect)) { + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { qCWarning(QT_BT_ANDROID) << "addService() failed due to missing permissions"; return nullptr; } diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp index 70eb47d9..c9b93459 100644 --- a/src/bluetooth/qlowenergycontroller_android.cpp +++ b/src/bluetooth/qlowenergycontroller_android.cpp @@ -105,7 +105,7 @@ void QLowEnergyControllerPrivateAndroid::connectToDevice() return; } - if (!ensureAndroidPermission(BluetoothPermission::Connect)) { + if (!ensureAndroidPermission(QBluetoothPermission::Access)) { // This is unlikely to happen as a valid local adapter is a precondition setError(QLowEnergyController::MissingPermissionsError); qCWarning(QT_BT_ANDROID) << "connectToDevice() failed due to missing permissions"; @@ -971,8 +971,7 @@ void QLowEnergyControllerPrivateAndroid::startAdvertising(const QLowEnergyAdvert { setState(QLowEnergyController::AdvertisingState); - if (!(ensureAndroidPermission(BluetoothPermission::Advertise) && - ensureAndroidPermission(BluetoothPermission::Connect))) { + if (!ensureAndroidPermission(QBluetoothPermission::Access | QBluetoothPermission::Advertise)) { qCWarning(QT_BT_ANDROID) << "startAdvertising() failed due to missing permissions"; setError(QLowEnergyController::MissingPermissionsError); setState(QLowEnergyController::UnconnectedState); -- cgit v1.2.1