summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@insta.fi>2022-09-04 16:52:49 +0300
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-09-13 07:30:14 +0000
commit39d7bdbf4cde6c1d1353c9df1837bd746b4273cc (patch)
treefe8fd4b6f544090a32f1ece78a952c3a92c43f9b
parent4fa14358e99d5cb4bbe8989db1b6be1d3e565892 (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) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-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.cpp24
-rw-r--r--src/bluetooth/android/androidutils_p.h4
-rw-r--r--src/bluetooth/android/jni_android_p.h2
-rw-r--r--src/bluetooth/android/serveracceptancethread.cpp3
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp6
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_android.cpp19
-rw-r--r--src/bluetooth/qbluetoothserver_android.cpp3
-rw-r--r--src/bluetooth/qbluetoothservicediscoveryagent_android.cpp6
-rw-r--r--src/bluetooth/qbluetoothsocket_android.cpp4
13 files changed, 103 insertions, 44 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 c3795b2b..7b163efb 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
@@ -121,7 +121,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 8f0a0f09..9671f11a 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
@@ -11,6 +11,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;
@@ -39,7 +40,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;
@@ -163,14 +164,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;
}
@@ -185,6 +195,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();
@@ -682,6 +697,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 e8b4bd1f..f595dec0 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
@@ -43,7 +43,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;
@@ -249,16 +249,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 4c470a55..cc78c5d7 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
@@ -5,7 +5,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;
@@ -19,6 +21,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;
@@ -31,8 +35,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");
}
@@ -46,7 +51,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 b33275b2..7b7c9cc1 100644
--- a/src/bluetooth/android/androidutils.cpp
+++ b/src/bluetooth/android/androidutils.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "androidutils_p.h"
+#include "jni_android_p.h"
#include <QtCore/QLoggingCategory>
#include <QtCore/private/qandroidextras_p.h>
@@ -43,4 +44,27 @@ bool ensureAndroidPermission(BluetoothPermission permission)
return false;
}
+QJniObject getDefaultBluetoothAdapter()
+{
+ QJniObject service = QJniObject::getStaticField<QtJniTypes::AndroidContext, jstring>(
+ "BLUETOOTH_SERVICE");
+ QJniObject context = QNativeInterface::QAndroidApplication::context();
+ QJniObject manager =
+ context.callMethod<jobject>("getSystemService", service.object<jstring>());
+ QJniObject adapter;
+ if (manager.isValid())
+ adapter = manager.callMethod<QtJniTypes::BluetoothAdapter>("getAdapter");
+
+ // ### 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.callMethod<QtJniTypes::BluetoothAdapter>("getAdapter");
+
+ return adapter;
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/android/androidutils_p.h b/src/bluetooth/android/androidutils_p.h
index a28a0fd5..9912ad38 100644
--- a/src/bluetooth/android/androidutils_p.h
+++ b/src/bluetooth/android/androidutils_p.h
@@ -16,6 +16,7 @@
//
#include <qglobal.h>
+#include <QtCore/QJniObject>
#include <QtCore/QString>
QT_BEGIN_NAMESPACE
@@ -30,6 +31,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/jni_android_p.h b/src/bluetooth/android/jni_android_p.h
index d4da9075..e172f637 100644
--- a/src/bluetooth/android/jni_android_p.h
+++ b/src/bluetooth/android/jni_android_p.h
@@ -41,12 +41,14 @@ Q_DECLARE_JNI_CLASS(BluetoothGattDescriptor, "android/bluetooth/BluetoothGattDes
Q_DECLARE_JNI_CLASS(BluetoothGattCharacteristic, "android/bluetooth/BluetoothGattCharacteristic")
Q_DECLARE_JNI_CLASS(BluetoothDevice, "android/bluetooth/BluetoothDevice")
Q_DECLARE_JNI_CLASS(IntentFilter, "android/content/IntentFilter")
+Q_DECLARE_JNI_CLASS(AndroidContext, "android/content/Context")
Q_DECLARE_JNI_CLASS(UUID, "java/util/UUID")
Q_DECLARE_JNI_TYPE(ParcelableArray, "[Landroid/os/Parcelable;")
Q_DECLARE_JNI_TYPE(ParcelUuidArray, "[Landroid/os/ParcelUuid;")
Q_DECLARE_JNI_TYPE(StringArray, "[Ljava/lang/String;")
+Q_DECLARE_JNI_TYPE(BluetoothManager, "Landroid/bluetooth/BluetoothManager;")
Q_DECLARE_JNI_TYPE(AdvertiseData, "Landroid/bluetooth/le/AdvertiseData;")
Q_DECLARE_JNI_TYPE(AdvertiseSettings, "Landroid/bluetooth/le/AdvertiseSettings;")
Q_DECLARE_JNI_TYPE(InputStream, "Ljava/io/InputStream;")
diff --git a/src/bluetooth/android/serveracceptancethread.cpp b/src/bluetooth/android/serveracceptancethread.cpp
index e9dc06ed..c96fce89 100644
--- a/src/bluetooth/android/serveracceptancethread.cpp
+++ b/src/bluetooth/android/serveracceptancethread.cpp
@@ -73,7 +73,8 @@ void ServerAcceptanceThread::run()
shutdownPendingConnections();
}
- javaThread = QJniObject::construct<QtJniTypes::QtBtSocketServer>();
+ javaThread = QJniObject::construct<QtJniTypes::QtBtSocketServer>(
+ QNativeInterface::QAndroidApplication::context());
if (!javaThread.isValid())
return;
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
index 3981954c..cd6327f5 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
@@ -33,8 +33,7 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
deviceDiscoveryStartAttemptsLeft(deviceDiscoveryStartMaxAttempts),
q_ptr(parent)
{
- adapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
+ adapter = getDefaultBluetoothAdapter();
if (!adapter.isValid())
qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
@@ -419,7 +418,8 @@ void QBluetoothDeviceDiscoveryAgentPrivate::startLowEnergyScan()
m_active = BtleScanActive;
if (!leScanner.isValid()) {
- leScanner = QJniObject::construct<QtJniTypes::QtBtLECentral>();
+ leScanner = QJniObject::construct<QtJniTypes::QtBtLECentral>(
+ 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 f2415013..ca7faed0 100644
--- a/src/bluetooth/qbluetoothlocaldevice_android.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp
@@ -46,23 +46,10 @@ QJniObject *QBluetoothLocalDevicePrivate::adapter()
return obj;
}
-static QJniObject getDefaultAdapter()
-{
- QJniObject adapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
-
- if (!adapter.isValid()) {
- // on some BT implementations the first call to getDefaultAdapter() may fail
- adapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(),
- "getDefaultAdapter");
- }
- 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;
@@ -309,7 +296,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.callMethod<jstring>("getName").toString());
diff --git a/src/bluetooth/qbluetoothserver_android.cpp b/src/bluetooth/qbluetoothserver_android.cpp
index 221bf0f3..3449542b 100644
--- a/src/bluetooth/qbluetoothserver_android.cpp
+++ b/src/bluetooth/qbluetoothserver_android.cpp
@@ -132,8 +132,7 @@ bool QBluetoothServer::listen(const QBluetoothAddress &localAdapter, quint16 por
return false;
//check Bluetooth is available and online
- QJniObject btAdapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
+ QJniObject btAdapter = getDefaultBluetoothAdapter();
if (!btAdapter.isValid()) {
qCWarning(QT_BT_ANDROID) << "Device does not support Bluetooth";
diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
index e3fa662b..f160eb75 100644
--- a/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothservicediscoveryagent_android.cpp
@@ -58,10 +58,8 @@ QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(
The logic below must change once there is more than one adapter.
*/
- if (createAdapter) {
- btAdapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
- }
+ if (createAdapter)
+ 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 b1f90822..754f223d 100644
--- a/src/bluetooth/qbluetoothsocket_android.cpp
+++ b/src/bluetooth/qbluetoothsocket_android.cpp
@@ -143,9 +143,7 @@ QBluetoothSocketPrivateAndroid::QBluetoothSocketPrivateAndroid()
inputThread(0)
{
secFlags = QBluetooth::Security::Secure;
- adapter = QJniObject::callStaticMethod<QtJniTypes::BluetoothAdapter>(
- QtJniTypes::className<QtJniTypes::BluetoothAdapter>(), "getDefaultAdapter");
-
+ adapter = getDefaultBluetoothAdapter();
qRegisterMetaType<QBluetoothSocket::SocketError>();
qRegisterMetaType<QBluetoothSocket::SocketState>();
}