diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SendVerificationMessageWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SendVerificationMessageWorker.kt index 2b049e0061..95376fb0cc 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SendVerificationMessageWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/SendVerificationMessageWorker.kt @@ -30,6 +30,10 @@ import im.vector.matrix.android.internal.worker.getSessionComponent import timber.log.Timber import javax.inject.Inject +/** + * Possible previous worker: None + * Possible next worker : None + */ internal class SendVerificationMessageWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { @@ -48,7 +52,7 @@ internal class SendVerificationMessageWorker(context: Context, lateinit var cryptoService: CryptoService override suspend fun doWork(): Result { - val errorOutputData = Data.Builder().putBoolean("failed", true).build() + val errorOutputData = Data.Builder().putBoolean(OUTPUT_KEY_FAILED, true).build() val params = WorkerParamsFactory.fromData(inputData) ?: return Result.success(errorOutputData) @@ -76,4 +80,12 @@ internal class SendVerificationMessageWorker(context: Context, } } } + + companion object { + private const val OUTPUT_KEY_FAILED = "failed" + + fun hasFailed(outputData: Data): Boolean { + return outputData.getBoolean(SendVerificationMessageWorker.OUTPUT_KEY_FAILED, false) + } + } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt index 75ffa5e082..c5c4772c51 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransport.kt @@ -34,6 +34,9 @@ internal interface VerificationTransport { onErrorReason: CancelCode, onDone: (() -> Unit)?) + /** + * @param callback will be called with eventId and ValidVerificationInfoRequest in case of success + */ fun sendVerificationRequest(supportedMethods: List, localId: String, otherUserId: String, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt index b7b7335011..77234e82f4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/VerificationTransportRoomMessage.kt @@ -115,7 +115,7 @@ internal class VerificationTransportRoomMessage( ?.filter { it.state == WorkInfo.State.SUCCEEDED } ?.firstOrNull { it.id == enqueueInfo.second } ?.let { wInfo -> - if (wInfo.outputData.getBoolean("failed", false)) { + if (SendVerificationMessageWorker.hasFailed(wInfo.outputData)) { Timber.e("## SAS verification [${tx?.transactionId}] failed to send verification message in state : ${tx?.state}") tx?.cancel(onErrorReason) } else { @@ -196,12 +196,15 @@ internal class VerificationTransportRoomMessage( ?.filter { it.state == WorkInfo.State.SUCCEEDED } ?.firstOrNull { it.id == workRequest.id } ?.let { wInfo -> - if (wInfo.outputData.getBoolean("failed", false)) { + if (SendVerificationMessageWorker.hasFailed(wInfo.outputData)) { callback(null, null) - } else if (wInfo.outputData.getString(localId) != null) { - callback(wInfo.outputData.getString(localId), validInfo) } else { - callback(null, null) + val eventId = wInfo.outputData.getString(localId) + if (eventId != null) { + callback(eventId, validInfo) + } else { + callback(null, null) + } } workLiveData.removeObserver(this) } 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 1b736d349f..03ae366ed5 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 @@ -46,6 +46,10 @@ private data class NewImageAttributes( val newFileSize: Int ) +/** + * Possible previous worker: None + * Possible next worker : Always [MultipleEventSendingDispatcherWorker] + */ internal class UploadContentWorker(val context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { @JsonClass(generateAdapter = true) @@ -64,12 +68,14 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) ?: return Result.success() + .also { Timber.e("Unable to parse work parameters") } + Timber.v("Starting upload media work with params $params") if (params.lastFailureMessage != null) { // Transmit the error - Timber.v("Stop upload media work due to input failure") return Result.success(inputData) + .also { Timber.e("Work cancelled due to input error from parent") } } // Just defensive code to ensure that we never have an uncaught exception that could break the queue 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 93705774e6..bb33212f9c 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 @@ -23,8 +23,13 @@ import com.squareup.moshi.JsonClass 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 timber.log.Timber import javax.inject.Inject +/** + * Possible previous worker: None + * Possible next worker : None + */ internal class GetGroupDataWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { @JsonClass(generateAdapter = true) @@ -39,6 +44,7 @@ internal class GetGroupDataWorker(context: Context, params: WorkerParameters) : override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) ?: return Result.failure() + .also { Timber.e("Unable to parse work parameters") } val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() sessionComponent.inject(this) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt index 3ca5a03822..9808b584aa 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/group/GroupSummaryUpdater.kt @@ -69,13 +69,13 @@ internal class GroupSummaryUpdater @Inject constructor( val workData = WorkerParamsFactory.toData(getGroupDataWorkerParams) - val sendWork = workManagerProvider.matrixOneTimeWorkRequestBuilder() + val getGroupWork = workManagerProvider.matrixOneTimeWorkRequestBuilder() .setInputData(workData) .setConstraints(WorkManagerProvider.workConstraints) .build() workManagerProvider.workManager - .beginUniqueWork(GET_GROUP_DATA_WORKER, ExistingWorkPolicy.APPEND, sendWork) + .beginUniqueWork(GET_GROUP_DATA_WORKER, ExistingWorkPolicy.APPEND, getGroupWork) .enqueue() } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddHttpPusherWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddHttpPusherWorker.kt index adb4bf32c2..ecc39cfdc2 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddHttpPusherWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/AddHttpPusherWorker.kt @@ -31,6 +31,7 @@ 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 org.greenrobot.eventbus.EventBus +import timber.log.Timber import javax.inject.Inject internal class AddHttpPusherWorker(context: Context, params: WorkerParameters) @@ -50,6 +51,7 @@ internal class AddHttpPusherWorker(context: Context, params: WorkerParameters) override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) ?: return Result.failure() + .also { Timber.e("Unable to parse work parameters") } val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() sessionComponent.inject(this) 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 5857eaa89b..9a8f1a7dc6 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 @@ -31,6 +31,7 @@ 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 org.greenrobot.eventbus.EventBus +import timber.log.Timber import javax.inject.Inject // TODO This is not used. Delete? @@ -51,10 +52,12 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters) : override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) ?: return Result.failure() + .also { Timber.e("Unable to parse work parameters") } if (params.lastFailureMessage != null) { // Transmit the error return Result.success(inputData) + .also { Timber.e("Work cancelled due to input error from parent") } } val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt index a99337695a..1037b7c79c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt @@ -228,7 +228,7 @@ internal class DefaultSendService @AssistedInject constructor( keys.forEach { isRoomEncrypted -> // Should never be empty val localEchoes = get(isRoomEncrypted).orEmpty() - val uploadWork = createUploadMediaWork(localEchoes, attachment, isRoomEncrypted, compressBeforeSending, startChain = true) + val uploadWork = createUploadMediaWork(localEchoes, attachment, isRoomEncrypted, compressBeforeSending) val dispatcherWork = createMultipleEventDispatcherWork(isRoomEncrypted) @@ -293,14 +293,13 @@ internal class DefaultSendService @AssistedInject constructor( private fun createUploadMediaWork(allLocalEchos: List, attachment: ContentAttachmentData, isRoomEncrypted: Boolean, - compressBeforeSending: Boolean, - startChain: Boolean): OneTimeWorkRequest { + compressBeforeSending: Boolean): OneTimeWorkRequest { val uploadMediaWorkerParams = UploadContentWorker.Params(sessionId, allLocalEchos, attachment, isRoomEncrypted, compressBeforeSending) val uploadWorkData = WorkerParamsFactory.toData(uploadMediaWorkerParams) return workManagerProvider.matrixOneTimeWorkRequestBuilder() .setConstraints(WorkManagerProvider.workConstraints) - .startChain(startChain) + .startChain(true) .setInputData(uploadWorkData) .setBackoffCriteria(BackoffPolicy.LINEAR, WorkManagerProvider.BACKOFF_DELAY, TimeUnit.MILLISECONDS) .build() 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 e4424f1cb3..6af2f8dab6 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 @@ -35,6 +35,10 @@ import im.vector.matrix.android.internal.worker.getSessionComponent import timber.log.Timber import javax.inject.Inject +/** + * Possible previous worker: None + * Possible next worker : Always [SendEventWorker] + */ internal class EncryptEventWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { @@ -53,14 +57,14 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters) override suspend fun doWork(): Result { Timber.v("Start Encrypt work") val params = WorkerParamsFactory.fromData(inputData) - ?: return Result.success().also { - Timber.e("Work cancelled due to input error from parent") - } + ?: return Result.success() + .also { Timber.e("Unable to parse work parameters") } Timber.v("Start Encrypt work for event ${params.event.eventId}") if (params.lastFailureMessage != null) { // Transmit the error return Result.success(inputData) + .also { Timber.e("Work cancelled due to input error from parent") } } val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt index 8c31dd1682..aec7cb3c5c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt @@ -25,6 +25,7 @@ import com.squareup.moshi.JsonClass import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.internal.di.WorkManagerProvider +import im.vector.matrix.android.internal.session.content.UploadContentWorker import im.vector.matrix.android.internal.session.room.timeline.TimelineSendEventWorkCommon import im.vector.matrix.android.internal.worker.SessionWorkerParams import im.vector.matrix.android.internal.worker.WorkerParamsFactory @@ -36,6 +37,9 @@ import javax.inject.Inject /** * This worker creates a new work for each events passed in parameter + * + * Possible previous worker: Always [UploadContentWorker] + * Possible next worker : None, but it will post new work to send events, encrypted or not */ internal class MultipleEventSendingDispatcherWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { @@ -55,9 +59,8 @@ internal class MultipleEventSendingDispatcherWorker(context: Context, params: Wo override suspend fun doWork(): Result { Timber.v("Start dispatch sending multiple event work") val params = WorkerParamsFactory.fromData(inputData) - ?: return Result.success().also { - Timber.e("Work cancelled due to input error from parent") - } + ?: return Result.success() + .also { Timber.e("Unable to parse work parameters") } val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() sessionComponent.inject(this) @@ -68,6 +71,7 @@ internal class MultipleEventSendingDispatcherWorker(context: Context, params: Wo } // Transmit the error if needed? return Result.success(inputData) + .also { Timber.e("Work cancelled due to input error from parent") } } // Create a work for every event 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 3ff318aa8a..7e0b665d63 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 @@ -26,8 +26,13 @@ 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 org.greenrobot.eventbus.EventBus +import timber.log.Timber import javax.inject.Inject +/** + * Possible previous worker: None + * Possible next worker : None + */ internal class RedactEventWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { @JsonClass(generateAdapter = true) @@ -46,10 +51,12 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) : C override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) ?: return Result.failure() + .also { Timber.e("Unable to parse work parameters") } if (params.lastFailureMessage != null) { // Transmit the error return Result.success(inputData) + .also { Timber.e("Work cancelled due to input error from parent") } } val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() 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 69d288a932..d55b9665f6 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 @@ -32,6 +32,10 @@ import org.greenrobot.eventbus.EventBus import timber.log.Timber import javax.inject.Inject +/** + * Possible previous worker: [EncryptEventWorker] or first worker + * Possible next worker : None + */ internal class SendEventWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) { @@ -49,9 +53,8 @@ internal class SendEventWorker(context: Context, override suspend fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) - ?: return Result.success().also { - Timber.e("Work cancelled due to input error from parent") - } + ?: return Result.success() + .also { Timber.e("Unable to parse work parameters") } val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() sessionComponent.inject(this) @@ -65,6 +68,7 @@ internal class SendEventWorker(context: Context, localEchoUpdater.updateSendState(event.eventId, SendState.UNDELIVERED) // Transmit the error return Result.success(inputData) + .also { Timber.e("Work cancelled due to input error from parent") } } return try { sendEvent(event) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncWorker.kt index c844db8d33..ab4e1938ce 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/sync/job/SyncWorker.kt @@ -35,6 +35,10 @@ import javax.inject.Inject private const val DEFAULT_LONG_POOL_TIMEOUT = 0L +/** + * Possible previous worker: None + * Possible next worker : None + */ internal class SyncWorker(context: Context, workerParameters: WorkerParameters ) : CoroutineWorker(context, workerParameters) { @@ -53,7 +57,10 @@ internal class SyncWorker(context: Context, override suspend fun doWork(): Result { Timber.i("Sync work starting") - val params = WorkerParamsFactory.fromData(inputData) ?: return Result.success() + val params = WorkerParamsFactory.fromData(inputData) + ?: return Result.success() + .also { Timber.e("Unable to parse work parameters") } + val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success() sessionComponent.inject(this) return runCatching { @@ -76,7 +83,6 @@ internal class SyncWorker(context: Context, } companion object { - private const val BG_SYNC_WORK_NAME = "BG_SYNCP" fun requireBackgroundSync(workManagerProvider: WorkManagerProvider, sessionId: String, serverTimeout: Long = 0) { 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 c05367cf10..3cbe6c7866 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 @@ -16,9 +16,16 @@ package im.vector.matrix.android.internal.worker +/** + * Note about the Worker usage: + * The workers we chain, or when using the append strategy, should never return Result.Failure(), else the chain will be broken forever + */ interface SessionWorkerParams { val sessionId: String - // Null is no error occurs. When chaining Workers, first step is to check that there is no lastFailureMessage from the previous workers + /** + * Null when no error occurs. When chaining Workers, first step is to check that there is no lastFailureMessage from the previous workers + * If it is the case, the worker should just transmit the error and shouldn't do anything else + */ val lastFailureMessage: String? }