mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
QML UI: move BT handling into core code
This shouldn't be part of the UI (qmlmanager), but part of our overall handling of dive computers and BT devices. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
3b993fbaad
commit
b14a522f4f
8 changed files with 305 additions and 199 deletions
|
@ -26,6 +26,7 @@ endif()
|
||||||
|
|
||||||
# compile the core library, in C.
|
# compile the core library, in C.
|
||||||
set(SUBSURFACE_CORE_LIB_SRCS
|
set(SUBSURFACE_CORE_LIB_SRCS
|
||||||
|
btdiscovery.cpp
|
||||||
cochran.c
|
cochran.c
|
||||||
datatrak.c
|
datatrak.c
|
||||||
deco.c
|
deco.c
|
||||||
|
|
165
core/btdiscovery.cpp
Normal file
165
core/btdiscovery.cpp
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
#include "btdiscovery.h"
|
||||||
|
#include "downloadfromdcthread.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
BTDiscovery *BTDiscovery::m_instance = NULL;
|
||||||
|
|
||||||
|
BTDiscovery::BTDiscovery(QObject *parent)
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent)
|
||||||
|
if (m_instance) {
|
||||||
|
qDebug() << "trying to create an additional BTDiscovery object";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_instance = this;
|
||||||
|
#if defined(BT_SUPPORT)
|
||||||
|
if (localBtDevice.isValid() &&
|
||||||
|
localBtDevice.hostMode() == QBluetoothLocalDevice::HostConnectable) {
|
||||||
|
btPairedDevices.clear();
|
||||||
|
qDebug() << "localDevice " + localBtDevice.name() + " is valid, starting discovery";
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
|
||||||
|
connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BTDiscovery::btDeviceDiscovered);
|
||||||
|
discoveryAgent->start();
|
||||||
|
#endif
|
||||||
|
#if defined(Q_OS_ANDROID) && defined(BT_SUPPORT)
|
||||||
|
getBluetoothDevices();
|
||||||
|
#endif
|
||||||
|
for (int i = 0; i < btPairedDevices.length(); i++) {
|
||||||
|
qDebug() << "Paired =" << btPairedDevices[i].name << btPairedDevices[i].address.toString();
|
||||||
|
}
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
discoveryAgent->stop();
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
qDebug() << "localBtDevice isn't valid";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
BTDiscovery::~BTDiscovery()
|
||||||
|
{
|
||||||
|
m_instance = NULL;
|
||||||
|
#if defined(BT_SUPPORT)
|
||||||
|
free(discoveryAgent);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
BTDiscovery *BTDiscovery::instance()
|
||||||
|
{
|
||||||
|
if (!m_instance)
|
||||||
|
m_instance = new BTDiscovery();
|
||||||
|
return m_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BT_SUPPORT)
|
||||||
|
|
||||||
|
extern void addBtUuid(QBluetoothUuid uuid);
|
||||||
|
extern QHash<QString, QStringList> productList;
|
||||||
|
extern QStringList vendorList;
|
||||||
|
|
||||||
|
void BTDiscovery::btDeviceDiscovered(const QBluetoothDeviceInfo &device)
|
||||||
|
{
|
||||||
|
btPairedDevice this_d;
|
||||||
|
this_d.address = device.address();
|
||||||
|
this_d.name = device.name();
|
||||||
|
btPairedDevices.append(this_d);
|
||||||
|
|
||||||
|
QString newDevice = device.name();
|
||||||
|
|
||||||
|
// all the HW OSTC BT computers show up as "OSTC" + some other text, depending on model
|
||||||
|
if (newDevice.startsWith("OSTC"))
|
||||||
|
newDevice = "OSTC 3";
|
||||||
|
QList<QBluetoothUuid> serviceUuids = device.serviceUuids();
|
||||||
|
foreach (QBluetoothUuid id, serviceUuids) {
|
||||||
|
addBtUuid(id);
|
||||||
|
qDebug() << id.toByteArray();
|
||||||
|
}
|
||||||
|
qDebug() << "Found new device " + newDevice + " (" + device.address().toString() + ")";
|
||||||
|
QString vendor, product;
|
||||||
|
foreach (vendor, productList.keys()) {
|
||||||
|
if (productList[vendor].contains(newDevice)) {
|
||||||
|
qDebug() << "this could be a " + vendor + " " +
|
||||||
|
(newDevice == "OSTC 3" ? "OSTC family" : newDevice);
|
||||||
|
struct btVendorProduct btVP;
|
||||||
|
btVP.btdi = device;
|
||||||
|
btVP.vendorIdx = vendorList.indexOf(vendor);
|
||||||
|
btVP.productIdx = productList[vendor].indexOf(newDevice);
|
||||||
|
qDebug() << "adding new btDCs entry" << newDevice << btVP.vendorIdx << btVP.productIdx;
|
||||||
|
btDCs << btVP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList <struct btVendorProduct> BTDiscovery::getBtDcs()
|
||||||
|
{
|
||||||
|
return btDCs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Android: As Qt is not able to pull the pairing data from a device, i
|
||||||
|
// a lengthy discovery process is needed to see what devices are paired. On
|
||||||
|
// https://forum.qt.io/topic/46075/solved-bluetooth-list-paired-devices
|
||||||
|
// user s.frings74 does, however, present a solution to this using JNI.
|
||||||
|
// Currently, this code is taken "as is".
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
void BTDiscovery::getBluetoothDevices()
|
||||||
|
{
|
||||||
|
struct BTDiscovery::btPairedDevice result;
|
||||||
|
// Query via Android Java API.
|
||||||
|
|
||||||
|
// returns a BluetoothAdapter
|
||||||
|
QAndroidJniObject adapter=QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter","getDefaultAdapter","()Landroid/bluetooth/BluetoothAdapter;");
|
||||||
|
if (checkException("BluetoothAdapter.getDefaultAdapter()", &adapter)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// returns a Set<BluetoothDevice>
|
||||||
|
QAndroidJniObject pairedDevicesSet=adapter.callObjectMethod("getBondedDevices","()Ljava/util/Set;");
|
||||||
|
if (checkException("BluetoothAdapter.getBondedDevices()", &pairedDevicesSet)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
jint size=pairedDevicesSet.callMethod<jint>("size");
|
||||||
|
checkException("Set<BluetoothDevice>.size()", &pairedDevicesSet);
|
||||||
|
if (size > 0) {
|
||||||
|
// returns an Iterator<BluetoothDevice>
|
||||||
|
QAndroidJniObject iterator=pairedDevicesSet.callObjectMethod("iterator","()Ljava/util/Iterator;");
|
||||||
|
if (checkException("Set<BluetoothDevice>.iterator()", &iterator)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
// returns a BluetoothDevice
|
||||||
|
QAndroidJniObject dev=iterator.callObjectMethod("next","()Ljava/lang/Object;");
|
||||||
|
if (checkException("Iterator<BluetoothDevice>.next()", &dev)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.address = QBluetoothAddress(dev.callObjectMethod("getAddress","()Ljava/lang/String;").toString());
|
||||||
|
result.name = dev.callObjectMethod("getName", "()Ljava/lang/String;").toString();
|
||||||
|
|
||||||
|
btPairedDevices.append(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BTDiscovery::checkException(const char* method, const QAndroidJniObject *obj)
|
||||||
|
{
|
||||||
|
static QAndroidJniEnvironment env;
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
qCritical("Exception in %s", method);
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
result=true;
|
||||||
|
}
|
||||||
|
if (!(obj == NULL || obj->isValid())) {
|
||||||
|
qCritical("Invalid object returned by %s", method);
|
||||||
|
result=true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif // Q_OS_ANDROID
|
||||||
|
#endif // BT_SUPPORT
|
64
core/btdiscovery.h
Normal file
64
core/btdiscovery.h
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
#ifndef BTDISCOVERY_H
|
||||||
|
#define BTDISCOVERY_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
#if defined(BT_SUPPORT)
|
||||||
|
#include <QBluetoothLocalDevice>
|
||||||
|
#include <QBluetoothDeviceDiscoveryAgent>
|
||||||
|
#include <QBluetoothUuid>
|
||||||
|
|
||||||
|
struct btVendorProduct {
|
||||||
|
QBluetoothDeviceInfo btdi;
|
||||||
|
int vendorIdx;
|
||||||
|
int productIdx;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
#include <QAndroidJniObject>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class BTDiscovery : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
BTDiscovery(QObject *parent = NULL);
|
||||||
|
~BTDiscovery();
|
||||||
|
static BTDiscovery *instance();
|
||||||
|
|
||||||
|
#if defined(BT_SUPPORT)
|
||||||
|
struct btPairedDevice {
|
||||||
|
QBluetoothAddress address;
|
||||||
|
QString name;
|
||||||
|
};
|
||||||
|
void btDeviceDiscovered(const QBluetoothDeviceInfo &device);
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
void getBluetoothDevices();
|
||||||
|
#endif
|
||||||
|
QList<struct btVendorProduct> getBtDcs();
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
static BTDiscovery *m_instance;
|
||||||
|
#if defined(BT_SUPPORT)
|
||||||
|
QList<struct btVendorProduct> btDCs;
|
||||||
|
#endif
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
bool checkException(const char* method, const QAndroidJniObject* obj);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BT_SUPPORT)
|
||||||
|
QList<struct btPairedDevice> btPairedDevices;
|
||||||
|
QBluetoothLocalDevice localBtDevice;
|
||||||
|
QBluetoothDeviceDiscoveryAgent *discoveryAgent;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void dcVendorChanged();
|
||||||
|
void dcProductChanged();
|
||||||
|
void dcBtChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BTDISCOVERY_H
|
|
@ -99,8 +99,15 @@ void fill_computer_list()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DCDeviceData *DCDeviceData::m_instance = NULL;
|
||||||
|
|
||||||
DCDeviceData::DCDeviceData(QObject *parent) : QObject(parent)
|
DCDeviceData::DCDeviceData(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
|
if (m_instance) {
|
||||||
|
qDebug() << "already have an instance of DCDevieData";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_instance = this;
|
||||||
memset(&data, 0, sizeof(data));
|
memset(&data, 0, sizeof(data));
|
||||||
data.trip = nullptr;
|
data.trip = nullptr;
|
||||||
data.download_table = nullptr;
|
data.download_table = nullptr;
|
||||||
|
@ -108,6 +115,18 @@ DCDeviceData::DCDeviceData(QObject *parent) : QObject(parent)
|
||||||
data.deviceid = 0;
|
data.deviceid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DCDeviceData *DCDeviceData::instance()
|
||||||
|
{
|
||||||
|
if (!m_instance)
|
||||||
|
m_instance = new DCDeviceData();
|
||||||
|
return m_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DCDeviceData::getProductListFromVendor(const QString &vendor)
|
||||||
|
{
|
||||||
|
return productList[vendor];
|
||||||
|
}
|
||||||
|
|
||||||
DCDeviceData * DownloadThread::data()
|
DCDeviceData * DownloadThread::data()
|
||||||
{
|
{
|
||||||
return m_data;
|
return m_data;
|
||||||
|
@ -222,3 +241,40 @@ device_data_t* DCDeviceData::internalData()
|
||||||
{
|
{
|
||||||
return &data;
|
return &data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DCDeviceData::getDetectedVendorIndex()
|
||||||
|
{
|
||||||
|
#if defined(BT_SUPPORT)
|
||||||
|
QList<btVendorProduct> btDCs = BTDiscovery::instance()->getBtDcs();
|
||||||
|
if (!btDCs.isEmpty()) {
|
||||||
|
qDebug() << "getVendorIdx" << btDCs.first().vendorIdx;
|
||||||
|
return btDCs.first().vendorIdx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DCDeviceData::getDetectedProductIndex()
|
||||||
|
{
|
||||||
|
#if defined(BT_SUPPORT)
|
||||||
|
QList<btVendorProduct> btDCs = BTDiscovery::instance()->getBtDcs();
|
||||||
|
if (!btDCs.isEmpty()) {
|
||||||
|
qDebug() << "getProductIdx" << btDCs.first().productIdx;
|
||||||
|
return btDCs.first().productIdx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DCDeviceData::getDetectedDeviceAddress()
|
||||||
|
{
|
||||||
|
#if BT_SUPPORT
|
||||||
|
QList<btVendorProduct> btDCs = BTDiscovery::instance()->getBtDcs();
|
||||||
|
if (!btDCs.isEmpty()) {
|
||||||
|
QString btAddr = btDCs.first().btdi.address().toString();
|
||||||
|
qDebug() << "getBtAddress" << btAddr;
|
||||||
|
return btAddr;
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -4,9 +4,11 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
#include "dive.h"
|
#include "dive.h"
|
||||||
#include "libdivecomputer.h"
|
#include "libdivecomputer.h"
|
||||||
|
#include "core/btdiscovery.h"
|
||||||
|
|
||||||
/* Helper object for access of Device Data in QML */
|
/* Helper object for access of Device Data in QML */
|
||||||
class DCDeviceData : public QObject {
|
class DCDeviceData : public QObject {
|
||||||
|
@ -25,6 +27,7 @@ class DCDeviceData : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DCDeviceData(QObject *parent = nullptr);
|
DCDeviceData(QObject *parent = nullptr);
|
||||||
|
static DCDeviceData *instance();
|
||||||
|
|
||||||
QString vendor() const;
|
QString vendor() const;
|
||||||
QString product() const;
|
QString product() const;
|
||||||
|
@ -41,6 +44,11 @@ public:
|
||||||
/* this needs to be a pointer to make the C-API happy */
|
/* this needs to be a pointer to make the C-API happy */
|
||||||
device_data_t* internalData();
|
device_data_t* internalData();
|
||||||
|
|
||||||
|
Q_INVOKABLE QStringList getProductListFromVendor(const QString& vendor);
|
||||||
|
Q_INVOKABLE int getDetectedVendorIndex();
|
||||||
|
Q_INVOKABLE int getDetectedProductIndex();
|
||||||
|
Q_INVOKABLE QString getDetectedDeviceAddress();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setVendor(const QString& vendor);
|
void setVendor(const QString& vendor);
|
||||||
void setProduct(const QString& product);
|
void setProduct(const QString& product);
|
||||||
|
@ -53,6 +61,7 @@ public slots:
|
||||||
void setSaveDump(bool dumpMode);
|
void setSaveDump(bool dumpMode);
|
||||||
void setSaveLog(bool saveLog);
|
void setSaveLog(bool saveLog);
|
||||||
private:
|
private:
|
||||||
|
static DCDeviceData *m_instance;
|
||||||
device_data_t data;
|
device_data_t data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -64,7 +73,7 @@ public:
|
||||||
DownloadThread();
|
DownloadThread();
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|
||||||
DCDeviceData *data();
|
Q_INVOKABLE DCDeviceData *data();
|
||||||
QString error;
|
QString error;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -57,11 +57,11 @@ Kirigami.Page {
|
||||||
id: comboVendor
|
id: comboVendor
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
model: vendorList
|
model: vendorList
|
||||||
currentIndex: manager.getVendorIndex()
|
currentIndex: downloadThread.data().getDetectedVendorIndex()
|
||||||
onCurrentTextChanged: {
|
onCurrentTextChanged: {
|
||||||
comboProduct.model = manager.getDCListFromVendor(comboVendor.currentText)
|
comboProduct.model = downloadThread.data().getProductListFromVendor(comboVendor.currentText)
|
||||||
if (currentIndex == manager.getVendorIndex())
|
if (currentIndex == downloadThread.data().getDetectedVendorIndex())
|
||||||
comboProduct.currentIndex = manager.getProductIndex()
|
comboProduct.currentIndex = downloadThread.data().getDetectedProductIndex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kirigami.Label { text: qsTr(" Dive Computer:") }
|
Kirigami.Label { text: qsTr(" Dive Computer:") }
|
||||||
|
@ -74,7 +74,7 @@ Kirigami.Page {
|
||||||
Kirigami.Label { text: qsTr("Bluetooth download:") }
|
Kirigami.Label { text: qsTr("Bluetooth download:") }
|
||||||
CheckBox {
|
CheckBox {
|
||||||
id: isBluetooth
|
id: isBluetooth
|
||||||
checked: manager.getVendorIndex() != -1
|
checked: downloadThread.data().getDetectedVendorIndex() != -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,28 +94,9 @@ QMLManager::QMLManager() : m_locationServiceEnabled(false),
|
||||||
alreadySaving(false)
|
alreadySaving(false)
|
||||||
{
|
{
|
||||||
#if defined(BT_SUPPORT)
|
#if defined(BT_SUPPORT)
|
||||||
if (localBtDevice.isValid() &&
|
// ensure that we start the BTDiscovery - this should be triggered by the export of the class
|
||||||
localBtDevice.hostMode() == QBluetoothLocalDevice::HostConnectable) {
|
// to QML, but that doesn't seem to always work
|
||||||
btPairedDevices.clear();
|
BTDiscovery *btDiscovery = BTDiscovery::instance();
|
||||||
QString localDeviceName = "localDevice " + localBtDevice.name() + " is valid, starting discovery";
|
|
||||||
appendTextToLog(localDeviceName.toUtf8().data());
|
|
||||||
#if defined(Q_OS_LINUX)
|
|
||||||
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
|
|
||||||
connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &QMLManager::btDeviceDiscovered);
|
|
||||||
discoveryAgent->start();
|
|
||||||
#endif
|
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
getBluetoothDevices();
|
|
||||||
#endif
|
|
||||||
for (int i = 0; i < btPairedDevices.length(); i++) {
|
|
||||||
qDebug() << "Paired =" << btPairedDevices[i].name << btPairedDevices[i].address.toString();
|
|
||||||
}
|
|
||||||
#if defined(Q_OS_LINUX)
|
|
||||||
discoveryAgent->stop();
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
appendTextToLog("localBtDevice isn't valid");
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
m_lastDevicePixelRatio = qApp->devicePixelRatio();
|
m_lastDevicePixelRatio = qApp->devicePixelRatio();
|
||||||
|
@ -217,78 +198,6 @@ void QMLManager::mergeLocalRepo()
|
||||||
process_dives(true, false);
|
process_dives(true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BT_SUPPORT)
|
|
||||||
|
|
||||||
extern void addBtUuid(QBluetoothUuid uuid);
|
|
||||||
|
|
||||||
void QMLManager::btDeviceDiscovered(const QBluetoothDeviceInfo &device)
|
|
||||||
{
|
|
||||||
btPairedDevice this_d;
|
|
||||||
this_d.address = device.address();
|
|
||||||
this_d.name = device.name();
|
|
||||||
btPairedDevices.append(this_d);
|
|
||||||
|
|
||||||
QString newDevice = device.name();
|
|
||||||
|
|
||||||
// all the HW OSTC BT computers show up as "OSTC" + some other text, depending on model
|
|
||||||
if (newDevice.startsWith("OSTC"))
|
|
||||||
newDevice = "OSTC 3";
|
|
||||||
QList<QBluetoothUuid> serviceUuids = device.serviceUuids();
|
|
||||||
foreach (QBluetoothUuid id, serviceUuids) {
|
|
||||||
addBtUuid(id);
|
|
||||||
qDebug() << id.toByteArray();
|
|
||||||
}
|
|
||||||
appendTextToLog("Found new device " + newDevice + " (" + device.address().toString() + ")");
|
|
||||||
QString vendor, product;
|
|
||||||
foreach (vendor, productList.keys()) {
|
|
||||||
if (productList[vendor].contains(newDevice)) {
|
|
||||||
appendTextToLog("this could be a " + vendor + " " +
|
|
||||||
(newDevice == "OSTC 3" ? "OSTC family" : newDevice));
|
|
||||||
struct btVendorProduct btVP;
|
|
||||||
btVP.btdi = device;
|
|
||||||
btVP.vendorIdx = vendorList.indexOf(vendor);
|
|
||||||
btVP.productIdx = productList[vendor].indexOf(newDevice);
|
|
||||||
qDebug() << "adding new btDCs entry" << newDevice << btVP.vendorIdx << btVP.productIdx;
|
|
||||||
btDCs << btVP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int QMLManager::getVendorIndex()
|
|
||||||
{
|
|
||||||
#if defined(BT_SUPPORT)
|
|
||||||
if (!btDCs.isEmpty()) {
|
|
||||||
qDebug() << "getVendorIdx" << btDCs.first().vendorIdx;
|
|
||||||
return btDCs.first().vendorIdx;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QMLManager::getProductIndex()
|
|
||||||
{
|
|
||||||
#if defined(BT_SUPPORT)
|
|
||||||
if (!btDCs.isEmpty()) {
|
|
||||||
qDebug() << "getProductIdx" << btDCs.first().productIdx;
|
|
||||||
return btDCs.first().productIdx;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QMLManager::getBtAddress()
|
|
||||||
{
|
|
||||||
#if BT_SUPPORT
|
|
||||||
if (!btDCs.isEmpty()) {
|
|
||||||
QString btAddr = btDCs.first().btdi.address().toString();
|
|
||||||
qDebug() << "getBtAddress" << btAddr;
|
|
||||||
return btAddr;
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void QMLManager::finishSetup()
|
void QMLManager::finishSetup()
|
||||||
{
|
{
|
||||||
// Initialize cloud credentials.
|
// Initialize cloud credentials.
|
||||||
|
@ -1611,74 +1520,3 @@ void QMLManager::setShowPin(bool enable)
|
||||||
m_showPin = enable;
|
m_showPin = enable;
|
||||||
emit showPinChanged();
|
emit showPinChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList QMLManager::getDCListFromVendor(const QString& vendor)
|
|
||||||
{
|
|
||||||
return productList[vendor];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Android: As Qt is not able to pull the pairing data from a device, i
|
|
||||||
// a lengthy discovery process is needed to see what devices are paired. On
|
|
||||||
// https://forum.qt.io/topic/46075/solved-bluetooth-list-paired-devices
|
|
||||||
// user s.frings74 does, however, present a solution to this using JNI.
|
|
||||||
// Currently, this code is taken "as is".
|
|
||||||
|
|
||||||
void QMLManager::getBluetoothDevices()
|
|
||||||
{
|
|
||||||
#if defined(Q_OS_ANDROID) && defined(BT_SUPPORT)
|
|
||||||
struct QMLManager::btPairedDevice result;
|
|
||||||
// Query via Android Java API.
|
|
||||||
|
|
||||||
// returns a BluetoothAdapter
|
|
||||||
QAndroidJniObject adapter=QAndroidJniObject::callStaticObjectMethod("android/bluetooth/BluetoothAdapter","getDefaultAdapter","()Landroid/bluetooth/BluetoothAdapter;");
|
|
||||||
if (checkException("BluetoothAdapter.getDefaultAdapter()", &adapter)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// returns a Set<BluetoothDevice>
|
|
||||||
QAndroidJniObject pairedDevicesSet=adapter.callObjectMethod("getBondedDevices","()Ljava/util/Set;");
|
|
||||||
if (checkException("BluetoothAdapter.getBondedDevices()", &pairedDevicesSet)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
jint size=pairedDevicesSet.callMethod<jint>("size");
|
|
||||||
checkException("Set<BluetoothDevice>.size()", &pairedDevicesSet);
|
|
||||||
if (size > 0) {
|
|
||||||
// returns an Iterator<BluetoothDevice>
|
|
||||||
QAndroidJniObject iterator=pairedDevicesSet.callObjectMethod("iterator","()Ljava/util/Iterator;");
|
|
||||||
if (checkException("Set<BluetoothDevice>.iterator()", &iterator)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
// returns a BluetoothDevice
|
|
||||||
QAndroidJniObject dev=iterator.callObjectMethod("next","()Ljava/lang/Object;");
|
|
||||||
if (checkException("Iterator<BluetoothDevice>.next()", &dev)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.address = QBluetoothAddress(dev.callObjectMethod("getAddress","()Ljava/lang/String;").toString());
|
|
||||||
result.name = dev.callObjectMethod("getName", "()Ljava/lang/String;").toString();
|
|
||||||
|
|
||||||
btPairedDevices.append(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
bool QMLManager::checkException(const char* method, const QAndroidJniObject *obj)
|
|
||||||
{
|
|
||||||
static QAndroidJniEnvironment env;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
|
||||||
qCritical("Exception in %s", method);
|
|
||||||
env->ExceptionDescribe();
|
|
||||||
env->ExceptionClear();
|
|
||||||
result=true;
|
|
||||||
}
|
|
||||||
if (!(obj == NULL || obj->isValid())) {
|
|
||||||
qCritical("Invalid object returned by %s", method);
|
|
||||||
result=true;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <QAndroidJniObject>
|
#include <QAndroidJniObject>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "core/btdiscovery.h"
|
||||||
#include "core/gpslocation.h"
|
#include "core/gpslocation.h"
|
||||||
#include "qt-models/divelistmodel.h"
|
#include "qt-models/divelistmodel.h"
|
||||||
|
|
||||||
|
@ -121,18 +122,6 @@ public:
|
||||||
QStringList cylinderInit() const;
|
QStringList cylinderInit() const;
|
||||||
bool showPin() const;
|
bool showPin() const;
|
||||||
void setShowPin(bool enable);
|
void setShowPin(bool enable);
|
||||||
Q_INVOKABLE QStringList getDCListFromVendor(const QString& vendor);
|
|
||||||
Q_INVOKABLE int getVendorIndex();
|
|
||||||
Q_INVOKABLE int getProductIndex();
|
|
||||||
Q_INVOKABLE QString getBtAddress();
|
|
||||||
#if defined(BT_SUPPORT)
|
|
||||||
struct btPairedDevice {
|
|
||||||
QBluetoothAddress address;
|
|
||||||
QString name;
|
|
||||||
};
|
|
||||||
void btDeviceDiscovered(const QBluetoothDeviceInfo &device);
|
|
||||||
void getBluetoothDevices();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void applicationStateChanged(Qt::ApplicationState state);
|
void applicationStateChanged(Qt::ApplicationState state);
|
||||||
|
@ -216,22 +205,6 @@ private:
|
||||||
bool currentGitLocalOnly;
|
bool currentGitLocalOnly;
|
||||||
bool m_showPin;
|
bool m_showPin;
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
|
||||||
bool checkException(const char* method, const QAndroidJniObject* obj);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(BT_SUPPORT)
|
|
||||||
QList<struct btPairedDevice> btPairedDevices;
|
|
||||||
QBluetoothLocalDevice localBtDevice;
|
|
||||||
QBluetoothDeviceDiscoveryAgent *discoveryAgent;
|
|
||||||
struct btVendorProduct {
|
|
||||||
QBluetoothDeviceInfo btdi;
|
|
||||||
int vendorIdx;
|
|
||||||
int productIdx;
|
|
||||||
};
|
|
||||||
QList<struct btVendorProduct> btDCs;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void cloudUserNameChanged();
|
void cloudUserNameChanged();
|
||||||
void cloudPasswordChanged();
|
void cloudPasswordChanged();
|
||||||
|
|
Loading…
Add table
Reference in a new issue