Skip to content
Snippets Groups Projects
Unverified Commit 99ce64c9 authored by Matthias Urhahn's avatar Matthias Urhahn Committed by GitHub
Browse files

Fix sporadic worker crash on older android versions (EXPOSUREAPP-3987) (#1727)

parent 4d8e65d9
No related branches found
No related tags found
No related merge requests found
...@@ -25,13 +25,29 @@ class CWAWorkerFactory @Inject constructor( ...@@ -25,13 +25,29 @@ class CWAWorkerFactory @Inject constructor(
workerClassName: String, workerClassName: String,
workerParameters: WorkerParameters workerParameters: WorkerParameters
): ListenableWorker? { ): ListenableWorker? {
Timber.v("Looking up worker for %s", workerClassName) Timber.v("Checking in known worker factories for %s", workerClassName)
val factory = factories.entries.find { val ourWorkerFactories = factories.entries.find {
Class.forName(workerClassName).isAssignableFrom(it.key) Class.forName(workerClassName).isAssignableFrom(it.key)
}?.value }?.value
requireNotNull(factory) { "Unknown worker: $workerClassName" } return if (ourWorkerFactories != null) {
Timber.v("Creating worker for %s with %s", workerClassName, workerParameters) Timber.v("It's one of ours, creating worker for %s with %s", workerClassName, workerParameters)
return factory.get().create(appContext, workerParameters) ourWorkerFactories.get().create(appContext, workerParameters).also {
Timber.i("Our worker was created: %s", it)
}
} else {
Timber.w("Unknown worker class, trying direct instantiation on %s", workerClassName)
workerClassName.toNewWorkerInstance(appContext, workerParameters).also {
Timber.i("Unknown worker was created: %s", it)
}
}
}
private fun String.toNewWorkerInstance(context: Context, workerParameters: WorkerParameters): ListenableWorker {
val workerClass = Class.forName(this).asSubclass(ListenableWorker::class.java)
Timber.v("Worker class created: %s", workerClass)
val workerConstructor = workerClass.getDeclaredConstructor(Context::class.java, WorkerParameters::class.java)
Timber.v("Worker constructor created: %s", workerConstructor)
return workerConstructor.newInstance(context, workerParameters)
} }
} }
package de.rki.coronawarnapp.util.worker
import android.content.Context
import androidx.work.ListenableWorker
import androidx.work.WorkerParameters
import androidx.work.impl.workers.DiagnosticsWorker
import de.rki.coronawarnapp.worker.DiagnosisKeyRetrievalOneTimeWorker
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.mockk.MockKAnnotations
import io.mockk.clearAllMocks
import io.mockk.every
import io.mockk.impl.annotations.MockK
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
import javax.inject.Provider
class CWAWorkerFactoryTest : BaseTest() {
private val workerFactories =
mutableMapOf<Class<out ListenableWorker>, Provider<InjectedWorkerFactory<out ListenableWorker>>>()
@MockK lateinit var context: Context
@MockK lateinit var workerParameters: WorkerParameters
@MockK lateinit var ourWorker: DiagnosisKeyRetrievalOneTimeWorker
@MockK lateinit var ourFactory: DiagnosisKeyRetrievalOneTimeWorker.Factory
@BeforeEach
fun setup() {
MockKAnnotations.init(this)
every { ourFactory.create(context, workerParameters) } returns ourWorker
workerFactories[DiagnosisKeyRetrievalOneTimeWorker::class.java] = Provider { ourFactory }
}
@AfterEach
fun teardown() {
clearAllMocks()
}
fun createInstance() = CWAWorkerFactory(
workerFactories
)
@Test
fun `instantiate one of our workers`() {
val instance = createInstance()
instance.createWorker(
context, DiagnosisKeyRetrievalOneTimeWorker::class.qualifiedName!!, workerParameters
) shouldBe ourWorker
}
@Test
fun `instantiate an unknown worker`() {
val instance = createInstance()
val worker1 = instance.createWorker(context, DiagnosticsWorker::class.qualifiedName!!, workerParameters)
worker1 shouldNotBe null
val worker2 = instance.createWorker(context, DiagnosticsWorker::class.qualifiedName!!, workerParameters)
worker1 shouldNotBe worker2
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment