summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@insta.fi>2022-05-05 11:42:06 +0300
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-05-12 06:28:56 +0000
commitd2137e6cb58550d084aa1128a30a2df737379416 (patch)
tree8605440680315060361f5f8ef41c4e05c76ea1aa
parentc5948259dd02ecf6640ac7bda7c092585538ec01 (diff)
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 <ivan.solovev@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io> (cherry picked from commit bb419a4c608b94ff311e1609306f5f0fbc59d3cf) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--examples/bluetooth/btchat/chat.cpp7
-rw-r--r--examples/bluetooth/pingpong/pingpong.cpp8
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java5
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java95
-rw-r--r--src/bluetooth/android/devicediscoverybroadcastreceiver.cpp12
-rw-r--r--src/bluetooth/android/servicediscoverybroadcastreceiver.cpp3
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp21
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_android.cpp5
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_android.cpp30
-rw-r--r--src/bluetooth/qbluetoothsocket_android.cpp123
-rw-r--r--src/bluetooth/qbluetoothsocket_android_p.h1
-rw-r--r--src/bluetooth/qlowenergycontroller_android.cpp17
-rw-r--r--tests/bttestui/btlocaldevice.cpp4
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<ScanFilter> filterList = new ArrayList<ScanFilter>();
- 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<jobject>());
- 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<jint>("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<jstring>(),
- paramTypes.object<jobjectArray>());
- } 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<jstring>(),
- paramTypes.object<jobjectArray>());
- }
- 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<jobject>());
-
- QJniObject invokeResult = method.callObjectMethod("invoke",
- "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;",
- remoteDevice.object<jobject>(), 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<QJniObject>();
-
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 &params)
{
- // 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