Skip to content
This repository was archived by the owner on Jun 20, 2023. It is now read-only.

Commit bb19623

Browse files
authored
EOL - Background Work (EXPOSUREAPP-14794) (#5852)
* Stop Dcc Wallet info * App starter * Update AppStarterTest.kt
1 parent 1d97c8b commit bb19623

File tree

7 files changed

+202
-62
lines changed

7 files changed

+202
-62
lines changed

Corona-Warn-App/src/main/java/de/rki/coronawarnapp/CoronaWarnApplication.kt

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import android.content.Context
66
import android.content.IntentFilter
77
import android.os.Bundle
88
import android.view.WindowManager
9-
import androidx.core.app.NotificationManagerCompat
109
import androidx.localbroadcastmanager.content.LocalBroadcastManager
1110
import androidx.work.WorkManager
1211
import coil.Coil
@@ -15,10 +14,9 @@ import dagger.android.AndroidInjector
1514
import dagger.android.DispatchingAndroidInjector
1615
import dagger.android.HasAndroidInjector
1716
import de.rki.coronawarnapp.bugreporting.loghistory.LogHistoryTree
18-
import de.rki.coronawarnapp.eol.AppEol
1917
import de.rki.coronawarnapp.exception.reporting.ErrorReportReceiver
2018
import de.rki.coronawarnapp.exception.reporting.ReportingConstants.ERROR_REPORT_LOCAL_BROADCAST_CHANNEL
21-
import de.rki.coronawarnapp.initializer.Initializer
19+
import de.rki.coronawarnapp.initializer.AppStarter
2220
import de.rki.coronawarnapp.util.BuildVersionWrap
2321
import de.rki.coronawarnapp.util.CWADebug
2422
import de.rki.coronawarnapp.util.coroutine.AppScope
@@ -27,29 +25,22 @@ import de.rki.coronawarnapp.util.di.AppInjector
2725
import de.rki.coronawarnapp.util.di.ApplicationComponent
2826
import de.rki.coronawarnapp.util.hasAPILevel
2927
import kotlinx.coroutines.CoroutineScope
30-
import kotlinx.coroutines.flow.first
3128
import kotlinx.coroutines.flow.launchIn
3229
import kotlinx.coroutines.flow.onEach
33-
import kotlinx.coroutines.launch
3430
import timber.log.Timber
3531
import javax.inject.Inject
36-
import javax.inject.Provider
3732

3833
class CoronaWarnApplication : Application(), HasAndroidInjector {
3934

35+
@Inject lateinit var appStarter: AppStarter
4036
@Inject lateinit var component: ApplicationComponent
4137
@Inject lateinit var androidInjector: DispatchingAndroidInjector<Any>
42-
4338
@Inject lateinit var workManager: WorkManager
4439
@Inject lateinit var imageLoaderFactory: ImageLoaderFactory
4540
@Inject lateinit var foregroundState: ForegroundState
46-
@Inject lateinit var initializers: Provider<Set<@JvmSuppressWildcards Initializer>>
4741
@AppScope @Inject lateinit var appScope: CoroutineScope
4842
@LogHistoryTree @Inject lateinit var rollingLogHistory: Timber.Tree
4943

50-
@Inject lateinit var appEol: AppEol
51-
@Inject lateinit var notificationManager: NotificationManagerCompat
52-
5344
override fun androidInjector(): AndroidInjector<Any> = androidInjector
5445

5546
override fun onCreate() {
@@ -68,19 +59,7 @@ class CoronaWarnApplication : Application(), HasAndroidInjector {
6859
compPreview.inject(this)
6960
}
7061

71-
appScope.launch {
72-
if (!appEol.isEol.first()) {
73-
initializers.get().forEach { initializer ->
74-
Timber.d("initialize => %s", initializer::class.simpleName)
75-
initializer.initialize()
76-
}
77-
} else {
78-
Timber.d("EOL -> cancel all notification")
79-
notificationManager.cancelAll()
80-
Timber.d("EOL -> no work scheduled")
81-
workManager.cancelAllWork()
82-
}
83-
}
62+
appStarter.start()
8463

8564
Timber.plant(rollingLogHistory)
8665

Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ccl/dccwalletinfo/update/DccWalletInfoUpdateTrigger.kt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import de.rki.coronawarnapp.ccl.dccwalletinfo.calculation.DccWalletInfoCalculati
88
import de.rki.coronawarnapp.covidcertificate.person.core.PersonCertificates
99
import de.rki.coronawarnapp.covidcertificate.person.core.PersonCertificatesProvider
1010
import de.rki.coronawarnapp.covidcertificate.person.core.PersonCertificatesSettings
11+
import de.rki.coronawarnapp.eol.AppEol
1112
import de.rki.coronawarnapp.tag
1213
import de.rki.coronawarnapp.util.coroutine.AppScope
1314
import kotlinx.coroutines.CoroutineScope
@@ -29,6 +30,7 @@ class DccWalletInfoUpdateTrigger @Inject constructor(
2930
private val personCertificateProvider: PersonCertificatesProvider,
3031
private val personCertificatesSettings: PersonCertificatesSettings,
3132
private val dccWalletInfoCalculationManager: DccWalletInfoCalculationManager,
33+
private val appEol: AppEol,
3234
) {
3335

3436
init {
@@ -45,16 +47,24 @@ class DccWalletInfoUpdateTrigger @Inject constructor(
4547
// delay to collect rapid changes and do only one recalculation
4648
.debounce(1000L)
4749
.collectLatest {
48-
runCatching {
49-
triggerNow(admissionScenarioId())
50-
}.onFailure {
51-
Timber.tag(TAG).d(it, "Failed to calculate dccWallet")
50+
if (!appEol.isEol.first()) {
51+
runCatching {
52+
triggerNow(admissionScenarioId())
53+
}.onFailure {
54+
Timber.tag(TAG).d(it, "Failed to calculate dccWallet")
55+
}
56+
} else {
57+
Timber.tag(TAG).d("EOL -> quit")
5258
}
5359
}
5460
}
5561
}
5662

5763
suspend fun triggerAfterConfigChange(configurationChanged: Boolean = false) {
64+
if (appEol.isEol.first()) {
65+
Timber.tag(TAG).d("EOL -> quit")
66+
return
67+
}
5868
Timber.tag(TAG).d("triggerAfterConfigChange()")
5969
dccWalletInfoCalculationManager.triggerAfterConfigChange(
6070
admissionScenarioId = admissionScenarioId(),

Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/retention/ContactDiaryRetentionCalculation.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@ class ContactDiaryRetentionCalculation @Inject constructor(
3838
return list.filter { entity -> isOutOfRetention(entity.date) }
3939
}
4040

41+
suspend fun clearOutdatedEntries() {
42+
clearObsoleteContactDiaryLocationVisits()
43+
Timber.d("Obsolete contact diary location visits cleaned up")
44+
45+
clearObsoleteContactDiaryPersonEncounters()
46+
Timber.d("Obsolete contact diary person encounters cleaned up")
47+
48+
clearObsoleteRiskPerDate()
49+
Timber.d("Obsolete Aggregated Risk Per Date Results cleaned up")
50+
51+
clearObsoleteCoronaTests()
52+
Timber.d("Obsolete Contact Diary Corona Tests cleaned up")
53+
54+
clearObsoleteSubmissions()
55+
Timber.d("Obsolete Contact Diary Submissions cleaned up")
56+
}
57+
4158
suspend fun clearObsoleteContactDiaryLocationVisits() {
4259
val list = repository.locationVisits.first()
4360
Timber.d("Contact Diary Location Visits total count: ${list.size}")
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package de.rki.coronawarnapp.initializer
2+
3+
import androidx.core.app.NotificationManagerCompat
4+
import androidx.work.WorkManager
5+
import de.rki.coronawarnapp.contactdiary.retention.ContactDiaryRetentionCalculation
6+
import de.rki.coronawarnapp.eol.AppEol
7+
import de.rki.coronawarnapp.reyclebin.cleanup.RecycleBinCleanUpScheduler
8+
import de.rki.coronawarnapp.util.coroutine.AppScope
9+
import kotlinx.coroutines.CoroutineScope
10+
import kotlinx.coroutines.flow.first
11+
import kotlinx.coroutines.launch
12+
import timber.log.Timber
13+
import javax.inject.Inject
14+
import javax.inject.Singleton
15+
16+
@Singleton
17+
class AppStarter @Inject constructor(
18+
@AppScope private val appScope: CoroutineScope,
19+
private val initializers: Set<@JvmSuppressWildcards Initializer>,
20+
private val appEol: AppEol,
21+
private val notificationManager: NotificationManagerCompat,
22+
private val workManager: WorkManager,
23+
private val recycleBinCleanUpScheduler: RecycleBinCleanUpScheduler,
24+
private val contactDiaryRetentionCalculation: ContactDiaryRetentionCalculation,
25+
) {
26+
fun start() = appScope.launch {
27+
try {
28+
if (!appEol.isEol.first()) {
29+
initializers.forEach { initializer ->
30+
Timber.d("initialize => %s", initializer::class.simpleName)
31+
initializer.initialize()
32+
}
33+
} else {
34+
Timber.d("EOL -> cancel all notifications")
35+
notificationManager.cancelAll()
36+
37+
Timber.d("EOL -> cancel all scheduled workers")
38+
workManager.cancelAllWork()
39+
40+
Timber.d("EOL -> clean recycle bin entries")
41+
recycleBinCleanUpScheduler.initialize()
42+
43+
Timber.d("EOL -> clean contact diary entries")
44+
contactDiaryRetentionCalculation.clearOutdatedEntries()
45+
}
46+
} catch (e: Exception) {
47+
Timber.d(e, "Starter failed!")
48+
}
49+
}
50+
}

Corona-Warn-App/src/test/java/de/rki/coronawarnapp/CoronaWarnApplicationTest.kt

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,21 @@ import coil.ImageLoaderFactory
55
import dagger.android.DispatchingAndroidInjector
66
import de.rki.coronawarnapp.coronatest.CoronaTestRepository
77
import de.rki.coronawarnapp.environment.EnvironmentSetup
8-
import de.rki.coronawarnapp.eol.AppEol
9-
import de.rki.coronawarnapp.initializer.Initializer
8+
import de.rki.coronawarnapp.initializer.AppStarter
109
import de.rki.coronawarnapp.notification.GeneralNotifications
1110
import de.rki.coronawarnapp.util.CWADebug
1211
import de.rki.coronawarnapp.util.device.ForegroundState
1312
import de.rki.coronawarnapp.util.di.AppInjector
1413
import de.rki.coronawarnapp.util.di.ApplicationComponent
15-
import io.github.classgraph.ClassGraph
16-
import io.kotest.matchers.collections.shouldContainAll
1714
import io.mockk.MockKAnnotations
1815
import io.mockk.Runs
19-
import io.mockk.coVerify
2016
import io.mockk.every
2117
import io.mockk.impl.annotations.MockK
2218
import io.mockk.just
2319
import io.mockk.mockk
2420
import io.mockk.mockkObject
2521
import io.mockk.mockkStatic
2622
import kotlinx.coroutines.CoroutineScope
27-
import kotlinx.coroutines.flow.flowOf
2823
import kotlinx.coroutines.test.advanceUntilIdle
2924
import kotlinx.coroutines.test.runTest
3025
import org.conscrypt.Conscrypt
@@ -33,7 +28,6 @@ import org.junit.jupiter.api.Test
3328
import testhelpers.BaseTest
3429
import timber.log.Timber
3530
import java.security.Security
36-
import javax.inject.Provider
3731

3832
class CoronaWarnApplicationTest : BaseTest() {
3933

@@ -45,8 +39,7 @@ class CoronaWarnApplicationTest : BaseTest() {
4539
@MockK lateinit var coronaTestRepository: CoronaTestRepository
4640
@MockK lateinit var environmentSetup: EnvironmentSetup
4741
@MockK lateinit var imageLoaderFactory: ImageLoaderFactory
48-
@MockK lateinit var appEol: AppEol
49-
private val initializers = DaggerInitializersTestComponent.create().initializers
42+
@MockK lateinit var appStarter: AppStarter
5043

5144
@BeforeEach
5245
fun setup() {
@@ -64,12 +57,11 @@ class CoronaWarnApplicationTest : BaseTest() {
6457
every { initAfterInjection(any()) } just Runs
6558
}
6659

67-
every { appEol.isEol } returns flowOf(false)
68-
6960
mockkObject(AppInjector)
7061
AppInjector.apply {
7162
every { init(any()) } returns applicationComponent
7263
}
64+
every { appStarter.start() } returns mockk()
7365
}
7466

7567
private fun setupAppComponent(scope: CoroutineScope) {
@@ -80,9 +72,8 @@ class CoronaWarnApplicationTest : BaseTest() {
8072
app.androidInjector = androidInjector
8173
app.foregroundState = foregroundState
8274
app.workManager = workManager
83-
app.appEol = appEol
84-
app.initializers = Provider { initializers }
8575
app.appScope = scope
76+
app.appStarter = appStarter
8677
app.rollingLogHistory = object : Timber.Tree() {
8778
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) = Unit
8879
}
@@ -92,28 +83,10 @@ class CoronaWarnApplicationTest : BaseTest() {
9283
}
9384

9485
@Test
95-
fun `test initializers`() = runTest {
86+
fun `test app starter`() = runTest {
9687
setupAppComponent(this)
97-
val app = createInstance()
98-
app.onCreate()
9988
advanceUntilIdle()
100-
val scanResult = ClassGraph()
101-
.acceptPackages("de.rki.coronawarnapp")
102-
.enableClassInfo()
103-
.scan()
104-
105-
val initializersClasses = scanResult
106-
.getClassesImplementing(Initializer::class.java)
107-
.filterNot { it.isAbstract }
108-
109-
println("initializersClasses [${initializersClasses.size}]")
110-
val injected = app.initializers.get().map { it::class.simpleName }.toSet()
111-
val existing = initializersClasses.map { it.simpleName }.toSet()
112-
injected shouldContainAll existing
113-
114-
coVerify {
115-
app.initializers.get().forEach { initializer -> initializer.initialize() }
116-
}
89+
appStarter.start()
11790
}
11891

11992
private fun createInstance() = CoronaWarnApplication()

Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ccl/dccwalletinfo/update/DccWalletInfoUpdateTriggerTest.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import de.rki.coronawarnapp.covidcertificate.person.core.PersonCertificates
99
import de.rki.coronawarnapp.covidcertificate.person.core.PersonCertificatesProvider
1010
import de.rki.coronawarnapp.covidcertificate.person.core.PersonCertificatesSettings
1111
import de.rki.coronawarnapp.covidcertificate.vaccination.core.VaccinationCertificate
12+
import de.rki.coronawarnapp.eol.AppEol
1213
import io.kotest.assertions.throwables.shouldNotThrow
1314
import io.mockk.MockKAnnotations
1415
import io.mockk.Runs
@@ -39,6 +40,7 @@ internal class DccWalletInfoUpdateTriggerTest : BaseTest() {
3940
@MockK lateinit var appConfigProvider: AppConfigProvider
4041
@MockK lateinit var cclSettings: CclSettings
4142
@MockK lateinit var personCertificatesSettings: PersonCertificatesSettings
43+
@MockK lateinit var appEol: AppEol
4244

4345
private val vc1 = mockk<VaccinationCertificate>().apply {
4446
every { qrCodeHash } returns "hash1"
@@ -82,6 +84,7 @@ internal class DccWalletInfoUpdateTriggerTest : BaseTest() {
8284
coEvery { cclSettings.saveAdmissionScenarioId(any()) } returns Job()
8385

8486
coEvery { personCertificatesSettings.cleanSettingsNotIn(any()) } just Runs
87+
every { appEol.isEol } returns flowOf(false)
8588
}
8689

8790
@Test
@@ -257,6 +260,7 @@ internal class DccWalletInfoUpdateTriggerTest : BaseTest() {
257260
appConfigProvider = appConfigProvider,
258261
personCertificateProvider = personCertificateProvider,
259262
personCertificatesSettings = personCertificatesSettings,
260-
dccWalletInfoCalculationManager = dccWalletInfoCalculationManager
263+
dccWalletInfoCalculationManager = dccWalletInfoCalculationManager,
264+
appEol = appEol,
261265
)
262266
}

0 commit comments

Comments
 (0)