Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,9 @@ class LoginActivity : AppCompatActivity(), SslUntrustedCertDialog.OnSslUntrusted
userAccount = intent.getParcelableExtra(EXTRA_ACCOUNT)

// Get values from savedInstanceState
if (savedInstanceState == null) {
if (authTokenType == null && userAccount != null) {
authenticationViewModel.supportsOAuth2((userAccount as Account).name)
}
} else {
if (savedInstanceState == null && authTokenType == null && userAccount != null) {
authenticationViewModel.supportsOAuth2((userAccount as Account).name)
} else if (savedInstanceState != null) {
authTokenType = savedInstanceState.getString(KEY_AUTH_TOKEN_TYPE)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import eu.opencloud.android.lib.resources.files.chunks.ChunkedUploadFromFileSyst
import eu.opencloud.android.lib.resources.files.tus.CreateTusUploadRemoteOperation
import eu.opencloud.android.lib.resources.files.tus.GetTusUploadOffsetRemoteOperation
import eu.opencloud.android.lib.resources.files.tus.PatchTusUploadChunkRemoteOperation
import eu.opencloud.android.domain.exceptions.FileNotFoundException
import timber.log.Timber
import java.io.File
import kotlin.math.min
Expand All @@ -21,6 +22,15 @@ import kotlin.math.min
class TusUploadHelper(
private val transferRepository: TransferRepository,
) {
@Volatile
private var cancelled = false
private var activePatchOperation: PatchTusUploadChunkRemoteOperation? = null

fun cancel() {
cancelled = true
Timber.d("TUS: upload cancellation requested")
activePatchOperation?.cancel()
}

/**
* Runs the full TUS upload flow. On success the method returns normally. On failure an exception
Expand All @@ -41,6 +51,8 @@ class TusUploadHelper(
progressCallback: ((Long, Long) -> Unit)? = null,
spaceWebDavUrl: String? = null,
) {
// Reset cancelled state for new upload
cancelled = false
Timber.d("TUS: starting upload for %s size=%d", remotePath, fileSize)

var tusUrl = transfer.tusUploadUrl
Expand Down Expand Up @@ -131,7 +143,8 @@ class TusUploadHelper(
tusSupport = tusSupport,
progressListener = progressListener,
progressCallback = progressCallback,
initialOffset = offset
initialOffset = offset,
uploadId = uploadId,
)

// Verify upload is actually complete
Expand Down Expand Up @@ -160,18 +173,24 @@ class TusUploadHelper(
tusSupport: OCCapability.TusSupport?,
progressListener: OnDatatransferProgressListener?,
progressCallback: ((Long, Long) -> Unit)?,
initialOffset: Long
initialOffset: Long,
uploadId: Long,
): Long {
var offset = initialOffset
val serverMaxChunk = tusSupport?.maxChunkSize?.takeIf { it > 0 }?.toLong()
val httpOverride = tusSupport?.httpMethodOverride
var consecutiveFailures = 0

while (offset < fileSize) {
while (offset < fileSize && !cancelled) {
val remaining = fileSize - offset
val chunkSize = min(DEFAULT_CHUNK_SIZE, min(remaining, serverMaxChunk ?: Long.MAX_VALUE))
Timber.d("TUS: uploading chunk=%d at offset=%d remaining=%d", chunkSize, offset, remaining)

if (cancelled) {
Timber.i("TUS: upload cancelled by user at offset %d", offset)
throw java.io.InterruptedIOException("TUS upload cancelled by user")
}

val patchOperation = PatchTusUploadChunkRemoteOperation(
localPath = localPath,
uploadUrl = resolvedTusUrl,
Expand All @@ -181,8 +200,10 @@ class TusUploadHelper(
).apply {
progressListener?.let { addDataTransferProgressListener(it) }
}
activePatchOperation = patchOperation

val patchResult = patchOperation.execute(client)
activePatchOperation = null
if (!patchResult.isSuccess || patchResult.data == null || patchResult.data!! < offset) {
consecutiveFailures++
Timber.w(
Expand All @@ -199,6 +220,7 @@ class TusUploadHelper(
currentOffset = offset,
totalSize = fileSize,
progressCallback = progressCallback,
uploadId = uploadId,
)

if (recoveredOffset != null && recoveredOffset > offset) {
Expand Down Expand Up @@ -285,6 +307,7 @@ class TusUploadHelper(
currentOffset: Long,
totalSize: Long,
progressCallback: ((Long, Long) -> Unit)?,
uploadId: Long,
): Long? = try {
val newOffset = executeRemoteOperation {
GetTusUploadOffsetRemoteOperation(tusUrl).execute(client)
Expand All @@ -309,6 +332,19 @@ class TusUploadHelper(
} catch (e: java.io.IOException) {
Timber.w(e, "TUS: recover offset failed")
throw e
} catch (e: FileNotFoundException) {
Timber.w(e, "TUS: upload not found on server (404), clearing state to restart")
transferRepository.updateTusState(
id = uploadId,
tusUploadUrl = null,
tusUploadLength = null,
tusUploadMetadata = null,
tusUploadChecksum = null,
tusResumableVersion = null,
tusUploadExpires = null,
tusUploadConcat = null,
)
throw java.io.IOException("TUS: upload session lost (404), forcing restart", e)
} catch (recoverError: Throwable) {
Timber.w(recoverError, "TUS: recover offset failed")
null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,11 @@ class UploadFileFromContentUriWorker(
}

private fun updateProgressFromTus(offset: Long, totalSize: Long) {
if (this.isStopped) {
Timber.w("Cancelling TUS upload. The worker is stopped by user or system")
tusUploadHelper.cancel()
}

if (totalSize <= 0) return
val percent: Int = (100.0 * offset.toDouble() / totalSize.toDouble()).toInt()
if (percent == lastPercent) return
Expand Down Expand Up @@ -453,6 +458,14 @@ class UploadFileFromContentUriWorker(
totalToTransfer: Long,
filePath: String
) {
if (this.isStopped) {
Timber.w("Cancelling upload operation. The worker is stopped by user or system")
if (::uploadFileOperation.isInitialized) {
uploadFileOperation.cancel()
uploadFileOperation.removeDataTransferProgressListener(this)
}
}

val percent: Int = (100.0 * totalTransferredSoFar.toDouble() / totalToTransfer.toDouble()).toInt()
if (percent == lastPercent) return

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ class UploadFileFromFileSystemWorker(
}

private fun updateProgressFromTus(offset: Long, totalSize: Long) {
if (this.isStopped) {
Timber.w("Cancelling TUS upload. The worker is stopped by user or system")
tusUploadHelper.cancel()
}

if (totalSize <= 0) return
val percent: Int = (100.0 * offset.toDouble() / totalSize.toDouble()).toInt()
if (percent == lastPercent) return
Expand Down Expand Up @@ -458,6 +463,15 @@ class UploadFileFromFileSystemWorker(
totalToTransfer: Long,
filePath: String
) {
if (this.isStopped) {
Timber.w("Cancelling upload operation. The worker is stopped by user or system")
tusUploadHelper.cancel()
if (::uploadFileOperation.isInitialized) {
uploadFileOperation.cancel()
uploadFileOperation.removeDataTransferProgressListener(this)
}
}

val percent: Int = (100.0 * totalTransferredSoFar.toDouble() / totalToTransfer.toDouble()).toInt()
if (percent == lastPercent) return

Expand Down
Loading