Throw clear error when MatrixWorkerFactory is not set up on worker configuration
This commit is contained in:
parent
cfaa7268a8
commit
30fe564a2c
|
@ -17,24 +17,38 @@
|
|||
package org.matrix.android.sdk.internal.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.work.Constraints
|
||||
import androidx.work.ListenableWorker
|
||||
import androidx.work.NetworkType
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkRequest
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import org.matrix.android.sdk.internal.worker.MatrixWorkerFactory
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
@SessionScope
|
||||
internal class WorkManagerProvider @Inject constructor(
|
||||
context: Context,
|
||||
@SessionId private val sessionId: String
|
||||
@SessionId private val sessionId: String,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val sessionScope: CoroutineScope
|
||||
) {
|
||||
private val tag = MATRIX_SDK_TAG_PREFIX + sessionId
|
||||
|
||||
val workManager = WorkManager.getInstance(context)
|
||||
|
||||
init {
|
||||
checkIfWorkerFactoryIsSetup()
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a OneTimeWorkRequestBuilder, with the Matrix SDK tag
|
||||
*/
|
||||
|
@ -60,6 +74,27 @@ internal class WorkManagerProvider @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun checkIfWorkerFactoryIsSetup() {
|
||||
sessionScope.launch(coroutineDispatchers.main) {
|
||||
val checkWorkerRequest = OneTimeWorkRequestBuilder<MatrixWorkerFactory.CheckFactoryWorker>().build()
|
||||
workManager.enqueue(checkWorkerRequest)
|
||||
val checkWorkerLiveState = workManager.getWorkInfoByIdLiveData(checkWorkerRequest.id)
|
||||
val observer = object : Observer<WorkInfo> {
|
||||
override fun onChanged(workInfo: WorkInfo) {
|
||||
if (workInfo.state.isFinished) {
|
||||
checkWorkerLiveState.removeObserver(this)
|
||||
if (workInfo.state == WorkInfo.State.FAILED) {
|
||||
throw RuntimeException("MatrixWorkerFactory is not being set on your worker configuration.\n" +
|
||||
"Makes sure to add it to a DelegatingWorkerFactory if you have your own factory or use it directly.\n" +
|
||||
"You can grab the instance through the Matrix class.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checkWorkerLiveState.observeForever(observer)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MATRIX_SDK_TAG_PREFIX = "MatrixSDK-"
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.matrix.android.sdk.internal.worker
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.ListenableWorker
|
||||
import androidx.work.WorkerFactory
|
||||
import androidx.work.WorkerParameters
|
||||
|
@ -51,7 +52,9 @@ internal class MatrixWorkerFactory @Inject constructor(private val sessionManage
|
|||
): ListenableWorker? {
|
||||
Timber.d("MatrixWorkerFactory.createWorker for $workerClassName")
|
||||
return when (workerClassName) {
|
||||
AddPusherWorker::class.java.name ->
|
||||
CheckFactoryWorker::class.java.name ->
|
||||
CheckFactoryWorker(appContext, workerParameters, true)
|
||||
AddPusherWorker::class.java.name ->
|
||||
AddPusherWorker(appContext, workerParameters, sessionManager)
|
||||
CancelGossipRequestWorker::class.java.name ->
|
||||
CancelGossipRequestWorker(appContext, workerParameters, sessionManager)
|
||||
|
@ -75,9 +78,29 @@ internal class MatrixWorkerFactory @Inject constructor(private val sessionManage
|
|||
UpdateTrustWorker(appContext, workerParameters, sessionManager)
|
||||
UploadContentWorker::class.java.name ->
|
||||
UploadContentWorker(appContext, workerParameters, sessionManager)
|
||||
else ->
|
||||
else -> {
|
||||
Timber.w("No worker defined on MatrixWorkerFactory for $workerClassName will delegate to default.")
|
||||
// Return null to delegate to the default WorkerFactory.
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This worker is launched by the factory with the isCreatedByMatrixWorkerFactory flag to true.
|
||||
* If the MatrixWorkerFactory is not set up, it will default to the other constructor and it will throw
|
||||
*/
|
||||
class CheckFactoryWorker(context: Context, workerParameters: WorkerParameters, private val isCreatedByMatrixWorkerFactory: Boolean) : CoroutineWorker(context, workerParameters) {
|
||||
|
||||
// Called by WorkManager if there is no MatrixWorkerFactory
|
||||
constructor(context: Context, workerParameters: WorkerParameters) : this(context, workerParameters, isCreatedByMatrixWorkerFactory = false)
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
return if (!isCreatedByMatrixWorkerFactory) {
|
||||
Result.failure()
|
||||
} else {
|
||||
Result.success()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue