mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 21:48:50 +03:00
Inject WorkManagerProvider, to avoid injecting the Android context
Also ensure WorkManager uses a distinct tags for each session (for future multi-sessions support)
This commit is contained in:
parent
4543658ae0
commit
494ad83704
12 changed files with 182 additions and 169 deletions
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package im.vector.matrix.android.internal.crypto.verification
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.work.*
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
|
@ -29,8 +28,9 @@ import im.vector.matrix.android.internal.crypto.model.rest.KeyVerificationStart
|
|||
import im.vector.matrix.android.internal.di.DeviceId
|
||||
import im.vector.matrix.android.internal.di.SessionId
|
||||
import im.vector.matrix.android.internal.di.UserId
|
||||
import im.vector.matrix.android.internal.di.WorkManagerProvider
|
||||
import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import im.vector.matrix.android.internal.util.StringProvider
|
||||
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
|
@ -41,7 +41,8 @@ import java.util.concurrent.TimeUnit
|
|||
import javax.inject.Inject
|
||||
|
||||
internal class SasTransportRoomMessage(
|
||||
private val context: Context,
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
private val stringProvider: StringProvider,
|
||||
private val sessionId: String,
|
||||
private val userId: String,
|
||||
private val userDeviceId: String?,
|
||||
|
@ -88,7 +89,8 @@ internal class SasTransportRoomMessage(
|
|||
// }
|
||||
// }, listenerExecutor)
|
||||
|
||||
val workLiveData = WorkManager.getInstance(context).getWorkInfosForUniqueWorkLiveData("${roomId}_VerificationWork")
|
||||
val workLiveData = workManagerProvider.workManager
|
||||
.getWorkInfosForUniqueWorkLiveData("${roomId}_VerificationWork")
|
||||
|
||||
val observer = object : Observer<List<WorkInfo>> {
|
||||
override fun onChanged(workInfoList: List<WorkInfo>?) {
|
||||
|
@ -122,7 +124,7 @@ internal class SasTransportRoomMessage(
|
|||
roomId: String,
|
||||
callback: (String?, MessageVerificationRequestContent?) -> Unit) {
|
||||
val info = MessageVerificationRequestContent(
|
||||
body = context.getString(R.string.key_verification_request_fallback_message, userId),
|
||||
body = stringProvider.getString(R.string.key_verification_request_fallback_message, userId),
|
||||
fromDevice = userDeviceId ?: "",
|
||||
toUserId = otherUserId,
|
||||
methods = listOf(KeyVerificationStart.VERIF_METHOD_SAS)
|
||||
|
@ -141,20 +143,21 @@ internal class SasTransportRoomMessage(
|
|||
event = event
|
||||
))
|
||||
|
||||
val workRequest = WorkManagerUtil.matrixOneTimeWorkRequestBuilder<SendVerificationMessageWorker>()
|
||||
.setConstraints(WorkManagerUtil.workConstraints)
|
||||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SendVerificationMessageWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setInputData(workerParams)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 2_000L, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
|
||||
WorkManager.getInstance(context)
|
||||
workManagerProvider.workManager
|
||||
.beginUniqueWork("${roomId}_VerificationWork", ExistingWorkPolicy.APPEND, workRequest)
|
||||
.enqueue()
|
||||
|
||||
// I cannot just listen to the given work request, because when used in a uniqueWork,
|
||||
// The callback is called while it is still Running ...
|
||||
|
||||
val workLiveData = WorkManager.getInstance(context).getWorkInfosForUniqueWorkLiveData("${roomId}_VerificationWork")
|
||||
val workLiveData = workManagerProvider.workManager
|
||||
.getWorkInfosForUniqueWorkLiveData("${roomId}_VerificationWork")
|
||||
|
||||
val observer = object : Observer<List<WorkInfo>> {
|
||||
override fun onChanged(workInfoList: List<WorkInfo>?) {
|
||||
|
@ -213,12 +216,12 @@ internal class SasTransportRoomMessage(
|
|||
}
|
||||
|
||||
private fun enqueueSendWork(workerParams: Data): Pair<Operation, UUID> {
|
||||
val workRequest = WorkManagerUtil.matrixOneTimeWorkRequestBuilder<SendVerificationMessageWorker>()
|
||||
.setConstraints(WorkManagerUtil.workConstraints)
|
||||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SendVerificationMessageWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setInputData(workerParams)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 2_000L, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
return WorkManager.getInstance(context)
|
||||
return workManagerProvider.workManager
|
||||
.beginUniqueWork("${roomId}_VerificationWork", ExistingWorkPolicy.APPEND, workRequest)
|
||||
.enqueue() to workRequest.id
|
||||
}
|
||||
|
@ -290,7 +293,8 @@ internal class SasTransportRoomMessage(
|
|||
}
|
||||
|
||||
internal class SasTransportRoomMessageFactory @Inject constructor(
|
||||
private val context: Context,
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
private val stringProvider: StringProvider,
|
||||
private val monarchy: Monarchy,
|
||||
@SessionId
|
||||
private val sessionId: String,
|
||||
|
@ -301,6 +305,6 @@ internal class SasTransportRoomMessageFactory @Inject constructor(
|
|||
private val localEchoEventFactory: LocalEchoEventFactory) {
|
||||
|
||||
fun createTransport(roomId: String, tx: SASVerificationTransaction?): SasTransportRoomMessage {
|
||||
return SasTransportRoomMessage(context, sessionId, userId, deviceId, roomId, monarchy, localEchoEventFactory, tx)
|
||||
return SasTransportRoomMessage(workManagerProvider, stringProvider, sessionId, userId, deviceId, roomId, monarchy, localEchoEventFactory, tx)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.*
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class WorkManagerProvider @Inject constructor(
|
||||
context: Context,
|
||||
@SessionId private val sessionId: String
|
||||
) {
|
||||
private val tag = MATRIX_SDK_TAG_PREFIX + sessionId
|
||||
|
||||
val workManager = WorkManager.getInstance(context)
|
||||
|
||||
/**
|
||||
* Create a OneTimeWorkRequestBuilder, with the Matrix SDK tag
|
||||
*/
|
||||
inline fun <reified W : ListenableWorker> matrixOneTimeWorkRequestBuilder() =
|
||||
OneTimeWorkRequestBuilder<W>()
|
||||
.addTag(tag)
|
||||
|
||||
/**
|
||||
* Cancel all works instantiated by the Matrix SDK for the current session, and not those from the SDK client, or for other sessions
|
||||
*/
|
||||
fun cancelAllWorks() {
|
||||
workManager.let {
|
||||
it.cancelAllWorkByTag(tag)
|
||||
it.pruneWork()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MATRIX_SDK_TAG_PREFIX = "MatrixSDK-"
|
||||
|
||||
/**
|
||||
* Default constraints: connected network
|
||||
*/
|
||||
val workConstraints = Constraints.Builder()
|
||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||
.build()
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package im.vector.matrix.android.internal.session
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.lifecycle.LiveData
|
||||
import dagger.Lazy
|
||||
|
@ -46,6 +45,7 @@ import im.vector.matrix.android.internal.auth.SessionParamsStore
|
|||
import im.vector.matrix.android.internal.crypto.DefaultCryptoService
|
||||
import im.vector.matrix.android.internal.database.LiveEntityObserver
|
||||
import im.vector.matrix.android.internal.di.SessionId
|
||||
import im.vector.matrix.android.internal.di.WorkManagerProvider
|
||||
import im.vector.matrix.android.internal.session.sync.SyncTaskSequencer
|
||||
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
|
||||
import im.vector.matrix.android.internal.session.sync.job.SyncThread
|
||||
|
@ -63,7 +63,7 @@ import javax.inject.Provider
|
|||
@SessionScope
|
||||
internal class DefaultSession @Inject constructor(
|
||||
override val sessionParams: SessionParams,
|
||||
private val context: Context,
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
private val eventBus: EventBus,
|
||||
@SessionId
|
||||
override val sessionId: String,
|
||||
|
@ -122,15 +122,15 @@ internal class DefaultSession @Inject constructor(
|
|||
}
|
||||
|
||||
override fun requireBackgroundSync() {
|
||||
SyncWorker.requireBackgroundSync(context, sessionId)
|
||||
SyncWorker.requireBackgroundSync(workManagerProvider, sessionId)
|
||||
}
|
||||
|
||||
override fun startAutomaticBackgroundSync(repeatDelay: Long) {
|
||||
SyncWorker.automaticallyBackgroundSync(context, sessionId, 0, repeatDelay)
|
||||
SyncWorker.automaticallyBackgroundSync(workManagerProvider, sessionId, 0, repeatDelay)
|
||||
}
|
||||
|
||||
override fun stopAnyBackgroundSync() {
|
||||
SyncWorker.stopAnyBackgroundSync(context)
|
||||
SyncWorker.stopAnyBackgroundSync(workManagerProvider)
|
||||
}
|
||||
|
||||
override fun startSync(fromForeground: Boolean) {
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
|
||||
package im.vector.matrix.android.internal.session.group
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.WorkManager
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.internal.database.RealmLiveEntityObserver
|
||||
|
@ -27,8 +25,7 @@ import im.vector.matrix.android.internal.database.model.GroupEntity
|
|||
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.di.SessionId
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
|
||||
import im.vector.matrix.android.internal.di.WorkManagerProvider
|
||||
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
|
||||
import io.realm.OrderedCollectionChangeSet
|
||||
import io.realm.RealmResults
|
||||
|
@ -38,7 +35,7 @@ import javax.inject.Inject
|
|||
private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
|
||||
|
||||
internal class GroupSummaryUpdater @Inject constructor(
|
||||
private val context: Context,
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
@SessionId private val sessionId: String,
|
||||
private val monarchy: Monarchy)
|
||||
: RealmLiveEntityObserver<GroupEntity>(monarchy.realmConfiguration) {
|
||||
|
@ -72,12 +69,12 @@ internal class GroupSummaryUpdater @Inject constructor(
|
|||
|
||||
val workData = WorkerParamsFactory.toData(getGroupDataWorkerParams)
|
||||
|
||||
val sendWork = matrixOneTimeWorkRequestBuilder<GetGroupDataWorker>()
|
||||
val sendWork = workManagerProvider.matrixOneTimeWorkRequestBuilder<GetGroupDataWorker>()
|
||||
.setInputData(workData)
|
||||
.setConstraints(WorkManagerUtil.workConstraints)
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.build()
|
||||
|
||||
WorkManager.getInstance(context)
|
||||
workManagerProvider.workManager
|
||||
.beginUniqueWork(GET_GROUP_DATA_WORKER, ExistingWorkPolicy.APPEND, sendWork)
|
||||
.enqueue()
|
||||
}
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
*/
|
||||
package im.vector.matrix.android.internal.session.pushers
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.work.BackoffPolicy
|
||||
import androidx.work.WorkManager
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.pushers.Pusher
|
||||
|
@ -27,17 +25,16 @@ import im.vector.matrix.android.internal.database.mapper.asDomain
|
|||
import im.vector.matrix.android.internal.database.model.PusherEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.di.SessionId
|
||||
import im.vector.matrix.android.internal.di.WorkManagerProvider
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.task.configureWith
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
|
||||
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultPusherService @Inject constructor(
|
||||
private val context: Context,
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
private val monarchy: Monarchy,
|
||||
@SessionId private val sessionId: String,
|
||||
private val getPusherTask: GetPushersTask,
|
||||
|
@ -68,12 +65,12 @@ internal class DefaultPusherService @Inject constructor(
|
|||
|
||||
val params = AddHttpPusherWorker.Params(sessionId, pusher)
|
||||
|
||||
val request = matrixOneTimeWorkRequestBuilder<AddHttpPusherWorker>()
|
||||
.setConstraints(WorkManagerUtil.workConstraints)
|
||||
val request = workManagerProvider.matrixOneTimeWorkRequestBuilder<AddHttpPusherWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setInputData(WorkerParamsFactory.toData(params))
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 10_000L, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
WorkManager.getInstance(context).enqueue(request)
|
||||
workManagerProvider.workManager.enqueue(request)
|
||||
return request.id
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package im.vector.matrix.android.internal.session.room.relation
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
|
@ -39,6 +38,7 @@ import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryE
|
|||
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.di.SessionId
|
||||
import im.vector.matrix.android.internal.di.WorkManagerProvider
|
||||
import im.vector.matrix.android.internal.session.room.send.EncryptEventWorker
|
||||
import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory
|
||||
import im.vector.matrix.android.internal.session.room.send.RedactEventWorker
|
||||
|
@ -53,8 +53,9 @@ import timber.log.Timber
|
|||
|
||||
internal class DefaultRelationService @AssistedInject constructor(
|
||||
@Assisted private val roomId: String,
|
||||
private val context: Context,
|
||||
@SessionId private val sessionId: String,
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
private val timeLineEveSendEventWorkCommon: TimelineSendEventWorkCommon,
|
||||
private val eventFactory: LocalEchoEventFactory,
|
||||
private val cryptoService: CryptoService,
|
||||
private val findReactionEventForUndoTask: FindReactionEventForUndoTask,
|
||||
|
@ -85,8 +86,8 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||
val event = eventFactory.createReactionEvent(roomId, targetEventId, reaction)
|
||||
.also { saveLocalEcho(it) }
|
||||
val sendRelationWork = createSendEventWork(event, true)
|
||||
TimelineSendEventWorkCommon.postWork(context, roomId, sendRelationWork)
|
||||
CancelableWork(context, sendRelationWork.id)
|
||||
timeLineEveSendEventWorkCommon.postWork(roomId, sendRelationWork)
|
||||
CancelableWork(workManagerProvider.workManager, sendRelationWork.id)
|
||||
} else {
|
||||
Timber.w("Reaction already added")
|
||||
NoOpCancellable
|
||||
|
@ -111,7 +112,7 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||
.also { saveLocalEcho(it) }
|
||||
val redactWork = createRedactEventWork(redactEvent, toRedact, null)
|
||||
|
||||
TimelineSendEventWorkCommon.postWork(context, roomId, redactWork)
|
||||
timeLineEveSendEventWorkCommon.postWork(roomId, redactWork)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +133,7 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||
eventId,
|
||||
reason)
|
||||
val redactWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
|
||||
return TimelineSendEventWorkCommon.createWork<RedactEventWorker>(redactWorkData, true)
|
||||
return timeLineEveSendEventWorkCommon.createWork<RedactEventWorker>(redactWorkData, true)
|
||||
}
|
||||
|
||||
override fun editTextMessage(targetEventId: String,
|
||||
|
@ -146,12 +147,12 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||
return if (cryptoService.isRoomEncrypted(roomId)) {
|
||||
val encryptWork = createEncryptEventWork(event, listOf("m.relates_to"))
|
||||
val workRequest = createSendEventWork(event, false)
|
||||
TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest)
|
||||
CancelableWork(context, encryptWork.id)
|
||||
timeLineEveSendEventWorkCommon.postSequentialWorks(roomId, encryptWork, workRequest)
|
||||
CancelableWork(workManagerProvider.workManager, encryptWork.id)
|
||||
} else {
|
||||
val workRequest = createSendEventWork(event, true)
|
||||
TimelineSendEventWorkCommon.postWork(context, roomId, workRequest)
|
||||
CancelableWork(context, workRequest.id)
|
||||
timeLineEveSendEventWorkCommon.postWork(roomId, workRequest)
|
||||
CancelableWork(workManagerProvider.workManager, workRequest.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,12 +169,12 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||
return if (cryptoService.isRoomEncrypted(roomId)) {
|
||||
val encryptWork = createEncryptEventWork(event, listOf("m.relates_to"))
|
||||
val workRequest = createSendEventWork(event, false)
|
||||
TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest)
|
||||
CancelableWork(context, encryptWork.id)
|
||||
timeLineEveSendEventWorkCommon.postSequentialWorks(roomId, encryptWork, workRequest)
|
||||
CancelableWork(workManagerProvider.workManager, encryptWork.id)
|
||||
} else {
|
||||
val workRequest = createSendEventWork(event, true)
|
||||
TimelineSendEventWorkCommon.postWork(context, roomId, workRequest)
|
||||
CancelableWork(context, workRequest.id)
|
||||
timeLineEveSendEventWorkCommon.postWork(roomId, workRequest)
|
||||
CancelableWork(workManagerProvider.workManager, workRequest.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,12 +195,12 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||
return if (cryptoService.isRoomEncrypted(roomId)) {
|
||||
val encryptWork = createEncryptEventWork(event, listOf("m.relates_to"))
|
||||
val workRequest = createSendEventWork(event, false)
|
||||
TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, workRequest)
|
||||
CancelableWork(context, encryptWork.id)
|
||||
timeLineEveSendEventWorkCommon.postSequentialWorks(roomId, encryptWork, workRequest)
|
||||
CancelableWork(workManagerProvider.workManager, encryptWork.id)
|
||||
} else {
|
||||
val workRequest = createSendEventWork(event, true)
|
||||
TimelineSendEventWorkCommon.postWork(context, roomId, workRequest)
|
||||
CancelableWork(context, workRequest.id)
|
||||
timeLineEveSendEventWorkCommon.postWork(roomId, workRequest)
|
||||
CancelableWork(workManagerProvider.workManager, workRequest.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,13 +208,13 @@ internal class DefaultRelationService @AssistedInject constructor(
|
|||
// Same parameter
|
||||
val params = EncryptEventWorker.Params(sessionId, roomId, event, keepKeys)
|
||||
val sendWorkData = WorkerParamsFactory.toData(params)
|
||||
return TimelineSendEventWorkCommon.createWork<EncryptEventWorker>(sendWorkData, true)
|
||||
return timeLineEveSendEventWorkCommon.createWork<EncryptEventWorker>(sendWorkData, true)
|
||||
}
|
||||
|
||||
private fun createSendEventWork(event: Event, startChain: Boolean): OneTimeWorkRequest {
|
||||
val sendContentWorkerParams = SendEventWorker.Params(sessionId, roomId, event)
|
||||
val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
|
||||
return TimelineSendEventWorkCommon.createWork<SendEventWorker>(sendWorkData, startChain)
|
||||
return timeLineEveSendEventWorkCommon.createWork<SendEventWorker>(sendWorkData, startChain)
|
||||
}
|
||||
|
||||
override fun getEventAnnotationsSummary(eventId: String): EventAnnotationsSummary? {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package im.vector.matrix.android.internal.session.room.send
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.*
|
||||
import com.squareup.inject.assisted.Assisted
|
||||
import com.squareup.inject.assisted.AssistedInject
|
||||
|
@ -38,12 +37,11 @@ import im.vector.matrix.android.internal.database.model.TimelineEventEntity
|
|||
import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates
|
||||
import im.vector.matrix.android.internal.database.query.where
|
||||
import im.vector.matrix.android.internal.di.SessionId
|
||||
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.util.CancelableWork
|
||||
import im.vector.matrix.android.internal.worker.AlwaysSuccessfulWorker
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
|
||||
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
|
||||
import im.vector.matrix.android.internal.worker.startChain
|
||||
import timber.log.Timber
|
||||
|
@ -55,7 +53,8 @@ private const val BACKOFF_DELAY = 10_000L
|
|||
|
||||
internal class DefaultSendService @AssistedInject constructor(
|
||||
@Assisted private val roomId: String,
|
||||
private val context: Context,
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
private val timelineSendEventWorkCommon: TimelineSendEventWorkCommon,
|
||||
@SessionId private val sessionId: String,
|
||||
private val localEchoEventFactory: LocalEchoEventFactory,
|
||||
private val cryptoService: CryptoService,
|
||||
|
@ -91,12 +90,12 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
Timber.v("Send event in encrypted room")
|
||||
val encryptWork = createEncryptEventWork(event, true)
|
||||
val sendWork = createSendEventWork(event, false)
|
||||
TimelineSendEventWorkCommon.postSequentialWorks(context, roomId, encryptWork, sendWork)
|
||||
CancelableWork(context, encryptWork.id)
|
||||
timelineSendEventWorkCommon.postSequentialWorks(roomId, encryptWork, sendWork)
|
||||
CancelableWork(workManagerProvider.workManager, encryptWork.id)
|
||||
} else {
|
||||
val sendWork = createSendEventWork(event, true)
|
||||
TimelineSendEventWorkCommon.postWork(context, roomId, sendWork)
|
||||
CancelableWork(context, sendWork.id)
|
||||
timelineSendEventWorkCommon.postWork(roomId, sendWork)
|
||||
CancelableWork(workManagerProvider.workManager, sendWork.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,8 +108,8 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
override fun redactEvent(event: Event, reason: String?): Cancelable {
|
||||
// TODO manage media/attachements?
|
||||
val redactWork = createRedactEventWork(event, reason)
|
||||
TimelineSendEventWorkCommon.postWork(context, roomId, redactWork)
|
||||
return CancelableWork(context, redactWork.id)
|
||||
timelineSendEventWorkCommon.postWork(roomId, redactWork)
|
||||
return CancelableWork(workManagerProvider.workManager, redactWork.id)
|
||||
}
|
||||
|
||||
override fun resendTextMessage(localEcho: TimelineEvent): Cancelable? {
|
||||
|
@ -168,16 +167,16 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
}
|
||||
|
||||
override fun clearSendingQueue() {
|
||||
TimelineSendEventWorkCommon.cancelAllWorks(context, roomId)
|
||||
WorkManager.getInstance(context).cancelUniqueWork(buildWorkName(UPLOAD_WORK))
|
||||
timelineSendEventWorkCommon.cancelAllWorks(roomId)
|
||||
workManagerProvider.workManager.cancelUniqueWork(buildWorkName(UPLOAD_WORK))
|
||||
|
||||
// Replace the worker chains with a AlwaysSuccessfulWorker, to ensure the queues are well emptied
|
||||
matrixOneTimeWorkRequestBuilder<AlwaysSuccessfulWorker>()
|
||||
workManagerProvider.matrixOneTimeWorkRequestBuilder<AlwaysSuccessfulWorker>()
|
||||
.build().let {
|
||||
TimelineSendEventWorkCommon.postWork(context, roomId, it, ExistingWorkPolicy.REPLACE)
|
||||
timelineSendEventWorkCommon.postWork(roomId, it, ExistingWorkPolicy.REPLACE)
|
||||
|
||||
// need to clear also image sending queue
|
||||
WorkManager.getInstance(context)
|
||||
workManagerProvider.workManager
|
||||
.beginUniqueWork(buildWorkName(UPLOAD_WORK), ExistingWorkPolicy.REPLACE, it)
|
||||
.enqueue()
|
||||
}
|
||||
|
@ -254,7 +253,7 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
if (isRoomEncrypted) {
|
||||
val encryptWork = createEncryptEventWork(localEcho, false /*not start of chain, take input error*/)
|
||||
|
||||
val op: Operation = WorkManager.getInstance(context)
|
||||
val op: Operation = workManagerProvider.workManager
|
||||
.beginUniqueWork(buildWorkName(UPLOAD_WORK), ExistingWorkPolicy.APPEND, uploadWork)
|
||||
.then(encryptWork)
|
||||
.then(sendWork)
|
||||
|
@ -267,13 +266,13 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
}
|
||||
}, workerFutureListenerExecutor)
|
||||
} else {
|
||||
WorkManager.getInstance(context)
|
||||
workManagerProvider.workManager
|
||||
.beginUniqueWork(buildWorkName(UPLOAD_WORK), ExistingWorkPolicy.APPEND, uploadWork)
|
||||
.then(sendWork)
|
||||
.enqueue()
|
||||
}
|
||||
|
||||
return CancelableWork(context, sendWork.id)
|
||||
return CancelableWork(workManagerProvider.workManager, sendWork.id)
|
||||
}
|
||||
|
||||
private fun saveLocalEcho(event: Event) {
|
||||
|
@ -289,8 +288,8 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
val params = EncryptEventWorker.Params(sessionId, roomId, event)
|
||||
val sendWorkData = WorkerParamsFactory.toData(params)
|
||||
|
||||
return matrixOneTimeWorkRequestBuilder<EncryptEventWorker>()
|
||||
.setConstraints(WorkManagerUtil.workConstraints)
|
||||
return workManagerProvider.matrixOneTimeWorkRequestBuilder<EncryptEventWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setInputData(sendWorkData)
|
||||
.startChain(startChain)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, BACKOFF_DELAY, TimeUnit.MILLISECONDS)
|
||||
|
@ -301,7 +300,7 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
val sendContentWorkerParams = SendEventWorker.Params(sessionId, roomId, event)
|
||||
val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
|
||||
|
||||
return TimelineSendEventWorkCommon.createWork<SendEventWorker>(sendWorkData, startChain)
|
||||
return timelineSendEventWorkCommon.createWork<SendEventWorker>(sendWorkData, startChain)
|
||||
}
|
||||
|
||||
private fun createRedactEventWork(event: Event, reason: String?): OneTimeWorkRequest {
|
||||
|
@ -310,7 +309,7 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
}
|
||||
val sendContentWorkerParams = RedactEventWorker.Params(sessionId, redactEvent.eventId!!, roomId, event.eventId, reason)
|
||||
val redactWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
|
||||
return TimelineSendEventWorkCommon.createWork<RedactEventWorker>(redactWorkData, true)
|
||||
return timelineSendEventWorkCommon.createWork<RedactEventWorker>(redactWorkData, true)
|
||||
}
|
||||
|
||||
private fun createUploadMediaWork(event: Event,
|
||||
|
@ -320,8 +319,8 @@ internal class DefaultSendService @AssistedInject constructor(
|
|||
val uploadMediaWorkerParams = UploadContentWorker.Params(sessionId, roomId, event, attachment, isRoomEncrypted)
|
||||
val uploadWorkData = WorkerParamsFactory.toData(uploadMediaWorkerParams)
|
||||
|
||||
return matrixOneTimeWorkRequestBuilder<UploadContentWorker>()
|
||||
.setConstraints(WorkManagerUtil.workConstraints)
|
||||
return workManagerProvider.matrixOneTimeWorkRequestBuilder<UploadContentWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.startChain(startChain)
|
||||
.setInputData(uploadWorkData)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, BACKOFF_DELAY, TimeUnit.MILLISECONDS)
|
||||
|
|
|
@ -15,32 +15,30 @@
|
|||
*/
|
||||
package im.vector.matrix.android.internal.session.room.timeline
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.*
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
|
||||
import im.vector.matrix.android.internal.di.WorkManagerProvider
|
||||
import im.vector.matrix.android.internal.worker.startChain
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
private const val SEND_WORK = "SEND_WORK"
|
||||
private const val BACKOFF_DELAY = 10_000L
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Helper class for sending event related works.
|
||||
* All send event from a room are using the same workchain, in order to ensure order.
|
||||
* WorkRequest must always return success (even if server error, in this case marking the event as failed to send)
|
||||
* , if not the chain will be doomed in failed state.
|
||||
*
|
||||
* WorkRequest must always return success (even if server error, in this case marking the event as failed to send),
|
||||
* if not the chain will be doomed in failed state.
|
||||
*/
|
||||
internal object TimelineSendEventWorkCommon {
|
||||
internal class TimelineSendEventWorkCommon @Inject constructor(
|
||||
// TODO @Assisted private val roomId: String,
|
||||
private val workManagerProvider: WorkManagerProvider
|
||||
) {
|
||||
|
||||
fun postSequentialWorks(context: Context, roomId: String, vararg workRequests: OneTimeWorkRequest) {
|
||||
fun postSequentialWorks(roomId: String, vararg workRequests: OneTimeWorkRequest) {
|
||||
when {
|
||||
workRequests.isEmpty() -> return
|
||||
workRequests.size == 1 -> postWork(context, roomId, workRequests.first())
|
||||
workRequests.size == 1 -> postWork(roomId, workRequests.first())
|
||||
else -> {
|
||||
val firstWork = workRequests.first()
|
||||
var continuation = WorkManager.getInstance(context)
|
||||
var continuation = workManagerProvider.workManager
|
||||
.beginUniqueWork(buildWorkName(roomId), ExistingWorkPolicy.APPEND, firstWork)
|
||||
for (i in 1 until workRequests.size) {
|
||||
val workRequest = workRequests[i]
|
||||
|
@ -51,15 +49,15 @@ internal object TimelineSendEventWorkCommon {
|
|||
}
|
||||
}
|
||||
|
||||
fun postWork(context: Context, roomId: String, workRequest: OneTimeWorkRequest, policy: ExistingWorkPolicy = ExistingWorkPolicy.APPEND) {
|
||||
WorkManager.getInstance(context)
|
||||
fun postWork(roomId: String, workRequest: OneTimeWorkRequest, policy: ExistingWorkPolicy = ExistingWorkPolicy.APPEND) {
|
||||
workManagerProvider.workManager
|
||||
.beginUniqueWork(buildWorkName(roomId), policy, workRequest)
|
||||
.enqueue()
|
||||
}
|
||||
|
||||
inline fun <reified W : ListenableWorker> createWork(data: Data, startChain: Boolean): OneTimeWorkRequest {
|
||||
return matrixOneTimeWorkRequestBuilder<W>()
|
||||
.setConstraints(WorkManagerUtil.workConstraints)
|
||||
return workManagerProvider.matrixOneTimeWorkRequestBuilder<W>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.startChain(startChain)
|
||||
.setInputData(data)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, BACKOFF_DELAY, TimeUnit.MILLISECONDS)
|
||||
|
@ -70,7 +68,13 @@ internal object TimelineSendEventWorkCommon {
|
|||
return "${roomId}_$SEND_WORK"
|
||||
}
|
||||
|
||||
fun cancelAllWorks(context: Context, roomId: String) {
|
||||
WorkManager.getInstance(context).cancelUniqueWork(buildWorkName(roomId))
|
||||
fun cancelAllWorks(roomId: String) {
|
||||
workManagerProvider.workManager
|
||||
.cancelUniqueWork(buildWorkName(roomId))
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SEND_WORK = "SEND_WORK"
|
||||
private const val BACKOFF_DELAY = 10_000L
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package im.vector.matrix.android.internal.session.signout
|
||||
|
||||
import android.content.Context
|
||||
import im.vector.matrix.android.BuildConfig
|
||||
import im.vector.matrix.android.api.failure.Failure
|
||||
import im.vector.matrix.android.api.failure.MatrixError
|
||||
|
@ -29,7 +28,6 @@ import im.vector.matrix.android.internal.network.executeRequest
|
|||
import im.vector.matrix.android.internal.session.SessionModule
|
||||
import im.vector.matrix.android.internal.session.cache.ClearCacheTask
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
@ -45,7 +43,7 @@ internal interface SignOutTask : Task<SignOutTask.Params, Unit> {
|
|||
}
|
||||
|
||||
internal class DefaultSignOutTask @Inject constructor(
|
||||
private val context: Context,
|
||||
private val workManagerProvider: WorkManagerProvider,
|
||||
@SessionId private val sessionId: String,
|
||||
private val signOutAPI: SignOutAPI,
|
||||
private val sessionManager: SessionManager,
|
||||
|
@ -87,7 +85,7 @@ internal class DefaultSignOutTask @Inject constructor(
|
|||
sessionManager.releaseSession(sessionId)
|
||||
|
||||
Timber.d("SignOut: cancel pending works...")
|
||||
WorkManagerUtil.cancelAllWorks(context)
|
||||
workManagerProvider.cancelAllWorks()
|
||||
|
||||
Timber.d("SignOut: delete session params...")
|
||||
sessionParamsStore.delete(sessionId)
|
||||
|
|
|
@ -16,15 +16,17 @@
|
|||
package im.vector.matrix.android.internal.session.sync.job
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.*
|
||||
import androidx.work.BackoffPolicy
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.WorkerParameters
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.failure.isTokenError
|
||||
import im.vector.matrix.android.internal.di.WorkManagerProvider
|
||||
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
|
||||
import im.vector.matrix.android.internal.session.sync.SyncTask
|
||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||
import im.vector.matrix.android.internal.worker.SessionWorkerParams
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil
|
||||
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
|
||||
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
|
||||
import im.vector.matrix.android.internal.worker.getSessionComponent
|
||||
import timber.log.Timber
|
||||
|
@ -75,30 +77,33 @@ internal class SyncWorker(context: Context,
|
|||
|
||||
companion object {
|
||||
|
||||
const val BG_SYNC_WORK_NAME = "BG_SYNCP"
|
||||
private const val BG_SYNC_WORK_NAME = "BG_SYNCP"
|
||||
|
||||
fun requireBackgroundSync(context: Context, sessionId: String, serverTimeout: Long = 0) {
|
||||
fun requireBackgroundSync(workManagerProvider: WorkManagerProvider, sessionId: String, serverTimeout: Long = 0) {
|
||||
val data = WorkerParamsFactory.toData(Params(sessionId, serverTimeout, false))
|
||||
val workRequest = matrixOneTimeWorkRequestBuilder<SyncWorker>()
|
||||
.setConstraints(WorkManagerUtil.workConstraints)
|
||||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SyncWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, 1_000, TimeUnit.MILLISECONDS)
|
||||
.setInputData(data)
|
||||
.build()
|
||||
WorkManager.getInstance(context).enqueueUniqueWork(BG_SYNC_WORK_NAME, ExistingWorkPolicy.REPLACE, workRequest)
|
||||
workManagerProvider.workManager
|
||||
.enqueueUniqueWork(BG_SYNC_WORK_NAME, ExistingWorkPolicy.REPLACE, workRequest)
|
||||
}
|
||||
|
||||
fun automaticallyBackgroundSync(context: Context, sessionId: String, serverTimeout: Long = 0, delay: Long = 30_000) {
|
||||
fun automaticallyBackgroundSync(workManagerProvider: WorkManagerProvider, sessionId: String, serverTimeout: Long = 0, delay: Long = 30_000) {
|
||||
val data = WorkerParamsFactory.toData(Params(sessionId, serverTimeout, true))
|
||||
val workRequest = matrixOneTimeWorkRequestBuilder<SyncWorker>()
|
||||
.setConstraints(WorkManagerUtil.workConstraints)
|
||||
val workRequest = workManagerProvider.matrixOneTimeWorkRequestBuilder<SyncWorker>()
|
||||
.setConstraints(WorkManagerProvider.workConstraints)
|
||||
.setInputData(data)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, delay, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
WorkManager.getInstance(context).enqueueUniqueWork(BG_SYNC_WORK_NAME, ExistingWorkPolicy.REPLACE, workRequest)
|
||||
workManagerProvider.workManager
|
||||
.enqueueUniqueWork(BG_SYNC_WORK_NAME, ExistingWorkPolicy.REPLACE, workRequest)
|
||||
}
|
||||
|
||||
fun stopAnyBackgroundSync(context: Context) {
|
||||
WorkManager.getInstance(context).cancelUniqueWork(BG_SYNC_WORK_NAME)
|
||||
fun stopAnyBackgroundSync(workManagerProvider: WorkManagerProvider) {
|
||||
workManagerProvider.workManager
|
||||
.cancelUniqueWork(BG_SYNC_WORK_NAME)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,15 +16,14 @@
|
|||
|
||||
package im.vector.matrix.android.internal.util
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.WorkManager
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import java.util.UUID
|
||||
import java.util.*
|
||||
|
||||
internal class CancelableWork(private val context: Context,
|
||||
internal class CancelableWork(private val workManager: WorkManager,
|
||||
private val workId: UUID) : Cancelable {
|
||||
|
||||
override fun cancel() {
|
||||
WorkManager.getInstance(context).cancelWorkById(workId)
|
||||
workManager.cancelWorkById(workId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.matrix.android.internal.worker
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.*
|
||||
|
||||
// TODO Multiaccount
|
||||
internal object WorkManagerUtil {
|
||||
private const val MATRIX_SDK_TAG = "MatrixSDK"
|
||||
|
||||
/**
|
||||
* Default constraints: connected network
|
||||
*/
|
||||
val workConstraints = Constraints.Builder()
|
||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||
.build()
|
||||
|
||||
/**
|
||||
* Create a OneTimeWorkRequestBuilder, with the Matrix SDK tag
|
||||
*/
|
||||
inline fun <reified W : ListenableWorker> matrixOneTimeWorkRequestBuilder() =
|
||||
OneTimeWorkRequestBuilder<W>()
|
||||
.addTag(MATRIX_SDK_TAG)
|
||||
|
||||
/**
|
||||
* Cancel all works instantiated by the Matrix SDK and not those from the SDK client
|
||||
*/
|
||||
fun cancelAllWorks(context: Context) {
|
||||
WorkManager.getInstance(context).also {
|
||||
it.cancelAllWorkByTag(MATRIX_SDK_TAG)
|
||||
it.pruneWork()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue