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
|
package org.matrix.android.sdk.internal.di
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
import androidx.work.Constraints
|
import androidx.work.Constraints
|
||||||
import androidx.work.ListenableWorker
|
import androidx.work.ListenableWorker
|
||||||
import androidx.work.NetworkType
|
import androidx.work.NetworkType
|
||||||
import androidx.work.OneTimeWorkRequestBuilder
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
import androidx.work.PeriodicWorkRequestBuilder
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
|
import androidx.work.WorkInfo
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import androidx.work.WorkRequest
|
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 java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@SessionScope
|
||||||
internal class WorkManagerProvider @Inject constructor(
|
internal class WorkManagerProvider @Inject constructor(
|
||||||
context: Context,
|
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
|
private val tag = MATRIX_SDK_TAG_PREFIX + sessionId
|
||||||
|
|
||||||
val workManager = WorkManager.getInstance(context)
|
val workManager = WorkManager.getInstance(context)
|
||||||
|
|
||||||
|
init {
|
||||||
|
checkIfWorkerFactoryIsSetup()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a OneTimeWorkRequestBuilder, with the Matrix SDK tag
|
* 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 {
|
companion object {
|
||||||
private const val MATRIX_SDK_TAG_PREFIX = "MatrixSDK-"
|
private const val MATRIX_SDK_TAG_PREFIX = "MatrixSDK-"
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.matrix.android.sdk.internal.worker
|
package org.matrix.android.sdk.internal.worker
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.work.CoroutineWorker
|
||||||
import androidx.work.ListenableWorker
|
import androidx.work.ListenableWorker
|
||||||
import androidx.work.WorkerFactory
|
import androidx.work.WorkerFactory
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
|
@ -51,6 +52,8 @@ internal class MatrixWorkerFactory @Inject constructor(private val sessionManage
|
||||||
): ListenableWorker? {
|
): ListenableWorker? {
|
||||||
Timber.d("MatrixWorkerFactory.createWorker for $workerClassName")
|
Timber.d("MatrixWorkerFactory.createWorker for $workerClassName")
|
||||||
return when (workerClassName) {
|
return when (workerClassName) {
|
||||||
|
CheckFactoryWorker::class.java.name ->
|
||||||
|
CheckFactoryWorker(appContext, workerParameters, true)
|
||||||
AddPusherWorker::class.java.name ->
|
AddPusherWorker::class.java.name ->
|
||||||
AddPusherWorker(appContext, workerParameters, sessionManager)
|
AddPusherWorker(appContext, workerParameters, sessionManager)
|
||||||
CancelGossipRequestWorker::class.java.name ->
|
CancelGossipRequestWorker::class.java.name ->
|
||||||
|
@ -75,9 +78,29 @@ internal class MatrixWorkerFactory @Inject constructor(private val sessionManage
|
||||||
UpdateTrustWorker(appContext, workerParameters, sessionManager)
|
UpdateTrustWorker(appContext, workerParameters, sessionManager)
|
||||||
UploadContentWorker::class.java.name ->
|
UploadContentWorker::class.java.name ->
|
||||||
UploadContentWorker(appContext, workerParameters, sessionManager)
|
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.
|
// Return null to delegate to the default WorkerFactory.
|
||||||
null
|
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