diff options
author | Alex Blasche <alexander.blasche@qt.io> | 2018-09-25 10:57:07 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2018-09-26 06:21:28 +0000 |
commit | f8c0572ddcd0cf152cfcf9f1d5478e520a6a457e (patch) | |
tree | beba4ce3fcf1aeece7b8be0fca2bda9637bcaa04 | |
parent | 7b40de8fbbaed22ca6217b5acc8dad1db6ae0600 (diff) |
Properly handle pin code pairing on Android
Most likely this paring variant was forgotten when Android support
for QBluetoothLocalDevice was implemented. This variant is rather uncommon
and Android's default pairing handler are likely to automatically
handle such requests too.
Fixes: QTBUG-70295
Change-Id: I618242da415574245e5a213a6e34f190c685c8e9
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
-rw-r--r-- | src/bluetooth/android/localdevicebroadcastreceiver.cpp | 41 | ||||
-rw-r--r-- | src/bluetooth/android/localdevicebroadcastreceiver_p.h | 1 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice_android.cpp | 11 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice_p.h | 1 |
4 files changed, 54 insertions, 0 deletions
diff --git a/src/bluetooth/android/localdevicebroadcastreceiver.cpp b/src/bluetooth/android/localdevicebroadcastreceiver.cpp index c6cb3680..2d247574 100644 --- a/src/bluetooth/android/localdevicebroadcastreceiver.cpp +++ b/src/bluetooth/android/localdevicebroadcastreceiver.cpp @@ -39,6 +39,7 @@ #include <QtCore/QLoggingCategory> #include <QtCore/private/qjnihelpers_p.h> +#include <QtCore/qrandom.h> #include "localdevicebroadcastreceiver_p.h" #include "android/jni_android_p.h" @@ -186,6 +187,46 @@ void LocalDeviceBroadcastReceiver::onReceive(JNIEnv *env, jobject context, jobje switch (variant) { case -1: //ignore -> no pairing variant set return; + case 0: //BluetoothDevice.PAIRING_VARIANT_PIN + { + //generate a random key + const QString pin = QStringLiteral("%1").arg(QRandomGenerator::global()->bounded(1000000), + 6, 10, QLatin1Char('0')); + const QAndroidJniObject javaPin = QAndroidJniObject::fromString(pin); + + //get BluetoothDevice + keyExtra = valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ExtraDevice); + QAndroidJniObject bluetoothDevice = + intentObject.callObjectMethod("getParcelableExtra", + "(Ljava/lang/String;)Landroid/os/Parcelable;", + keyExtra.object<jstring>()); + if (!bluetoothDevice.isValid()) + return; + + QAndroidJniObject bytePin = QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothDevice", + "convertPinToBytes", + "(Ljava/lang/String;)[B", + javaPin.object<jstring>()); + if (!bytePin.isValid()) { + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } + return; + } + + jboolean result = bluetoothDevice.callMethod<jboolean>("setPin", "([B)Z", bytePin.object<jbyteArray>()); + if (!result) { + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } + return; + } + + const QBluetoothAddress address(bluetoothDevice.callObjectMethod<jstring>("getAddress").toString()); + emit pairingDisplayPinCode(address, pin); + } case 2: //BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION { keyExtra = valueForStaticField(JavaNames::BluetoothDevice, diff --git a/src/bluetooth/android/localdevicebroadcastreceiver_p.h b/src/bluetooth/android/localdevicebroadcastreceiver_p.h index c6ae424d..09e50fb1 100644 --- a/src/bluetooth/android/localdevicebroadcastreceiver_p.h +++ b/src/bluetooth/android/localdevicebroadcastreceiver_p.h @@ -72,6 +72,7 @@ signals: void pairingStateChanged(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing); void connectDeviceChanges(const QBluetoothAddress &address, bool isConnectEvent); void pairingDisplayConfirmation(const QBluetoothAddress &address, const QString& pin); + void pairingDisplayPinCode(const QBluetoothAddress &address, const QString& pin); private: int previousScanMode; QAndroidJniObject pairingDevice; diff --git a/src/bluetooth/qbluetoothlocaldevice_android.cpp b/src/bluetooth/qbluetoothlocaldevice_android.cpp index f36e184c..0144a5ef 100644 --- a/src/bluetooth/qbluetoothlocaldevice_android.cpp +++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp @@ -73,6 +73,8 @@ QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate( this, SLOT(processConnectDeviceChanges(QBluetoothAddress, bool))); connect(receiver, SIGNAL(pairingDisplayConfirmation(QBluetoothAddress, QString)), this, SLOT(processDisplayConfirmation(QBluetoothAddress, QString))); + connect(receiver, &LocalDeviceBroadcastReceiver::pairingDisplayPinCode, + this, &QBluetoothLocalDevicePrivate::processDisplayPinCode); } QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate() @@ -215,6 +217,15 @@ void QBluetoothLocalDevicePrivate::processDisplayConfirmation(const QBluetoothAd return; emit q_ptr->pairingDisplayConfirmation(address, pin); +} + +void QBluetoothLocalDevicePrivate::processDisplayPinCode(const QBluetoothAddress &address, const QString &pin) +{ + // only send pairing notification for pairing requests issued by + // this QBluetoothLocalDevice instance + if (pendingPairing(address) == -1) + return; + emit q_ptr->pairingDisplayPinCode(address, pin); } diff --git a/src/bluetooth/qbluetoothlocaldevice_p.h b/src/bluetooth/qbluetoothlocaldevice_p.h index 038effcd..8752504d 100644 --- a/src/bluetooth/qbluetoothlocaldevice_p.h +++ b/src/bluetooth/qbluetoothlocaldevice_p.h @@ -113,6 +113,7 @@ private slots: QBluetoothLocalDevice::Pairing pairing); void processConnectDeviceChanges(const QBluetoothAddress &address, bool isConnectEvent); void processDisplayConfirmation(const QBluetoothAddress &address, const QString &pin); + void processDisplayPinCode(const QBluetoothAddress &address, const QString &pin); private: QBluetoothLocalDevice *q_ptr; |