From a664097b71130f88ee5d103f2a052f9b264b1fb1 Mon Sep 17 00:00:00 2001 From: zerox80 Date: Tue, 12 May 2026 11:42:23 +0200 Subject: [PATCH 1/3] Guard upload progress when total size is unknown --- .../workers/UploadFileFromContentUriWorker.kt | 4 +- .../workers/UploadFileFromFileSystemWorker.kt | 4 +- .../workers/UploadProgressCalculator.kt | 27 +++++++++++ .../workers/UploadProgressCalculatorTest.kt | 45 +++++++++++++++++++ 4 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 opencloudApp/src/main/java/eu/opencloud/android/workers/UploadProgressCalculator.kt create mode 100644 opencloudApp/src/test/java/eu/opencloud/android/workers/UploadProgressCalculatorTest.kt diff --git a/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromContentUriWorker.kt b/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromContentUriWorker.kt index bee2f350d..ffe443605 100644 --- a/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromContentUriWorker.kt +++ b/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromContentUriWorker.kt @@ -380,7 +380,7 @@ class UploadFileFromContentUriWorker( } if (totalSize <= 0) return - val percent: Int = (100.0 * offset.toDouble() / totalSize.toDouble()).toInt() + val percent: Int = UploadProgressCalculator.percent(offset, totalSize) if (percent == lastPercent) return CoroutineScope(Dispatchers.IO).launch { @@ -479,7 +479,7 @@ class UploadFileFromContentUriWorker( } } - val percent: Int = (100.0 * totalTransferredSoFar.toDouble() / totalToTransfer.toDouble()).toInt() + val percent: Int = UploadProgressCalculator.percent(totalTransferredSoFar, totalToTransfer) if (percent == lastPercent) return // Set current progress. Observers will listen. diff --git a/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromFileSystemWorker.kt b/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromFileSystemWorker.kt index 91296f842..6c01a1567 100644 --- a/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromFileSystemWorker.kt +++ b/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadFileFromFileSystemWorker.kt @@ -347,7 +347,7 @@ class UploadFileFromFileSystemWorker( } if (totalSize <= 0) return - val percent: Int = (100.0 * offset.toDouble() / totalSize.toDouble()).toInt() + val percent: Int = UploadProgressCalculator.percent(offset, totalSize) if (percent == lastPercent) return CoroutineScope(Dispatchers.IO).launch { @@ -480,7 +480,7 @@ class UploadFileFromFileSystemWorker( } } - val percent: Int = (100.0 * totalTransferredSoFar.toDouble() / totalToTransfer.toDouble()).toInt() + val percent: Int = UploadProgressCalculator.percent(totalTransferredSoFar, totalToTransfer) if (percent == lastPercent) return // Set current progress. Observers will listen. diff --git a/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadProgressCalculator.kt b/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadProgressCalculator.kt new file mode 100644 index 000000000..7ea85798d --- /dev/null +++ b/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadProgressCalculator.kt @@ -0,0 +1,27 @@ +/** + * openCloud Android client application + * + * Copyright (C) 2026 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package eu.opencloud.android.workers + +internal object UploadProgressCalculator { + fun percent(transferred: Long, total: Long): Int = + if (total <= 0L || transferred <= 0L) { + 0 + } else { + (100.0 * transferred.toDouble() / total.toDouble()).toInt().coerceIn(0, 100) + } +} diff --git a/opencloudApp/src/test/java/eu/opencloud/android/workers/UploadProgressCalculatorTest.kt b/opencloudApp/src/test/java/eu/opencloud/android/workers/UploadProgressCalculatorTest.kt new file mode 100644 index 000000000..655f54d3a --- /dev/null +++ b/opencloudApp/src/test/java/eu/opencloud/android/workers/UploadProgressCalculatorTest.kt @@ -0,0 +1,45 @@ +/** + * openCloud Android client application + * + * Copyright (C) 2026 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package eu.opencloud.android.workers + +import org.junit.Assert.assertEquals +import org.junit.Test + +class UploadProgressCalculatorTest { + @Test + fun `percent returns zero when total is unknown or zero`() { + assertEquals(0, UploadProgressCalculator.percent(transferred = 25, total = -1)) + assertEquals(0, UploadProgressCalculator.percent(transferred = 25, total = 0)) + } + + @Test + fun `percent returns zero when transferred is zero or negative`() { + assertEquals(0, UploadProgressCalculator.percent(transferred = 0, total = 100)) + assertEquals(0, UploadProgressCalculator.percent(transferred = -1, total = 100)) + } + + @Test + fun `percent calculates normal progress`() { + assertEquals(25, UploadProgressCalculator.percent(transferred = 25, total = 100)) + } + + @Test + fun `percent clamps over complete progress`() { + assertEquals(100, UploadProgressCalculator.percent(transferred = 125, total = 100)) + } +} From 029139c4043474dda50922b5df51c7af9f78a510 Mon Sep 17 00:00:00 2001 From: zerox80 <115537871+zerox80@users.noreply.github.com> Date: Tue, 12 May 2026 12:04:28 +0200 Subject: [PATCH 2/3] Update UploadProgressCalculatorTest.kt --- .../opencloud/android/workers/UploadProgressCalculatorTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opencloudApp/src/test/java/eu/opencloud/android/workers/UploadProgressCalculatorTest.kt b/opencloudApp/src/test/java/eu/opencloud/android/workers/UploadProgressCalculatorTest.kt index 655f54d3a..afeaa75d9 100644 --- a/opencloudApp/src/test/java/eu/opencloud/android/workers/UploadProgressCalculatorTest.kt +++ b/opencloudApp/src/test/java/eu/opencloud/android/workers/UploadProgressCalculatorTest.kt @@ -1,7 +1,7 @@ /** * openCloud Android client application * - * Copyright (C) 2026 ownCloud GmbH. + * Copyright (C) 2026 OpenCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, From e1fbba2d13f74ec1463ea32d7ea5cd734af044ae Mon Sep 17 00:00:00 2001 From: zerox80 <115537871+zerox80@users.noreply.github.com> Date: Tue, 12 May 2026 12:04:56 +0200 Subject: [PATCH 3/3] Update UploadProgressCalculator.kt --- .../eu/opencloud/android/workers/UploadProgressCalculator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadProgressCalculator.kt b/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadProgressCalculator.kt index 7ea85798d..06229862d 100644 --- a/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadProgressCalculator.kt +++ b/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadProgressCalculator.kt @@ -1,7 +1,7 @@ /** * openCloud Android client application * - * Copyright (C) 2026 ownCloud GmbH. + * Copyright (C) 2026 OpenCloud GmbH. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2,