@@ -50,6 +50,7 @@ import kotlinx.coroutines.Dispatchers
5050import kotlinx.coroutines.ensureActive
5151import kotlinx.coroutines.withContext
5252import java.io.File
53+ import java.util.concurrent.ConcurrentHashMap
5354import kotlin.random.Random
5455
5556@Suppress(" LongParameterList" , " TooGenericExceptionCaught" )
@@ -80,8 +81,6 @@ class FileUploadWorker(
8081 const val TOTAL_UPLOAD_SIZE = " total_upload_size"
8182 const val SHOW_SAME_FILE_ALREADY_EXISTS_NOTIFICATION = " show_same_file_already_exists_notification"
8283
83- var currentUploadFileOperation: UploadFileOperation ? = null
84-
8584 private const val BATCH_SIZE = 100
8685
8786 const val EXTRA_ACCOUNT_NAME = " ACCOUNT_NAME"
@@ -91,21 +90,26 @@ class FileUploadWorker(
9190 const val LOCAL_BEHAVIOUR_FORGET = 2
9291 const val LOCAL_BEHAVIOUR_DELETE = 3
9392
94- fun cancelCurrentUpload (remotePath : String , accountName : String , onCompleted : () -> Unit ) {
95- currentUploadFileOperation?.let {
96- if (it.remotePath == remotePath && it.user.accountName == accountName) {
97- it.cancel(ResultCode .USER_CANCELLED )
98- onCompleted()
99- }
93+ private val activeOperations = ConcurrentHashMap <Long , UploadFileOperation >()
94+
95+ @JvmOverloads
96+ fun cancelUpload (remotePath : String? , accountName : String? , onCompleted : () -> Unit = {}) {
97+ val operation =
98+ activeOperations.values.find { it.remotePath == remotePath && it.user.accountName == accountName }
99+
100+ operation?.let {
101+ Log_OC .d(TAG , " upload operation is cancelled: $remotePath " )
102+ operation.cancel(ResultCode .USER_CANCELLED )
103+ activeOperations.remove(operation.ocUploadId)
100104 }
105+
106+ onCompleted()
101107 }
102108
103- fun isUploading (remotePath : String? , accountName : String? ): Boolean {
104- currentUploadFileOperation?.let {
105- return it.remotePath == remotePath && it.user.accountName == accountName
106- }
109+ fun getCurrentUpload (id : Long? ): UploadFileOperation ? = activeOperations[id]
107110
108- return false
111+ fun isUploading (remotePath : String? , accountName : String? ): Boolean = activeOperations.values.any {
112+ it.remotePath == remotePath && it.user.accountName == accountName
109113 }
110114
111115 fun getUploadAction (action : String ): Int = when (action) {
@@ -135,7 +139,8 @@ class FileUploadWorker(
135139 result
136140 } catch (t: Throwable ) {
137141 Log_OC .e(TAG , " exception $t " )
138- currentUploadFileOperation?.cancel(null )
142+ activeOperations.values.forEach { it.cancel(null ) }
143+ activeOperations.clear()
139144 Result .failure()
140145 } finally {
141146 // Ensure all database operations are complete before signaling completion
@@ -256,7 +261,7 @@ class FileUploadWorker(
256261
257262 fileUploadEventBroadcaster.sendUploadEnqueued(context)
258263 val operation = createUploadFileOperation(upload, user)
259- currentUploadFileOperation = operation
264+ activeOperations[upload.uploadId] = operation
260265
261266 val currentIndex = (index + 1 )
262267 val currentUploadIndex = (currentIndex + previouslyUploadedFileSize)
@@ -270,7 +275,7 @@ class FileUploadWorker(
270275 val result = withContext(Dispatchers .IO ) {
271276 upload(upload, operation, user, client)
272277 }
273- currentUploadFileOperation = null
278+ activeOperations.remove(upload.uploadId)
274279
275280 if (result.code == ResultCode .QUOTA_EXCEEDED ) {
276281 Log_OC .w(TAG , " Quota exceeded, stopping uploads" )
@@ -379,24 +384,24 @@ class FileUploadWorker(
379384 }
380385 }
381386 result = RemoteOperationResult (e)
382- } finally {
383- if ( ! isStopped) {
384- UploadErrorNotificationManager .handleResult(
385- context,
386- notificationManager ,
387- operation ,
388- result ,
389- onSameFileConflict = {
390- withContext( Dispatchers . Main ) {
391- val showSameFileAlreadyExistsNotification =
392- inputData.getBoolean( SHOW_SAME_FILE_ALREADY_EXISTS_NOTIFICATION , false )
393- if (showSameFileAlreadyExistsNotification) {
394- notificationManager.showSameFileAlreadyExistsNotification(operation.fileName)
395- }
387+ }
388+
389+ if ( ! isStopped) {
390+ UploadErrorNotificationManager .handleResult(
391+ context ,
392+ notificationManager ,
393+ operation ,
394+ result,
395+ onSameFileConflict = {
396+ withContext( Dispatchers . Main ) {
397+ val showSameFileAlreadyExistsNotification =
398+ inputData.getBoolean( SHOW_SAME_FILE_ALREADY_EXISTS_NOTIFICATION , false )
399+ if (showSameFileAlreadyExistsNotification) {
400+ notificationManager.showSameFileAlreadyExistsNotification(operation.fileName)
396401 }
397402 }
398- )
399- }
403+ }
404+ )
400405 }
401406
402407 return @withContext result
@@ -421,6 +426,9 @@ class FileUploadWorker(
421426
422427 if (percent != lastPercent && (currentTime - lastUpdateTime) >= minProgressUpdateInterval) {
423428 notificationManager.run {
429+ val currentUploadFileOperation =
430+ activeOperations.values.find { it.originalStoragePath == fileAbsoluteName }
431+
424432 val accountName = currentUploadFileOperation?.user?.accountName
425433 val remotePath = currentUploadFileOperation?.remotePath
426434
0 commit comments