android/usb: parse the usbDevice when responding to intent

This vastly simplifies our handling of devive information as we simply use
what is already in the descriptor. This way we do not duplicate information
about USB devices in the QMLManager.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2020-03-14 18:05:06 -07:00
parent b0eccec8ed
commit 4cd453dc92
2 changed files with 62 additions and 73 deletions

View file

@ -54,6 +54,12 @@
#include "commands/command_base.h" #include "commands/command_base.h"
#include "commands/command.h" #include "commands/command.h"
#if defined(Q_OS_ANDROID)
#include "core/serial_usb_android.h"
std::vector<android_usb_serial_device_descriptor> androidSerialDevices;
#endif
QMLManager *QMLManager::m_instance = NULL; QMLManager *QMLManager::m_instance = NULL;
bool noCloudToCloud = false; bool noCloudToCloud = false;
@ -2046,84 +2052,61 @@ void QMLManager::setGitLocalOnly(const bool &value)
git_local_only = value; git_local_only = value;
} }
void QMLManager::showDownloadPage(QString deviceString) #if defined(Q_OS_ANDROID)
// try to guess which dive computer was plugged into the USB port
QString QMLManager::getProductVendorConnectionIdx(android_usb_serial_device_descriptor descriptor)
{ {
// we pass the indices for the three combo boxes for vendor, product, and connection // convert the information we get from the Android USB layer into indices for the three
// to the QML UI // combo boxes for vendor, product, and connection in the QML UI
// for each of these values '-1' means that no entry should be pre-selected // for each of these values '-1' means that no entry should be pre-selected
QString name("-1;-1;-1"); QString uiString = QString::fromStdString(descriptor.uiRepresentation);
QString product = QString::fromStdString(descriptor.usbProduct);
int connIdx = connectionListModel.indexOf(uiString);
int vendIdx = -1;
int prodIdx = -1;
// try to guess the dive computer (or at least vendor) from the string that if (!descriptor.manufacturer.empty())
// we get from the Intent vendIdx = vendorList.indexOf(QString::fromStdString(descriptor.manufacturer));
// the first couple we do text based because we know exactly what to look for, if (!descriptor.product.empty())
// the rest is based on the vendor and product IDs prodIdx = productList[vendorList[vendIdx]].indexOf(QString::fromStdString(descriptor.product));
if (deviceString.contains("HeinrichsWeikamp OSTC3")) {
name = QString("%1;%2;%3") // the rest of them simply will get the default -1:-1:index of the uiString
.arg(vendorList.indexOf("Heinrichs Weikamp")) return QString("%1;%2;%3").arg(vendIdx).arg(prodIdx).arg(connIdx);
.arg(productList["Heinrichs Weikamp"].indexOf("OSTC 3")) }
.arg(connectionListModel.indexOf("usb-serial"));
} else if (deviceString.contains("HeinrichsWeikamp OSTC 2N")) { void QMLManager::showDownloadPage(QAndroidJniObject usbDevice)
name = QString("%1;%2;%3") {
.arg(vendorList.indexOf("Heinrichs Weikamp")) if (!usbDevice.isValid()) {
.arg(productList["Heinrichs Weikamp"].indexOf("OSTC 2N")) // this happens if we get called by the permission granted intent
.arg(connectionListModel.indexOf("usb-serial")); // if that happens, just make sure the DownloadPage is reopened
} else if (deviceString.contains("mVendorId=1027") && // FTDI: 0x0403 / 0x6001,0x6010,0x6011,0x6014,0x6015 m_pluggedInDeviceName = QString("reopen");
(deviceString.contains("mProductId=24577") || } else {
deviceString.contains("mProductId=24592") || // parse the usbDevice
deviceString.contains("mProductId=24593") || android_usb_serial_device_descriptor usbDeviceDescriptor = getDescriptor(usbDevice);
deviceString.contains("mProductId=24596") ||
deviceString.contains("mProductId=24597"))) { // let's understand what devices are available
name = QString("-1;-1;%1").arg(connectionListModel.indexOf("usb-serial")); androidSerialDevices = serial_usb_android_get_devices();
} else if (deviceString.contains("mVendorId=1027") && // 0x0403 / 0xf460 appendTextToLog(QString("entered showDownloadPage with %1 devices reported").arg(androidSerialDevices.size()));
deviceString.contains("mProductId=62560")) {
name = QString("%1;-1;%2") // list all USB devices, this will include the one that triggered the intent
.arg(vendorList.indexOf("Oceanic")) for (unsigned int i = 0; i < androidSerialDevices.size(); i++) {
.arg(connectionListModel.indexOf("usb-serial")); // the expected case -- does this match the deviceString we got from the intent?
} else if (deviceString.contains("mVendorId=1027") && // 0x0403 / 0xf680 QString uiString = QString::fromStdString(androidSerialDevices[i].uiRepresentation);
deviceString.contains("mProductId=63104")) { //QString deviceName = uiString.left(uiString.indexOf(QString(" (")) + 1);
name = QString("%1;-1;%2") appendTextToLog(QString("looking at USB device with ui representation %1").arg(uiString));
.arg(vendorList.indexOf("Suunto")) if (androidSerialDevices[i].uiRepresentation == usbDeviceDescriptor.uiRepresentation) {
.arg(connectionListModel.indexOf("usb-serial")); appendTextToLog("matches the information we received from the intent");
} else if (deviceString.contains("mVendorId=1027") && // 0x0403 / 0x87d0 } else {
deviceString.contains("mProductId=34768")) { appendTextToLog("doesn't match the device received from the intent");
name = QString("%1;-1;%2") }
.arg(vendorList.indexOf("Cressi")) connectionListModel.addAddress(QString::fromStdString(androidSerialDevices[i].uiRepresentation));
.arg(connectionListModel.indexOf("usb-serial")); }
} else if (deviceString.contains("mVendorId=65535") && // 0xffff / 0x0005 // inform the QML UI that it should show the download page
deviceString.contains("mProductId=5")) { m_pluggedInDeviceName = getProductVendorConnectionIdx(usbDeviceDescriptor);
name = QString("%1;%2;%3")
.arg(vendorList.indexOf("Mares"))
.arg(productList["Mares"].indexOf("Icon HD"))
.arg(connectionListModel.indexOf("usb-serial"));
} else if (deviceString.contains("mVendorId=4292") && // SiLabs: 0x10c4 / 0xea60,0xea70,0xea71,0xea80
(deviceString.contains("mProductId=60000") ||
deviceString.contains("mProductId=60016") ||
deviceString.contains("mProductId=60017") ||
deviceString.contains("mProductId=60032"))) {
name = QString("-1;-1;%1")
.arg(connectionListModel.indexOf("usb-serial"));
} else if (deviceString.contains("mVendorId=1659") && // Prolific: 0x067b / 0x2303
deviceString.contains("mProductId=8963")) {
name = QString("-1;-1;%1")
.arg(connectionListModel.indexOf("usb-serial"));
} else if (deviceString.contains("mVendorId=1208") && // Prolific: 0x04b8 / 0x0521,0x0522
(deviceString.contains("mProductId=1313") ||
deviceString.contains("mProductId=1314"))) {
name = QString("-1;-1;%1")
.arg(connectionListModel.indexOf("usb-serial"));
} else if (deviceString.contains("mVendorId=6790") && // QINHENG: 0x1a86 / 0x7523
deviceString.contains("mProductId=29987")) {
name = QString("-1;-1;%1")
.arg(connectionListModel.indexOf("usb-serial"));
} else if (deviceString.contains("mVendorId=3368") && // ARM mBed: 0x0d28 / 0x0204
deviceString.contains("mProductId=516")) {
name = QString("-1;-1;%1")
.arg(connectionListModel.indexOf("usb-serial"));
} }
// inform the QML UI that it should show the download page
m_pluggedInDeviceName = strdup(qPrintable(name));
emit pluggedInDeviceNameChanged(); emit pluggedInDeviceNameChanged();
} }
#endif
void QMLManager::setFilter(const QString filterText, int index) void QMLManager::setFilter(const QString filterText, int index)
{ {

View file

@ -18,6 +18,10 @@
#include "core/settings/qPrefCloudStorage.h" #include "core/settings/qPrefCloudStorage.h"
#include "core/subsurface-qt/divelistnotifier.h" #include "core/subsurface-qt/divelistnotifier.h"
#if defined(Q_OS_ANDROID)
#include "core/serial_usb_android.h"
#endif
class QAction; class QAction;
class DiveObjectHelper; class DiveObjectHelper;
class DiveSiteChange; // An obscure implementation artifact - remove in due course. class DiveSiteChange; // An obscure implementation artifact - remove in due course.
@ -227,7 +231,9 @@ public slots:
void quit(); void quit();
void hasLocationSourceChanged(); void hasLocationSourceChanged();
void btRescan(); void btRescan();
void showDownloadPage(QString deviceString); #if defined(Q_OS_ANDROID)
void showDownloadPage(QAndroidJniObject usbDevice);
#endif
void divesChanged(const QVector<dive *> &dives, DiveField field); void divesChanged(const QVector<dive *> &dives, DiveField field);
private: private: