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..06229862d --- /dev/null +++ b/opencloudApp/src/main/java/eu/opencloud/android/workers/UploadProgressCalculator.kt @@ -0,0 +1,27 @@ +/** + * openCloud Android client application + * + * 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, + * 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..afeaa75d9 --- /dev/null +++ b/opencloudApp/src/test/java/eu/opencloud/android/workers/UploadProgressCalculatorTest.kt @@ -0,0 +1,45 @@ +/** + * openCloud Android client application + * + * 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, + * 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)) + } +}