summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@insta.fi>2022-09-04 16:52:49 +0300
committerJuha Vuolle <juha.vuolle@insta.fi>2022-09-15 08:24:40 +0300
commit3875ca3ffea989257f59fefa1ee98a28d8e22547 (patch)
tree931c432ba09fe0daebb9c8d286578a09023dd731
parentcf3cf2e6140d8e80f65449d101ed16cc43510374 (diff)
Android BT fix deprecated "getDefaultAdapter" method usage
The currently used method has been deprecated in Android API 31, and it is strongly recommended not to use anymore. The replacing API has been introduced in API 18. Fixes: QTBUG-105487 Change-Id: I0d1972f600103bf33c7be1f8ba2ddf52a8d4255c Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io> (cherry picked from commit 8a01a353557454042bc9a27a1f38079e884fc807)
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothBroadcastReceiver.java10
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLE.java30
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java19
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java17
-rw-r--r--src/bluetooth/android/androidutils.cpp25
-rw-r--r--src/bluetooth/android/androidutils_p.h4
-rw-r--r--src/bluetooth/android/serveracceptancethread.cpp5
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp13
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_android.cpp20
-rw-r--r--src/bluetooth/qbluetoothserver_android.cpp6
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_android.cpp5
-rw-r--r--src/bluetooth/qbluetoothsocket_android.cpp4
12 files changed, 108 insertions, 50 deletions
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 cdc66fa7..2ced7c12 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
@@ -157,7 +157,15 @@ public class QtBluetoothBroadcastReceiver extends BroadcastReceiver
static public boolean setPairingMode(String address, boolean isPairing)
{
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothManager manager =
+ (BluetoothManager)qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
+ if (manager == null)
+ return false;
+
+ BluetoothAdapter adapter = manager.getAdapter();
+ if (adapter == null)
+ return false;
+
// Uses reflection as the removeBond() is not part of public API
try {
BluetoothDevice device = adapter.getRemoteDevice(address);
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 17611210..53f0feda 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
@@ -47,6 +47,7 @@ import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
@@ -75,7 +76,7 @@ import java.util.UUID;
public class QtBluetoothLE {
private static final String TAG = "QtBluetoothGatt";
- private final BluetoothAdapter mBluetoothAdapter;
+ private BluetoothAdapter mBluetoothAdapter = null;
private boolean mLeScanRunning = false;
private BluetoothGatt mBluetoothGatt = null;
@@ -199,14 +200,23 @@ public class QtBluetoothLE {
Context qtContext = null;
@SuppressWarnings("WeakerAccess")
- public QtBluetoothLE() {
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ public QtBluetoothLE(Context context) {
+ qtContext = context;
+
+ BluetoothManager manager =
+ (BluetoothManager)qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
+ if (manager == null)
+ return;
+
+ mBluetoothAdapter = manager.getAdapter();
+ if (mBluetoothAdapter == null)
+ return;
+
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
}
public QtBluetoothLE(final String remoteAddress, Context context) {
- this();
- qtContext = context;
+ this(context);
mRemoteGattAddress = remoteAddress;
}
@@ -221,6 +231,11 @@ public class QtBluetoothLE {
if (isEnabled == mLeScanRunning)
return true;
+ if (mBluetoothLeScanner == null) {
+ Log.w(TAG, "Cannot start LE scan, no bluetooth scanner");
+ return false;
+ }
+
if (isEnabled) {
Log.d(TAG, "Attempting to start BTLE scan");
ScanSettings.Builder settingsBuilder = new ScanSettings.Builder();
@@ -718,6 +733,11 @@ public class QtBluetoothLE {
public synchronized boolean connect() {
BluetoothDevice mRemoteGattDevice;
+ if (mBluetoothAdapter == null) {
+ Log.w(TAG, "Cannot connect, no bluetooth adapter");
+ return false;
+ }
+
try {
mRemoteGattDevice = mBluetoothAdapter.getRemoteDevice(mRemoteGattAddress);
} catch (IllegalArgumentException ex) {
diff --git a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java
index f3cc3041..1a358aa5 100644
--- a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java
+++ b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothLEServer.java
@@ -79,7 +79,7 @@ public class QtBluetoothLEServer {
private Context qtContext = null;
// Bluetooth members
- private final BluetoothAdapter mBluetoothAdapter;
+ private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothManager mBluetoothManager = null;
private BluetoothGattServer mGattServer = null;
private BluetoothLeAdvertiser mLeAdvertiser = null;
@@ -285,16 +285,21 @@ public class QtBluetoothLEServer {
public QtBluetoothLEServer(Context context)
{
qtContext = context;
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
-
- if (mBluetoothAdapter == null || qtContext == null) {
- Log.w(TAG, "Missing Bluetooth adapter or Qt context. Peripheral role disabled.");
+ if (qtContext == null) {
+ Log.w(TAG, "Missing context object. Peripheral role disabled.");
return;
}
- mBluetoothManager = (BluetoothManager) qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
+ mBluetoothManager =
+ (BluetoothManager) qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
- Log.w(TAG, "Bluetooth service not available.");
+ Log.w(TAG, "Bluetooth service not available. Peripheral role disabled.");
+ return;
+ }
+
+ mBluetoothAdapter = mBluetoothManager.getAdapter();
+ if (mBluetoothAdapter == null) {
+ Log.w(TAG, "Missing Bluetooth adapter. Peripheral role disabled.");
return;
}
diff --git a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java
index 34d8be77..f71a9f30 100644
--- a/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java
+++ b/src/android/bluetooth/src/org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer.java
@@ -41,7 +41,9 @@ package org.qtproject.qt.android.bluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothSocket;
+import android.content.Context;
import android.util.Log;
import java.io.IOException;
import java.util.UUID;
@@ -55,6 +57,8 @@ public class QtBluetoothSocketServer extends Thread
long qtObject = 0;
@SuppressWarnings({"WeakerAccess", "CanBeFinal"})
public boolean logEnabled = false;
+ @SuppressWarnings("WeakerAccess")
+ static Context qtContext = null;
private static final String TAG = "QtBluetooth";
private boolean m_isSecure = false;
@@ -67,8 +71,9 @@ public class QtBluetoothSocketServer extends Thread
private static final int QT_LISTEN_FAILED = 1;
private static final int QT_ACCEPT_FAILED = 2;
- public QtBluetoothSocketServer()
+ public QtBluetoothSocketServer(Context context)
{
+ qtContext = context;
setName("QtSocketServerThread");
}
@@ -82,7 +87,15 @@ public class QtBluetoothSocketServer extends Thread
public void run()
{
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothManager manager =
+ (BluetoothManager)qtContext.getSystemService(Context.BLUETOOTH_SERVICE);
+
+ if (manager == null) {
+ errorOccurred(qtObject, QT_NO_BLUETOOTH_SUPPORTED);
+ return;
+ }
+
+ BluetoothAdapter adapter = manager.getAdapter();
if (adapter == null) {
errorOccurred(qtObject, QT_NO_BLUETOOTH_SUPPORTED);
return;
diff --git a/src/bluetooth/android/androidutils.cpp b/src/bluetooth/android/androidutils.cpp
index 369bb93c..f8a2d8e2 100644
--- a/src/bluetooth/android/androidutils.cpp
+++ b/src/bluetooth/android/androidutils.cpp
@@ -79,4 +79,29 @@ bool ensureAndroidPermission(BluetoothPermission permission)
return false;
}
+QJniObject getDefaultBluetoothAdapter()
+{
+ QJniObject service = QJniObject::getStaticObjectField("android/content/Context",
+ "BLUETOOTH_SERVICE",
+ "Ljava/lang/String;");
+ QJniObject context = QNativeInterface::QAndroidApplication::context();
+ QJniObject manager = context.callObjectMethod("getSystemService",
+ "(Ljava/lang/String;)Ljava/lang/Object;",
+ service.object());
+ QJniObject adapter;
+ if (manager.isValid())
+ adapter = manager.callObjectMethod("getAdapter", "()Landroid/bluetooth/BluetoothAdapter;");
+
+ // ### Qt 7 check if the below double-get of the adapter can be removed.
+ // It is a workaround for QTBUG-57489, fixed in 2016. According to the bug it occurred on
+ // a certain device running Android 6.0.1 (Qt 6 supports Android 6.0 as the minimum).
+ // For completeness: the original workaround was for the deprecated getDefaultAdapter()
+ // method, and it is thus unclear if this is needed even in Qt 6 anymore. In addition the
+ // impacted device is updateable to Android 8 which may also have fixed the issue.
+ if (!adapter.isValid())
+ adapter = manager.callObjectMethod("getAdapter", "()Landroid/bluetooth/BluetoothAdapter;");
+
+ return adapter;
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/android/androidutils_p.h b/src/bluetooth/android/androidutils_p.h
index 1efb4c2b..c45426a3 100644
--- a/src/bluetooth/android/androidutils_p.h
+++ b/src/bluetooth/android/androidutils_p.h
@@ -52,6 +52,7 @@
//
#include <qglobal.h>
+#include <QtCore/QJniObject>
#include <QtCore/QString>
QT_BEGIN_NAMESPACE
@@ -66,6 +67,9 @@ enum class BluetoothPermission {
// Returns true if permission is successfully authorized
bool ensureAndroidPermission(BluetoothPermission permission);
+// Returns the default bluetooth adapter, or an invalid object if not available
+QJniObject getDefaultBluetoothAdapter();
+
QT_END_NAMESPACE
#endif // QANDROIDBLUETOOTHUTILS_H
diff --git a/src/bluetooth/android/serveracceptancethread.cpp b/src/bluetooth/android/serveracceptancethread.cpp
index 9c6876c0..0ebaf840 100644
--- a/src/bluetooth/android/serveracceptancethread.cpp
+++ b/src/bluetooth/android/serveracceptancethread.cpp
@@ -39,6 +39,7 @@
#include <QtCore/QLoggingCategory>
#include <QtCore/QJniEnvironment>
+#include <QtCore/QCoreApplication>
#include "android/serveracceptancethread_p.h"
@@ -108,7 +109,9 @@ void ServerAcceptanceThread::run()
shutdownPendingConnections();
}
- javaThread = QJniObject("org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer");
+ javaThread = QJniObject("org/qtproject/qt/android/bluetooth/QtBluetoothSocketServer",
+ "(Landroid/content/Context;)V",
+ QNativeInterface::QAndroidApplication::context());
if (!javaThread.isValid())
return;
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
index 2fda5be3..a79fea79 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
@@ -68,13 +68,10 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
deviceDiscoveryStartAttemptsLeft(deviceDiscoveryStartMaxAttempts),
q_ptr(parent)
{
- QJniEnvironment env;
- adapter = QJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter",
- "getDefaultAdapter",
- "()Landroid/bluetooth/BluetoothAdapter;");
- if (!adapter.isValid()) {
+ adapter = getDefaultBluetoothAdapter();
+
+ if (!adapter.isValid())
qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
- }
}
QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate()
@@ -454,7 +451,9 @@ void QBluetoothDeviceDiscoveryAgentPrivate::startLowEnergyScan()
m_active = BtleScanActive;
if (!leScanner.isValid()) {
- leScanner = QJniObject("org/qtproject/qt/android/bluetooth/QtBluetoothLE");
+ leScanner = QJniObject("org/qtproject/qt/android/bluetooth/QtBluetoothLE",
+ "(Landroid/content/Context;)V",
+ QNativeInterface::QAndroidApplication::context());
if (!leScanner.isValid()) {
qCWarning(QT_BT_ANDROID) << "Cannot load BTLE device scan class";
m_active = NoScanActive;
diff --git a/src/bluetooth/qbluetoothlocaldevice_android.cpp b/src/bluetooth/qbluetoothlocaldevice_android.cpp
index 4afae162..e9148ec1 100644
--- a/src/bluetooth/qbluetoothlocaldevice_android.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp
@@ -81,24 +81,10 @@ QJniObject *QBluetoothLocalDevicePrivate::adapter()
return obj;
}
-static QJniObject getDefaultAdapter()
-{
- QJniObject adapter = QJniObject::callStaticObjectMethod(
- "android/bluetooth/BluetoothAdapter", "getDefaultAdapter",
- "()Landroid/bluetooth/BluetoothAdapter;");
- if (!adapter.isValid()) {
-
- // workaround stupid bt implementations where first call of BluetoothAdapter.getDefaultAdapter() always fails
- adapter = QJniObject::callStaticObjectMethod(
- "android/bluetooth/BluetoothAdapter", "getDefaultAdapter",
- "()Landroid/bluetooth/BluetoothAdapter;");
- }
- return adapter;
-}
-
void QBluetoothLocalDevicePrivate::initialize(const QBluetoothAddress &address)
{
- QJniObject adapter = getDefaultAdapter();
+ QJniObject adapter = getDefaultBluetoothAdapter();
+
if (!adapter.isValid()) {
qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
return;
@@ -347,7 +333,7 @@ QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices()
// Android only supports max of one device (so far)
QList<QBluetoothHostInfo> localDevices;
- QJniObject o = getDefaultAdapter();
+ QJniObject o = getDefaultBluetoothAdapter();
if (o.isValid()) {
QBluetoothHostInfo info;
info.setName(o.callObjectMethod("getName", "()Ljava/lang/String;").toString());
diff --git a/src/bluetooth/qbluetoothserver_android.cpp b/src/bluetooth/qbluetoothserver_android.cpp
index 5089d3ce..5bc88e8c 100644
--- a/src/bluetooth/qbluetoothserver_android.cpp
+++ b/src/bluetooth/qbluetoothserver_android.cpp
@@ -167,10 +167,8 @@ bool QBluetoothServer::listen(const QBluetoothAddress &localAdapter, quint16 por
return false;
//check Bluetooth is available and online
- QJniObject btAdapter = QJniObject::callStaticObjectMethod(
- "android/bluetooth/BluetoothAdapter",
- "getDefaultAdapter",
- "()Landroid/bluetooth/BluetoothAdapter;");
+ QJniObject btAdapter = getDefaultBluetoothAdapter();
+
if (!btAdapter.isValid()) {
qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
d->m_lastError = QBluetoothServer::UnknownError;
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
index a0635cd9..90e75667 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
@@ -94,9 +94,8 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
*/
if (createAdapter)
- btAdapter = QJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter",
- "getDefaultAdapter",
- "()Landroid/bluetooth/BluetoothAdapter;");
+ btAdapter = getDefaultBluetoothAdapter();
+
if (!btAdapter.isValid())
qCWarning(QT_BT_ANDROID) << "Platform does not support Bluetooth";
diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp
index 36fddf2c..a23a7be5 100644
--- a/src/bluetooth/qbluetoothsocket_android.cpp
+++ b/src/bluetooth/qbluetoothsocket_android.cpp
@@ -177,9 +177,7 @@ QBluetoothSocketPrivateAndroid::QBluetoothSocketPrivateAndroid()
inputThread(0)
{
secFlags = QBluetooth::Security::Secure;
- adapter = QJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter",
- "getDefaultAdapter",
- "()Landroid/bluetooth/BluetoothAdapter;");
+ adapter = getDefaultBluetoothAdapter();
qRegisterMetaType<QBluetoothSocket::SocketError>();
qRegisterMetaType<QBluetoothSocket::SocketState>();
}