iOS: Update bluetooth permission handling to the new QPermission system
This commit is contained in:
parent
0f8c2a879e
commit
238e86c930
@ -77,16 +77,6 @@ void JsonRpcClient::registerNotificationHandler(QObject *handler, const QString
|
|||||||
m_notificationHandlers.insert(nameSpace, handler);
|
m_notificationHandlers.insert(nameSpace, handler);
|
||||||
m_notificationHandlerMethods.insert(handler, method);
|
m_notificationHandlerMethods.insert(handler, method);
|
||||||
|
|
||||||
// Clean up if the handler gets destroyed so we don't dereference dangling pointers when
|
|
||||||
// processing notifications.
|
|
||||||
connect(handler, &QObject::destroyed, this, [this](QObject *obj){
|
|
||||||
for (const QString &ns : m_notificationHandlers.keys(obj)) {
|
|
||||||
m_notificationHandlers.remove(ns, obj);
|
|
||||||
}
|
|
||||||
m_notificationHandlerMethods.remove(obj);
|
|
||||||
setNotificationsEnabled();
|
|
||||||
});
|
|
||||||
|
|
||||||
setNotificationsEnabled();
|
setNotificationsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,8 @@
|
|||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QBluetoothLocalDevice>
|
#include <QBluetoothLocalDevice>
|
||||||
#include <QBluetoothUuid>
|
#include <QBluetoothUuid>
|
||||||
|
#include <QBluetoothPermission>
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(dcBluetoothDiscovery);
|
Q_DECLARE_LOGGING_CATEGORY(dcBluetoothDiscovery);
|
||||||
@ -64,8 +66,6 @@ BluetoothDiscovery::BluetoothDiscovery(QObject *parent) :
|
|||||||
#else
|
#else
|
||||||
// Note: on iOS there is no QBluetoothLocalDevice available, therefore we have to assume there is one and
|
// Note: on iOS there is no QBluetoothLocalDevice available, therefore we have to assume there is one and
|
||||||
// start the discovery agent with the default constructor.
|
// start the discovery agent with the default constructor.
|
||||||
// https://bugreports.qt.io/browse/QTBUG-65547
|
|
||||||
|
|
||||||
m_bluetoothAvailable = true;
|
m_bluetoothAvailable = true;
|
||||||
|
|
||||||
// Always start with assuming BT is enabled
|
// Always start with assuming BT is enabled
|
||||||
@ -88,13 +88,16 @@ bool BluetoothDiscovery::bluetoothEnabled() const
|
|||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
return m_bluetoothAvailable && m_bluetoothEnabled;
|
return m_bluetoothAvailable && m_bluetoothEnabled;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qCDebug(dcBluetoothDiscovery) << "bluetoothEnabled(): m_bluetoothAvailable:" << m_bluetoothAvailable;
|
qCDebug(dcBluetoothDiscovery) << "bluetoothEnabled(): m_bluetoothAvailable:" << m_bluetoothAvailable;
|
||||||
return m_bluetoothAvailable && m_localDevice->hostMode() != QBluetoothLocalDevice::HostPoweredOff;
|
return m_bluetoothAvailable && m_localDevice->hostMode() != QBluetoothLocalDevice::HostPoweredOff;
|
||||||
}
|
}
|
||||||
void BluetoothDiscovery::setBluetoothEnabled(bool bluetoothEnabled) {
|
|
||||||
if (!m_bluetoothAvailable) {
|
void BluetoothDiscovery::setBluetoothEnabled(bool bluetoothEnabled)
|
||||||
|
{
|
||||||
|
if (!m_bluetoothAvailable)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (bluetoothEnabled) {
|
if (bluetoothEnabled) {
|
||||||
if (m_localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) {
|
if (m_localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) {
|
||||||
m_localDevice->powerOn();
|
m_localDevice->powerOn();
|
||||||
@ -151,26 +154,30 @@ void BluetoothDiscovery::onBluetoothHostModeChanged(const QBluetoothLocalDevice:
|
|||||||
#endif
|
#endif
|
||||||
emit bluetoothEnabledChanged(false);
|
emit bluetoothEnabledChanged(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Note: discovery works in all other modes
|
// Note: discovery works in all other modes
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
m_bluetoothEnabled = true;
|
m_bluetoothEnabled = true;
|
||||||
#endif
|
#endif
|
||||||
emit bluetoothEnabledChanged(hostMode != QBluetoothLocalDevice::HostPoweredOff);
|
emit bluetoothEnabledChanged(hostMode != QBluetoothLocalDevice::HostPoweredOff);
|
||||||
|
|
||||||
if (!m_discoveryAgent) {
|
if (!m_discoveryAgent) {
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(m_localDevice->address(), this);
|
m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(m_localDevice->address(), this);
|
||||||
#else
|
#else
|
||||||
m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
|
m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
|
||||||
#endif
|
#endif
|
||||||
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothDiscovery::deviceDiscovered);
|
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceUpdated, this, &BluetoothDiscovery::deviceDiscovered);
|
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceUpdated, this, &BluetoothDiscovery::deviceDiscovered);
|
||||||
#elif (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0))
|
#endif
|
||||||
|
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0))
|
||||||
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::errorOccurred, this, &BluetoothDiscovery::onError);
|
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::errorOccurred, this, &BluetoothDiscovery::onError);
|
||||||
#else
|
#else
|
||||||
connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(onError(QBluetoothDeviceDiscoveryAgent::Error)));
|
connect(m_discoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), this, SLOT(onError(QBluetoothDeviceDiscoveryAgent::Error)));
|
||||||
#endif
|
#endif
|
||||||
|
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothDiscovery::deviceDiscovered);
|
||||||
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothDiscovery::discoveryFinished);
|
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothDiscovery::discoveryFinished);
|
||||||
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &BluetoothDiscovery::discoveryCancelled);
|
connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &BluetoothDiscovery::discoveryCancelled);
|
||||||
}
|
}
|
||||||
@ -241,13 +248,11 @@ void BluetoothDiscovery::onError(const QBluetoothDeviceDiscoveryAgent::Error &er
|
|||||||
|
|
||||||
void BluetoothDiscovery::start()
|
void BluetoothDiscovery::start()
|
||||||
{
|
{
|
||||||
if (!m_discoveryAgent || !bluetoothEnabled()) {
|
if (!m_discoveryAgent || !bluetoothEnabled())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (m_discoveryAgent->isActive()) {
|
if (m_discoveryAgent->isActive())
|
||||||
m_discoveryAgent->stop();
|
m_discoveryAgent->stop();
|
||||||
}
|
|
||||||
|
|
||||||
foreach (const QBluetoothDeviceInfo &info, m_discoveryAgent->discoveredDevices()) {
|
foreach (const QBluetoothDeviceInfo &info, m_discoveryAgent->discoveredDevices()) {
|
||||||
qCDebug(dcBluetoothDiscovery()) << "Already discovered device:" << info.name();
|
qCDebug(dcBluetoothDiscovery()) << "Already discovered device:" << info.name();
|
||||||
@ -255,7 +260,9 @@ void BluetoothDiscovery::start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(dcBluetoothDiscovery) << "Starting discovery.";
|
qCDebug(dcBluetoothDiscovery) << "Starting discovery.";
|
||||||
m_discoveryAgent->start();
|
|
||||||
|
// Since we are only interested in low energy results, this speed up the result significantly
|
||||||
|
m_discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
|
||||||
emit discoveringChanged();
|
emit discoveringChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -179,15 +179,16 @@ ios: {
|
|||||||
-framework CoreBluetooth \
|
-framework CoreBluetooth \
|
||||||
-framework CoreNFC
|
-framework CoreNFC
|
||||||
|
|
||||||
|
|
||||||
# Add Firebase SDK
|
# Add Firebase SDK
|
||||||
QMAKE_LFLAGS += -ObjC $(inherited)
|
QMAKE_LFLAGS += -ObjC $(inherited)
|
||||||
DEFINES += FIREBASE_ANALYTICS_SUPPRESS_WARNING
|
DEFINES += FIREBASE_ANALYTICS_SUPPRESS_WARNING
|
||||||
firebase_files.files += $$files($${IOS_PACKAGE_DIR}/GoogleService-Info.plist)
|
firebase_files.files += $$files($${IOS_PACKAGE_DIR}/GoogleService-Info.plist)
|
||||||
QMAKE_BUNDLE_DATA += firebase_files
|
QMAKE_BUNDLE_DATA += firebase_files
|
||||||
INCLUDEPATH += ../3rdParty/ios/
|
INCLUDEPATH += ../3rdParty/ios/
|
||||||
|
|
||||||
LIBS += -F$$PWD/../3rdParty/ios/Firebase/FirebaseAnalytics/ \
|
LIBS += -F$$PWD/../3rdParty/ios/Firebase/FirebaseAnalytics/ \
|
||||||
-F$$PWD/../3rdParty/ios/Firebase/FirebaseMessaging
|
-F$$PWD/../3rdParty/ios/Firebase/FirebaseMessaging
|
||||||
|
|
||||||
LIBS += -framework "FirebaseMessaging" \
|
LIBS += -framework "FirebaseMessaging" \
|
||||||
-framework "GoogleUtilities" \
|
-framework "GoogleUtilities" \
|
||||||
-framework "Protobuf" \
|
-framework "Protobuf" \
|
||||||
@ -196,13 +197,13 @@ ios: {
|
|||||||
-framework "FirebaseInstallations" \
|
-framework "FirebaseInstallations" \
|
||||||
-framework "PromisesObjC" \
|
-framework "PromisesObjC" \
|
||||||
|
|
||||||
|
|
||||||
LIBS += -L$$top_builddir/libnymea-app -lnymea-app \
|
LIBS += -L$$top_builddir/libnymea-app -lnymea-app \
|
||||||
-L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning \
|
-L$$top_builddir/experiences/airconditioning -lnymea-app-airconditioning \
|
||||||
|
-L$$top_builddir/experiences/evdash -lnymea-app-evdash
|
||||||
|
|
||||||
PRE_TARGETDEPS += $$top_builddir/libnymea-app/libnymea-app.a \
|
PRE_TARGETDEPS += $$top_builddir/libnymea-app/libnymea-app.a \
|
||||||
$$top_builddir/experiences/airconditioning/libnymea-app-airconditioning.a
|
$$top_builddir/experiences/airconditioning/libnymea-app-airconditioning.a \
|
||||||
|
$$top_builddir/experiences/evdash/libnymea-app-evdash.a
|
||||||
|
|
||||||
# Configure generated xcode project to have our bundle id
|
# Configure generated xcode project to have our bundle id
|
||||||
QMAKE_TARGET_BUNDLE_PREFIX=$${IOS_BUNDLE_PREFIX}
|
QMAKE_TARGET_BUNDLE_PREFIX=$${IOS_BUNDLE_PREFIX}
|
||||||
@ -220,6 +221,9 @@ ios: {
|
|||||||
ios_launch_images.files += $${IOS_PACKAGE_DIR}/NymeaLaunchScreen.storyboard
|
ios_launch_images.files += $${IOS_PACKAGE_DIR}/NymeaLaunchScreen.storyboard
|
||||||
QMAKE_BUNDLE_DATA += ios_launch_images
|
QMAKE_BUNDLE_DATA += ios_launch_images
|
||||||
|
|
||||||
|
DEFINES += QT_STATICPLUGIN
|
||||||
|
QTPLUGIN += qdarwinbluetoothpermission
|
||||||
|
|
||||||
IOS_DEVELOPMENT_TEAM.name = DEVELOPMENT_TEAM
|
IOS_DEVELOPMENT_TEAM.name = DEVELOPMENT_TEAM
|
||||||
IOS_DEVELOPMENT_TEAM.value = $$IOS_TEAM_ID
|
IOS_DEVELOPMENT_TEAM.value = $$IOS_TEAM_ID
|
||||||
QMAKE_MAC_XCODE_SETTINGS += IOS_DEVELOPMENT_TEAM
|
QMAKE_MAC_XCODE_SETTINGS += IOS_DEVELOPMENT_TEAM
|
||||||
|
|||||||
@ -26,6 +26,11 @@
|
|||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QPermission>
|
||||||
|
#include <QBluetoothPermission>
|
||||||
|
|
||||||
|
#include "logging.h"
|
||||||
|
NYMEA_LOGGING_CATEGORY(dcPlatformPermissions, "PlatformPermissions")
|
||||||
|
|
||||||
PlatformPermissionsIOS *PlatformPermissionsIOS::s_instance = nullptr;
|
PlatformPermissionsIOS *PlatformPermissionsIOS::s_instance = nullptr;
|
||||||
|
|
||||||
@ -65,9 +70,9 @@ PlatformPermissions::PermissionStatus PlatformPermissionsIOS::checkPermission(Pe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlatformPermissionsIOS::requestPermission(Permission permission)
|
void PlatformPermissionsIOS::requestPermission(Permission platformPermission)
|
||||||
{
|
{
|
||||||
switch (permission) {
|
switch (platformPermission) {
|
||||||
case PermissionNone:
|
case PermissionNone:
|
||||||
break;
|
break;
|
||||||
case PermissionLocalNetwork:
|
case PermissionLocalNetwork:
|
||||||
|
|||||||
@ -32,9 +32,11 @@
|
|||||||
#if __OBJC__
|
#if __OBJC__
|
||||||
@class CLLocationManager;
|
@class CLLocationManager;
|
||||||
@class CBCentralManager;
|
@class CBCentralManager;
|
||||||
|
@class BluetoothManagerDelegate;
|
||||||
#else
|
#else
|
||||||
typedef void CLLocationManager;
|
typedef void CLLocationManager;
|
||||||
typedef void CBCentralManager;
|
typedef void CBCentralManager;
|
||||||
|
typedef void BluetoothManagerDelegate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class PlatformPermissionsIOS : public PlatformPermissions
|
class PlatformPermissionsIOS : public PlatformPermissions
|
||||||
@ -44,8 +46,8 @@ public:
|
|||||||
explicit PlatformPermissionsIOS(QObject *parent = nullptr);
|
explicit PlatformPermissionsIOS(QObject *parent = nullptr);
|
||||||
static PlatformPermissionsIOS *instance();
|
static PlatformPermissionsIOS *instance();
|
||||||
|
|
||||||
PermissionStatus checkPermission(Permission permission) const override;
|
PermissionStatus checkPermission(Permission ) const override;
|
||||||
void requestPermission(Permission permission) override;
|
void requestPermission(Permission platformPermission) override;
|
||||||
void openPermissionSettings() override;
|
void openPermissionSettings() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -62,14 +64,15 @@ private:
|
|||||||
void requestLocalNetworkPermission();
|
void requestLocalNetworkPermission();
|
||||||
void requestNotificationPermission();
|
void requestNotificationPermission();
|
||||||
void requestBluetoothPermission();
|
void requestBluetoothPermission();
|
||||||
|
void requestBluetoothPermissionLegacy();
|
||||||
void requestLocationPermission();
|
void requestLocationPermission();
|
||||||
void requestBackgroundLocationPermission();
|
void requestBackgroundLocationPermission();
|
||||||
|
|
||||||
PermissionStatus m_notificationPermissions = PermissionStatusNotDetermined;
|
PermissionStatus m_notificationPermissions = PermissionStatusNotDetermined;
|
||||||
|
|
||||||
|
|
||||||
CLLocationManager *m_locationManager = nullptr;
|
CLLocationManager *m_locationManager = nullptr;
|
||||||
CBCentralManager *m_bluetoothManager = nullptr;
|
CBCentralManager *m_bluetoothManager = nullptr;
|
||||||
|
BluetoothManagerDelegate *m_bluetoothDelegate = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PLATFORMPERMISSIONSIOS_H
|
#endif // PLATFORMPERMISSIONSIOS_H
|
||||||
|
|||||||
@ -1,11 +1,25 @@
|
|||||||
#include "platformpermissionsios.h"
|
#include "platformpermissionsios.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QBluetoothPermission>
|
||||||
|
#include <QPermission>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QtPlugin>
|
||||||
|
|
||||||
#import <UserNotifications/UNUserNotificationCenter.h>
|
#import <UserNotifications/UNUserNotificationCenter.h>
|
||||||
#import <UserNotifications/UNNotificationSettings.h>
|
#import <UserNotifications/UNNotificationSettings.h>
|
||||||
#import <CoreLocation/CoreLocation.h>
|
#import <CoreLocation/CoreLocation.h>
|
||||||
#import <CoreBluetooth/CoreBluetooth.h>
|
#import <CoreBluetooth/CoreBluetooth.h>
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#include "logging.h"
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(dcPlatformPermissions)
|
||||||
|
|
||||||
|
#ifdef QT_STATICPLUGIN
|
||||||
|
Q_IMPORT_PLUGIN(QDarwinBluetoothPermissionPlugin)
|
||||||
|
#endif
|
||||||
|
|
||||||
@interface LocationManagerPermissionDelegate : NSObject <CLLocationManagerDelegate>
|
@interface LocationManagerPermissionDelegate : NSObject <CLLocationManagerDelegate>
|
||||||
@end
|
@end
|
||||||
@implementation LocationManagerPermissionDelegate
|
@implementation LocationManagerPermissionDelegate
|
||||||
@ -69,28 +83,112 @@ void PlatformPermissionsIOS::requestNotificationPermission()
|
|||||||
|
|
||||||
PlatformPermissions::PermissionStatus PlatformPermissionsIOS::checkBluetoothPermission() const
|
PlatformPermissions::PermissionStatus PlatformPermissionsIOS::checkBluetoothPermission() const
|
||||||
{
|
{
|
||||||
// iOS 13.0 would have an api but it's more complicated and also deprecated... Ignoring...
|
qCDebug(dcPlatformPermissions()) << "Checking bluetooth permission...";
|
||||||
|
QBluetoothPermission btPermission;
|
||||||
|
btPermission.setCommunicationModes(QBluetoothPermission::Access);
|
||||||
|
const auto qtStatus = qGuiApp->checkPermission(btPermission);
|
||||||
|
if (qtStatus == Qt::PermissionStatus::Granted) {
|
||||||
|
qCDebug(dcPlatformPermissions()) << "Bluetooth permisson granted (Qt plugin)";
|
||||||
|
return PermissionStatusGranted;
|
||||||
|
} else {
|
||||||
|
qCDebug(dcPlatformPermissions()) << "Bluetooth permisson NOT granted (Qt plugin)";
|
||||||
|
}
|
||||||
|
|
||||||
|
PermissionStatus fallbackStatus = PermissionStatusGranted;
|
||||||
if (@available(iOS 13.1, *)) {
|
if (@available(iOS 13.1, *)) {
|
||||||
switch (CBCentralManager.authorization) {
|
switch (CBCentralManager.authorization) {
|
||||||
case CBManagerAuthorizationAllowedAlways:
|
case CBManagerAuthorizationAllowedAlways:
|
||||||
|
fallbackStatus = PermissionStatusGranted;
|
||||||
|
break;
|
||||||
case CBManagerAuthorizationRestricted:
|
case CBManagerAuthorizationRestricted:
|
||||||
return PermissionStatusGranted;
|
fallbackStatus = PermissionStatusGranted;
|
||||||
|
break;
|
||||||
case CBManagerAuthorizationDenied:
|
case CBManagerAuthorizationDenied:
|
||||||
return PermissionStatusDenied;
|
fallbackStatus = PermissionStatusDenied;
|
||||||
|
break;
|
||||||
case CBManagerAuthorizationNotDetermined:
|
case CBManagerAuthorizationNotDetermined:
|
||||||
return PermissionStatusNotDetermined;
|
fallbackStatus = PermissionStatusNotDetermined;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Before iOS 13, Bluetooth permissions are not required
|
// Before iOS 13, Bluetooth permissions are not required
|
||||||
return PermissionStatusGranted;
|
fallbackStatus = PermissionStatusGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (qtStatus) {
|
||||||
|
case Qt::PermissionStatus::Denied:
|
||||||
|
qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied by Qt plugin, fallback reports" << fallbackStatus;
|
||||||
|
break;
|
||||||
|
case Qt::PermissionStatus::Undetermined:
|
||||||
|
qCWarning(dcPlatformPermissions()) << "QBluetoothPermission status Undetermined...using fallback.";
|
||||||
|
break;
|
||||||
|
case Qt::PermissionStatus::Granted:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallbackStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlatformPermissionsIOS::requestBluetoothPermission()
|
void PlatformPermissionsIOS::requestBluetoothPermission()
|
||||||
{
|
{
|
||||||
// Instantiating a Bluetooth manager just trigger the popup...
|
qCDebug(dcPlatformPermissions()) << "Requesting bluetooth permission...";
|
||||||
|
auto handlePermissionResult = [](const QPermission &permission) {
|
||||||
|
switch (permission.status()) {
|
||||||
|
case Qt::PermissionStatus::Granted:
|
||||||
|
qCDebug(dcPlatformPermissions()) << "Bluetooth permission granted.";
|
||||||
|
emit s_instance->bluetoothPermissionChanged();
|
||||||
|
return;
|
||||||
|
case Qt::PermissionStatus::Denied:
|
||||||
|
if (s_instance->checkBluetoothPermission() == PermissionStatusNotDetermined) {
|
||||||
|
qCWarning(dcPlatformPermissions()) << "Bluetooth permission plugin unavailable, falling back to CoreBluetooth request.";
|
||||||
|
s_instance->requestBluetoothPermissionLegacy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qCWarning(dcPlatformPermissions()) << "Bluetooth permission denied.";
|
||||||
|
emit s_instance->bluetoothPermissionChanged();
|
||||||
|
return;
|
||||||
|
case Qt::PermissionStatus::Undetermined:
|
||||||
|
qCWarning(dcPlatformPermissions()) << "Bluetooth permission plugin unavailable, falling back to CoreBluetooth request.";
|
||||||
|
s_instance->requestBluetoothPermissionLegacy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QBluetoothPermission btPermission;
|
||||||
|
btPermission.setCommunicationModes(QBluetoothPermission::Access);
|
||||||
|
|
||||||
|
if (qApp->checkPermission(btPermission) == Qt::PermissionStatus::Undetermined) {
|
||||||
|
auto permissionHandled = QSharedPointer<bool>::create(false);
|
||||||
|
|
||||||
|
qApp->requestPermission(btPermission, [handlePermissionResult, permissionHandled](const QPermission &permission) {
|
||||||
|
*permissionHandled = true;
|
||||||
|
handlePermissionResult(permission);
|
||||||
|
});
|
||||||
|
|
||||||
|
// The Qt permission plugin might be missing from certain builds. If we still don't have
|
||||||
|
// a decision after giving it a moment, fall back to the CoreBluetooth prompt.
|
||||||
|
QTimer::singleShot(2000, this, [this, permissionHandled]() {
|
||||||
|
if (*permissionHandled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (checkBluetoothPermission() == PermissionStatusNotDetermined) {
|
||||||
|
qCWarning(dcPlatformPermissions()) << "Bluetooth permission plugin unavailable, falling back to CoreBluetooth request.";
|
||||||
|
requestBluetoothPermissionLegacy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePermissionResult(btPermission);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlatformPermissionsIOS::requestBluetoothPermissionLegacy()
|
||||||
|
{
|
||||||
|
qCDebug(dcPlatformPermissions()) << "Requesting bluetooth permission legacy...";
|
||||||
|
// Instantiating a Bluetooth manager triggers the native dialog on first use.
|
||||||
if (!m_bluetoothManager) {
|
if (!m_bluetoothManager) {
|
||||||
BluetoothManagerDelegate *delegate = [[BluetoothManagerDelegate alloc] init];
|
m_bluetoothDelegate = [[BluetoothManagerDelegate alloc] init];
|
||||||
m_bluetoothManager = [[CBCentralManager alloc] initWithDelegate:delegate queue:nil];
|
m_bluetoothManager = [[CBCentralManager alloc] initWithDelegate:m_bluetoothDelegate queue:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,14 @@
|
|||||||
<string>_jsonrpc._tcp</string>
|
<string>_jsonrpc._tcp</string>
|
||||||
<string>_ws._tcp</string>
|
<string>_ws._tcp</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<!-- Fallback: allow all loads, including self-signed LAN TLS. -->
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSAllowsLocalNetworking</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>XSAppIconAssets</key>
|
<key>XSAppIconAssets</key>
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
1.11.1
|
1.11.1
|
||||||
687
|
689
|
||||||
|
|||||||
Reference in New Issue
Block a user