From 0b72495413e8b060b58b96aa6d6a0ce96baa168c Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 15 Mar 2020 12:27:10 -0700 Subject: [PATCH] android/usb: simply restart the download after receiving permission If the user tries to download from a device that he hasn't given the app permission to read from, Android will pop up a dialogue asking for that permission. With this after giving the permission we continue (well, technically, restart) the download which is likely the expected behavior. Signed-off-by: Dirk Hohndel --- .../mobile/SubsurfaceMobileActivity.java | 10 ++++++-- core/android.cpp | 21 +++++++++++++++- .../qml/DownloadFromDiveComputer.qml | 25 ++++++++++++++----- mobile-widgets/qmlmanager.cpp | 24 +++++++++++++++--- mobile-widgets/qmlmanager.h | 2 ++ 5 files changed, 70 insertions(+), 12 deletions(-) diff --git a/android-mobile/src/org/subsurfacedivelog/mobile/SubsurfaceMobileActivity.java b/android-mobile/src/org/subsurfacedivelog/mobile/SubsurfaceMobileActivity.java index 0d6e5bbe1..b9bc216d2 100644 --- a/android-mobile/src/org/subsurfacedivelog/mobile/SubsurfaceMobileActivity.java +++ b/android-mobile/src/org/subsurfacedivelog/mobile/SubsurfaceMobileActivity.java @@ -28,6 +28,7 @@ public class SubsurfaceMobileActivity extends QtActivity public static boolean isInitialized; private static final String TAG = "subsurfacedivelog.mobile"; public static native void setUsbDevice(UsbDevice usbDevice); + public static native void restartDownload(UsbDevice usbDevice); private static Context appContext; // we need to provide two endpoints: @@ -116,8 +117,13 @@ public class SubsurfaceMobileActivity extends QtActivity if ("org.subsurfacedivelog.mobile.USB_PERMISSION".equals(action)) { synchronized (this) { if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { - Log.d(TAG, "USB device permission granted"); - setUsbDevice(null); + UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); + if (device == null) { + Log.i(TAG, " permission granted but null device"); + return; + } + Log.d(TAG, "USB device permission granted for " + device.getDeviceName()); + restartDownload(device); } else { Log.d(TAG, "USB device permission denied"); } diff --git a/core/android.cpp b/core/android.cpp index 0c4520ae4..b86f2e557 100644 --- a/core/android.cpp +++ b/core/android.cpp @@ -181,7 +181,7 @@ Java_org_subsurfacedivelog_mobile_SubsurfaceMobileActivity_setUsbDevice(JNIEnv * if (usbDevice.isValid()) { android_usb_serial_device_descriptor descriptor = getDescriptor(usbDevice); - LOG(QString("called by intent for device %1").arg(QString::fromStdString(descriptor.uiRepresentation))); + LOG(QString("called by connect intent for device %1").arg(QString::fromStdString(descriptor.uiRepresentation))); } #if defined(SUBSURFACE_MOBILE) QMLManager::instance()->showDownloadPage(usbDevice); @@ -189,6 +189,25 @@ Java_org_subsurfacedivelog_mobile_SubsurfaceMobileActivity_setUsbDevice(JNIEnv * return; } +JNIEXPORT void JNICALL +Java_org_subsurfacedivelog_mobile_SubsurfaceMobileActivity_restartDownload(JNIEnv *env, + jobject obj, + jobject javaUsbDevice) +{ + Q_UNUSED (obj) + Q_UNUSED (env) + QAndroidJniObject usbDevice(javaUsbDevice); + if (usbDevice.isValid()) { + android_usb_serial_device_descriptor descriptor = getDescriptor(usbDevice); + + LOG(QString("called by permission granted intent for device %1").arg(QString::fromStdString(descriptor.uiRepresentation))); + } +#if defined(SUBSURFACE_MOBILE) + QMLManager::instance()->restartDownload(usbDevice); +#endif + return; +} + /* NOP wrappers to comform with windows.c */ int subsurface_rename(const char *path, const char *newpath) { diff --git a/mobile-widgets/qml/DownloadFromDiveComputer.qml b/mobile-widgets/qml/DownloadFromDiveComputer.qml index 8ef4520a2..5a732b73f 100644 --- a/mobile-widgets/qml/DownloadFromDiveComputer.qml +++ b/mobile-widgets/qml/DownloadFromDiveComputer.qml @@ -293,6 +293,24 @@ Kirigami.Page { Layout.fillWidth: true Layout.topMargin: Kirigami.Units.smallSpacing spacing: Kirigami.Units.smallSpacing + + + function doDownload() { + var message = "DCDownloadThread started for " + manager.DC_vendor + " " + manager.DC_product + " on " + manager.DC_devName; + message += " downloading " + (manager.DC_forceDownload ? "all" : "only new" ) + " dives"; + manager.appendTextToLog(message) + progressBar.visible = true + divesDownloaded = false // this allows the progressMessage to be displayed + importModel.startDownload() + } + + Connections { + target: manager + onRestartDownloadSignal: { + buttonBar.doDownload() + } + } + TemplateButton { id: download text: qsTr("Download") @@ -322,12 +340,7 @@ Kirigami.Page { manager.DC_bluetoothMode = false; manager.DC_devName = connectionString; } - var message = "DCDownloadThread started for " + manager.DC_vendor + " " + manager.DC_product + " on " + manager.DC_devName; - message += " downloading " + (manager.DC_forceDownload ? "all" : "only new" ) + " dives"; - manager.appendTextToLog(message) - progressBar.visible = true - divesDownloaded = false // this allows the progressMessage to be displayed - importModel.startDownload() + buttonBar.doDownload() } } TemplateButton { diff --git a/mobile-widgets/qmlmanager.cpp b/mobile-widgets/qmlmanager.cpp index b271af6ea..184ce023f 100644 --- a/mobile-widgets/qmlmanager.cpp +++ b/mobile-widgets/qmlmanager.cpp @@ -2120,9 +2120,8 @@ void QMLManager::androidUsbPopoulateConnections() void QMLManager::showDownloadPage(QAndroidJniObject usbDevice) { if (!usbDevice.isValid()) { - // this happens if we get called by the permission granted intent - // if that happens, just make sure the DownloadPage is reopened - m_pluggedInDeviceName = QString("reopen"); + // this really shouldn't happen anymore, but just in case... + m_pluggedInDeviceName = ""; } else { // repopulate the connection list rescanConnections(); @@ -2135,6 +2134,25 @@ void QMLManager::showDownloadPage(QAndroidJniObject usbDevice) } emit pluggedInDeviceNameChanged(); } + +void QMLManager::restartDownload(QAndroidJniObject usbDevice) +{ + // this gets called if we received a permission intent after + // already trying to download from USB + if (!usbDevice.isValid()) { + appendTextToLog("permission intent with invalid UsbDevice - ignoring"); + } else { + // inform that QML code that it should retry downloading + // we get the usbDevice again and could verify that this is + // still the same - but I don't see how this could change while we are waiting + // for permission + android_usb_serial_device_descriptor usbDeviceDescriptor = getDescriptor(usbDevice); + appendTextToLog(QString("got permission from Android, restarting download for %1") + .arg(QString::fromStdString(usbDeviceDescriptor.uiRepresentation))); + emit restartDownloadSignal(); + } +} + #endif void QMLManager::setFilter(const QString filterText, int index) diff --git a/mobile-widgets/qmlmanager.h b/mobile-widgets/qmlmanager.h index c0d036aec..7bd9e5e89 100644 --- a/mobile-widgets/qmlmanager.h +++ b/mobile-widgets/qmlmanager.h @@ -235,6 +235,7 @@ public slots: void rescanConnections(); #if defined(Q_OS_ANDROID) void showDownloadPage(QAndroidJniObject usbDevice); + void restartDownload(QAndroidJniObject usbDevice); void androidUsbPopoulateConnections(); QString getProductVendorConnectionIdx(android_usb_serial_device_descriptor descriptor); #endif @@ -307,6 +308,7 @@ signals: void oldStatusChanged(); void undoTextChanged(); void redoTextChanged(); + void restartDownloadSignal(); // From upload process void uploadFinish(bool success, const QString &text);