diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-02-12 03:01:05 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-02-12 03:01:05 +0100 |
commit | 9d3b31bc306f75fa2a736261b7da3b83b697db04 (patch) | |
tree | 5ab630668577faa29a464d99299c1c890cba0aca /src | |
parent | 8af2bea29a4aec10d68f022520d4abca7320ebb1 (diff) | |
parent | a3ffef76acdd4ea4b81bde481948ed4b953289af (diff) |
Merge remote-tracking branch 'origin/5.13' into dev
Change-Id: I572be0994aa38a7f6fbfdd5e80738ee350c637d7
Diffstat (limited to 'src')
-rw-r--r-- | src/bluetooth/doc/src/bluetooth-index.qdoc | 2 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtcentralmanager.mm | 4 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtledeviceinquiry.mm | 87 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent.cpp | 5 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent_android.cpp | 42 | ||||
-rw-r--r-- | src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp | 16 | ||||
-rw-r--r-- | src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h | 10 | ||||
-rw-r--r-- | src/nfc/qnearfieldmanager.h | 2 |
8 files changed, 112 insertions, 56 deletions
diff --git a/src/bluetooth/doc/src/bluetooth-index.qdoc b/src/bluetooth/doc/src/bluetooth-index.qdoc index 2a4f72bc..a0e2a048 100644 --- a/src/bluetooth/doc/src/bluetooth-index.qdoc +++ b/src/bluetooth/doc/src/bluetooth-index.qdoc @@ -41,7 +41,7 @@ Currently, the API is supported on the following platforms: \li \l {Qt for Android}{Android} \li \l {Qt for iOS}{iOS} \li \l {Qt for Linux/X11}{Linux (BlueZ 4.x/5.x)} - \li \l {Qt for OS X}{macOS} + \li \l \macos \li \l {Qt for WinRT}{WinRT} \li \l {Qt for Windows}{Win32} \row diff --git a/src/bluetooth/osx/osxbtcentralmanager.mm b/src/bluetooth/osx/osxbtcentralmanager.mm index cadabbaf..41713909 100644 --- a/src/bluetooth/osx/osxbtcentralmanager.mm +++ b/src/bluetooth/osx/osxbtcentralmanager.mm @@ -1245,6 +1245,7 @@ QT_USE_NAMESPACE if (notifier) emit notifier->CBManagerError(QLowEnergyController::InvalidBluetoothAdapterError); } + [self stopWatchers]; return; } @@ -1266,6 +1267,7 @@ QT_USE_NAMESPACE if (notifier) emit notifier->CBManagerError(QLowEnergyController::InvalidBluetoothAdapterError); } + [self stopWatchers]; return; } @@ -1280,7 +1282,7 @@ QT_USE_NAMESPACE } } else { // We actually handled all known states, but .. Core Bluetooth can change? - Q_ASSERT_X(0, Q_FUNC_INFO, "invalid centra's state"); + Q_ASSERT_X(0, Q_FUNC_INFO, "invalid central's state"); } #pragma clang diagnostic pop diff --git a/src/bluetooth/osx/osxbtledeviceinquiry.mm b/src/bluetooth/osx/osxbtledeviceinquiry.mm index c56b6da3..70b96ab7 100644 --- a/src/bluetooth/osx/osxbtledeviceinquiry.mm +++ b/src/bluetooth/osx/osxbtledeviceinquiry.mm @@ -121,6 +121,11 @@ QT_END_NAMESPACE QT_USE_NAMESPACE +@interface QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry)(PrivateAPI) +- (void)stopScanSafe; +- (void)stopNotifier; +@end + @implementation QT_MANGLE_NAMESPACE(OSXBTLEDeviceInquiry) { LECBManagerNotifier *notifier; @@ -147,17 +152,10 @@ QT_USE_NAMESPACE - (void)dealloc { - if (manager) { - [manager setDelegate:nil]; - if (internalState == InquiryActive) - [manager stopScan]; - } - - if (notifier) { - notifier->disconnect(); - notifier->deleteLater(); - } - + [self stopScanSafe]; + [manager setDelegate:nil]; + [elapsedTimer cancelTimer]; + [self stopNotifier]; [super dealloc]; } @@ -166,7 +164,7 @@ QT_USE_NAMESPACE Q_UNUSED(sender) if (internalState == InquiryActive) { - [manager stopScan]; + [self stopScanSafe]; [manager setDelegate:nil]; internalState = InquiryFinished; Q_ASSERT(notifier); @@ -228,7 +226,7 @@ QT_USE_NAMESPACE } else if (state == CBCentralManagerStateUnsupported || state == CBCentralManagerStateUnauthorized) { #endif if (internalState == InquiryActive) { - [manager stopScan]; + [self stopScanSafe]; // Not sure how this is possible at all, // probably, can never happen. internalState = ErrorPoweredOff; @@ -244,8 +242,9 @@ QT_USE_NAMESPACE #else } else if (state == CBCentralManagerStatePoweredOff) { #endif + +#ifndef Q_OS_MACOS if (internalState == InquiryStarting) { -#ifndef Q_OS_OSX // On iOS a user can see at this point an alert asking to // enable Bluetooth in the "Settings" app. If a user does so, // we'll receive 'PoweredOn' state update later. @@ -254,17 +253,19 @@ QT_USE_NAMESPACE elapsedTimer.resetWithoutRetain([[GCDTimerObjC alloc] initWithDelegate:self]); [elapsedTimer startWithTimeout:powerOffTimeoutMS step:300]; return; + } #else Q_UNUSED(powerOffTimeoutMS) -#endif - internalState = ErrorPoweredOff; - emit notifier->CBManagerError(QBluetoothDeviceDiscoveryAgent::PoweredOffError); - } else { - [manager stopScan]; - emit notifier->CBManagerError(QBluetoothDeviceDiscoveryAgent::PoweredOffError); - } - +#endif // Q_OS_MACOS + [elapsedTimer cancelTimer]; + [self stopScanSafe]; [manager setDelegate:nil]; + internalState = ErrorPoweredOff; + // On macOS we report PoweredOffError and our C++ owner will delete us + // (here we're kwnon as 'self'). Connection is Qt::QueuedConnection so we + // are apparently safe to call -stopNotifier after the signal. + emit notifier->CBManagerError(QBluetoothDeviceDiscoveryAgent::PoweredOffError); + [self stopNotifier]; } else { // The following two states we ignore (from Apple's docs): //" @@ -281,19 +282,45 @@ QT_USE_NAMESPACE #pragma clang diagnostic pop } -- (void)stop +- (void)stopScanSafe { - if (internalState == InquiryActive) - [manager stopScan]; + // CoreBluetooth warns about API misused if we call stopScan in a state + // other than powered on. Hence this 'Safe' ... + if (!manager) + return; - [elapsedTimer cancelTimer]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + + if (internalState == InquiryActive) { + const auto state = manager.data().state; + #if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_10_0) || QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_13) + if (state == CBManagerStatePoweredOn) + #else + if (state == CBCentralManagerStatePoweredOn) + #endif + [manager stopScan]; + } + +#pragma clang diagnostic pop +} + +- (void)stopNotifier +{ + if (notifier) { + notifier->disconnect(); + notifier->deleteLater(); + notifier = nullptr; + } +} +- (void)stop +{ + [self stopScanSafe]; [manager setDelegate:nil]; + [elapsedTimer cancelTimer]; + [self stopNotifier]; internalState = InquiryCancelled; - - notifier->disconnect(); - notifier->deleteLater(); - notifier = nullptr; } - (void)centralManager:(CBCentralManager *)central diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.cpp b/src/bluetooth/qbluetoothservicediscoveryagent.cpp index a5fc7654..da9c1386 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent.cpp @@ -169,6 +169,11 @@ QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(QObject *parent \note On WinRT the passed adapter address will be ignored. + \note On Android passing any \a deviceAdapter address is meaningless as Android 6.0 or later does not publish + the local Bluetooth address anymore. Subsequently, the passed adapter address can never be matched + against the local adapter address. Therefore the subsequent call to \l start() will always trigger + \l InvalidBluetoothAdapterError. + \sa error() */ QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(const QBluetoothAddress &deviceAdapter, QObject *parent) diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp index ce2911d3..ddc53421 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp @@ -55,21 +55,33 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID) QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate( - QBluetoothServiceDiscoveryAgent *qp, const QBluetoothAddress &/*deviceAdapter*/) + QBluetoothServiceDiscoveryAgent *qp, const QBluetoothAddress &deviceAdapter) : error(QBluetoothServiceDiscoveryAgent::NoError), + m_deviceAdapterAddress(deviceAdapter), state(Inactive), mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery), singleDevice(false), q_ptr(qp) { - QList<QBluetoothHostInfo> devices = QBluetoothLocalDevice::allDevices(); - Q_ASSERT(devices.count() <= 1); //Android only supports one device at the moment - - if (devices.isEmpty()) { - error = QBluetoothServiceDiscoveryAgent::InvalidBluetoothAdapterError; - errorString = QBluetoothServiceDiscoveryAgent::tr("Invalid Bluetooth adapter address"); - return; + // If a specific adapter address is requested we need to check it matches + // the current local adapter. If it does not match we emit + // InvalidBluetoothAdapterError when calling start() + + bool createAdapter = true; + if (!deviceAdapter.isNull()) { + const QList<QBluetoothHostInfo> devices = QBluetoothLocalDevice::allDevices(); + if (devices.isEmpty()) { + createAdapter = false; + } else { + auto match = [deviceAdapter](const QBluetoothHostInfo& info) { + return info.address() == deviceAdapter; + }; + + auto result = std::find_if(devices.begin(), devices.end(), match); + if (result == devices.end()) + createAdapter = false; + } } if (QtAndroidPrivate::androidSdkVersion() < 15) @@ -84,7 +96,8 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate( The logic below must change once there is more than one adapter. */ - btAdapter = QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter", + if (createAdapter) + btAdapter = QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter", "getDefaultAdapter", "()Landroid/bluetooth/BluetoothAdapter;"); if (!btAdapter.isValid()) @@ -110,8 +123,15 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr Q_Q(QBluetoothServiceDiscoveryAgent); if (!btAdapter.isValid()) { - error = QBluetoothServiceDiscoveryAgent::UnknownError; - errorString = QBluetoothServiceDiscoveryAgent::tr("Platform does not support Bluetooth"); + if (m_deviceAdapterAddress.isNull()) { + error = QBluetoothServiceDiscoveryAgent::UnknownError; + errorString = QBluetoothServiceDiscoveryAgent::tr("Platform does not support Bluetooth"); + } else { + // specific adapter was requested which does not match the locally + // existing adapter + error = QBluetoothServiceDiscoveryAgent::InvalidBluetoothAdapterError; + errorString = QBluetoothServiceDiscoveryAgent::tr("Invalid Bluetooth adapter address"); + } //abort any outstanding discoveries discoveredDevices.clear(); diff --git a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp index 6b2f32f3..6213355e 100644 --- a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp +++ b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp @@ -165,14 +165,6 @@ QDeclarativeBluetoothDiscoveryModel::QDeclarativeBluetoothDiscoveryModel(QObject this, &QDeclarativeBluetoothDiscoveryModel::errorDiscovery); d->m_serviceAgent->setObjectName(QStringLiteral("ServiceDiscoveryAgent")); - - QHash<int, QByteArray> roleNames; - roleNames = QAbstractItemModel::roleNames(); - roleNames.insert(Name, "name"); - roleNames.insert(ServiceRole, "service"); - roleNames.insert(RemoteAddress, "remoteAddress"); - roleNames.insert(DeviceName, "deviceName"); - setRoleNames(roleNames); } QDeclarativeBluetoothDiscoveryModel::~QDeclarativeBluetoothDiscoveryModel() @@ -314,6 +306,14 @@ QVariant QDeclarativeBluetoothDiscoveryModel::data(const QModelIndex &index, int return QVariant(); } +QHash<int,QByteArray> QDeclarativeBluetoothDiscoveryModel::roleNames() const +{ + return {{Name, "name"}, + {ServiceRole, "service"}, + {RemoteAddress, "remoteAddress"}, + {DeviceName, "deviceName"}}; +} + /*! \qmlsignal BluetoothDiscoveryModel::serviceDiscovered(BluetoothService service) diff --git a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h index 0aa134f5..6cbde088 100644 --- a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h +++ b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel_p.h @@ -106,13 +106,15 @@ public: Error error() const; - void componentComplete(); + void componentComplete() override; - void classBegin() { } + void classBegin() override { } // From QAbstractListModel - int rowCount(const QModelIndex &parent) const; - QVariant data(const QModelIndex &index, int role) const; + int rowCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + + QHash<int,QByteArray> roleNames() const override; DiscoveryMode discoveryMode() const; void setDiscoveryMode(DiscoveryMode discovery); diff --git a/src/nfc/qnearfieldmanager.h b/src/nfc/qnearfieldmanager.h index 500b9631..22506e7e 100644 --- a/src/nfc/qnearfieldmanager.h +++ b/src/nfc/qnearfieldmanager.h @@ -99,7 +99,7 @@ public: bool unregisterNdefMessageHandler(int handlerId); Q_SIGNALS: - void adapterStateChanged(AdapterState state); + void adapterStateChanged(QNearFieldManager::AdapterState state); void targetDetected(QNearFieldTarget *target); void targetLost(QNearFieldTarget *target); |