From ff2f199eed20b11386887ab55c8d4de43a32bb19 Mon Sep 17 00:00:00 2001
From: Dirk Hohndel <dirk@hohndel.org>
Date: Sat, 14 Mar 2020 18:52:45 -0700
Subject: [PATCH] mobile UI: rescan button on DC Download page rescans
 BT/BLE/USB

This way even if a USB device wasn't added through an Android intent, we
still have a way to scan for it and select it. This is especially
important in case a user has a cable that we haven't seen yet (i.e. with
a VID/PID that we haven't added to Subsurface-mobile), but that
nevertheless works with the android usb serial drivers.

This also makes the flow a little more logical / consistent when
deciding which connections to show.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
---
 .../qml/DownloadFromDiveComputer.qml          |  2 +-
 mobile-widgets/qmlmanager.cpp                 | 51 ++++++++++++-------
 mobile-widgets/qmlmanager.h                   |  3 ++
 3 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/mobile-widgets/qml/DownloadFromDiveComputer.qml b/mobile-widgets/qml/DownloadFromDiveComputer.qml
index 74730d2f5..b0eda16f3 100644
--- a/mobile-widgets/qml/DownloadFromDiveComputer.qml
+++ b/mobile-widgets/qml/DownloadFromDiveComputer.qml
@@ -353,7 +353,7 @@ Kirigami.Page {
 				text: qsTr("Rescan")
 				enabled: manager.btEnabled
 				onClicked: {
-					manager.btRescan()
+					manager.rescanConnections()
 				}
 			}
 
diff --git a/mobile-widgets/qmlmanager.cpp b/mobile-widgets/qmlmanager.cpp
index e7a557155..b271af6ea 100644
--- a/mobile-widgets/qmlmanager.cpp
+++ b/mobile-widgets/qmlmanager.cpp
@@ -155,6 +155,23 @@ void QMLManager::btRescan()
 	BTDiscovery::instance()->BTDiscoveryReDiscover();
 }
 
+void QMLManager::rescanConnections()
+{
+	connectionListModel.removeAllAddresses();
+	btRescan();
+	usbRescan();
+#if defined(SERIAL_FTDI)
+	connectionListModel.addAddress("FTDI");
+#endif
+}
+
+void QMLManager::usbRescan()
+{
+#if defined(Q_OS_ANDROID)
+	androidUsbPopoulateConnections();
+#endif
+}
+
 QMLManager::QMLManager() : m_locationServiceEnabled(false),
 	m_verboseEnabled(false),
 	alreadySaving(false),
@@ -2086,6 +2103,20 @@ QString QMLManager::getProductVendorConnectionIdx(android_usb_serial_device_desc
 	return QString("%1;%2;%3").arg(vendIdx).arg(prodIdx).arg(connIdx);
 }
 
+void QMLManager::androidUsbPopoulateConnections()
+{
+	// let's understand what devices are available
+	androidSerialDevices = serial_usb_android_get_devices();
+	appendTextToLog(QString("rescanning USB: %1 devices reported").arg(androidSerialDevices.size()));
+
+	// list all USB devices, this will include the one that triggered the intent
+	for (unsigned int i = 0; i < androidSerialDevices.size(); i++) {
+		QString uiString = QString::fromStdString(androidSerialDevices[i].uiRepresentation);
+		appendTextToLog(QString("found USB device with ui string %1").arg(uiString));
+		connectionListModel.addAddress(uiString);
+	}
+}
+
 void QMLManager::showDownloadPage(QAndroidJniObject usbDevice)
 {
 	if (!usbDevice.isValid()) {
@@ -2093,26 +2124,12 @@ void QMLManager::showDownloadPage(QAndroidJniObject usbDevice)
 		// if that happens, just make sure the DownloadPage is reopened
 		m_pluggedInDeviceName = QString("reopen");
 	} else {
+		// repopulate the connection list
+		rescanConnections();
+
 		// parse the usbDevice
 		android_usb_serial_device_descriptor usbDeviceDescriptor = getDescriptor(usbDevice);
 
-		// let's understand what devices are available
-		androidSerialDevices = serial_usb_android_get_devices();
-		appendTextToLog(QString("entered showDownloadPage with %1 devices reported").arg(androidSerialDevices.size()));
-
-		// list all USB devices, this will include the one that triggered the intent
-		for (unsigned int i = 0; i < androidSerialDevices.size(); i++) {
-			// the expected case -- does this match the deviceString we got from the intent?
-			QString uiString = QString::fromStdString(androidSerialDevices[i].uiRepresentation);
-			//QString deviceName = uiString.left(uiString.indexOf(QString(" (")) + 1);
-			appendTextToLog(QString("looking at USB device with ui representation %1").arg(uiString));
-			if (androidSerialDevices[i].uiRepresentation == usbDeviceDescriptor.uiRepresentation) {
-				appendTextToLog("matches the information we received from the intent");
-			} else {
-				appendTextToLog("doesn't match the device received from the intent");
-			}
-			connectionListModel.addAddress(QString::fromStdString(androidSerialDevices[i].uiRepresentation));
-		}
 		// inform the QML UI that it should show the download page
 		m_pluggedInDeviceName = getProductVendorConnectionIdx(usbDeviceDescriptor);
 	}
diff --git a/mobile-widgets/qmlmanager.h b/mobile-widgets/qmlmanager.h
index 08fead029..c0d036aec 100644
--- a/mobile-widgets/qmlmanager.h
+++ b/mobile-widgets/qmlmanager.h
@@ -231,8 +231,11 @@ public slots:
 	void quit();
 	void hasLocationSourceChanged();
 	void btRescan();
+	void usbRescan();
+	void rescanConnections();
 #if defined(Q_OS_ANDROID)
 	void showDownloadPage(QAndroidJniObject usbDevice);
+	void androidUsbPopoulateConnections();
 	QString getProductVendorConnectionIdx(android_usb_serial_device_descriptor descriptor);
 #endif
 	void divesChanged(const QVector<dive *> &dives, DiveField field);