Garmin: fix transfer notification leaks and stray pre-start posts

Three lifecycle bugs in GarminSupport's transferNotification:

* addFileToDownloadList incremented totalSize unconditionally, so a directory listing arriving on connect posted a notification with the unlocalised "Unknown transfer" fallback title before any transfer started.

* The start/finish pair gated on gbDevice.isBusy(), which other paths set and clear — start could be skipped while the matching finish ran anyway, or vice versa.

* dispose() didn't finish the notification, leaving it pinned after a mid-sync disconnect.

Gate the increments and the start/finish pair on the private isBusyFetching flag, and finish + clear the flag in dispose().
This commit is contained in:
Ingvar Stepanyan
2026-06-06 21:26:51 +02:00
committed by José Rebelo
parent 3b9b4126ba
commit 3d48db83c9
@@ -213,6 +213,10 @@ public class GarminSupport extends AbstractBTLESingleDeviceSupport implements IC
public void dispose() {
synchronized (ConnectionMonitor) {
LOG.info("Garmin dispose()");
// Clear any in-flight transfer notification; otherwise a disconnect
// mid-sync leaves the progress notification pinned indefinitely.
transferNotification.finish();
isBusyFetching = false;
if (communicator != null) {
communicator.dispose();
}
@@ -248,14 +252,16 @@ public class GarminSupport extends AbstractBTLESingleDeviceSupport implements IC
return;
}
filesToDownload.add(new FileToDownload(directoryEntry));
if (directoryEntry.getFiletype() != FileType.FILETYPE.DIRECTORY) {
// Only grow the visible total once a transfer is active; before start()
// the initial size is computed from the queue sum in processDownloadQueue.
if (isBusyFetching && directoryEntry.getFiletype() != FileType.FILETYPE.DIRECTORY) {
transferNotification.incrementTotalSize(directoryEntry.getFileSize());
}
}
public void addFileToDownloadList(GdiFileSyncService.File file) {
filesToDownload.add(new FileToDownload(file));
if (file.hasSize()) {
if (isBusyFetching && file.hasSize()) {
transferNotification.incrementTotalSize(file.getSize());
}
}
@@ -866,7 +872,10 @@ public class GarminSupport extends AbstractBTLESingleDeviceSupport implements IC
if (!filesToDownload.isEmpty() && currentlyDownloading == null) {
LOG.debug("Processing next file of {}", filesToDownload.size());
if (!gbDevice.isBusy()) {
// Gate on our own fetch state, not gbDevice.isBusy(): the latter can
// be set/cleared by unrelated paths and would desync the notification's
// start/finish pairing.
if (!isBusyFetching) {
LOG.debug("Starting download queue");
isBusyFetching = true;
@@ -937,7 +946,7 @@ public class GarminSupport extends AbstractBTLESingleDeviceSupport implements IC
if (filesToProcess.isEmpty()) {
LOG.debug("No pending files to process");
// No downloaded fit files to process
if (gbDevice.isBusy() && isBusyFetching) {
if (isBusyFetching) {
getDevice().unsetBusyTask();
GB.signalActivityDataFinish(getDevice());
transferNotification.finish();