From a54edd4a53664b34773cea195255885be75eede1 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 11 Jun 2026 10:59:48 +0200 Subject: [PATCH 1/6] add session time out to nextcloud client Signed-off-by: alperozturk96 --- .../main/java/com/nextcloud/common/NextcloudClient.kt | 10 ++++++++++ .../lib/resources/files/DownloadFileRemoteOperation.kt | 7 +++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/library/src/main/java/com/nextcloud/common/NextcloudClient.kt b/library/src/main/java/com/nextcloud/common/NextcloudClient.kt index 830822308f..c13ac0d659 100644 --- a/library/src/main/java/com/nextcloud/common/NextcloudClient.kt +++ b/library/src/main/java/com/nextcloud/common/NextcloudClient.kt @@ -207,6 +207,16 @@ class NextcloudClient private constructor( } } + fun withSessionTimeOut(sessionTimeOut: SessionTimeOut): NextcloudClient { + val newClient = + client + .newBuilder() + .readTimeout(sessionTimeOut.readTimeOut.toLong(), TimeUnit.MILLISECONDS) + .connectTimeout(sessionTimeOut.connectionTimeOut.toLong(), TimeUnit.MILLISECONDS) + .build() + return NextcloudClient(delegate, credentials, newClient, context) + } + fun getUserIdEncoded(): String = delegate.userIdEncoded!! fun getUserIdPlain(): String = delegate.userId!! diff --git a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt index 0500c1c7a2..7a87ef8e99 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt @@ -9,6 +9,8 @@ package com.owncloud.android.lib.resources.files import android.os.Build import androidx.annotation.RequiresApi import com.nextcloud.common.NextcloudClient +import com.nextcloud.common.SessionTimeOut +import com.nextcloud.common.defaultSessionTimeOut import com.nextcloud.operations.GetMethod import com.owncloud.android.lib.common.network.OnDatatransferProgressListener import com.owncloud.android.lib.common.network.WebdavUtils @@ -29,7 +31,8 @@ import java.util.concurrent.atomic.AtomicBoolean @RequiresApi(Build.VERSION_CODES.O) class DownloadFileRemoteOperation( private val remotePath: String, - private val temporalFolderPath: String? + private val temporalFolderPath: String?, + private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut ) : RemoteOperation() { private val dataTransferListeners = ConcurrentHashMap.newKeySet() private val cancellationRequested = AtomicBoolean(false) @@ -63,7 +66,7 @@ class DownloadFileRemoteOperation( client: NextcloudClient, targetPath: Path ): Int { - val status = client.execute(getMethod) + val status = client.withSessionTimeOut(sessionTimeOut).execute(getMethod) if (!isSuccess(status)) { getMethod.releaseConnection() return status From 612f50e6ebacb6a98ce276a5ed01be47ac9c9309 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 11 Jun 2026 11:14:40 +0200 Subject: [PATCH 2/6] add tests Signed-off-by: alperozturk96 --- .../files/DownloadFileRemoteOperationIT.kt | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/library/src/androidTest/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperationIT.kt b/library/src/androidTest/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperationIT.kt index 0485f2993b..f3f8ab3e5c 100644 --- a/library/src/androidTest/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperationIT.kt +++ b/library/src/androidTest/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperationIT.kt @@ -8,7 +8,15 @@ */ package com.owncloud.android.lib.resources.files +import com.nextcloud.common.NextcloudClient import com.owncloud.android.AbstractIT +import okhttp3.Interceptor +import okhttp3.Response +import okhttp3.ResponseBody +import okio.Buffer +import okio.BufferedSource +import okio.ForwardingSource +import okio.buffer import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertSame @@ -167,4 +175,62 @@ class DownloadFileRemoteOperationIT : AbstractIT() { assertTrue("Downloaded file should exist at expected path", expectedFile.exists()) assertTrue("Downloaded file should not be empty", expectedFile.length() >= 0) } + + @Test + fun downloadLargeFileSucceedsWithNoCallTimeout() { + val filePath = createFile("large_no_call_timeout", 1000) + val remotePath = "/large_no_call_timeout.txt" + assertTrue( + UploadFileRemoteOperation(filePath, remotePath, "text/plain", RANDOM_MTIME) + .execute(client) + .isSuccess + ) + + val slowOkHttpClient = + nextcloudClient.client + .newBuilder() + .addInterceptor(ChunkDelayInterceptor(delayMs = 100)) + .build() + val slowNextcloudClient = + NextcloudClient(url, nextcloudClient.getUserIdPlain(), nextcloudClient.credentials, slowOkHttpClient, nextcloudClient.context) + + assertTrue( + DownloadFileRemoteOperation(remotePath, cacheDir) + .execute(slowNextcloudClient) + .isSuccess + ) + + assertEquals(File(filePath).length(), File(cacheDir + remotePath).length()) + } + + /** + * Used for create delay for test + */ + private class ChunkDelayInterceptor(private val delayMs: Long) : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val response = chain.proceed(chain.request()) + val body = response.body + val slowSource = + object : ForwardingSource(body.source()) { + override fun read( + sink: Buffer, + byteCount: Long + ): Long { + Thread.sleep(delayMs) + return super.read(sink, byteCount) + } + } + val slowBody = + object : ResponseBody() { + private val bufferedSource: BufferedSource = slowSource.buffer() + + override fun contentType() = body.contentType() + + override fun contentLength() = body.contentLength() + + override fun source() = bufferedSource + } + return response.newBuilder().body(slowBody).build() + } + } } From 955fd1107b97bc75320a6eab6f33c98f874c22f6 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 11 Jun 2026 11:42:59 +0200 Subject: [PATCH 3/6] calculateSessionTimeOut based on file size Signed-off-by: alperozturk96 --- .../files/DownloadFileRemoteOperationIT.kt | 12 +- .../com/nextcloud/common/NextcloudClient.kt | 3 +- .../files/DownloadFileRemoteOperation.kt | 225 ++++++++++-------- 3 files changed, 134 insertions(+), 106 deletions(-) diff --git a/library/src/androidTest/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperationIT.kt b/library/src/androidTest/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperationIT.kt index f3f8ab3e5c..d3e8c2f76c 100644 --- a/library/src/androidTest/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperationIT.kt +++ b/library/src/androidTest/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperationIT.kt @@ -192,7 +192,13 @@ class DownloadFileRemoteOperationIT : AbstractIT() { .addInterceptor(ChunkDelayInterceptor(delayMs = 100)) .build() val slowNextcloudClient = - NextcloudClient(url, nextcloudClient.getUserIdPlain(), nextcloudClient.credentials, slowOkHttpClient, nextcloudClient.context) + NextcloudClient( + url, + nextcloudClient.getUserIdPlain(), + nextcloudClient.credentials, + slowOkHttpClient, + nextcloudClient.context + ) assertTrue( DownloadFileRemoteOperation(remotePath, cacheDir) @@ -206,7 +212,9 @@ class DownloadFileRemoteOperationIT : AbstractIT() { /** * Used for create delay for test */ - private class ChunkDelayInterceptor(private val delayMs: Long) : Interceptor { + private class ChunkDelayInterceptor( + private val delayMs: Long + ) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val response = chain.proceed(chain.request()) val body = response.body diff --git a/library/src/main/java/com/nextcloud/common/NextcloudClient.kt b/library/src/main/java/com/nextcloud/common/NextcloudClient.kt index c13ac0d659..65a4f26e8c 100644 --- a/library/src/main/java/com/nextcloud/common/NextcloudClient.kt +++ b/library/src/main/java/com/nextcloud/common/NextcloudClient.kt @@ -1,7 +1,8 @@ /* * Nextcloud Android Library * - * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2019-2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2026 Alper Ozturk * SPDX-FileCopyrightText: 2019-2024 Tobias Kaminsky * SPDX-FileCopyrightText: 2023 Elv1zz * SPDX-FileCopyrightText: 2022 Álvaro Brey diff --git a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt index 7a87ef8e99..62ede748d9 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt @@ -29,129 +29,148 @@ import java.util.concurrent.atomic.AtomicBoolean @Suppress("NestedBlockDepth", "TooGenericExceptionCaught", "ThrowsCount") @RequiresApi(Build.VERSION_CODES.O) -class DownloadFileRemoteOperation( - private val remotePath: String, - private val temporalFolderPath: String?, - private val sessionTimeOut: SessionTimeOut = defaultSessionTimeOut -) : RemoteOperation() { - private val dataTransferListeners = ConcurrentHashMap.newKeySet() - private val cancellationRequested = AtomicBoolean(false) - var modificationTimestamp: Long = 0 - private set - var etag: String = "" - private set - - @Suppress("DEPRECATION") - override fun run(client: NextcloudClient): RemoteOperationResult { - val targetPath = Paths.get(tmpPath) - return try { - val parent = targetPath.parent ?: throw IOException("No parent directory for: $targetPath") - Files.createDirectories(parent) - val getMethod = GetMethod(client.getFilesDavUri(remotePath), false) - val status = downloadFile(getMethod, client, targetPath) - RemoteOperationResult(isSuccess(status), getMethod).also { - Log_OC.i(TAG, "Download of $remotePath to $targetPath: ${it.logMessage}") - } - } catch (e: Exception) { - RemoteOperationResult(e).also { - Log_OC.e(TAG, "Download of $remotePath to $targetPath: ${it.logMessage}", e) +class DownloadFileRemoteOperation + @JvmOverloads + constructor( + private val remotePath: String, + private val temporalFolderPath: String?, + private val fileSizeInBytes: Long? = null + ) : RemoteOperation() { + private val dataTransferListeners = ConcurrentHashMap.newKeySet() + private val cancellationRequested = AtomicBoolean(false) + var modificationTimestamp: Long = 0 + private set + var etag: String = "" + private set + + @Suppress("DEPRECATION") + override fun run(client: NextcloudClient): RemoteOperationResult { + val targetPath = Paths.get(tmpPath) + return try { + val parent = targetPath.parent ?: throw IOException("No parent directory for: $targetPath") + Files.createDirectories(parent) + val getMethod = GetMethod(client.getFilesDavUri(remotePath), false) + val status = downloadFile(getMethod, client, targetPath) + RemoteOperationResult(isSuccess(status), getMethod).also { + Log_OC.i(TAG, "Download of $remotePath to $targetPath: ${it.logMessage}") + } + } catch (e: Exception) { + RemoteOperationResult(e).also { + Log_OC.e(TAG, "Download of $remotePath to $targetPath: ${it.logMessage}", e) + } } } - } - // region private methods - @Throws(IOException::class, OperationCancelledException::class, CreateLocalFileException::class) - private fun downloadFile( - getMethod: GetMethod, - client: NextcloudClient, - targetPath: Path - ): Int { - val status = client.withSessionTimeOut(sessionTimeOut).execute(getMethod) - if (!isSuccess(status)) { - getMethod.releaseConnection() + // region private methods + @Throws(IOException::class, OperationCancelledException::class, CreateLocalFileException::class) + private fun downloadFile( + getMethod: GetMethod, + client: NextcloudClient, + targetPath: Path + ): Int { + val sessionTimeOut = fileSizeInBytes?.let { calculateSessionTimeOut(it) } ?: defaultSessionTimeOut + val downloadClient = client.withSessionTimeOut(sessionTimeOut) + val status = downloadClient.execute(getMethod) + if (!isSuccess(status)) { + getMethod.releaseConnection() + return status + } + + try { + writeResponseToFile(getMethod, targetPath) + readMetadata(getMethod) + } finally { + getMethod.releaseConnection() + } + return status } - try { - writeResponseToFile(getMethod, targetPath) - readMetadata(getMethod) - } finally { - getMethod.releaseConnection() + private fun calculateSessionTimeOut(fileSizeInBytes: Long): SessionTimeOut { + if (fileSizeInBytes <= 0) return defaultSessionTimeOut + val readTimeOut = + (READ_TIMEOUT_PER_GB * fileSizeInBytes / BYTES_PER_GB_LONG) + .coerceIn(READ_TIMEOUT_MIN, READ_TIMEOUT_MAX) + .toInt() + return SessionTimeOut(readTimeOut = readTimeOut, connectionTimeOut = CONNECTION_TIMEOUT) } - return status - } - - private fun writeResponseToFile( - getMethod: GetMethod, - targetPath: Path - ) { - val responseStream = - getMethod.getResponseBodyAsStream() - ?: throw IOException("Empty response body for $remotePath") - - val outputStream = - try { - Files.newOutputStream(targetPath) - } catch (ex: IOException) { - Log_OC.e(TAG, "Error creating file $targetPath", ex) - throw CreateLocalFileException(targetPath.toString(), ex) - } catch (ex: SecurityException) { - Log_OC.e(TAG, "Error creating file $targetPath", ex) - throw CreateLocalFileException(targetPath.toString(), ex) - } + private fun writeResponseToFile( + getMethod: GetMethod, + targetPath: Path + ) { + val responseStream = + getMethod.getResponseBodyAsStream() + ?: throw IOException("Empty response body for $remotePath") + + val outputStream = + try { + Files.newOutputStream(targetPath) + } catch (ex: IOException) { + Log_OC.e(TAG, "Error creating file $targetPath", ex) + throw CreateLocalFileException(targetPath.toString(), ex) + } catch (ex: SecurityException) { + Log_OC.e(TAG, "Error creating file $targetPath", ex) + throw CreateLocalFileException(targetPath.toString(), ex) + } - BufferedInputStream(responseStream).use { bis -> - outputStream.use { fos -> - val buffer = ByteArray(BUFFER_SIZE) - var bytesRead: Int - while (bis.read(buffer).also { bytesRead = it } != -1) { - if (cancellationRequested.get()) throw OperationCancelledException() - fos.write(buffer, 0, bytesRead) + BufferedInputStream(responseStream).use { bis -> + outputStream.use { fos -> + val buffer = ByteArray(BUFFER_SIZE) + var bytesRead: Int + while (bis.read(buffer).also { bytesRead = it } != -1) { + if (cancellationRequested.get()) throw OperationCancelledException() + fos.write(buffer, 0, bytesRead) + } } } } - } - private fun readMetadata(getMethod: GetMethod) { - val modificationTime = - getMethod.getResponseHeader("Last-Modified") - ?: getMethod.getResponseHeader("last-modified") + private fun readMetadata(getMethod: GetMethod) { + val modificationTime = + getMethod.getResponseHeader("Last-Modified") + ?: getMethod.getResponseHeader("last-modified") - if (modificationTime != null) { - modificationTimestamp = WebdavUtils.parseResponseDate(modificationTime)?.time ?: 0 - } else { - Log_OC.e(TAG, "Could not read modification time from response downloading $remotePath") - } + if (modificationTime != null) { + modificationTimestamp = WebdavUtils.parseResponseDate(modificationTime)?.time ?: 0 + } else { + Log_OC.e(TAG, "Could not read modification time from response downloading $remotePath") + } - etag = WebdavUtils.getEtagFromResponse(getMethod) - if (etag.isEmpty()) { - Log_OC.e(TAG, "Could not read eTag from response downloading $remotePath") + etag = WebdavUtils.getEtagFromResponse(getMethod) + if (etag.isEmpty()) { + Log_OC.e(TAG, "Could not read eTag from response downloading $remotePath") + } } - } - private fun isSuccess(status: Int) = (status == HttpStatus.SC_OK) + private fun isSuccess(status: Int) = (status == HttpStatus.SC_OK) - private val tmpPath: String - get() = temporalFolderPath + remotePath - // endregion + private val tmpPath: String + get() = temporalFolderPath + remotePath + // endregion - // region public methods - fun addProgressListener(listener: OnDatatransferProgressListener) { - dataTransferListeners.add(listener) - } + // region public methods + fun addProgressListener(listener: OnDatatransferProgressListener) { + dataTransferListeners.add(listener) + } - fun removeProgressListener(listener: OnDatatransferProgressListener) { - dataTransferListeners.remove(listener) - } + fun removeProgressListener(listener: OnDatatransferProgressListener) { + dataTransferListeners.remove(listener) + } - fun cancel() { - cancellationRequested.set(true) - } - // endregion + fun cancel() { + cancellationRequested.set(true) + } + // endregion + + companion object { + private val TAG = DownloadFileRemoteOperation::class.java.simpleName + private const val BUFFER_SIZE = 4096 - companion object { - private val TAG = DownloadFileRemoteOperation::class.java.simpleName - private const val BUFFER_SIZE = 4096 + private const val BYTES_PER_GB_LONG = 1_000_000_000L + private const val READ_TIMEOUT_MIN = 60 * 1000L // 1 min + private const val READ_TIMEOUT_PER_GB = 3 * 60 * 1000L // 3 min per GB + private const val READ_TIMEOUT_MAX = 30 * 60 * 1000L // 30 min cap + private const val CONNECTION_TIMEOUT = 15 * 1000 // 15 s + } } -} From d37c997a4a6b6282261691597b6fcf5e1f540034 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 11 Jun 2026 11:43:44 +0200 Subject: [PATCH 4/6] calculateSessionTimeOut based on file size Signed-off-by: alperozturk96 --- .../lib/resources/files/DownloadFileRemoteOperation.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt index 62ede748d9..f2d85fbeca 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt @@ -68,7 +68,7 @@ class DownloadFileRemoteOperation client: NextcloudClient, targetPath: Path ): Int { - val sessionTimeOut = fileSizeInBytes?.let { calculateSessionTimeOut(it) } ?: defaultSessionTimeOut + val sessionTimeOut = calculateSessionTimeOut(fileSizeInBytes) val downloadClient = client.withSessionTimeOut(sessionTimeOut) val status = downloadClient.execute(getMethod) if (!isSuccess(status)) { @@ -86,7 +86,8 @@ class DownloadFileRemoteOperation return status } - private fun calculateSessionTimeOut(fileSizeInBytes: Long): SessionTimeOut { + private fun calculateSessionTimeOut(fileSizeInBytes: Long?): SessionTimeOut { + fileSizeInBytes ?: return defaultSessionTimeOut if (fileSizeInBytes <= 0) return defaultSessionTimeOut val readTimeOut = (READ_TIMEOUT_PER_GB * fileSizeInBytes / BYTES_PER_GB_LONG) From cbfa63952216fa87b3bd95b3e68cb2e5056297d9 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 11 Jun 2026 13:47:55 +0200 Subject: [PATCH 5/6] fix download progress Signed-off-by: alperozturk96 --- .../java/com/nextcloud/common/NextcloudClient.kt | 3 +++ .../resources/files/DownloadFileRemoteOperation.kt | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/library/src/main/java/com/nextcloud/common/NextcloudClient.kt b/library/src/main/java/com/nextcloud/common/NextcloudClient.kt index 65a4f26e8c..1307feb2a7 100644 --- a/library/src/main/java/com/nextcloud/common/NextcloudClient.kt +++ b/library/src/main/java/com/nextcloud/common/NextcloudClient.kt @@ -214,6 +214,9 @@ class NextcloudClient private constructor( .newBuilder() .readTimeout(sessionTimeOut.readTimeOut.toLong(), TimeUnit.MILLISECONDS) .connectTimeout(sessionTimeOut.connectionTimeOut.toLong(), TimeUnit.MILLISECONDS) + + // needed to prevent cancellation, seems like default value not applied + .callTimeout(0, TimeUnit.MILLISECONDS) .build() return NextcloudClient(delegate, credentials, newClient, context) } diff --git a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt index f2d85fbeca..35cff893eb 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt @@ -115,6 +115,9 @@ class DownloadFileRemoteOperation throw CreateLocalFileException(targetPath.toString(), ex) } + val totalToTransfer = fileSizeInBytes ?: 0L + var totalBytesRead = 0L + BufferedInputStream(responseStream).use { bis -> outputStream.use { fos -> val buffer = ByteArray(BUFFER_SIZE) @@ -122,6 +125,15 @@ class DownloadFileRemoteOperation while (bis.read(buffer).also { bytesRead = it } != -1) { if (cancellationRequested.get()) throw OperationCancelledException() fos.write(buffer, 0, bytesRead) + totalBytesRead += bytesRead + dataTransferListeners.forEach { listener -> + listener.onTransferProgress( + bytesRead.toLong(), + totalBytesRead, + totalToTransfer, + targetPath.toString() + ) + } } } } From db0b541a73f18bc39aad13b8d5ffec4338e346e1 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Thu, 11 Jun 2026 13:52:12 +0200 Subject: [PATCH 6/6] wip Signed-off-by: alperozturk96 --- library/src/main/java/com/nextcloud/common/NextcloudClient.kt | 1 - .../android/lib/resources/files/DownloadFileRemoteOperation.kt | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/main/java/com/nextcloud/common/NextcloudClient.kt b/library/src/main/java/com/nextcloud/common/NextcloudClient.kt index 1307feb2a7..7f51e6437a 100644 --- a/library/src/main/java/com/nextcloud/common/NextcloudClient.kt +++ b/library/src/main/java/com/nextcloud/common/NextcloudClient.kt @@ -214,7 +214,6 @@ class NextcloudClient private constructor( .newBuilder() .readTimeout(sessionTimeOut.readTimeOut.toLong(), TimeUnit.MILLISECONDS) .connectTimeout(sessionTimeOut.connectionTimeOut.toLong(), TimeUnit.MILLISECONDS) - // needed to prevent cancellation, seems like default value not applied .callTimeout(0, TimeUnit.MILLISECONDS) .build() diff --git a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt index 35cff893eb..734074c758 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt +++ b/library/src/main/java/com/owncloud/android/lib/resources/files/DownloadFileRemoteOperation.kt @@ -86,6 +86,7 @@ class DownloadFileRemoteOperation return status } + @Suppress("ReturnCount") private fun calculateSessionTimeOut(fileSizeInBytes: Long?): SessionTimeOut { fileSizeInBytes ?: return defaultSessionTimeOut if (fileSizeInBytes <= 0) return defaultSessionTimeOut