From d2137e6cb58550d084aa1128a30a2df737379416 Mon Sep 17 00:00:00 2001 From: Juha Vuolle Date: Thu, 5 May 2022 11:42:06 +0300 Subject: Remove unsupported Android bluetooth codepaths Minimum Android level supported on Qt 6 is Android 6 / API Level 23. This commit removes older unsupported code in order to simplify. This concerns primarily: - sdkVersion() checks - Java reflections (API availability was uncertain) Task-number: QTBUG-102497 Change-Id: Ia90248a0a8f8e32130b8394998c2676c97a02eb5 Reviewed-by: Ivan Solovev Reviewed-by: Alex Blasche (cherry picked from commit bb419a4c608b94ff311e1609306f5f0fbc59d3cf) Reviewed-by: Qt Cherry-pick Bot --- examples/bluetooth/btchat/chat.cpp | 7 +- examples/bluetooth/pingpong/pingpong.cpp | 8 +- .../bluetooth/QtBluetoothBroadcastReceiver.java | 5 +- .../qt/android/bluetooth/QtBluetoothLE.java | 95 +++++----------- .../android/devicediscoverybroadcastreceiver.cpp | 12 +- .../android/servicediscoverybroadcastreceiver.cpp | 3 +- .../qbluetoothdevicediscoveryagent_android.cpp | 21 +--- src/bluetooth/qbluetoothlocaldevice_android.cpp | 5 +- .../qbluetoothservicediscoveryagent_android.cpp | 30 ----- src/bluetooth/qbluetoothsocket_android.cpp | 123 ++------------------- src/bluetooth/qbluetoothsocket_android_p.h | 1 - src/bluetooth/qlowenergycontroller_android.cpp | 17 --- tests/bttestui/btlocaldevice.cpp | 4 +- 13 files changed, 59 insertions(+), 272 deletions(-) diff --git a/examples/bluetooth/btchat/chat.cpp b/examples/bluetooth/btchat/chat.cpp index 7fb84ca0..51723813 100644 --- a/examples/bluetooth/btchat/chat.cpp +++ b/examples/bluetooth/btchat/chat.cpp @@ -200,10 +200,9 @@ void Chat::connectClicked() RemoteSelector remoteSelector(adapter); #ifdef Q_OS_ANDROID - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) - remoteSelector.startDiscovery(QBluetoothUuid(reverseUuid)); - else - remoteSelector.startDiscovery(QBluetoothUuid(serviceUuid)); + // QTBUG-61392 + Q_UNUSED(serviceUuid); + remoteSelector.startDiscovery(QBluetoothUuid(reverseUuid)); #else remoteSelector.startDiscovery(QBluetoothUuid(serviceUuid)); #endif diff --git a/examples/bluetooth/pingpong/pingpong.cpp b/examples/bluetooth/pingpong/pingpong.cpp index 8053fe4e..f3ee70a4 100644 --- a/examples/bluetooth/pingpong/pingpong.cpp +++ b/examples/bluetooth/pingpong/pingpong.cpp @@ -291,11 +291,9 @@ void PingPong::startClient() this, &PingPong::done); connect(discoveryAgent, &QBluetoothServiceDiscoveryAgent::errorOccurred, this, &PingPong::serviceScanError); -#ifdef Q_OS_ANDROID //see QTBUG-61392 - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) - discoveryAgent->setUuidFilter(QBluetoothUuid(androidUuid)); - else - discoveryAgent->setUuidFilter(QBluetoothUuid(serviceUuid)); +#ifdef Q_OS_ANDROID + // QTBUG-61392 + discoveryAgent->setUuidFilter(QBluetoothUuid(androidUuid)); #else discoveryAgent->setUuidFilter(QBluetoothUuid(serviceUuid)); #endif diff --git a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java index b709e8e5..c96e2b69 100644 --- a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java +++ b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java @@ -43,13 +43,15 @@ package org.qtproject.qt.android.bluetooth; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; -import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Field; import java.util.HashSet; import java.util.List; @@ -157,6 +159,7 @@ public class QtBluetoothBroadcastReceiver extends BroadcastReceiver static public boolean setPairingMode(String address, boolean isPairing) { BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + // Uses reflection as the removeBond() is not part of public API try { BluetoothDevice device = adapter.getRemoteDevice(address); String methodName = "createBond"; diff --git a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java index b4a41307..17611210 100644 --- a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java +++ b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java @@ -102,7 +102,6 @@ public class QtBluetoothLE { private final int RUNNABLE_TIMEOUT = 3000; // 3 seconds private final Handler timeoutHandler = new Handler(Looper.getMainLooper()); - /* New BTLE scanner setup since Android SDK v21 */ private BluetoothLeScanner mBluetoothLeScanner = null; private class TimeoutRunnable implements Runnable { @@ -223,18 +222,19 @@ public class QtBluetoothLE { return true; if (isEnabled) { - Log.d(TAG, "New BTLE scanning API"); + Log.d(TAG, "Attempting to start BTLE scan"); ScanSettings.Builder settingsBuilder = new ScanSettings.Builder(); settingsBuilder = settingsBuilder.setScanMode(ScanSettings.SCAN_MODE_BALANCED); ScanSettings settings = settingsBuilder.build(); List filterList = new ArrayList(); - mBluetoothLeScanner.startScan(filterList, settings, leScanCallback21); + mBluetoothLeScanner.startScan(filterList, settings, leScanCallback); mLeScanRunning = true; } else { + Log.d(TAG, "Attempting to stop BTLE scan"); try { - mBluetoothLeScanner.stopScan(leScanCallback21); + mBluetoothLeScanner.stopScan(leScanCallback); } catch (IllegalStateException isex) { // when trying to stop a scan while bluetooth is offline // java.lang.IllegalStateException: BT Adapter is not turned ON @@ -246,8 +246,7 @@ public class QtBluetoothLE { return (mLeScanRunning == isEnabled); } - // Device scan callback (SDK v21+) - private final ScanCallback leScanCallback21 = new ScanCallback() { + private final ScanCallback leScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); @@ -688,7 +687,7 @@ public class QtBluetoothLE { super.onDescriptorWrite(gatt, descriptor, status); handleOnDescriptorWrite(gatt, descriptor, status); } - //TODO Requires Android API 21 which is not available on CI yet. + //TODO currently not supported // public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt gatt, // int status) { // System.out.println("onReliableWriteCompleted"); @@ -699,7 +698,6 @@ public class QtBluetoothLE { // System.out.println("onReadRemoteRssi"); // } - // requires Android API v21 public void onMtuChanged(android.bluetooth.BluetoothGatt gatt, int mtu, int status) { super.onMtuChanged(gatt, mtu, status); @@ -763,7 +761,7 @@ public class QtBluetoothLE { if (mBluetoothGatt == null) { try { - //This API element is currently: greylist-max-o, reflection, allowed + //This API element is currently: greylist-max-o (API level 27), reflection, allowed //It may change in the future Class[] constr_args = new Class[5]; constr_args[0] = android.bluetooth.BluetoothGattService.class; @@ -781,34 +779,15 @@ public class QtBluetoothLE { Nevertheless we continue with best effort. */ } - try { - // BluetoothDevice.connectGatt(Context, boolean, BluetoothGattCallback, int) was - // officially introduced by Android API v23. Earlier Android versions have a - // private - // implementation already though. Let's check at runtime and use it if possible. - // - // In general the new connectGatt() seems to be much more reliable than the - // function - // that doesn't specify the transport layer. - - Class[] args = new Class[4]; - args[0] = android.content.Context.class; - args[1] = boolean.class; - args[2] = android.bluetooth.BluetoothGattCallback.class; - args[3] = int.class; - Method connectMethod = mRemoteGattDevice.getClass().getDeclaredMethod("connectGatt", args); - if (connectMethod != null) { - mBluetoothGatt = (BluetoothGatt) connectMethod.invoke(mRemoteGattDevice, qtContext, false, - gattCallback, 2 /* TRANSPORT_LE */); - Log.w(TAG, "Using Android v23 BluetoothDevice.connectGatt()"); - } - } catch (Exception ex) { - // fallback to less reliable API 18 version - mBluetoothGatt = mRemoteGattDevice.connectGatt(qtContext, false, gattCallback); + mBluetoothGatt = + mRemoteGattDevice.connectGatt(qtContext, false, + gattCallback, 2 /* TRANSPORT_LE */); + } catch (IllegalArgumentException ex) { + Log.w(TAG, "Gatt connection failed"); + ex.printStackTrace(); } } - return mBluetoothGatt != null; } @@ -1136,26 +1115,18 @@ public class QtBluetoothLE { handleDiscoveredService + 1, discoveredService.endHandle + 1); } - // Executes under "this" client mutex + // Executes under "this" client mutex. Returns true + // if no actual MTU exchange is initiated private boolean executeMtuExchange() { - if (Build.VERSION.SDK_INT >= 21) { - try { - Method mtuMethod = mBluetoothGatt.getClass().getDeclaredMethod("requestMtu", int.class); - if (mtuMethod != null) { - Boolean success = (Boolean) mtuMethod.invoke(mBluetoothGatt, MAX_MTU); - if (success.booleanValue()) { - Log.w(TAG, "MTU change initiated"); - return false; - } else { - Log.w(TAG, "MTU change request failed"); - } - } - } catch (Exception ex) {} + if (mBluetoothGatt.requestMtu(MAX_MTU)) { + Log.w(TAG, "MTU change initiated"); + return false; + } else { + Log.w(TAG, "MTU change request failed"); } - Log.w(TAG, "Assuming default MTU value of 23 bytes"); - + Log.w(TAG, "Assuming default MTU value of 23 bytes"); mSupportedMtu = DEFAULT_MTU; return true; } @@ -1723,22 +1694,16 @@ public class QtBluetoothLE { if (mBluetoothGatt == null) return false; - try { - //Android API v21 - Method connectionUpdateMethod = mBluetoothGatt.getClass().getDeclaredMethod( - "requestConnectionPriority", int.class); - if (connectionUpdateMethod == null) - return false; - - int requestPriority = 0; // BluetoothGatt.CONNECTION_PRIORITY_BALANCED - if (minimalInterval < 30) - requestPriority = 1; // BluetoothGatt.CONNECTION_PRIORITY_HIGH - else if (minimalInterval > 100) - requestPriority = 2; //BluetoothGatt/CONNECTION_PRIORITY_LOW_POWER + int requestPriority = 0; // BluetoothGatt.CONNECTION_PRIORITY_BALANCED + if (minimalInterval < 30) + requestPriority = 1; // BluetoothGatt.CONNECTION_PRIORITY_HIGH + else if (minimalInterval > 100) + requestPriority = 2; //BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER - Object result = connectionUpdateMethod.invoke(mBluetoothGatt, requestPriority); - return (Boolean) result; - } catch (Exception ex) { + try { + return mBluetoothGatt.requestConnectionPriority(requestPriority); + } catch (IllegalArgumentException ex) { + Log.w(TAG, "Connection update priority out of range: " + requestPriority); return false; } } diff --git a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp index 1fec7f81..caaabadf 100644 --- a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp +++ b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp @@ -595,14 +595,10 @@ QBluetoothDeviceInfo DeviceDiscoveryBroadcastReceiver::retrieveDeviceInfo(const env->ReleaseByteArrayElements(scanRecord, elems, JNI_ABORT); } - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 18) { - auto methodId = env.findMethod(bluetoothDevice.objectClass(), - "getType", - "()I"); - jint javaBtType = env->CallIntMethod(bluetoothDevice.object(), methodId); - if (!env.checkAndClearExceptions()) { - info.setCoreConfigurations(qtBtTypeForJavaBtType(javaBtType)); - } + auto methodId = env.findMethod(bluetoothDevice.objectClass(), "getType", "()I"); + jint javaBtType = env->CallIntMethod(bluetoothDevice.object(), methodId); + if (!env.checkAndClearExceptions()) { + info.setCoreConfigurations(qtBtTypeForJavaBtType(javaBtType)); } return info; diff --git a/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp b/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp index b1a6551e..a23de9d7 100644 --- a/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp +++ b/src/bluetooth/android/servicediscoverybroadcastreceiver.cpp @@ -51,8 +51,7 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID) ServiceDiscoveryBroadcastReceiver::ServiceDiscoveryBroadcastReceiver(QObject* parent): AndroidBroadcastReceiver(parent) { - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 15) - addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionUuid)); //API 15+ + addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionUuid)); } void ServiceDiscoveryBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobject intent) diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp index 6b6cfa20..f1569266 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp @@ -235,18 +235,6 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent if (requestedMethods & QBluetoothDeviceDiscoveryAgent::LowEnergyMethod) { // LE search only requested or classic discovery failed but lets try LE scan anyway Q_ASSERT(requestedMethods & QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); - - if (QNativeInterface::QAndroidApplication::sdkVersion() < 18) { - qCDebug(QT_BT_ANDROID) << "Skipping Bluetooth Low Energy device scan due to " - "insufficient Android version" - << QNativeInterface::QAndroidApplication::sdkVersion(); - m_active = NoScanActive; - lastError = QBluetoothDeviceDiscoveryAgent::UnsupportedDiscoveryMethod; - errorString = QBluetoothDeviceDiscoveryAgent::tr("Low Energy Discovery not supported"); - emit q->errorOccurred(lastError); - return; - } - startLowEnergyScan(); } } @@ -311,14 +299,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::processSdpDiscoveryFinished() return; } - // start LE scan if supported - if (QNativeInterface::QAndroidApplication::sdkVersion() < 18) { - qCDebug(QT_BT_ANDROID) << "Skipping Bluetooth Low Energy device scan"; - m_active = NoScanActive; - emit q->finished(); - } else { - startLowEnergyScan(); - } + startLowEnergyScan(); } } diff --git a/src/bluetooth/qbluetoothlocaldevice_android.cpp b/src/bluetooth/qbluetoothlocaldevice_android.cpp index 8c40ab62..4afae162 100644 --- a/src/bluetooth/qbluetoothlocaldevice_android.cpp +++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp @@ -379,9 +379,8 @@ void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pai return; } - // BluetoothDevice::createBond() requires Android API 15 - if (QNativeInterface::QAndroidApplication::sdkVersion() < 15 || !d_ptr->adapter()) { - qCWarning(QT_BT_ANDROID) << "Unable to pair: requires Android API 15+"; + if (!d_ptr->adapter()) { + qCWarning(QT_BT_ANDROID) << "Unable to pair, invalid adapter"; QMetaObject::invokeMethod(this, "errorOccurred", Qt::QueuedConnection, Q_ARG(QBluetoothLocalDevice::Error, QBluetoothLocalDevice::PairingError)); diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp index 48b09eff..5b9d1965 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp @@ -86,13 +86,6 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate( } } - if (QNativeInterface::QAndroidApplication::sdkVersion() < 15) - qCWarning(QT_BT_ANDROID) - << "SDP not supported by Android API below version 15. Detected version: " - << QNativeInterface::QAndroidApplication::sdkVersion() - << "Service discovery will return empty list."; - - /* We assume that the current local adapter has been passed. The logic below must change once there is more than one adapter. @@ -152,29 +145,6 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr return; } - /* SDP discovery was officially added by Android API v15 - * BluetoothDevice.getUuids() existed in earlier APIs already and in the future we may use - * reflection to support earlier Android versions than 15. Unfortunately - * BluetoothDevice.fetchUuidsWithSdp() and related APIs had some structure changes - * over time. Therefore we won't attempt this with reflection. - * - * TODO: Use reflection to support getUuuids() where possible. - * */ - if (QNativeInterface::QAndroidApplication::sdkVersion() < 15) { - qCWarning(QT_BT_ANDROID) << "Aborting SDP enquiry due to too low Android API version (requires v15+)"; - - error = QBluetoothServiceDiscoveryAgent::UnknownError; - errorString = QBluetoothServiceDiscoveryAgent::tr("Android API below v15 does not support SDP discovery"); - - //abort any outstanding discoveries - sdpCache.clear(); - discoveredDevices.clear(); - emit q->errorOccurred(error); - _q_serviceDiscoveryFinished(); - - return; - } - QJniObject inputString = QJniObject::fromString(address.toString()); QJniObject remoteDevice = btAdapter.callObjectMethod("getRemoteDevice", diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp index 40969e8b..36fddf2c 100644 --- a/src/bluetooth/qbluetoothsocket_android.cpp +++ b/src/bluetooth/qbluetoothsocket_android.cpp @@ -54,7 +54,6 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID) -#define FALLBACK_CHANNEL 1 #define USE_FALLBACK true Q_DECLARE_METATYPE(QJniObject) @@ -200,104 +199,9 @@ bool QBluetoothSocketPrivateAndroid::ensureNativeSocket(QBluetoothServiceInfo::P return false; } -bool QBluetoothSocketPrivateAndroid::fallBackConnect(QJniObject uuid, int channel) -{ - qCWarning(QT_BT_ANDROID) << "Falling back to getServiceChannel() workaround."; - - QJniEnvironment env; - - QJniObject remoteDeviceClass = remoteDevice.callObjectMethod("getClass", "()Ljava/lang/Class;"); - if (!remoteDeviceClass.isValid()) { - qCWarning(QT_BT_ANDROID) << "Could not invoke BluetoothDevice.getClass."; - return false; - } - - QJniObject integerObject = QJniObject::getStaticObjectField( - "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); - if (!integerObject.isValid()) { - qCWarning(QT_BT_ANDROID) << "Could not get Integer.TYPE"; - return false; - } - - jclass classClass = env.findClass("java/lang/Class"); - jobjectArray rawArray = env->NewObjectArray(1, classClass, - integerObject.object()); - QJniObject paramTypes(rawArray); - env->DeleteLocalRef(rawArray); - if (!paramTypes.isValid()) { - qCWarning(QT_BT_ANDROID) << "Could not create new Class[]{Integer.TYPE}"; - return false; - } - - QJniObject parcelUuid("android/os/ParcelUuid", "(Ljava/util/UUID;)V", - uuid.object()); - if (parcelUuid.isValid()) { - auto methodId = env.findMethod(remoteDevice.objectClass(), "getServiceChannel", - "(Landroid/os/ParcelUuid;)I"); - jint socketChannel = 0; - if (methodId) { - socketChannel = env->CallIntMethod(remoteDevice.object(), methodId, parcelUuid.object()); - if (!env.checkAndClearExceptions()) { - if (socketChannel - == remoteDevice.getStaticField("android/bluetooth/BluetoothDevice", "ERROR") - || socketChannel == -1) { - qCWarning(QT_BT_ANDROID) << "Cannot determine RFCOMM service channel."; - } else { - qCWarning(QT_BT_ANDROID) << "Using found rfcomm channel" << socketChannel; - channel = socketChannel; - } - } - } - } - QJniObject method; - if (secFlags == QBluetooth::SecurityFlags(QBluetooth::Security::NoSecurity)) { - qCDebug(QT_BT_ANDROID) << "Connnecting via insecure rfcomm"; - method = remoteDeviceClass.callObjectMethod( - "getMethod", - "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", - QJniObject::fromString(QLatin1String("createInsecureRfcommSocket")).object(), - paramTypes.object()); - } else { - qCDebug(QT_BT_ANDROID) << "Connnecting via secure rfcomm"; - method = remoteDeviceClass.callObjectMethod( - "getMethod", - "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", - QJniObject::fromString(QLatin1String("createRfcommSocket")).object(), - paramTypes.object()); - } - if (!method.isValid()) { - qCWarning(QT_BT_ANDROID) << "Could not invoke getMethod"; - return false; - } - - jclass objectClass = env.findClass("java/lang/Object"); - QJniObject channelObject = QJniObject::callStaticObjectMethod( - "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", channel); - rawArray = env->NewObjectArray(1, objectClass, channelObject.object()); - - QJniObject invokeResult = method.callObjectMethod("invoke", - "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", - remoteDevice.object(), rawArray); - env->DeleteLocalRef(rawArray); - if (!invokeResult.isValid()) - { - qCWarning(QT_BT_ANDROID) << "Invoke Resulted with error."; - return false; - } - - socketObject = QJniObject(invokeResult); - - WorkerThread *workerThread = new WorkerThread(); - workerThread->setupWorker(this, socketObject, uuid, USE_FALLBACK); - workerThread->start(); - emit connectJavaSocket(); - - qCWarning(QT_BT_ANDROID) << "Workaround thread invoked."; - return true; -} - /* - * Workaround for QTBUG-61392 + * Workaround for QTBUG-61392. If the underlying Android bug gets fixed, + * we need to consider restoring the non-reversed fallbackConnect from the repository. */ bool QBluetoothSocketPrivateAndroid::fallBackReversedConnect(const QBluetoothUuid &uuid) { @@ -353,14 +257,13 @@ bool QBluetoothSocketPrivateAndroid::fallBackReversedConnect(const QBluetoothUui * 3. if threaded connect succeeds call socketConnectSuccess() via signals * -> done * 4. if threaded connect fails call defaultSocketConnectFailed() via signals - * 5. call fallBackConnect() if Android version 22 or below - * -> Android 23+ complete failure of entire connectToServiceHelper() - * 6. call fallBackReversedConnect() if Android version 23 or above + * 5. call fallBackReversedConnect() * -> if failure entire connectToServiceHelper() fails - * 7. if threaded connect on one of above fallbacks succeeds call socketConnectSuccess() + * Note: This fallback can be disabled with private API boolean + * 6. if threaded connect on one of above fallbacks succeeds call socketConnectSuccess() * via signals * -> done - * 8. if threaded connect on fallback channel fails call fallbackSocketConnectFailed() + * 7. if threaded connect on fallback channel fails call fallbackSocketConnectFailed() * -> complete failure of entire connectToServiceHelper() * */ void QBluetoothSocketPrivateAndroid::connectToServiceHelper(const QBluetoothAddress &address, @@ -599,6 +502,7 @@ void QBluetoothSocketPrivateAndroid::defaultSocketConnectFailed( const QJniObject &socket, const QJniObject &targetUuid, const QBluetoothUuid &qtTargetUuid) { + Q_UNUSED(targetUuid); Q_Q(QBluetoothSocket); // test we didn't get a fail from a previous connect @@ -606,18 +510,12 @@ void QBluetoothSocketPrivateAndroid::defaultSocketConnectFailed( if (socket != socketObject) return; - bool success = false; - if (QNativeInterface::QAndroidApplication::sdkVersion() <= 22) - success = fallBackConnect(targetUuid, FALLBACK_CHANNEL); - else if (useReverseUuidWorkAroundConnect) // version 23+ has Android bug (see QTBUG-61392) - success = fallBackReversedConnect(qtTargetUuid); - - if (!success) { + if (!useReverseUuidWorkAroundConnect || !fallBackReversedConnect(qtTargetUuid)) { errorString = QBluetoothSocket::tr("Connection to service failed"); socketObject = remoteDevice = QJniObject(); q->setSocketError(QBluetoothSocket::SocketError::ServiceNotFoundError); q->setSocketState(QBluetoothSocket::SocketState::UnconnectedState); - qCWarning(QT_BT_ANDROID) << "Workaround failed"; + qCWarning(QT_BT_ANDROID) << "Socket connect workaround failed"; } } @@ -918,9 +816,6 @@ qint64 QBluetoothSocketPrivateAndroid::bytesToWrite() const */ QBluetoothUuid QBluetoothSocketPrivateAndroid::reverseUuid(const QBluetoothUuid &serviceUuid) { - if (QNativeInterface::QAndroidApplication::sdkVersion() < 23) - return serviceUuid; - if (serviceUuid.isNull()) return QBluetoothUuid(); diff --git a/src/bluetooth/qbluetoothsocket_android_p.h b/src/bluetooth/qbluetoothsocket_android_p.h index ca1c4864..e1dc9270 100644 --- a/src/bluetooth/qbluetoothsocket_android_p.h +++ b/src/bluetooth/qbluetoothsocket_android_p.h @@ -81,7 +81,6 @@ public: void connectToService(const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode) override; - bool fallBackConnect(QJniObject uuid, int channel); bool fallBackReversedConnect(const QBluetoothUuid &uuid); bool ensureNativeSocket(QBluetoothServiceInfo::Protocol type) override; diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp index 17bab6f3..4ba7a7ce 100644 --- a/src/bluetooth/qlowenergycontroller_android.cpp +++ b/src/bluetooth/qlowenergycontroller_android.cpp @@ -92,20 +92,10 @@ QLowEnergyControllerPrivateAndroid::~QLowEnergyControllerPrivateAndroid() void QLowEnergyControllerPrivateAndroid::init() { - // Android Central/Client support starts with v18 - // Peripheral/Server support requires Android API v21 const bool isPeripheral = (role == QLowEnergyController::PeripheralRole); - const jint version = QNativeInterface::QAndroidApplication::sdkVersion(); if (isPeripheral) { - if (version < 21) { - qWarning() << "Qt Bluetooth LE Peripheral support not available" - "on Android devices below version 21"; - return; - } - qRegisterMetaType(); - hub = new LowEnergyNotificationHub(remoteDevice, isPeripheral, this); // we only connect to the peripheral role specific signals // TODO add connections as they get added later on @@ -120,12 +110,6 @@ void QLowEnergyControllerPrivateAndroid::init() connect(hub, &LowEnergyNotificationHub::serverDescriptorWritten, this, &QLowEnergyControllerPrivateAndroid::serverDescriptorWritten); } else { - if (version < 18) { - qWarning() << "Qt Bluetooth LE Central/Client support not available" - "on Android devices below version 18"; - return; - } - hub = new LowEnergyNotificationHub(remoteDevice, isPeripheral, this); // we only connect to the central role specific signals connect(hub, &LowEnergyNotificationHub::connectionUpdated, @@ -1053,7 +1037,6 @@ void QLowEnergyControllerPrivateAndroid::stopAdvertising() void QLowEnergyControllerPrivateAndroid::requestConnectionUpdate(const QLowEnergyConnectionParameters ¶ms) { - // Possible since Android v21 // Android does not permit specification of specific latency or min/max // connection intervals (see BluetoothGatt.requestConnectionPriority() // In fact, each device manufacturer is permitted to change those values via a config diff --git a/tests/bttestui/btlocaldevice.cpp b/tests/bttestui/btlocaldevice.cpp index 2cb74e13..53634a78 100644 --- a/tests/bttestui/btlocaldevice.cpp +++ b/tests/bttestui/btlocaldevice.cpp @@ -315,8 +315,8 @@ void BtLocalDevice::serviceDiscovered(const QBluetoothServiceInfo &info) bool matchingService = (info.serviceUuid() == QBluetoothUuid(QString(TEST_SERVICE_UUID))); #ifdef Q_OS_ANDROID - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 23) //bug introduced by Android 6.0.1 - matchingService = matchingService + // QTBUG-61392 + matchingService = matchingService || (info.serviceUuid() == QBluetoothUuid(QString(TEST_REVERSE_SERVICE_UUID))); #endif -- cgit v1.2.3