android/usb: pass in the UsbDevice when downloading

This finally allows us to download from not just the first device, but specifically
the device that the user picks.

Passing the object through a void pointer is not nice - but since this traverses
C code other solutions (like passing an index into the list) seemed even worse.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2020-03-14 18:11:46 -07:00
parent 1495aa2dbf
commit ec3a968df9
8 changed files with 38 additions and 11 deletions

View file

@ -220,6 +220,9 @@ DCDeviceData::DCDeviceData()
#else
data.libdc_log = false;
#endif
#if defined(Q_OS_ANDROID)
data.androidUsbDeviceDescriptor = nullptr;
#endif
}
DCDeviceData *DCDeviceData::instance()
@ -320,6 +323,13 @@ void DCDeviceData::setDevName(const QString &devName)
data.devname = copy_qstring(devName);
}
#if defined(Q_OS_ANDROID)
void DCDeviceData::setUsbDevice(void *device)
{
data.androidUsbDeviceDescriptor = device;
}
#endif
void DCDeviceData::setDevBluetoothName(const QString &name)
{
m_devBluetoothName = name;

View file

@ -31,7 +31,7 @@ public:
int diveId() const;
/* this needs to be a pointer to make the C-API happy */
device_data_t* internalData();
device_data_t *internalData();
QStringList getProductListFromVendor(const QString& vendor);
int getMatchingAddress(const QString &vendor, const QString &product);
@ -49,6 +49,9 @@ public:
void setForceDownload(bool force);
void setSaveDump(bool dumpMode);
void setSaveLog(bool saveLog);
#if defined(Q_OS_ANDROID)
void setUsbDevice(void *device);
#endif
private:
device_data_t data;

View file

@ -1336,8 +1336,8 @@ dc_status_t divecomputer_device_open(device_data_t *data)
return ftdi_open(&data->iostream, context);
#endif
#ifdef __ANDROID__
if (!strcasecmp(data->devname, "usb-serial"))
return serial_usb_android_open(&data->iostream, context);
if (data->androidUsbDeviceDescriptor)
return serial_usb_android_open(&data->iostream, context, data->androidUsbDeviceDescriptor);
#endif
rc = dc_serial_open(&data->iostream, context, data->devname);
if (rc == DC_STATUS_SUCCESS)

View file

@ -48,6 +48,7 @@ typedef struct dc_user_device_t
FILE *libdc_logfile;
struct dive_table *download_table;
struct dive_site_table *sites;
void *androidUsbDeviceDescriptor;
} device_data_t;
const char *errmsg (dc_status_t rc);
@ -67,7 +68,7 @@ extern char *dumpfile_name;
dc_status_t ble_packet_open(dc_iostream_t **iostream, dc_context_t *context, const char* devaddr, void *userdata);
dc_status_t rfcomm_stream_open(dc_iostream_t **iostream, dc_context_t *context, const char* devaddr);
dc_status_t ftdi_open(dc_iostream_t **iostream, dc_context_t *context);
dc_status_t serial_usb_android_open(dc_iostream_t **iostream, dc_context_t *context);
dc_status_t serial_usb_android_open(dc_iostream_t **iostream, dc_context_t *context, void *androidUsbDevice);
dc_status_t divecomputer_device_open(device_data_t *data);

View file

@ -348,13 +348,12 @@ std::vector<android_usb_serial_device_descriptor> serial_usb_android_get_devices
* For testing and compatibility only, can be removed after the UI changes. Behaves exactly like the "old"
* implementation if only one device is attached.
*/
dc_status_t serial_usb_android_open(dc_iostream_t **iostream, dc_context_t *context)
dc_status_t serial_usb_android_open(dc_iostream_t **iostream, dc_context_t *context, void *androidUsbDevice)
{
std::vector<android_usb_serial_device_descriptor> devices = serial_usb_android_get_devices();
if(devices.empty())
if (!androidUsbDevice)
return DC_STATUS_NODEVICE;
android_usb_serial_device_descriptor *usbDeviceDescriptor = (android_usb_serial_device_descriptor *)androidUsbDevice;
return serial_usb_android_open(iostream, context, devices[0].usbDevice, devices[0].className);
// danger, danger, we need to pick the correct device here - passing the index around assumes that the table didn't change
return serial_usb_android_open(iostream, context, usbDeviceDescriptor->usbDevice, usbDeviceDescriptor->className);
}

View file

@ -19,6 +19,7 @@ struct android_usb_serial_device_descriptor {
uint16_t vid;
};
std::vector<android_usb_serial_device_descriptor> serial_usb_android_get_devices(bool driverSelection);
std::vector<android_usb_serial_device_descriptor> serial_usb_android_get_devices();
android_usb_serial_device_descriptor getDescriptor(QAndroidJniObject usbDevice);
#endif

View file

@ -1999,6 +1999,18 @@ void QMLManager::DC_setProduct(const QString& product)
void QMLManager::DC_setDevName(const QString& devName)
{
DCDeviceData::instance()->setDevName(devName);
#if defined(Q_OS_ANDROID)
// get the currently valid list of devices and set up the USB device descriptor
// if the connection string matches a connection in that list
androidSerialDevices = serial_usb_android_get_devices();
std::string connection = devName.toStdString();
for (unsigned int i = 0; i < androidSerialDevices.size(); i++) {
if (androidSerialDevices[i].uiRepresentation == connection) {
appendTextToLog(QString("setDevName matches USB device %1").arg(i));
DCDeviceData::instance()->setUsbDevice((void *)&androidSerialDevices[i]);
}
}
#endif
}
void QMLManager::DC_setDevBluetoothName(const QString& devBluetoothName)

View file

@ -233,6 +233,7 @@ public slots:
void btRescan();
#if defined(Q_OS_ANDROID)
void showDownloadPage(QAndroidJniObject usbDevice);
QString getProductVendorConnectionIdx(android_usb_serial_device_descriptor descriptor);
#endif
void divesChanged(const QVector<dive *> &dives, DiveField field);