diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/UploadContentWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/UploadContentWorker.kt index a6bdda3c..2597ef4e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/UploadContentWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/content/UploadContentWorker.kt @@ -47,7 +47,8 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) : val roomId: String, val event: Event, val attachment: ContentAttachmentData, - val isRoomEncrypted: Boolean + val isRoomEncrypted: Boolean, + override var lastFailureMessage: String? = null ) : SessionWorkerParams @Inject lateinit var fileUploader: FileUploader @@ -57,6 +58,11 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) : val params = WorkerParamsFactory.fromData(inputData) ?: return Result.success() + if (params.lastFailureMessage != null) { + // Transmit the error + return Result.success(inputData) + } + val sessionComponent = getSessionComponent(params.userId) ?: return Result.success() sessionComponent.inject(this) @@ -110,7 +116,7 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) : uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo fileUploader - .uploadByteArray(encryptionResult.encryptedByteArray, attachment.name, attachment.mimeType, progressListener) + .uploadByteArray(encryptionResult.encryptedByteArray, attachment.name, "application/octet-stream", progressListener) } else { fileUploader .uploadFile(attachmentFile, attachment.name, attachment.mimeType, progressListener) @@ -118,7 +124,7 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) : return contentUploadResponse .fold( - { handleFailure(params) }, + { handleFailure(params, it) }, { handleSuccess(params, it.contentUri, uploadedFileEncryptedFileInfo, uploadedThumbnailUrl, uploadedThumbnailEncryptedFileInfo) } ) } @@ -132,9 +138,15 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) : } } - private fun handleFailure(params: Params): Result { + private fun handleFailure(params: Params, failure: Throwable): Result { contentUploadStateTracker.setFailure(params.event.eventId!!) - return Result.success() + return Result.success( + WorkerParamsFactory.toData( + params.copy( + lastFailureMessage = failure.localizedMessage + ) + ) + ) } private fun handleSuccess(params: Params, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt index 4b3d6453..a619b83a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GetGroupDataWorker.kt @@ -20,28 +20,26 @@ import android.content.Context import androidx.work.CoroutineWorker import androidx.work.WorkerParameters import arrow.core.Try -import com.squareup.inject.assisted.Assisted -import com.squareup.inject.assisted.AssistedInject import com.squareup.moshi.JsonClass -import im.vector.matrix.android.internal.worker.DelegateWorkerFactory import im.vector.matrix.android.internal.worker.SessionWorkerParams import im.vector.matrix.android.internal.worker.WorkerParamsFactory import im.vector.matrix.android.internal.worker.getSessionComponent import javax.inject.Inject -internal class GetGroupDataWorker (context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { +internal class GetGroupDataWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { @JsonClass(generateAdapter = true) internal data class Params( override val userId: String, - val groupIds: List - ): SessionWorkerParams + val groupIds: List, + override var lastFailureMessage: String? = null + ) : SessionWorkerParams @Inject lateinit var getGroupDataTask: GetGroupDataTask override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) - ?: return Result.failure() + ?: return Result.failure() val sessionComponent = getSessionComponent(params.userId) ?: return Result.success() sessionComponent.inject(this) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt index 8d93c8b0..31c381f4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/DefaultRelationService.kt @@ -31,10 +31,8 @@ import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.internal.database.RealmLiveData import im.vector.matrix.android.internal.database.helper.addSendingEvent import im.vector.matrix.android.internal.database.mapper.asDomain -import im.vector.matrix.android.internal.database.model.ChunkEntity import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity import im.vector.matrix.android.internal.database.model.RoomEntity -import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.session.room.send.EncryptEventWorker import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory @@ -107,9 +105,12 @@ internal class DefaultRelationService @Inject constructor(private val context: C //TODO duplicate with send service? private fun createRedactEventWork(localEvent: Event, eventId: String, reason: String?): OneTimeWorkRequest { - - val sendContentWorkerParams = RedactEventWorker.Params(credentials.userId, localEvent.eventId!!, - roomId, eventId, reason) + val sendContentWorkerParams = RedactEventWorker.Params( + credentials.userId, + localEvent.eventId!!, + roomId, + eventId, + reason) val redactWorkData = WorkerParamsFactory.toData(sendContentWorkerParams) return TimelineSendEventWorkCommon.createWork(redactWorkData) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt index 16e5f52f..a04c7b3e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/relation/SendRelationWorker.kt @@ -39,7 +39,8 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters) : override val userId: String, val roomId: String, val event: Event, - val relationType: String? = null + val relationType: String? = null, + override var lastFailureMessage: String? ) : SessionWorkerParams @Inject lateinit var roomAPI: RoomAPI @@ -48,6 +49,11 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters) : val params = WorkerParamsFactory.fromData(inputData) ?: return Result.failure() + if (params.lastFailureMessage != null) { + // Transmit the error + return Result.success(inputData) + } + val sessionComponent = getSessionComponent(params.userId) ?: return Result.success() sessionComponent.inject(this) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt index 9e68f6d1..44046a1d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/EncryptEventWorker.kt @@ -41,7 +41,8 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) val roomId: String, val event: Event, /**Do not encrypt these keys, keep them as is in encrypted content (e.g. m.relates_to)*/ - val keepKeys: List? = null + val keepKeys: List? = null, + override var lastFailureMessage: String? = null ) : SessionWorkerParams @Inject lateinit var crypto: CryptoService @@ -52,6 +53,11 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) val params = WorkerParamsFactory.fromData(inputData) ?: return Result.success() + if (params.lastFailureMessage != null) { + // Transmit the error + return Result.success(inputData) + } + val sessionComponent = getSessionComponent(params.userId) ?: return Result.success() sessionComponent.inject(this) @@ -105,16 +111,15 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) ) val nextWorkerParams = SendEventWorker.Params(params.userId, params.roomId, encryptedEvent) return Result.success(WorkerParamsFactory.toData(nextWorkerParams)) - + } else { + val sendState = when (error) { + is Failure.CryptoError -> SendState.FAILED_UNKNOWN_DEVICES + else -> SendState.UNDELIVERED + } + localEchoUpdater.updateSendState(localEvent.eventId, sendState) + //always return success, or the chain will be stuck for ever! + val nextWorkerParams = SendEventWorker.Params(params.userId, params.roomId, localEvent, error?.localizedMessage ?: "Error") + return Result.success(WorkerParamsFactory.toData(nextWorkerParams)) } - - val safeError = error - val sendState = when (safeError) { - is Failure.CryptoError -> SendState.FAILED_UNKNOWN_DEVICES - else -> SendState.UNDELIVERED - } - localEchoUpdater.updateSendState(localEvent.eventId, sendState) - //always return success, or the chain will be stuck for ever! - return Result.success() } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt index b3e2edcf..38e0e23b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/RedactEventWorker.kt @@ -35,7 +35,8 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) : C val txID: String, val roomId: String, val eventId: String, - val reason: String? + val reason: String?, + override var lastFailureMessage: String? = null ) : SessionWorkerParams @Inject lateinit var roomAPI: RoomAPI @@ -44,6 +45,11 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) : C val params = WorkerParamsFactory.fromData(inputData) ?: return Result.failure() + if (params.lastFailureMessage != null) { + // Transmit the error + return Result.success(inputData) + } + val sessionComponent = getSessionComponent(params.userId) ?: return Result.success() sessionComponent.inject(this) @@ -62,7 +68,9 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) : C else -> { //TODO mark as failed to send? //always return success, or the chain will be stuck for ever! - Result.success() + Result.success(WorkerParamsFactory.toData(params.copy( + lastFailureMessage = it.localizedMessage + ))) } } }, { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt index 6b6585ef..315ea457 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendEventWorker.kt @@ -38,14 +38,14 @@ internal class SendEventWorker constructor(context: Context, params: WorkerParam internal data class Params( override val userId: String, val roomId: String, - val event: Event + val event: Event, + override var lastFailureMessage: String? = null ) : SessionWorkerParams @Inject lateinit var localEchoUpdater: LocalEchoUpdater @Inject lateinit var roomAPI: RoomAPI override suspend fun doWork(): Result { - val params = WorkerParamsFactory.fromData(inputData) ?: return Result.success() @@ -57,6 +57,13 @@ internal class SendEventWorker constructor(context: Context, params: WorkerParam return Result.success() } + if (params.lastFailureMessage != null) { + localEchoUpdater.updateSendState(event.eventId, SendState.UNDELIVERED) + + // Transmit the error + return Result.success(inputData) + } + localEchoUpdater.updateSendState(event.eventId, SendState.SENDING) val result = executeRequest { apiCall = roomAPI.send( diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/worker/SessionWorkerParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/worker/SessionWorkerParams.kt index 874254cc..99fe3142 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/worker/SessionWorkerParams.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/worker/SessionWorkerParams.kt @@ -18,4 +18,7 @@ package im.vector.matrix.android.internal.worker interface SessionWorkerParams { val userId: String -} \ No newline at end of file + + // Null is no error occurs. When chaining Workers, first step is to check that there is no lastFailureMessage from the previous workers + var lastFailureMessage: String? +}