diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/ContactDiaryDayFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/ContactDiaryDayFragmentTest.kt index 147a5961f1456b673ea39bad904d3f79b9a2be7d..cc57ba6dbf4711c57544025f1a8d630feea1f9f1 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/ContactDiaryDayFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/ContactDiaryDayFragmentTest.kt @@ -112,10 +112,10 @@ class ContactDiaryDayFragmentTest : BaseUITest() { fragmentArgs = fragmentArgs, themeResId = R.style.AppTheme_Main ) - takeScreenshot<ContactDiaryDayFragment>(suffix) + takeScreenshot<ContactDiaryDayFragment>("persons_$suffix") onView(withId(R.id.contact_diary_day_tab_layout)) .perform(selectTabAtPosition(1)) - takeScreenshot<ContactDiaryDayFragment>(suffix + "_2") + takeScreenshot<ContactDiaryDayFragment>("locations_$suffix") } private fun setupViewModels() { diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt index c4a5e96b418d6347da251672d8374473cb7dbb76..6181fbc5e9f83af068a8b3f6c30e9613b5730186 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/contactdiary/DiaryData.kt @@ -3,63 +3,50 @@ package de.rki.coronawarnapp.ui.contactdiary import de.rki.coronawarnapp.R import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson +import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryLocation import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryLocationVisit import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryPerson import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryPersonEncounter import de.rki.coronawarnapp.contactdiary.ui.day.tabs.location.DiaryLocationListItem import de.rki.coronawarnapp.contactdiary.ui.day.tabs.person.DiaryPersonListItem -import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ListItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day.DayOverviewItem import org.joda.time.Duration import org.joda.time.LocalDate object DiaryData { val DATA_ITEMS = listOf( - ListItem.Data( - R.drawable.ic_contact_diary_person_item, - "Max Mustermann", - null, - listOf( - R.string.contact_diary_person_encounter_duration_below_15_min, - R.string.contact_diary_person_encounter_mask_with, - R.string.contact_diary_person_encounter_environment_inside - ), - "Notizen notizen", - ListItem.Type.PERSON + DayOverviewItem.Data( + R.drawable.ic_contact_diary_location_item, + "Rewe", + Duration.standardMinutes(30), + attributes = null, + circumstances = null, + DayOverviewItem.Type.LOCATION ), - - ListItem.Data( + DayOverviewItem.Data( R.drawable.ic_contact_diary_person_item, - "Erika Mustermann", + "Andrea Steinhauer", null, listOf( - R.string.contact_diary_person_encounter_environment_inside + R.string.contact_diary_person_encounter_duration_below_15_min, + R.string.contact_diary_person_encounter_environment_outside ), - "Notizen notizen", - ListItem.Type.PERSON - ), - - ListItem.Data( - R.drawable.ic_contact_diary_location, - "Fitnessstudio", - Duration.millis(1800000), null, - "Notizen notizen", - ListItem.Type.LOCATION + DayOverviewItem.Type.PERSON ), - - ListItem.Data( - R.drawable.ic_contact_diary_location, - "Supermarket", + DayOverviewItem.Data( + R.drawable.ic_contact_diary_location_item, + "Büro", null, null, null, - ListItem.Type.LOCATION + DayOverviewItem.Type.LOCATION ) ) - val HIGH_RISK = ListItem.Risk( + val HIGH_RISK = DayOverviewItem.Risk( title = R.string.contact_diary_high_risk_title, body = R.string.contact_diary_risk_body, bodyExtended = R.string.contact_diary_risk_body_extended, @@ -68,7 +55,7 @@ object DiaryData { val HIGH_RISK_DUE_LOW_RISK_ENCOUNTERS = HIGH_RISK.copy(body = R.string.contact_diary_risk_body_high_risk_due_to_low_risk_encounters) - val LOW_RISK = ListItem.Risk( + val LOW_RISK = DayOverviewItem.Risk( title = R.string.contact_diary_low_risk_title, body = R.string.contact_diary_risk_body, bodyExtended = R.string.contact_diary_risk_body_extended, @@ -77,10 +64,11 @@ object DiaryData { val LOCATIONS: List<DiaryLocationListItem> = listOf( DiaryLocationListItem( - item = DefaultContactDiaryLocation(locationName = "Sport"), + item = DefaultContactDiaryLocation(locationName = "Physiotherapie"), visit = DefaultContactDiaryLocationVisit( contactDiaryLocation = DefaultContactDiaryLocation(locationName = ""), - date = LocalDate.now() + date = LocalDate.now(), + duration = Duration.standardMinutes(90) ), onItemClick = {}, onDurationChanged = { _, _ -> }, @@ -89,19 +77,7 @@ object DiaryData { onDurationDialog = { _, _ -> } ), DiaryLocationListItem( - item = DefaultContactDiaryLocation(locationName = "Büro"), - visit = DefaultContactDiaryLocationVisit( - contactDiaryLocation = DefaultContactDiaryLocation(locationName = ""), - date = LocalDate.now() - ), - onItemClick = {}, - onDurationChanged = { _, _ -> }, - onCircumstancesChanged = { _, _ -> }, - onCircumStanceInfoClicked = {}, - onDurationDialog = { _, _ -> } - ), - DiaryLocationListItem( - item = DefaultContactDiaryLocation(locationName = "Supermarkt"), + item = DefaultContactDiaryLocation(locationName = "Hausarzt"), visit = null, onItemClick = {}, onDurationChanged = { _, _ -> }, @@ -113,10 +89,14 @@ object DiaryData { val PERSONS: List<DiaryPersonListItem> = listOf( DiaryPersonListItem( - item = DefaultContactDiaryPerson(fullName = "Erika Mustermann"), + item = DefaultContactDiaryPerson(fullName = "Andrea Steinhauer"), personEncounter = DefaultContactDiaryPersonEncounter( contactDiaryPerson = DefaultContactDiaryPerson(fullName = ""), - date = LocalDate.now() + date = LocalDate.now(), + durationClassification = ContactDiaryPersonEncounter.DurationClassification.LESS_THAN_15_MINUTES, + withMask = false, + wasOutside = true, + circumstances = "saßen nah beieinander" ), onItemClick = {}, onDurationChanged = { _, _ -> }, @@ -126,7 +106,7 @@ object DiaryData { onCircumstanceInfoClicked = {} ), DiaryPersonListItem( - item = DefaultContactDiaryPerson(fullName = "Max Mustermann"), + item = DefaultContactDiaryPerson(fullName = "Constantin Frenzel"), personEncounter = DefaultContactDiaryPersonEncounter( contactDiaryPerson = DefaultContactDiaryPerson(fullName = ""), date = LocalDate.now() @@ -137,16 +117,6 @@ object DiaryData { onWithMaskChanged = { _, _ -> }, onWasOutsideChanged = { _, _ -> }, onCircumstanceInfoClicked = {} - ), - DiaryPersonListItem( - item = DefaultContactDiaryPerson(fullName = "John Doe"), - personEncounter = null, - onItemClick = {}, - onDurationChanged = { _, _ -> }, - onCircumstancesChanged = { _, _ -> }, - onWithMaskChanged = { _, _ -> }, - onWasOutsideChanged = { _, _ -> }, - onCircumstanceInfoClicked = {} ) ) diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/MainActivityTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/MainActivityTest.kt index 63e5c8a119760fe4f0dc3efde12ac9ce35a4aca7..33e8494ef2f7407181362bed1786160df35ce486 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/MainActivityTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/main/MainActivityTest.kt @@ -17,7 +17,9 @@ import de.rki.coronawarnapp.contactdiary.ui.ContactDiarySettings import de.rki.coronawarnapp.contactdiary.ui.exporter.ContactDiaryExporter import de.rki.coronawarnapp.contactdiary.ui.overview.ContactDiaryOverviewFragment import de.rki.coronawarnapp.contactdiary.ui.overview.ContactDiaryOverviewViewModel -import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ListItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.DiaryOverviewItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day.DayOverviewItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.subheader.OverviewSubHeaderItem import de.rki.coronawarnapp.datadonation.analytics.worker.DataDonationAnalyticsScheduler import de.rki.coronawarnapp.deadman.DeadmanNotificationScheduler import de.rki.coronawarnapp.environment.EnvironmentSetup @@ -291,7 +293,7 @@ class MainActivityTest : BaseUITest() { takeScreenshot<ContactDiaryOverviewFragment>() onView(withId(R.id.contact_diary_overview_recyclerview)) - .perform(recyclerScrollTo(1)) + .perform(recyclerScrollTo(4)) takeScreenshot<ContactDiaryOverviewFragment>("2") } @@ -322,21 +324,35 @@ class MainActivityTest : BaseUITest() { } ) - private fun contactDiaryOverviewItemLiveData(): LiveData<List<ListItem>> = - MutableLiveData( - (0 until ContactDiaryOverviewViewModel.DAY_COUNT) - .map { LocalDate.now().minusDays(it) } - .mapIndexed { index, localDate -> - ListItem(localDate).apply { - data.addAll(DiaryData.DATA_ITEMS) - risk = when (index % 3) { - 0 -> DiaryData.HIGH_RISK - 1 -> DiaryData.HIGH_RISK_DUE_LOW_RISK_ENCOUNTERS - else -> DiaryData.LOW_RISK - } + private fun contactDiaryOverviewItemLiveData(): LiveData<List<DiaryOverviewItem>> { + val data = mutableListOf<DiaryOverviewItem>() + data.add(OverviewSubHeaderItem) + val dayData = (0 until ContactDiaryOverviewViewModel.DAY_COUNT) + .map { LocalDate.now().minusDays(it) } + .mapIndexed { index, localDate -> + val dayData = mutableListOf<DayOverviewItem.Data>().apply { + if (index == 1) { + add(DiaryData.DATA_ITEMS[0]) + add(DiaryData.DATA_ITEMS[1]) + } else if (index == 3) { + add(DiaryData.DATA_ITEMS[2]) } } - ) + val risk = when (index % 5) { + 3 -> DiaryData.HIGH_RISK_DUE_LOW_RISK_ENCOUNTERS + else -> null // DiaryData.LOW_RISK OR DiaryData.HIGH_RISK POSSIBLE + } + DayOverviewItem( + date = localDate, + data = dayData, + risk = risk + ) { + // onClick + } + } + data.addAll(dayData) + return MutableLiveData(data) + } // ViewModels creators private fun mainActivityViewModelSpy() = spyk( diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsFragmentTest.kt index eaf88daf0bfa813ccc1a453083c58ef0feae1004..634908d8bedf93147d08614b1d69c075480182aa 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsFragmentTest.kt @@ -13,6 +13,7 @@ import io.mockk.coEvery import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.spyk +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import org.junit.After @@ -71,6 +72,7 @@ class OnboardingAnalyticsFragmentTest : BaseUITest() { private fun onboardingAnalyticsViewModelSpy() = spyk( OnboardingAnalyticsViewModel( + appScope = GlobalScope, settings = settings, districts = districts, dispatcherProvider = TestDispatcherProvider(), diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionConsentFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionConsentFragmentTest.kt index 0fde6ecaf2d8d1ce3e3c09bcb967d9c070e7bf91..7748ab27cde652375f87387997882dea0eec59a9 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionConsentFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionConsentFragmentTest.kt @@ -3,6 +3,7 @@ package de.rki.coronawarnapp.ui.submission import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.nearby.modules.tekhistory.TEKHistoryProvider import de.rki.coronawarnapp.storage.interoperability.InteroperabilityRepository import de.rki.coronawarnapp.submission.SubmissionRepository @@ -30,6 +31,7 @@ class SubmissionConsentFragmentTest : BaseUITest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var interoperabilityRepository: InteroperabilityRepository @MockK lateinit var tekHistoryProvider: TEKHistoryProvider + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector @Rule @JvmField @@ -49,7 +51,8 @@ class SubmissionConsentFragmentTest : BaseUITest() { submissionRepository, interoperabilityRepository, TestDispatcherProvider(), - tekHistoryProvider + tekHistoryProvider, + analyticsKeySubmissionCollector ) setupMockViewModel( object : SubmissionConsentViewModel.Factory { diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt index 943df7ec90e9868c1f5914330b2fcde74e8131e9..aa15d484e3d19014de85adbf21aa08caf8ac0c7e 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomCalendarFragmentTest.kt @@ -8,6 +8,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.Symptoms import de.rki.coronawarnapp.submission.auto.AutoSubmission @@ -36,6 +37,7 @@ class SubmissionSymptomCalendarFragmentTest : BaseUITest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var autoSubmission: AutoSubmission + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector @Rule @JvmField @@ -54,7 +56,8 @@ class SubmissionSymptomCalendarFragmentTest : BaseUITest() { Symptoms.Indication.POSITIVE, TestDispatcherProvider(), submissionRepository, - autoSubmission + autoSubmission, + analyticsKeySubmissionCollector ) ) with(viewModel) { diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomIntroFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomIntroFragmentTest.kt index 9e86f9de03d7bb207f3652ace363a8c32ea6a14d..b1bf713e0d6302806fa5a017014fbafbcc7e981e 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomIntroFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionSymptomIntroFragmentTest.kt @@ -9,6 +9,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.Symptoms import de.rki.coronawarnapp.submission.auto.AutoSubmission @@ -38,6 +39,7 @@ class SubmissionSymptomIntroFragmentTest : BaseUITest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var autoSubmission: AutoSubmission + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector @Rule @JvmField @@ -55,7 +57,8 @@ class SubmissionSymptomIntroFragmentTest : BaseUITest() { SubmissionSymptomIntroductionViewModel( TestDispatcherProvider(), submissionRepository, - autoSubmission + autoSubmission, + analyticsKeySubmissionCollector ) ) with(viewModel) { diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultAvailableFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultAvailableFragmentTest.kt index 82b41af38b9680a2cb43a620c1e9c3ed1d57e120..33dc537e4cc00d5866850b2411f9bd2c90c86ad9 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultAvailableFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultAvailableFragmentTest.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.MutableLiveData import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.auto.AutoSubmission import de.rki.coronawarnapp.submission.data.tekhistory.TEKHistoryUpdater_Factory_Impl @@ -37,6 +38,7 @@ class SubmissionTestResultAvailableFragmentTest : BaseUITest() { @MockK lateinit var tekHistoryUpdaterFactory: TEKHistoryUpdater_Factory_Impl @MockK lateinit var autoSubmission: AutoSubmission @MockK lateinit var appShortcutsHelper: AppShortcutsHelper + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector @Rule @JvmField @@ -58,7 +60,8 @@ class SubmissionTestResultAvailableFragmentTest : BaseUITest() { TestDispatcherProvider(), tekHistoryUpdaterFactory, submissionRepository, - autoSubmission + autoSubmission, + analyticsKeySubmissionCollector ) ) diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt index 2ddeb46116948b3086b0916d7f9ddee5acb65d2a..352a9a57e08923857aa906ed603bbea20aa37b17 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultConsentGivenFragmentTest.kt @@ -12,6 +12,7 @@ import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiT import dagger.Module import dagger.android.ContributesAndroidInjector import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.auto.AutoSubmission @@ -45,6 +46,7 @@ class SubmissionTestResultConsentGivenFragmentTest : BaseUITest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var autoSubmission: AutoSubmission @MockK lateinit var testResultAvailableNotificationService: TestResultAvailableNotificationService + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector @Rule @JvmField @@ -70,6 +72,7 @@ class SubmissionTestResultConsentGivenFragmentTest : BaseUITest() { submissionRepository, autoSubmission, testResultAvailableNotificationService, + analyticsKeySubmissionCollector, TestDispatcherProvider() ) ) diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNoConsentGivenFragmentTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNoConsentGivenFragmentTest.kt index 1aaa59220916d29cf48878e26bda36b579f790cc..8c640d2568570c263e634009b2f896b8d8de3fde 100644 --- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNoConsentGivenFragmentTest.kt +++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultNoConsentGivenFragmentTest.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.MutableLiveData import androidx.test.ext.junit.runners.AndroidJUnit4 import dagger.Module import dagger.android.ContributesAndroidInjector +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState @@ -32,6 +33,7 @@ class SubmissionTestResultNoConsentGivenFragmentTest : BaseUITest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var testResultAvailableNotificationService: TestResultAvailableNotificationService + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector @Rule @JvmField @@ -46,7 +48,13 @@ class SubmissionTestResultNoConsentGivenFragmentTest : BaseUITest() { fun setup() { MockKAnnotations.init(this, relaxed = true) viewModel = - spyk(SubmissionTestResultNoConsentViewModel(submissionRepository, testResultAvailableNotificationService)) + spyk( + SubmissionTestResultNoConsentViewModel( + submissionRepository, + testResultAvailableNotificationService, + analyticsKeySubmissionCollector + ) + ) setupMockViewModel( object : SubmissionTestResultNoConsentViewModel.Factory { override fun create(): SubmissionTestResultNoConsentViewModel = viewModel diff --git a/Corona-Warn-App/src/androidTest/java/testhelpers/ScreenShotter.kt b/Corona-Warn-App/src/androidTest/java/testhelpers/ScreenShotter.kt index 4d9f4cea6269d3119a667f9373c88bac80d0c3db..b189086d8e18ecd94f81b614b2bbe28d9f7ea922 100644 --- a/Corona-Warn-App/src/androidTest/java/testhelpers/ScreenShotter.kt +++ b/Corona-Warn-App/src/androidTest/java/testhelpers/ScreenShotter.kt @@ -9,6 +9,7 @@ import androidx.annotation.StyleRes import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentFactory import androidx.test.espresso.ViewAction +import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import de.rki.coronawarnapp.R import tools.fastlane.screengrab.Screengrab @@ -31,7 +32,8 @@ inline fun <reified T> takeScreenshot(suffix: String = "", delay: Long = SCREENS val contentResolver = getInstrumentation().targetContext.contentResolver val testLabSetting = Settings.System.getString(contentResolver, "firebase.test.lab") - if ("true" == testLabSetting) { + val androidStudioMode = InstrumentationRegistry.getArguments().getString("androidStudioMode") + if ("true" in listOf(testLabSetting, androidStudioMode)) { Screengrab.screenshot( name, UiAutomatorScreenshotStrategy(), diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt index c7e21989fd781d408136627899c6b122adea96bc..31529a2382e582f02eba099eb398e189fccea157 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryLocationEntity.kt @@ -5,6 +5,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import de.rki.coronawarnapp.contactdiary.model.ContactDiaryLocation +import de.rki.coronawarnapp.util.trimToLength import kotlinx.parcelize.Parcelize @Parcelize @@ -19,10 +20,13 @@ data class ContactDiaryLocationEntity( get() = locationId } +private const val MAX_CHARACTERS = 250 +private fun String.trimMaxCharacters(): String = this.trimToLength(MAX_CHARACTERS) + fun ContactDiaryLocation.toContactDiaryLocationEntity(): ContactDiaryLocationEntity = ContactDiaryLocationEntity( locationId = this.locationId, - locationName = this.locationName, - phoneNumber = this.phoneNumber, - emailAddress = this.emailAddress + locationName = this.locationName.trimMaxCharacters(), + phoneNumber = this.phoneNumber?.trimMaxCharacters(), + emailAddress = this.emailAddress?.trimMaxCharacters() ) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt index f9a10824c76675487d7466cfb996a0a3131b517b..df4c008029586a80d117d193c66860de31cc737e 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/storage/entity/ContactDiaryPersonEntity.kt @@ -5,6 +5,7 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPerson +import de.rki.coronawarnapp.util.trimToLength import kotlinx.parcelize.Parcelize @Parcelize @@ -19,10 +20,13 @@ data class ContactDiaryPersonEntity( get() = personId } +private const val MAX_CHARACTERS = 250 +private fun String.trimMaxCharacters(): String = this.trimToLength(MAX_CHARACTERS) + fun ContactDiaryPerson.toContactDiaryPersonEntity(): ContactDiaryPersonEntity = ContactDiaryPersonEntity( personId = this.personId, - fullName = this.fullName, - phoneNumber = this.phoneNumber, - emailAddress = this.emailAddress + fullName = this.fullName.trimMaxCharacters(), + phoneNumber = this.phoneNumber?.trimMaxCharacters(), + emailAddress = this.emailAddress?.trimMaxCharacters() ) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/durationpicker/ContactDiaryDurationPickerFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/durationpicker/ContactDiaryDurationPickerFragment.kt index a33bc0e11e588448dbf12ee41458b1839c7a7db7..5e14d2498e8c64bc8a44643e14a3b528f1dc0f4f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/durationpicker/ContactDiaryDurationPickerFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/durationpicker/ContactDiaryDurationPickerFragment.kt @@ -45,8 +45,8 @@ class ContactDiaryDurationPickerFragment : DialogFragment() { var duration = requireArguments().getString(DURATION_ARGUMENT_KEY)!!.split(":").toTypedArray() if (duration.size < 2) duration = arrayOf("00", "00") - hours.value = if (hoursArray.size > duration[0].toInt()) hoursArray.indexOf(duration[0]) else 0 - minutes.value = if (minutesArray.size > duration[1].toInt()) minutesArray.indexOf(duration[1]) else 0 + hours.value = hoursArray.indexOf(duration[0]) + minutes.value = minutesArray.indexOf(duration[1]) cancelButton.setOnClickListener { dismiss() } okButton.setOnClickListener { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/location/ContactDiaryAddLocationFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/location/ContactDiaryAddLocationFragment.kt index b7540115e47f5e7109b60d9a9369739b37112298..8e35cbf814b1e79ac44fac7171e58a29893f2f2d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/location/ContactDiaryAddLocationFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/location/ContactDiaryAddLocationFragment.kt @@ -52,8 +52,8 @@ class ContactDiaryAddLocationFragment : Fragment(R.layout.contact_diary_add_loca it.hideKeyboard() viewModel.updateLocation( location, - phoneNumber = binding.locationPhoneInput.text.toString().trim(), - emailAddress = binding.locationEmailInput.text.toString().trim() + phoneNumber = binding.locationPhoneInput.text.toString(), + emailAddress = binding.locationEmailInput.text.toString() ) } } @@ -64,8 +64,8 @@ class ContactDiaryAddLocationFragment : Fragment(R.layout.contact_diary_add_loca locationSaveButton.setOnClickListener { it.hideKeyboard() viewModel.addLocation( - phoneNumber = binding.locationPhoneInput.text.toString().trim(), - emailAddress = binding.locationEmailInput.text.toString().trim() + phoneNumber = binding.locationPhoneInput.text.toString(), + emailAddress = binding.locationEmailInput.text.toString() ) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/location/ContactDiaryAddLocationViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/location/ContactDiaryAddLocationViewModel.kt index 3f0b7c7ab96dfecadf57e861e7a475b3ad9f09d9..ca648415609b7a88a35d40c3b53ad836e4a0a5b3 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/location/ContactDiaryAddLocationViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/location/ContactDiaryAddLocationViewModel.kt @@ -39,7 +39,7 @@ class ContactDiaryAddLocationViewModel @AssistedInject constructor( .asLiveData() fun locationChanged(value: String) { - locationName.value = value.trim() + locationName.value = value } fun addLocation(phoneNumber: String, emailAddress: String) = launch(coroutineExceptionHandler) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragment.kt index f305c29de6d8b2fc9fdc90397f6ac616b4d3d31b..db541a96cecd37aa2d5e3d26e6c7cab90065158d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewFragment.kt @@ -7,12 +7,10 @@ import androidx.appcompat.widget.Toolbar import androidx.core.app.ShareCompat import androidx.fragment.app.Fragment import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ContactDiaryOverviewAdapter -import de.rki.coronawarnapp.contactdiary.util.getLocale -import de.rki.coronawarnapp.contactdiary.util.toFormattedDay -import de.rki.coronawarnapp.contactdiary.util.toFormattedDayForAccessibility +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.DiaryOverviewAdapter import de.rki.coronawarnapp.databinding.ContactDiaryOverviewFragmentBinding import de.rki.coronawarnapp.util.di.AutoInject +import de.rki.coronawarnapp.util.lists.diffutil.update import de.rki.coronawarnapp.util.ui.doNavigate import de.rki.coronawarnapp.util.ui.observe2 import de.rki.coronawarnapp.util.ui.viewBindingLazy @@ -29,24 +27,20 @@ class ContactDiaryOverviewFragment : Fragment(R.layout.contact_diary_overview_fr override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val adapter = ContactDiaryOverviewAdapter( - { it.toFormattedDay(requireContext().getLocale()) }, - { it.toFormattedDayForAccessibility(requireContext().getLocale()) }, - { vm.onItemPress(it) } - ) - setupMenu(binding.toolbar) + val adapter = DiaryOverviewAdapter() binding.apply { contactDiaryOverviewRecyclerview.adapter = adapter + setupMenu(toolbar) toolbar.setNavigationOnClickListener { vm.onBackButtonPress() } } vm.listItems.observe2(this) { - adapter.setItems(it) + adapter.update(it) } vm.routeToScreen.observe2(this) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt index c90a2d9856a443a69502c578efb145df438f5123..497b3fbf113c473ef459bed221d068903be99921 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModel.kt @@ -13,7 +13,9 @@ import de.rki.coronawarnapp.contactdiary.model.ContactDiaryPersonEncounter.Durat import de.rki.coronawarnapp.contactdiary.retention.ContactDiaryCleanTask import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository import de.rki.coronawarnapp.contactdiary.ui.exporter.ContactDiaryExporter -import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ListItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.DiaryOverviewItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day.DayOverviewItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.subheader.OverviewSubHeaderItem import de.rki.coronawarnapp.risk.result.AggregatedRiskPerDateResult import de.rki.coronawarnapp.risk.storage.RiskLevelStorage import de.rki.coronawarnapp.server.protocols.internal.v2.RiskCalculationParametersOuterClass @@ -55,8 +57,11 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor( locationVisitsFlow, personEncountersFlow, riskLevelPerDateFlow - ) { dateList, locationVisitList, personEncounterList, riskLevelPerDateList -> - createListItemList(dateList, locationVisitList, personEncounterList, riskLevelPerDateList) + ) { dateList, locationVisists, personEncounters, riskLevelPerDateList -> + mutableListOf<DiaryOverviewItem>().apply { + add(OverviewSubHeaderItem) + addAll(createListItemList(dateList, locationVisists, personEncounters, riskLevelPerDateList)) + }.toList() }.asLiveData(dispatcherProvider.Default) init { @@ -70,30 +75,27 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor( private fun createListItemList( dateList: List<LocalDate>, - locationVisitList: List<ContactDiaryLocationVisit>, - personEncounterList: List<ContactDiaryPersonEncounter>, + visits: List<ContactDiaryLocationVisit>, + encounters: List<ContactDiaryPersonEncounter>, riskLevelPerDateList: List<AggregatedRiskPerDateResult> - ): List<ListItem> { + ): List<DiaryOverviewItem> { Timber.v( - "createListItemList(dateList=$dateList, " + - "locationVisitList=$locationVisitList, " + - "personEncounterList=$personEncounterList)" + - "riskLevelPerDateList=$riskLevelPerDateList" + "createListItemList(dateList=%s, visits=%s, encounters=%s, riskLevelPerDateList=%s", + dateList, + visits, + encounters, + riskLevelPerDateList ) - return dateList - .map { - ListItem(it) - .apply { - data.addPersonEncountersForDate(personEncounterList, date) - data.addLocationVisitsForDate(locationVisitList, date) - risk = riskLevelPerDateList - .firstOrNull { riskLevelPerDate -> riskLevelPerDate.day == it } - ?.toRisk(data.isNotEmpty()) - } - } + return dateList.map { date -> + val dayData = getEncountersForDate(encounters, date) + getVisitsForDate(visits, date) + val risk = riskLevelPerDateList + .firstOrNull { riskLevelPerDate -> riskLevelPerDate.day == date } + ?.toRisk(dayData.isNotEmpty()) + DayOverviewItem(date = date, data = dayData, risk = risk) { onItemPress(it) } + } } - private fun AggregatedRiskPerDateResult.toRisk(locationOrPerson: Boolean): ListItem.Risk { + private fun AggregatedRiskPerDateResult.toRisk(locationOrPerson: Boolean): DayOverviewItem.Risk { @StringRes val title: Int @StringRes var body: Int = R.string.contact_diary_risk_body @DrawableRes val drawableId: Int @@ -114,50 +116,46 @@ class ContactDiaryOverviewViewModel @AssistedInject constructor( drawableId = R.drawable.ic_low_risk_alert } - return ListItem.Risk(title, body, bodyExtend, drawableId) + return DayOverviewItem.Risk(title, body, bodyExtend, drawableId) } - private fun MutableList<ListItem.Data>.addPersonEncountersForDate( + private fun getEncountersForDate( personEncounterList: List<ContactDiaryPersonEncounter>, date: LocalDate - ) { - this += personEncounterList - .filter { personEncounter -> personEncounter.date == date } - .map { personEncounter -> - ListItem.Data( - R.drawable.ic_contact_diary_person_item, - name = personEncounter.contactDiaryPerson.fullName, - duration = null, - attributes = getPersonAttributes(personEncounter), - circumstances = personEncounter.circumstances, - ListItem.Type.PERSON - ) - } - } + ) = personEncounterList + .filter { personEncounter -> personEncounter.date == date } + .map { personEncounter -> + DayOverviewItem.Data( + R.drawable.ic_contact_diary_person_item, + name = personEncounter.contactDiaryPerson.fullName, + duration = null, + attributes = getPersonAttributes(personEncounter), + circumstances = personEncounter.circumstances, + DayOverviewItem.Type.PERSON + ) + } - private fun MutableList<ListItem.Data>.addLocationVisitsForDate( + private fun getVisitsForDate( locationVisitList: List<ContactDiaryLocationVisit>, date: LocalDate - ) { - this += locationVisitList - .filter { locationVisit -> locationVisit.date == date } - .map { locationVisit -> - ListItem.Data( - R.drawable.ic_contact_diary_location_item, - locationVisit.contactDiaryLocation.locationName, - duration = locationVisit.duration, - attributes = null, - circumstances = locationVisit.circumstances, - ListItem.Type.LOCATION - ) - } - } + ) = locationVisitList + .filter { locationVisit -> locationVisit.date == date } + .map { locationVisit -> + DayOverviewItem.Data( + R.drawable.ic_contact_diary_location_item, + locationVisit.contactDiaryLocation.locationName, + duration = locationVisit.duration, + attributes = null, + circumstances = locationVisit.circumstances, + DayOverviewItem.Type.LOCATION + ) + } fun onBackButtonPress() { routeToScreen.postValue(ContactDiaryOverviewNavigationEvents.NavigateToMainActivity) } - fun onItemPress(listItem: ListItem) { + fun onItemPress(listItem: DayOverviewItem) { routeToScreen.postValue(ContactDiaryOverviewNavigationEvents.NavigateToContactDiaryDayFragment(listItem.date)) } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt deleted file mode 100644 index e58c708ef1b935e6a1a3e0f091cedec570a230cf..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewAdapter.kt +++ /dev/null @@ -1,73 +0,0 @@ -package de.rki.coronawarnapp.contactdiary.ui.overview.adapter - -import android.view.ViewGroup -import androidx.core.view.isGone -import de.rki.coronawarnapp.R -import de.rki.coronawarnapp.contactdiary.util.clearAndAddAll -import de.rki.coronawarnapp.databinding.ContactDiaryOverviewListItemBinding -import de.rki.coronawarnapp.ui.lists.BaseAdapter -import de.rki.coronawarnapp.util.lists.BindableVH -import org.joda.time.LocalDate - -class ContactDiaryOverviewAdapter( - private val dateFormatter: (LocalDate) -> String, - private val dateFormatterForAccessibility: (LocalDate) -> String, - private val onItemSelectionListener: (ListItem) -> Unit -) : BaseAdapter<ContactDiaryOverviewAdapter.OverviewElementHolder>() { - - private val elements: MutableList<ListItem> = mutableListOf() - - fun setItems(elements: List<ListItem>) { - this.elements.clearAndAddAll(elements) - notifyDataSetChanged() - } - - override fun getItemCount() = elements.size - - override fun onCreateBaseVH(parent: ViewGroup, viewType: Int): OverviewElementHolder = OverviewElementHolder(parent) - - override fun onBindBaseVH(holder: OverviewElementHolder, position: Int, payloads: MutableList<Any>) = - holder.bind(elements[position], payloads) - - inner class OverviewElementHolder(parent: ViewGroup) : - BaseAdapter.VH(R.layout.contact_diary_overview_list_item, parent), - BindableVH<ListItem, ContactDiaryOverviewListItemBinding> { - - private val nestedItemAdapter by lazy { ContactDiaryOverviewNestedAdapter() } - - override val viewBinding: Lazy<ContactDiaryOverviewListItemBinding> = - lazy { ContactDiaryOverviewListItemBinding.bind(itemView) } - - override val onBindData: ContactDiaryOverviewListItemBinding.(item: ListItem, payloads: List<Any>) -> Unit = - { item, _ -> - contactDiaryOverviewNestedRecyclerView.adapter = nestedItemAdapter - contactDiaryOverviewNestedRecyclerView.suppressLayout(true) - contactDiaryOverviewElementBody.setOnClickListener { onItemSelectionListener(item) } - - contactDiaryOverviewElementBody.contentDescription = dateFormatterForAccessibility(item.date) - - contactDiaryOverviewElementName.apply { - text = dateFormatter(item.date) - } - - contactDiaryOverviewNestedElementGroup.isGone = item.data.isEmpty() - nestedItemAdapter.setItems(item.data) - - contactDiaryOverviewNestedListItemRisk.apply { - item.risk?.let { - this.contactDiaryOverviewRiskItem.isGone = false - this.contactDiaryOverviewItemRiskTitle.text = context.getString(it.title) - this.contactDiaryOverviewRiskItemImage.setImageResource(it.drawableId) - - val sb = StringBuilder().append(context.getString(it.body)) - - it.bodyExtended?.let { extend -> - sb.appendLine().append(context.getString(extend)) - } - - this.contactDiaryOverviewItemRiskBody.text = sb - } ?: run { this.contactDiaryOverviewRiskItem.isGone = true } - } - } - } -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/DiaryOverviewAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/DiaryOverviewAdapter.kt new file mode 100644 index 0000000000000000000000000000000000000000..43d8d0a0aa5ee0d61c04ee5c4bce058f310af275 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/DiaryOverviewAdapter.kt @@ -0,0 +1,41 @@ +package de.rki.coronawarnapp.contactdiary.ui.overview.adapter + +import android.view.ViewGroup +import androidx.annotation.LayoutRes +import androidx.viewbinding.ViewBinding +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day.DayOverviewItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day.DayOverviewVH +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.subheader.OverviewSubHeaderItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.subheader.OverviewSubHeaderVH +import de.rki.coronawarnapp.util.lists.BindableVH +import de.rki.coronawarnapp.util.lists.diffutil.AsyncDiffUtilAdapter +import de.rki.coronawarnapp.util.lists.diffutil.AsyncDiffer +import de.rki.coronawarnapp.util.lists.modular.ModularAdapter +import de.rki.coronawarnapp.util.lists.modular.mods.DataBinderMod +import de.rki.coronawarnapp.util.lists.modular.mods.StableIdMod +import de.rki.coronawarnapp.util.lists.modular.mods.TypedVHCreatorMod + +class DiaryOverviewAdapter : + ModularAdapter<DiaryOverviewAdapter.ItemVH<DiaryOverviewItem, ViewBinding>>(), + AsyncDiffUtilAdapter<DiaryOverviewItem> { + + override val asyncDiffer: AsyncDiffer<DiaryOverviewItem> = AsyncDiffer(adapter = this) + + init { + modules.addAll( + listOf( + StableIdMod(data), + DataBinderMod<DiaryOverviewItem, ItemVH<DiaryOverviewItem, ViewBinding>>(data), + TypedVHCreatorMod({ data[it] is DayOverviewItem }) { DayOverviewVH(it) }, + TypedVHCreatorMod({ data[it] is OverviewSubHeaderItem }) { OverviewSubHeaderVH(it) }, + ) + ) + } + + override fun getItemCount(): Int = data.size + + abstract class ItemVH<Item : DiaryOverviewItem, VB : ViewBinding>( + @LayoutRes layoutRes: Int, + parent: ViewGroup + ) : ModularAdapter.VH(layoutRes, parent), BindableVH<Item, VB> +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/DiaryOverviewItem.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/DiaryOverviewItem.kt new file mode 100644 index 0000000000000000000000000000000000000000..fdd230356340fe70d541d5d4b9d95acb86f53c52 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/DiaryOverviewItem.kt @@ -0,0 +1,5 @@ +package de.rki.coronawarnapp.contactdiary.ui.overview.adapter + +import de.rki.coronawarnapp.util.lists.HasStableId + +interface DiaryOverviewItem : HasStableId diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/day/DayDataNestedAdapter.kt similarity index 77% rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/day/DayDataNestedAdapter.kt index 0185b24a95bed3906b7f1764a0129f2fb0478c97..adeb5f4ab50a89894610b09b4fbf56f144456a6b 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ContactDiaryOverviewNestedAdapter.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/day/DayDataNestedAdapter.kt @@ -1,4 +1,4 @@ -package de.rki.coronawarnapp.contactdiary.ui.overview.adapter +package de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day import android.view.View import android.view.ViewGroup @@ -10,11 +10,11 @@ import de.rki.coronawarnapp.ui.lists.BaseAdapter import de.rki.coronawarnapp.util.lists.BindableVH import org.joda.time.Duration -class ContactDiaryOverviewNestedAdapter : BaseAdapter<ContactDiaryOverviewNestedAdapter.NestedItemViewHolder>() { +class DayDataNestedAdapter : BaseAdapter<DayDataNestedAdapter.NestedItemViewHolder>() { - private val dataList: MutableList<ListItem.Data> = mutableListOf() + private val dataList: MutableList<DayOverviewItem.Data> = mutableListOf() - fun setItems(dataList: List<ListItem.Data>) { + fun setItems(dataList: List<DayOverviewItem.Data>) { this.dataList.clearAndAddAll(dataList) notifyDataSetChanged() } @@ -29,17 +29,19 @@ class ContactDiaryOverviewNestedAdapter : BaseAdapter<ContactDiaryOverviewNested inner class NestedItemViewHolder(parent: ViewGroup) : BaseAdapter.VH(R.layout.contact_diary_overview_nested_list_item, parent), - BindableVH<ListItem.Data, ContactDiaryOverviewNestedListItemBinding> { + BindableVH<DayOverviewItem.Data, ContactDiaryOverviewNestedListItemBinding> { override val viewBinding: Lazy<ContactDiaryOverviewNestedListItemBinding> = lazy { ContactDiaryOverviewNestedListItemBinding.bind(itemView) } - override val onBindData: ContactDiaryOverviewNestedListItemBinding.(item: ListItem.Data, payloads: List<Any>) - -> Unit = { key, _ -> + override val onBindData: ContactDiaryOverviewNestedListItemBinding.( + item: DayOverviewItem.Data, + payloads: List<Any> + ) -> Unit = { key, _ -> contactDiaryOverviewElementImage.setImageResource(key.drawableId) contactDiaryOverviewElementName.text = key.name contactDiaryOverviewElementName.contentDescription = when (key.type) { - ListItem.Type.LOCATION -> context.getString(R.string.accessibility_location, key.name) - ListItem.Type.PERSON -> context.getString(R.string.accessibility_person, key.name) + DayOverviewItem.Type.LOCATION -> context.getString(R.string.accessibility_location, key.name) + DayOverviewItem.Type.PERSON -> context.getString(R.string.accessibility_person, key.name) } val attributes = getAttributes(key.duration, key.attributes, key.circumstances) if (attributes.isNotEmpty()) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/day/DayOverviewItem.kt similarity index 61% rename from Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt rename to Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/day/DayOverviewItem.kt index f155c87bccc2d84c968fdc4f45504ef4e4e3060c..983df3ff3294df13cabf7fb507b7f9c186752936 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/ListItem.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/day/DayOverviewItem.kt @@ -1,15 +1,19 @@ -package de.rki.coronawarnapp.contactdiary.ui.overview.adapter +package de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day import androidx.annotation.DrawableRes import androidx.annotation.StringRes +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.DiaryOverviewItem import org.joda.time.Duration import org.joda.time.LocalDate -data class ListItem( - val date: LocalDate -) { - val data: MutableList<Data> = mutableListOf() - var risk: Risk? = null +data class DayOverviewItem( + val date: LocalDate, + val data: List<Data>, + val risk: Risk?, + val onItemSelectionListener: (DayOverviewItem) -> Unit +) : DiaryOverviewItem { + + override val stableId: Long = date.hashCode().toLong() data class Data( @DrawableRes val drawableId: Int, diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/day/DayOverviewVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/day/DayOverviewVH.kt new file mode 100644 index 0000000000000000000000000000000000000000..c52682b1c41d7b0830a63ca2bd77c147237b2bb1 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/day/DayOverviewVH.kt @@ -0,0 +1,55 @@ +package de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day + +import android.view.ViewGroup +import androidx.core.view.isGone +import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.DiaryOverviewAdapter +import de.rki.coronawarnapp.contactdiary.util.getLocale +import de.rki.coronawarnapp.contactdiary.util.toFormattedDay +import de.rki.coronawarnapp.contactdiary.util.toFormattedDayForAccessibility +import de.rki.coronawarnapp.databinding.ContactDiaryOverviewListItemBinding + +class DayOverviewVH(parent: ViewGroup) : + DiaryOverviewAdapter.ItemVH<DayOverviewItem, ContactDiaryOverviewListItemBinding>( + layoutRes = R.layout.contact_diary_overview_list_item, + parent = parent + ) { + + private val nestedItemAdapter by lazy { DayDataNestedAdapter() } + + override val viewBinding: Lazy<ContactDiaryOverviewListItemBinding> = + lazy { ContactDiaryOverviewListItemBinding.bind(itemView) } + + override val onBindData: ContactDiaryOverviewListItemBinding.(item: DayOverviewItem, payloads: List<Any>) -> Unit = + { item, _ -> + contactDiaryOverviewNestedRecyclerView.adapter = nestedItemAdapter + contactDiaryOverviewNestedRecyclerView.suppressLayout(true) + contactDiaryOverviewElementBody.setOnClickListener { item.onItemSelectionListener(item) } + + contactDiaryOverviewElementBody.contentDescription = + item.date.toFormattedDayForAccessibility(context.getLocale()) + + contactDiaryOverviewElementName.apply { + text = item.date.toFormattedDay(context.getLocale()) + } + + contactDiaryOverviewNestedElementGroup.isGone = item.data.isEmpty() + nestedItemAdapter.setItems(item.data) + + contactDiaryOverviewNestedListItemRisk.apply { + item.risk?.let { + this.contactDiaryOverviewRiskItem.isGone = false + this.contactDiaryOverviewItemRiskTitle.text = context.getString(it.title) + this.contactDiaryOverviewRiskItemImage.setImageResource(it.drawableId) + + val sb = StringBuilder().append(context.getString(it.body)) + + it.bodyExtended?.let { extend -> + sb.appendLine().append(context.getString(extend)) + } + + this.contactDiaryOverviewItemRiskBody.text = sb + } ?: run { this.contactDiaryOverviewRiskItem.isGone = true } + } + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/subheader/OverviewSubHeaderItem.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/subheader/OverviewSubHeaderItem.kt new file mode 100644 index 0000000000000000000000000000000000000000..8609770446bc478ba912a9b5a4e8b40c5151e901 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/subheader/OverviewSubHeaderItem.kt @@ -0,0 +1,8 @@ +package de.rki.coronawarnapp.contactdiary.ui.overview.adapter.subheader + +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.DiaryOverviewItem + +object OverviewSubHeaderItem : DiaryOverviewItem { + + override val stableId: Long = this.hashCode().toLong() +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/subheader/OverviewSubHeaderVH.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/subheader/OverviewSubHeaderVH.kt new file mode 100644 index 0000000000000000000000000000000000000000..35923cdc632852cd3f1661060e24a3612da3a679 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/overview/adapter/subheader/OverviewSubHeaderVH.kt @@ -0,0 +1,23 @@ +package de.rki.coronawarnapp.contactdiary.ui.overview.adapter.subheader + +import android.view.ViewGroup +import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.DiaryOverviewAdapter +import de.rki.coronawarnapp.databinding.ContactDiaryOverviewListSubheaderBinding + +class OverviewSubHeaderVH(parent: ViewGroup) : + DiaryOverviewAdapter.ItemVH<OverviewSubHeaderItem, ContactDiaryOverviewListSubheaderBinding>( + layoutRes = R.layout.contact_diary_overview_list_subheader, + parent = parent + ) { + + override val viewBinding: Lazy<ContactDiaryOverviewListSubheaderBinding> = + lazy { ContactDiaryOverviewListSubheaderBinding.bind(itemView) } + + override val onBindData: ContactDiaryOverviewListSubheaderBinding.( + item: OverviewSubHeaderItem, + payloads: List<Any> + ) -> Unit = { _, _ -> + // NOOP + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/person/ContactDiaryAddPersonFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/person/ContactDiaryAddPersonFragment.kt index ae8716f9fd970d59bf157a4dce9b2813f602e256..e54cede4df8d31fdc7e82a5d309f34f7b4803c32 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/person/ContactDiaryAddPersonFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/person/ContactDiaryAddPersonFragment.kt @@ -54,8 +54,8 @@ class ContactDiaryAddPersonFragment : it.hideKeyboard() viewModel.updatePerson( person, - phoneNumber = binding.personPhoneNumberInput.text.toString().trim(), - emailAddress = binding.personEmailInput.text.toString().trim() + phoneNumber = binding.personPhoneNumberInput.text.toString(), + emailAddress = binding.personEmailInput.text.toString() ) } } @@ -65,8 +65,8 @@ class ContactDiaryAddPersonFragment : binding.personSaveButton.setOnClickListener { it.hideKeyboard() viewModel.addPerson( - phoneNumber = binding.personPhoneNumberInput.text.toString().trim(), - emailAddress = binding.personEmailInput.text.toString().trim() + phoneNumber = binding.personPhoneNumberInput.text.toString(), + emailAddress = binding.personEmailInput.text.toString() ) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/person/ContactDiaryAddPersonViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/person/ContactDiaryAddPersonViewModel.kt index f00889cfb4be8cc61242db89f5a8bc90f1fb271a..34eb68336c02d2300dd75fda71a27ce5310af72d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/person/ContactDiaryAddPersonViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/contactdiary/ui/person/ContactDiaryAddPersonViewModel.kt @@ -38,7 +38,7 @@ class ContactDiaryAddPersonViewModel @AssistedInject constructor( .asLiveData() fun nameChanged(value: String) { - name.value = value.trim() + name.value = value } fun addPerson(phoneNumber: String, emailAddress: String) = launch(coroutineExceptionHandler) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/AnalyticsModule.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/AnalyticsModule.kt index 52c57ad78da01d091532ca8f6e0c890e83f7d205..0fdf9704e2e08868c4d3d8ab2b95389cb4fdfeba 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/AnalyticsModule.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/AnalyticsModule.kt @@ -7,6 +7,7 @@ import dagger.multibindings.IntoSet import de.rki.coronawarnapp.datadonation.analytics.modules.DonorModule import de.rki.coronawarnapp.datadonation.analytics.modules.clientmetadata.ClientMetadataDonor import de.rki.coronawarnapp.datadonation.analytics.modules.exposureriskmetadata.ExposureRiskMetadataDonor +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionDonor import de.rki.coronawarnapp.datadonation.analytics.modules.registeredtest.TestResultDonor import de.rki.coronawarnapp.datadonation.analytics.modules.exposurewindows.AnalyticsExposureWindowDonor import de.rki.coronawarnapp.datadonation.analytics.modules.usermetadata.UserMetadataDonor @@ -45,9 +46,9 @@ class AnalyticsModule { @Provides fun newExposureWindows(module: AnalyticsExposureWindowDonor): DonorModule = module -// @IntoSet -// @Provides -// fun keySubmission(module: KeySubmissionStateDonor): DonorModule = module + @IntoSet + @Provides + fun keySubmission(module: AnalyticsKeySubmissionDonor): DonorModule = module @IntoSet @Provides diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/common/PpaDataExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/common/PpaDataExtensions.kt index 5a24f909c2f226fb4088d51c13a5d1ce8f47a0fd..2a898e5a0a3d943d7321b3d111dbe5d86dfecaab 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/common/PpaDataExtensions.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/common/PpaDataExtensions.kt @@ -2,6 +2,8 @@ package de.rki.coronawarnapp.datadonation.analytics.common import androidx.annotation.StringRes import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.risk.RiskLevelResult +import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.server.protocols.internal.ppdd.PpaData val PpaData.PPAAgeGroup.labelStringRes: Int @@ -64,3 +66,9 @@ val PpaData.PPAFederalState.federalStateShortName: String "PpaData.PPAFederalState.UNRECOGNIZED has no short name" ) } + +fun RiskLevelResult.toMetadataRiskLevel(): PpaData.PPARiskLevel = + when (riskState) { + RiskState.INCREASED_RISK -> PpaData.PPARiskLevel.RISK_LEVEL_HIGH + else -> PpaData.PPARiskLevel.RISK_LEVEL_LOW + } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionCollector.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionCollector.kt new file mode 100644 index 0000000000000000000000000000000000000000..138e26fa4fd7b0076569ae63527f2ca5d0479487 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionCollector.kt @@ -0,0 +1,110 @@ +package de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission + +import de.rki.coronawarnapp.datadonation.analytics.common.toMetadataRiskLevel +import de.rki.coronawarnapp.datadonation.analytics.storage.AnalyticsSettings +import de.rki.coronawarnapp.risk.RiskLevelSettings +import de.rki.coronawarnapp.risk.storage.RiskLevelStorage +import de.rki.coronawarnapp.risk.tryLatestResultsWithDefaults +import de.rki.coronawarnapp.server.protocols.internal.ppdd.PpaData +import de.rki.coronawarnapp.util.TimeStamper +import kotlinx.coroutines.flow.first +import org.joda.time.Duration +import javax.inject.Inject + +class AnalyticsKeySubmissionCollector @Inject constructor( + private val timeStamper: TimeStamper, + private val analyticsSettings: AnalyticsSettings, + private val analyticsKeySubmissionStorage: AnalyticsKeySubmissionStorage, + private val riskLevelStorage: RiskLevelStorage, + private val riskLevelSettings: RiskLevelSettings +) { + + fun reset() { + analyticsKeySubmissionStorage.clear() + } + + fun reportPositiveTestResultReceived() { + if (disabled) return + analyticsKeySubmissionStorage.testResultReceivedAt.update { timeStamper.nowUTC.millis } + } + + suspend fun reportTestRegistered() { + if (disabled) return + val testRegisteredAt = timeStamper.nowUTC + analyticsKeySubmissionStorage.testRegisteredAt.update { testRegisteredAt.millis } + + val lastRiskResult = riskLevelStorage + .latestAndLastSuccessful + .first() + .tryLatestResultsWithDefaults() + .lastCalculated + val riskLevelAtRegistration = lastRiskResult.toMetadataRiskLevel() + analyticsKeySubmissionStorage.riskLevelAtTestRegistration.update { + riskLevelAtRegistration.number + } + + if (riskLevelAtRegistration == PpaData.PPARiskLevel.RISK_LEVEL_HIGH) { + riskLevelSettings.lastChangeToHighRiskLevelTimestamp?.let { + val hours = Duration( + it, + testRegisteredAt + ).standardHours.toInt() + analyticsKeySubmissionStorage.hoursSinceHighRiskWarningAtTestRegistration.update { + hours + } + } + } + } + + fun reportSubmitted() { + if (disabled) return + analyticsKeySubmissionStorage.submitted.update { true } + analyticsKeySubmissionStorage.submittedAt.update { timeStamper.nowUTC.millis } + } + + fun reportSubmittedInBackground() { + if (disabled) return + analyticsKeySubmissionStorage.submittedInBackground.update { true } + } + + fun reportSubmittedAfterCancel() { + if (disabled) return + analyticsKeySubmissionStorage.submittedAfterCancel.update { true } + } + + fun reportSubmittedAfterSymptomFlow() { + if (disabled) return + analyticsKeySubmissionStorage.submittedAfterSymptomFlow.update { true } + } + + fun reportLastSubmissionFlowScreen(screen: Screen) { + if (disabled) return + analyticsKeySubmissionStorage.lastSubmissionFlowScreen.update { screen.code } + } + + fun reportAdvancedConsentGiven() { + if (disabled) return + analyticsKeySubmissionStorage.advancedConsentGiven.update { true } + } + + fun reportConsentWithdrawn() { + if (disabled) return + analyticsKeySubmissionStorage.advancedConsentGiven.update { false } + } + + fun reportRegisteredWithTeleTAN() { + if (disabled) return + analyticsKeySubmissionStorage.registeredWithTeleTAN.update { true } + } + + private val disabled: Boolean + get() = !analyticsSettings.analyticsEnabled.value +} + +enum class Screen(val code: Int) { + UNKNOWN(PpaData.PPALastSubmissionFlowScreen.SUBMISSION_FLOW_SCREEN_UNKNOWN_VALUE), + TEST_RESULT(PpaData.PPALastSubmissionFlowScreen.SUBMISSION_FLOW_SCREEN_TEST_RESULT_VALUE), + WARN_OTHERS(PpaData.PPALastSubmissionFlowScreen.SUBMISSION_FLOW_SCREEN_WARN_OTHERS_VALUE), + SYMPTOMS(PpaData.PPALastSubmissionFlowScreen.SUBMISSION_FLOW_SCREEN_SYMPTOMS_VALUE), + SYMPTOM_ONSET(PpaData.PPALastSubmissionFlowScreen.SUBMISSION_FLOW_SCREEN_SYMPTOM_ONSET_VALUE) +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionDonor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionDonor.kt new file mode 100644 index 0000000000000000000000000000000000000000..43be380985e0258331d73625b7e037fe7dcc700b --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionDonor.kt @@ -0,0 +1,81 @@ +package de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission + +import androidx.annotation.VisibleForTesting +import de.rki.coronawarnapp.datadonation.analytics.modules.DonorModule +import de.rki.coronawarnapp.server.protocols.internal.ppdd.PpaData +import de.rki.coronawarnapp.util.TimeStamper +import org.joda.time.Duration +import org.joda.time.Instant +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class AnalyticsKeySubmissionDonor @Inject constructor( + val repository: AnalyticsKeySubmissionRepository, + private val timeStamper: TimeStamper +) : DonorModule { + + override suspend fun beginDonation(request: DonorModule.Request): DonorModule.Contribution { + + val hours = request.currentConfig.analytics.hoursSinceTestResultToSubmitKeySubmissionMetadata + val timeSinceTestResultToSubmit = Duration.standardHours(hours.toLong()) + + return if (shouldSubmitData(timeSinceTestResultToSubmit)) { + object : DonorModule.Contribution { + override suspend fun injectData(protobufContainer: PpaData.PPADataAndroid.Builder) { + val data = createContribution() + protobufContainer.addKeySubmissionMetadataSet(data) + } + + override suspend fun finishDonation(successful: Boolean) { + if (successful) repository.reset() + } + } + } else { + AnalyticsKeySubmissionNoContribution + } + } + + private fun createContribution() = + PpaData.PPAKeySubmissionMetadata.newBuilder() + .setAdvancedConsentGiven(repository.advancedConsentGiven) + .setDaysSinceMostRecentDateAtRiskLevelAtTestRegistration( + repository.daysSinceMostRecentDateAtRiskLevelAtTestRegistration + ) + .setHoursSinceHighRiskWarningAtTestRegistration( + repository.hoursSinceHighRiskWarningAtTestRegistration + ) + .setHoursSinceTestResult(repository.hoursSinceTestResult) + .setHoursSinceTestRegistration(repository.hoursSinceTestRegistration) + .setLastSubmissionFlowScreenValue(repository.lastSubmissionFlowScreen) + .setSubmitted(repository.submitted) + .setSubmittedAfterSymptomFlow(repository.submittedAfterSymptomFlow) + .setSubmittedAfterCancel(repository.submittedAfterCancel) + .setSubmittedInBackground(repository.submittedInBackground) + .setSubmittedWithTeleTAN(repository.submittedWithTeleTAN) + + private fun shouldSubmitData(timeSinceTestResultToSubmit: Duration): Boolean { + return positiveTestResultReceived && ( + keysSubmitted || enoughTimeHasPassedSinceResult(timeSinceTestResultToSubmit) + ) + } + + private val positiveTestResultReceived: Boolean + get() = repository.testResultReceivedAt > 0 + + private val keysSubmitted: Boolean + get() = repository.submitted + + private fun enoughTimeHasPassedSinceResult(timeSinceTestResultToSubmit: Duration): Boolean = + timeStamper.nowUTC.minus(timeSinceTestResultToSubmit) > Instant.ofEpochMilli(repository.testResultReceivedAt) + + override suspend fun deleteData() { + repository.reset() + } +} + +@VisibleForTesting +object AnalyticsKeySubmissionNoContribution : DonorModule.Contribution { + override suspend fun injectData(protobufContainer: PpaData.PPADataAndroid.Builder) = Unit + override suspend fun finishDonation(successful: Boolean) = Unit +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionRepository.kt new file mode 100644 index 0000000000000000000000000000000000000000..8982f68c86e54aa6a91873ed41244e1446ac447c --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionRepository.kt @@ -0,0 +1,59 @@ +package de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission + +import de.rki.coronawarnapp.risk.RiskLevelSettings +import org.joda.time.Duration +import org.joda.time.Instant +import javax.inject.Inject +import kotlin.math.max + +class AnalyticsKeySubmissionRepository @Inject constructor( + private val storage: AnalyticsKeySubmissionStorage, + private val riskLevelSettings: RiskLevelSettings +) { + val testResultReceivedAt: Long + get() = storage.testResultReceivedAt.value + + private val testRegisteredAt: Long + get() = storage.testRegisteredAt.value + + val submitted: Boolean + get() = storage.submitted.value + + private val submittedAt: Long + get() = storage.submittedAt.value + + val submittedInBackground: Boolean + get() = submitted && storage.submittedInBackground.value + + val submittedAfterCancel: Boolean + get() = submitted && storage.submittedAfterCancel.value + + val submittedAfterSymptomFlow: Boolean + get() = submitted && storage.submittedAfterSymptomFlow.value + + val submittedWithTeleTAN: Boolean + get() = submitted && storage.registeredWithTeleTAN.value + + val lastSubmissionFlowScreen: Int + get() = storage.lastSubmissionFlowScreen.value + + val advancedConsentGiven: Boolean + get() = storage.advancedConsentGiven.value + + val hoursSinceTestResult: Int + get() = Duration.millis(max(submittedAt - testResultReceivedAt, 0)).toStandardHours().hours + + val hoursSinceTestRegistration: Int + get() = Duration.millis(max(submittedAt - testRegisteredAt, 0L)).toStandardHours().hours + + val daysSinceMostRecentDateAtRiskLevelAtTestRegistration: Int + get() = Duration( + riskLevelSettings.lastChangeCheckedRiskLevelTimestamp, + Instant.ofEpochMilli(testRegisteredAt) + ).standardDays.toInt() + + val hoursSinceHighRiskWarningAtTestRegistration: Int + get() = storage.hoursSinceHighRiskWarningAtTestRegistration.value + + fun reset() = storage.clear() +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionStorage.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionStorage.kt new file mode 100644 index 0000000000000000000000000000000000000000..085c5fe727216fee0a3f963e2548ac568412cf70 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionStorage.kt @@ -0,0 +1,79 @@ +package de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission + +import android.content.Context +import de.rki.coronawarnapp.util.di.AppContext +import de.rki.coronawarnapp.util.preferences.clearAndNotify +import de.rki.coronawarnapp.util.preferences.createFlowPreference +import javax.inject.Inject + +class AnalyticsKeySubmissionStorage @Inject constructor( + @AppContext val context: Context +) { + private val prefs by lazy { + context.getSharedPreferences("analytics_key_submission_localdata", Context.MODE_PRIVATE) + } + + val testResultReceivedAt = prefs.createFlowPreference( + key = "analytics_key_submission_testResultReceivedAt", + defaultValue = -1L + ) + + val testRegisteredAt = prefs.createFlowPreference( + key = "analytics_key_submission_testRegisteredAt", + defaultValue = -1L + ) + + val submitted = prefs.createFlowPreference( + key = "analytics_key_submission_submitted", + defaultValue = false + ) + + val submittedAt = prefs.createFlowPreference( + key = "analytics_key_submission_submittedAt", + defaultValue = -1L + ) + + val submittedInBackground = prefs.createFlowPreference( + key = "analytics_key_submission_submittedInBackground", + defaultValue = false + ) + + val submittedAfterCancel = prefs.createFlowPreference( + key = "analytics_key_submission_submittedAfterCancel", + defaultValue = false + ) + + val submittedAfterSymptomFlow = prefs.createFlowPreference( + key = "analytics_key_submission_submittedAfterSymptomFlow", + defaultValue = false + ) + + val lastSubmissionFlowScreen = prefs.createFlowPreference( + key = "analytics_key_submission_lastSubmissionFlowScreen", + defaultValue = Screen.UNKNOWN.code + ) + + val advancedConsentGiven = prefs.createFlowPreference( + key = "analytics_key_submission_advancedConsentGiven", + defaultValue = false + ) + + val registeredWithTeleTAN = prefs.createFlowPreference( + key = "analytics_key_submission_registeredWithTeleTAN", + defaultValue = false + ) + + val riskLevelAtTestRegistration = prefs.createFlowPreference( + key = "analytics_key_submission_riskLevelAtTestRegistration", + defaultValue = -1 + ) + + val hoursSinceHighRiskWarningAtTestRegistration = prefs.createFlowPreference( + key = "analytics_key_submission_hoursSinceHighRiskWarningAtTestRegistration", + defaultValue = -1 + ) + + fun clear() { + prefs.clearAndNotify() + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/KeySubmissionStateDonor.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/KeySubmissionStateDonor.kt deleted file mode 100644 index 7b254464f587eb6eba7da463db17f63ec3358f26..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/KeySubmissionStateDonor.kt +++ /dev/null @@ -1,27 +0,0 @@ -package de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission - -import de.rki.coronawarnapp.datadonation.analytics.modules.DonorModule -import de.rki.coronawarnapp.server.protocols.internal.ppdd.PpaData -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class KeySubmissionStateDonor @Inject constructor() : DonorModule { - - override suspend fun beginDonation(request: DonorModule.Request): DonorModule.Contribution { - // TODO - return object : DonorModule.Contribution { - override suspend fun injectData(protobufContainer: PpaData.PPADataAndroid.Builder) { - // TODO - } - - override suspend fun finishDonation(successful: Boolean) { - // TODO - } - } - } - - override suspend fun deleteData() { - // TODO - } -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/storage/AnalyticsSettings.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/storage/AnalyticsSettings.kt index 9c240c16e7269c78546b020de46897865fa7d329..d8cd04f462c68679ded5ef54d7b502db2c69b2d3 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/storage/AnalyticsSettings.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/storage/AnalyticsSettings.kt @@ -90,6 +90,11 @@ class AnalyticsSettings @Inject constructor( defaultValue = false ) + val lastOnboardingVersionCode = prefs.createFlowPreference( + key = PKEY_ONBOARDED_VERSION_CODE, + defaultValue = 0L + ) + fun clear() = prefs.clearAndNotify() companion object { @@ -99,5 +104,6 @@ class AnalyticsSettings @Inject constructor( private const val PKEY_USERINFO_DISTRICT = "userinfo.district" private const val PKEY_LAST_SUBMITTED_TIMESTAMP = "analytics.submission.timestamp" private const val PKEY_ANALYTICS_ENABLED = "analytics.enabled" + private const val PKEY_ONBOARDED_VERSION_CODE = "analytics.onboarding.versionCode" } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/storage/TestResultDonorSettings.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/storage/TestResultDonorSettings.kt index 84f9345ae6220ae41a2eb9e4162698849608bfad..11b76710c64c003c3c22715ce996e2afaee6d2f3 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/storage/TestResultDonorSettings.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/datadonation/analytics/storage/TestResultDonorSettings.kt @@ -1,8 +1,8 @@ package de.rki.coronawarnapp.datadonation.analytics.storage import android.content.Context +import de.rki.coronawarnapp.datadonation.analytics.common.toMetadataRiskLevel import de.rki.coronawarnapp.risk.RiskLevelResult -import de.rki.coronawarnapp.risk.RiskState import de.rki.coronawarnapp.server.protocols.internal.ppdd.PpaData import de.rki.coronawarnapp.util.di.AppContext import de.rki.coronawarnapp.util.formatter.TestResult @@ -77,12 +77,6 @@ class TestResultDonorSettings @Inject constructor( fun clear() = prefs.clearAndNotify() - private fun RiskLevelResult.toMetadataRiskLevel(): PpaData.PPARiskLevel = - when (riskState) { - RiskState.INCREASED_RISK -> PpaData.PPARiskLevel.RISK_LEVEL_HIGH - else -> PpaData.PPARiskLevel.RISK_LEVEL_LOW - } - companion object { private const val PREFS_KEY_TEST_SCANNED_AFTER_CONSENT = "testResultDonor.testScannedAfterConsent" private const val PREFS_KEY_TEST_RESULT_AT_REGISTRATION = "testResultDonor.testResultAtRegistration" diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoFragment.kt index 55741441fd6f7001ce7351a8818b5f91a2236a1b..5e090ad1587a0af310a71330d55f70c8cdc643d9 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.View import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent +import androidx.activity.OnBackPressedCallback import androidx.core.view.isGone import androidx.fragment.app.Fragment import androidx.navigation.fragment.navArgs @@ -52,16 +53,21 @@ class NewReleaseInfoFragment : Fragment(R.layout.new_release_info_screen_fragmen recyclerView.adapter = ItemAdapter(getItems()) } + // Override android back button to bypass the infinite loop + val backCallback = object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() = vm.onNextButtonClick() + } + requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backCallback) + vm.routeToScreen.observe2(this) { - if (it is NewReleaseInfoNavigationEvents.CloseScreen) { - if (args.comesFromInfoScreen) { + when (it) { + is NewReleaseInfoNavigationEvents.CloseScreen -> popBackStack() - } else { + is NewReleaseInfoNavigationEvents.NavigateToOnboardingDeltaAnalyticsFragment -> doNavigate( NewReleaseInfoFragmentDirections .actionNewReleaseInfoFragmentToOnboardingDeltaAnalyticsFragment() ) - } } } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoNavigationEvents.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoNavigationEvents.kt index e485871c4a3ab9b3e9a8ffec4acc29b42bdf5877..d9fe60928f22b5b3fd49f3df5cf690a7c89dcd25 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoNavigationEvents.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoNavigationEvents.kt @@ -2,4 +2,5 @@ package de.rki.coronawarnapp.release sealed class NewReleaseInfoNavigationEvents { object CloseScreen : NewReleaseInfoNavigationEvents() + object NavigateToOnboardingDeltaAnalyticsFragment : NewReleaseInfoNavigationEvents() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoViewModel.kt index 476bbd9bdf9b5c47276ac58fb1a8746d2d7c512e..6a872ed31b89446f265d33b3e10c6cdb4f75198d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/release/NewReleaseInfoViewModel.kt @@ -4,6 +4,7 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import de.rki.coronawarnapp.BuildConfig import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.datadonation.analytics.storage.AnalyticsSettings import de.rki.coronawarnapp.environment.BuildConfigWrap import de.rki.coronawarnapp.main.CWASettings import de.rki.coronawarnapp.ui.SingleLiveEvent @@ -15,7 +16,8 @@ import timber.log.Timber class NewReleaseInfoViewModel @AssistedInject constructor( dispatcherProvider: DispatcherProvider, - private val settings: CWASettings + private val appSettings: CWASettings, + private val analyticsSettings: AnalyticsSettings ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { val routeToScreen: SingleLiveEvent<NewReleaseInfoNavigationEvents> = SingleLiveEvent() @@ -23,8 +25,12 @@ class NewReleaseInfoViewModel @AssistedInject constructor( val title = R.string.release_info_version_title.toResolvingString(BuildConfig.VERSION_NAME) fun onNextButtonClick() { - settings.lastChangelogVersion.update { BuildConfigWrap.VERSION_CODE } - routeToScreen.postValue(NewReleaseInfoNavigationEvents.CloseScreen) + appSettings.lastChangelogVersion.update { BuildConfigWrap.VERSION_CODE } + if (analyticsSettings.lastOnboardingVersionCode.value == 0L) { + routeToScreen.postValue(NewReleaseInfoNavigationEvents.NavigateToOnboardingDeltaAnalyticsFragment) + } else { + routeToScreen.postValue(NewReleaseInfoNavigationEvents.CloseScreen) + } } fun getItems( diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetector.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetector.kt index b377e9942036e23f79b16100f3c8dd26d99f3bc7..a746ab02146edcda3bf436f4f485e7cd93b318ed 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetector.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelChangeDetector.kt @@ -85,6 +85,10 @@ class RiskLevelChangeDetector @Inject constructor( surveys.resetSurvey(Surveys.Type.HIGH_RISK_ENCOUNTER) } + + if (oldRiskState == RiskState.LOW_RISK && newRiskState == RiskState.INCREASED_RISK) { + riskLevelSettings.lastChangeToHighRiskLevelTimestamp = newResult.calculatedAt + } } companion object { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelSettings.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelSettings.kt index 4e2eb9cf9883e8bf9d5e557df24e9dca5123a89f..652905a0d75ad32267f8c1e4c1bb19764a9087ca 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelSettings.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevelSettings.kt @@ -33,9 +33,19 @@ class RiskLevelSettings @Inject constructor( putLong(PKEY_LAST_CHANGE_CHECKED_RISKLEVEL_TIMESTAMP, value?.millis ?: 0L) } + var lastChangeToHighRiskLevelTimestamp: Instant? + get() = prefs.getLong(PKEY_LAST_CHANGE_TO_HIGH_RISKLEVEL_TIMESTAMP, 0L).let { + if (it != 0L) Instant.ofEpochMilli(it) else null + } + set(value) = prefs.edit { + putLong(PKEY_LAST_CHANGE_TO_HIGH_RISKLEVEL_TIMESTAMP, value?.millis ?: 0L) + } + companion object { private const val NAME_SHARED_PREFS = "risklevel_localdata" private const val PKEY_RISKLEVEL_CALC_LAST_CONFIG_ID = "risklevel.config.identifier.last" private const val PKEY_LAST_CHANGE_CHECKED_RISKLEVEL_TIMESTAMP = "PKEY_RISKLEVEL_CALC_LAST_CONFIG_ID" + private const val PKEY_LAST_CHANGE_TO_HIGH_RISKLEVEL_TIMESTAMP = + "PKEY_RISKLEVEL_CALC_LAST_CHANGE_TO_HIGH_RISKLEVEL" } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionRepository.kt index 37dfa4e4733cfe44b327076495d62c4edfa62235..fc70b8d81502d4dba3bb15c703443778ce207dd2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionRepository.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/SubmissionRepository.kt @@ -1,6 +1,7 @@ package de.rki.coronawarnapp.submission import androidx.annotation.VisibleForTesting +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.deadman.DeadmanNotificationScheduler import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException @@ -33,7 +34,8 @@ class SubmissionRepository @Inject constructor( @AppScope private val scope: CoroutineScope, private val timeStamper: TimeStamper, private val tekHistoryStorage: TEKHistoryStorage, - private val deadmanNotificationScheduler: DeadmanNotificationScheduler + private val deadmanNotificationScheduler: DeadmanNotificationScheduler, + private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector ) { private val testResultReceivedDateFlowInternal = MutableStateFlow(Date()) val testResultReceivedDateFlow: Flow<Date> = testResultReceivedDateFlowInternal @@ -124,6 +126,8 @@ class SubmissionRepository @Inject constructor( updateTestResult(registrationData.testResult) LocalData.devicePairingSuccessfulTimestamp(timeStamper.nowUTC.millis) BackgroundNoise.getInstance().scheduleDummyPattern() + analyticsKeySubmissionCollector.reportTestRegistered() + analyticsKeySubmissionCollector.reportRegisteredWithTeleTAN() } suspend fun asyncRegisterDeviceViaGUID(guid: String): TestResult { @@ -132,6 +136,7 @@ class SubmissionRepository @Inject constructor( updateTestResult(registrationData.testResult) LocalData.devicePairingSuccessfulTimestamp(timeStamper.nowUTC.millis) BackgroundNoise.getInstance().scheduleDummyPattern() + analyticsKeySubmissionCollector.reportTestRegistered() return registrationData.testResult } @@ -147,6 +152,7 @@ class SubmissionRepository @Inject constructor( if (testResult == TestResult.POSITIVE) { LocalData.isAllowedToSubmitDiagnosisKeys(true) + analyticsKeySubmissionCollector.reportPositiveTestResultReceived() deadmanNotificationScheduler.cancelScheduledWork() } @@ -175,6 +181,7 @@ class SubmissionRepository @Inject constructor( fun removeTestFromDevice() { submissionSettings.hasViewedTestResult.update { false } submissionSettings.hasGivenConsent.update { false } + analyticsKeySubmissionCollector.reset() revokeConsentToSubmission() LocalData.registrationToken(null) LocalData.devicePairingSuccessfulTimestamp(0L) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt index 7e37f823d25bb2cc9ca30e03bafad9215db86e59..2bd1faa295558ef435ff124e78fc28ac8ea8c828 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/submission/task/SubmissionTask.kt @@ -2,6 +2,7 @@ package de.rki.coronawarnapp.submission.task import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey import de.rki.coronawarnapp.appconfig.AppConfigProvider +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException import de.rki.coronawarnapp.notification.ShareTestResultNotificationService import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService @@ -26,6 +27,7 @@ import timber.log.Timber import javax.inject.Inject import javax.inject.Provider +@Suppress("LongParameterList") class SubmissionTask @Inject constructor( private val playbook: Playbook, private val appConfigProvider: AppConfigProvider, @@ -35,7 +37,8 @@ class SubmissionTask @Inject constructor( private val autoSubmission: AutoSubmission, private val timeStamper: TimeStamper, private val shareTestResultNotificationService: ShareTestResultNotificationService, - private val testResultAvailableNotificationService: TestResultAvailableNotificationService + private val testResultAvailableNotificationService: TestResultAvailableNotificationService, + private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector ) : Task<DefaultProgress, SubmissionTask.Result> { private val internalProgress = ConflatedBroadcastChannel<DefaultProgress>() @@ -43,14 +46,20 @@ class SubmissionTask @Inject constructor( private var isCanceled = false + private var inBackground = false + override suspend fun run(arguments: Task.Arguments): Result { try { Timber.tag(TAG).d("Running with arguments=%s", arguments) arguments as Arguments - if (arguments.checkUserActivity && hasRecentUserActivity()) { - Timber.tag(TAG).w("User has recently been active in submission, skipping submission.") - return Result(state = Result.State.SKIPPED) + if (arguments.checkUserActivity) { + if (hasRecentUserActivity()) { + Timber.tag(TAG).w("User has recently been active in submission, skipping submission.") + return Result(state = Result.State.SKIPPED) + } else { + inBackground = true + } } if (!submissionSettings.hasGivenConsent.value) { @@ -141,6 +150,9 @@ class SubmissionTask @Inject constructor( Timber.tag(TAG).d("Submitting %s", submissionData) playbook.submit(submissionData) + analyticsKeySubmissionCollector.reportSubmitted() + if (inBackground) analyticsKeySubmissionCollector.reportSubmittedInBackground() + Timber.tag(TAG).d("Submission successful, deleting submission data.") tekHistoryStorage.clear() submissionSettings.symptoms.update { null } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsFragment.kt index 8727896d40b0c3a0b5dc66dd67e45e14d2edcdee..cd2d2231d7a44bb90c1a2ec4a51690bcf5aecb73 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsFragment.kt @@ -26,8 +26,8 @@ class OnboardingAnalyticsFragment : Fragment(R.layout.fragment_onboarding_ppa), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.apply { - onboardingButtonNext.setOnClickListener { viewModel.onNextButtonClick() } - onboardingButtonDisable.setOnClickListener { viewModel.onDisableClick() } + onboardingButtonNext.setOnClickListener { viewModel.onProceed(true) } + onboardingButtonDisable.setOnClickListener { viewModel.onProceed(false) } onboardingButtonBack.buttonIcon.setOnClickListener { requireActivity().onBackPressed() } federalStateRow.setOnClickListener { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsViewModel.kt index ea44c1ea5a76bd05879084de383d0439d6b91041..600c2405f51c51168d9355634cc2f233bdc43d4a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsViewModel.kt @@ -7,18 +7,23 @@ import dagger.assisted.AssistedInject import de.rki.coronawarnapp.datadonation.analytics.Analytics import de.rki.coronawarnapp.datadonation.analytics.common.Districts import de.rki.coronawarnapp.datadonation.analytics.storage.AnalyticsSettings +import de.rki.coronawarnapp.environment.BuildConfigWrap import de.rki.coronawarnapp.ui.SingleLiveEvent +import de.rki.coronawarnapp.util.coroutine.AppScope import de.rki.coronawarnapp.util.coroutine.DispatcherProvider import de.rki.coronawarnapp.util.flow.combine import de.rki.coronawarnapp.util.viewmodel.CWAViewModel import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.launch class OnboardingAnalyticsViewModel @AssistedInject constructor( - settings: AnalyticsSettings, - dispatcherProvider: DispatcherProvider, + private val settings: AnalyticsSettings, + private val dispatcherProvider: DispatcherProvider, private val analytics: Analytics, - val districts: Districts + val districts: Districts, + @AppScope private val appScope: CoroutineScope ) : CWAViewModel() { val completedOnboardingEvent = SingleLiveEvent<Unit>() @@ -32,19 +37,11 @@ class OnboardingAnalyticsViewModel @AssistedInject constructor( districtsList.singleOrNull { it.districtId == id } }.asLiveData(dispatcherProvider.IO) - fun onNextButtonClick() { - launch { - analytics.setAnalyticsEnabled(enabled = true) + fun onProceed(enable: Boolean) { + appScope.launch(context = dispatcherProvider.IO) { + analytics.setAnalyticsEnabled(enabled = enable) } - - completedOnboardingEvent.postValue(Unit) - } - - fun onDisableClick() { - launch { - analytics.setAnalyticsEnabled(enabled = false) - } - + settings.lastOnboardingVersionCode.update { BuildConfigWrap.VERSION_CODE } completedOnboardingEvent.postValue(Unit) } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingDeltaAnalyticsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingDeltaAnalyticsFragment.kt index e6e9ba278c958b0c58fd8e89619de7a0f1d12751..8efd0a961f244f665593e68517fbe20438e21050 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingDeltaAnalyticsFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingDeltaAnalyticsFragment.kt @@ -3,6 +3,7 @@ package de.rki.coronawarnapp.ui.onboarding import android.os.Bundle import android.view.View import android.view.accessibility.AccessibilityEvent +import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentOnboardingDeltaPpaBinding @@ -26,9 +27,15 @@ class OnboardingDeltaAnalyticsFragment : Fragment(R.layout.fragment_onboarding_d override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + val backCallback = object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() = viewModel.onProceed(false) + } + requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, backCallback) + binding.apply { - onboardingButtonNext.setOnClickListener { viewModel.onNextButtonClick() } - onboardingButtonDisable.setOnClickListener { viewModel.onDisableClick() } + onboardingButtonNext.setOnClickListener { viewModel.onProceed(true) } + onboardingButtonDisable.setOnClickListener { viewModel.onProceed(false) } onboardingButtonBack.buttonIcon.setOnClickListener { requireActivity().onBackPressed() } federalStateRow.setOnClickListener { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetViewModel.kt index 2ecbb6d1767484e24eb7c0bf5df2dee0ceef5617..e9128ec667395042f895de51c2d97e5fa0712b22 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetViewModel.kt @@ -7,10 +7,10 @@ import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.reporting.report import de.rki.coronawarnapp.nearby.InternalExposureNotificationClient import de.rki.coronawarnapp.notification.ShareTestResultNotificationService -import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.SingleLiveEvent import de.rki.coronawarnapp.util.DataReset import de.rki.coronawarnapp.util.coroutine.DispatcherProvider +import de.rki.coronawarnapp.util.shortcuts.AppShortcutsHelper import de.rki.coronawarnapp.util.viewmodel.CWAViewModel import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory import de.rki.coronawarnapp.worker.BackgroundWorkScheduler @@ -19,7 +19,7 @@ class SettingsResetViewModel @AssistedInject constructor( dispatcherProvider: DispatcherProvider, private val dataReset: DataReset, private val shareTestResultNotificationService: ShareTestResultNotificationService, - private val submissionRepository: SubmissionRepository + private val shortcutsHelper: AppShortcutsHelper ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { val clickEvent: SingleLiveEvent<SettingsEvents> = SingleLiveEvent() @@ -51,6 +51,7 @@ class SettingsResetViewModel @AssistedInject constructor( shareTestResultNotificationService.resetSharePositiveTestResultNotification() dataReset.clearAllLocalData() + shortcutsHelper.removeAppShortcut() clickEvent.postValue(SettingsEvents.GoToOnboarding) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModel.kt index f65e937154ccab0401ca5e1be6b7460652a4ced9..1428e0f4fc1d1a3862db37a91653c4a934ae0704 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.asLiveData import com.google.android.gms.common.api.ApiException import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.nearby.modules.tekhistory.TEKHistoryProvider import de.rki.coronawarnapp.storage.interoperability.InteroperabilityRepository import de.rki.coronawarnapp.submission.SubmissionRepository @@ -13,13 +14,13 @@ import de.rki.coronawarnapp.util.ui.SingleLiveEvent import de.rki.coronawarnapp.util.viewmodel.CWAViewModel import de.rki.coronawarnapp.util.viewmodel.SimpleCWAViewModelFactory import timber.log.Timber -import kotlin.Exception class SubmissionConsentViewModel @AssistedInject constructor( private val submissionRepository: SubmissionRepository, interoperabilityRepository: InteroperabilityRepository, dispatcherProvider: DispatcherProvider, - private val tekHistoryProvider: TEKHistoryProvider + private val tekHistoryProvider: TEKHistoryProvider, + private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { val routeToScreen: SingleLiveEvent<SubmissionNavigationEvents> = SingleLiveEvent() @@ -29,6 +30,7 @@ class SubmissionConsentViewModel @AssistedInject constructor( fun onConsentButtonClick() { submissionRepository.giveConsentToSubmission() + analyticsKeySubmissionCollector.reportAdvancedConsentGiven() launch { try { val preAuthorized = tekHistoryProvider.preAuthorizeExposureKeyHistory() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultavailable/SubmissionTestResultAvailableViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultavailable/SubmissionTestResultAvailableViewModel.kt index a5f0aa610694698ce6a3edcc50589ac7fa9938a5..89e79f6b9d6cf2ddfcb3d1dd0e091b7bf008d8b7 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultavailable/SubmissionTestResultAvailableViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/resultavailable/SubmissionTestResultAvailableViewModel.kt @@ -7,6 +7,7 @@ import androidx.navigation.NavDirections import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.reporting.report import de.rki.coronawarnapp.submission.SubmissionRepository @@ -23,7 +24,8 @@ class SubmissionTestResultAvailableViewModel @AssistedInject constructor( dispatcherProvider: DispatcherProvider, tekHistoryUpdaterFactory: TEKHistoryUpdater.Factory, submissionRepository: SubmissionRepository, - private val autoSubmission: AutoSubmission + private val autoSubmission: AutoSubmission, + private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { val routeToScreen = SingleLiveEvent<NavDirections>() @@ -113,6 +115,7 @@ class SubmissionTestResultAvailableViewModel @AssistedInject constructor( tekHistoryUpdater.updateTEKHistoryOrRequestPermission() } else { Timber.d("routeToScreen:SubmissionTestResultNoConsentFragment") + analyticsKeySubmissionCollector.reportConsentWithdrawn() showKeysRetrievalProgress.postValue(false) routeToScreen.postValue( SubmissionTestResultAvailableFragmentDirections diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModel.kt index 85af09cf324159ace2456eb156beb62d47331314..249f7e24e09d257c549b102d63de380f2d2e014f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModel.kt @@ -8,6 +8,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import de.rki.coronawarnapp.bugreporting.reportProblem +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.Symptoms import de.rki.coronawarnapp.submission.auto.AutoSubmission @@ -23,7 +25,8 @@ class SubmissionSymptomCalendarViewModel @AssistedInject constructor( @Assisted val symptomIndication: Symptoms.Indication, dispatcherProvider: DispatcherProvider, private val submissionRepository: SubmissionRepository, - private val autoSubmission: AutoSubmission + private val autoSubmission: AutoSubmission, + private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { private val symptomStartInternal = MutableStateFlow<Symptoms.StartOf?>(null) @@ -84,18 +87,19 @@ class SubmissionSymptomCalendarViewModel @AssistedInject constructor( startOfSymptoms = symptomStartInternal.value ).also { Timber.tag(TAG).v("Symptoms updated to %s", it) } } - performSubmission() + performSubmission { analyticsKeySubmissionCollector.reportSubmittedAfterSymptomFlow() } } fun onCancelConfirmed() { Timber.d("onCancelConfirmed() clicked on calendar screen.") - performSubmission() + performSubmission { analyticsKeySubmissionCollector.reportSubmittedAfterCancel() } } - private fun performSubmission() { + private fun performSubmission(onSubmitted: () -> Unit) { launch { try { autoSubmission.runSubmissionNow() + onSubmitted() } catch (e: Exception) { Timber.tag(TAG).e(e, "performSubmission() failed.") } finally { @@ -110,6 +114,7 @@ class SubmissionSymptomCalendarViewModel @AssistedInject constructor( fun onNewUserActivity() { Timber.d("onNewUserActivity()") + analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOM_ONSET) autoSubmission.updateLastSubmissionUserActivity() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModel.kt index 9bed16e6f78f7ebe9a84c14d4e3bf5b1868cea74..5d422d14af934617dc1bc59bb78338e361f0678d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModel.kt @@ -4,6 +4,8 @@ import androidx.lifecycle.asLiveData import androidx.navigation.NavDirections import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.Symptoms import de.rki.coronawarnapp.submission.auto.AutoSubmission @@ -17,7 +19,8 @@ import timber.log.Timber class SubmissionSymptomIntroductionViewModel @AssistedInject constructor( dispatcherProvider: DispatcherProvider, private val submissionRepository: SubmissionRepository, - private val autoSubmission: AutoSubmission + private val autoSubmission: AutoSubmission, + private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { private val symptomIndicationInternal = MutableStateFlow<Symptoms.Indication?>(null) @@ -105,6 +108,7 @@ class SubmissionSymptomIntroductionViewModel @AssistedInject constructor( fun onNewUserActivity() { Timber.d("onNewUserActivity()") + analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.SYMPTOMS) autoSubmission.updateLastSubmissionUserActivity() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt index 43592aca074da95e7fca9d478207f9508dd9875a..a1277d4c81ad3c6ffd3e2a4df94e520c82891496 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultConsentGivenViewModel.kt @@ -4,6 +4,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.auto.AutoSubmission @@ -21,6 +23,7 @@ class SubmissionTestResultConsentGivenViewModel @AssistedInject constructor( private val submissionRepository: SubmissionRepository, private val autoSubmission: AutoSubmission, private val testResultAvailableNotificationService: TestResultAvailableNotificationService, + private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector, dispatcherProvider: DispatcherProvider ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { @@ -69,6 +72,7 @@ class SubmissionTestResultConsentGivenViewModel @AssistedInject constructor( fun onNewUserActivity() { Timber.d("onNewUserActivity()") + analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT) autoSubmission.updateLastSubmissionUserActivity() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentFragment.kt index 46577e1306d66b5a93e1da1aebab986539d7f6c1..2b1fa0d5a3a26617ed28f3031f18c4e5ef0fb68a 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentFragment.kt @@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentSubmissionTestResultPositiveNoConsentBinding import de.rki.coronawarnapp.util.di.AutoInject +import de.rki.coronawarnapp.util.shortcuts.AppShortcutsHelper import de.rki.coronawarnapp.util.ui.doNavigate import de.rki.coronawarnapp.util.ui.observe2 import de.rki.coronawarnapp.util.ui.viewBindingLazy @@ -24,6 +25,7 @@ class SubmissionTestResultNoConsentFragment : Fragment(R.layout.fragment_submission_test_result_positive_no_consent), AutoInject { + @Inject lateinit var appShortcutsHelper: AppShortcutsHelper @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory private val viewModel: SubmissionTestResultNoConsentViewModel by cwaViewModels { viewModelFactory } private val binding: FragmentSubmissionTestResultPositiveNoConsentBinding by viewBindingLazy() @@ -31,8 +33,6 @@ class SubmissionTestResultNoConsentFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewModel.onTestOpened() - val backCallback = object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { showCancelDialog() @@ -60,6 +60,8 @@ class SubmissionTestResultNoConsentFragment : override fun onResume() { super.onResume() + appShortcutsHelper.removeAppShortcut() + viewModel.onTestOpened() binding.submissionTestResultContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT) } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt index ae6984fb4adc10cb12eca293448f9afbffd43ad4..49b07dec8537509cf4040c211f5203004102b380 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/testresult/positive/SubmissionTestResultNoConsentViewModel.kt @@ -4,6 +4,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.ui.submission.testresult.TestResultUIState @@ -14,7 +16,8 @@ import kotlinx.coroutines.Dispatchers class SubmissionTestResultNoConsentViewModel @AssistedInject constructor( private val submissionRepository: SubmissionRepository, - private val testResultAvailableNotificationService: TestResultAvailableNotificationService + private val testResultAvailableNotificationService: TestResultAvailableNotificationService, + private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector ) : CWAViewModel() { val uiState: LiveData<TestResultUIState> = combine( @@ -29,6 +32,7 @@ class SubmissionTestResultNoConsentViewModel @AssistedInject constructor( }.asLiveData(context = Dispatchers.Default) fun onTestOpened() { + analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.TEST_RESULT) submissionRepository.setViewedTestResult() testResultAvailableNotificationService.cancelTestResultAvailableNotification() } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentFragment.kt index 0592f38a373238dd7eca3dda0d547bd46f76dc41..4d245b7f5bf0022d5156ccf891cc251e603cd840 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentFragment.kt @@ -11,6 +11,7 @@ import de.rki.coronawarnapp.tracing.ui.TracingConsentDialog import de.rki.coronawarnapp.ui.submission.SubmissionBlockingDialog import de.rki.coronawarnapp.util.DialogHelper import de.rki.coronawarnapp.util.di.AutoInject +import de.rki.coronawarnapp.util.shortcuts.AppShortcutsHelper import de.rki.coronawarnapp.util.ui.doNavigate import de.rki.coronawarnapp.util.ui.observe2 import de.rki.coronawarnapp.util.ui.viewBindingLazy @@ -25,6 +26,7 @@ import javax.inject.Inject class SubmissionResultPositiveOtherWarningNoConsentFragment : Fragment(R.layout.fragment_submission_no_consent_positive_other_warning), AutoInject { + @Inject lateinit var appShortcutsHelper: AppShortcutsHelper @Inject lateinit var viewModelFactory: CWAViewModelFactoryProvider.Factory private val viewModel: SubmissionResultPositiveOtherWarningNoConsentViewModel by cwaViewModelsAssisted( factoryProducer = { viewModelFactory }, @@ -89,6 +91,8 @@ class SubmissionResultPositiveOtherWarningNoConsentFragment : override fun onResume() { super.onResume() + viewModel.onResume() + appShortcutsHelper.removeAppShortcut() binding.submissionPositiveOtherPrivacyContainer.sendAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT) } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModel.kt index 9a9befc9f5786f017f5e97c23cc22406497cb42d..c02bbe34e37c171ee8e060def68fd83f9e4362d9 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModel.kt @@ -7,6 +7,8 @@ import androidx.navigation.NavDirections import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.Screen import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.reporting.report import de.rki.coronawarnapp.nearby.ENFClient @@ -27,7 +29,8 @@ class SubmissionResultPositiveOtherWarningNoConsentViewModel @AssistedInject con private val autoSubmission: AutoSubmission, tekHistoryUpdaterFactory: TEKHistoryUpdater.Factory, interoperabilityRepository: InteroperabilityRepository, - private val submissionRepository: SubmissionRepository + private val submissionRepository: SubmissionRepository, + private val analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector ) : CWAViewModel(dispatcherProvider = dispatcherProvider) { val routeToScreen = SingleLiveEvent<NavDirections>() @@ -115,6 +118,10 @@ class SubmissionResultPositiveOtherWarningNoConsentViewModel @AssistedInject con tekHistoryUpdater.handleActivityResult(requestCode, resultCode, data) } + fun onResume() { + analyticsKeySubmissionCollector.reportLastSubmissionFlowScreen(Screen.WARN_OTHERS) + } + @AssistedFactory interface Factory : CWAViewModelFactory<SubmissionResultPositiveOtherWarningNoConsentViewModel> { fun create(): SubmissionResultPositiveOtherWarningNoConsentViewModel diff --git a/Corona-Warn-App/src/main/res/drawable/contact_diary_duration_background_selected.xml b/Corona-Warn-App/src/main/res/drawable/contact_diary_duration_background_selected.xml index b230c96594d3925ca38a19c3802cfaeb1fd3ebc9..9a9dca8a8dd80db9dd568aa67c778b4d9e81f7b1 100644 --- a/Corona-Warn-App/src/main/res/drawable/contact_diary_duration_background_selected.xml +++ b/Corona-Warn-App/src/main/res/drawable/contact_diary_duration_background_selected.xml @@ -4,4 +4,4 @@ <corners android:radius="@dimen/radius_card" /> <solid android:color="@color/colorSurface1" /> <stroke android:width="2dip" android:color="@color/colorAccent" /> -</shape> \ No newline at end of file +</shape> diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_add_location_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_add_location_fragment.xml index 1e1ec8dbe6c01241da337b636491fd0a4209fc6a..b2b7e568adcf48b11c6cf027b5eeb4d1e2966ca6 100644 --- a/Corona-Warn-App/src/main/res/layout/contact_diary_add_location_fragment.xml +++ b/Corona-Warn-App/src/main/res/layout/contact_diary_add_location_fragment.xml @@ -63,6 +63,7 @@ android:id="@+id/location_name_input_edit" android:layout_width="match_parent" android:layout_height="wrap_content" + android:maxLength="250" android:imeOptions="actionNext" android:inputType="textCapWords" /> @@ -85,6 +86,7 @@ android:id="@+id/location_phone_input" android:layout_width="match_parent" android:layout_height="wrap_content" + android:maxLength="250" android:imeOptions="actionNext" android:inputType="phone" /> @@ -107,6 +109,7 @@ android:id="@+id/location_email_input" android:layout_width="match_parent" android:layout_height="wrap_content" + android:maxLength="250" android:imeOptions="actionDone" android:inputType="textEmailAddress" /> diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_add_person_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_add_person_fragment.xml index 2163a98fb554e92ad433c7b14c37fcca9376e0bd..b77f760528b0e1d2d540246c7e0d9de019734410 100644 --- a/Corona-Warn-App/src/main/res/layout/contact_diary_add_person_fragment.xml +++ b/Corona-Warn-App/src/main/res/layout/contact_diary_add_person_fragment.xml @@ -62,6 +62,7 @@ android:id="@+id/person_name_input" android:layout_width="match_parent" android:layout_height="wrap_content" + android:maxLength="250" android:imeOptions="actionNext" android:inputType="textCapWords" /> @@ -84,6 +85,7 @@ android:id="@+id/person_phone_number_input" android:layout_width="match_parent" android:layout_height="wrap_content" + android:maxLength="250" android:imeOptions="actionNext" android:inputType="phone" /> @@ -107,6 +109,7 @@ android:id="@+id/person_email_input" android:layout_width="match_parent" android:layout_height="wrap_content" + android:maxLength="250" android:imeOptions="actionDone" android:inputType="textEmailAddress" /> diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_duration_picker_dialog_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_duration_picker_dialog_fragment.xml index b222b3df117080fe443a2c65fe306bc5ca791ba2..882b3e971552b8a976f45642f1cc8cda17d39a67 100644 --- a/Corona-Warn-App/src/main/res/layout/contact_diary_duration_picker_dialog_fragment.xml +++ b/Corona-Warn-App/src/main/res/layout/contact_diary_duration_picker_dialog_fragment.xml @@ -59,31 +59,28 @@ app:layout_constraintStart_toEndOf="@+id/divider" app:layout_constraintTop_toBottomOf="@+id/title" /> - <Button + <com.google.android.material.button.MaterialButton android:id="@+id/cancel_button" - style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog" + style="@style/Widget.MaterialComponents.Button.TextButton.Dialog.Flush" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginTop="29dp" - android:layout_marginBottom="@dimen/spacing_small" - android:letterSpacing="0.08" + android:layout_marginEnd="8dp" android:text="@string/duration_dialog_cancel_button" - android:textColor="@color/colorTextTint" - app:layout_constraintBottom_toBottomOf="parent" + android:textColor="@color/colorAccent" + app:layout_constraintBottom_toBottomOf="@+id/ok_button" app:layout_constraintEnd_toStartOf="@id/ok_button" - app:layout_constraintTop_toBottomOf="@+id/minutes" /> + app:layout_constraintTop_toTopOf="@+id/ok_button" /> - <Button + <com.google.android.material.button.MaterialButton android:id="@+id/ok_button" - style="@style/Widget.AppCompat.Button.ButtonBar.AlertDialog" + style="@style/Widget.MaterialComponents.Button.TextButton.Dialog.Flush" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginTop="29dp" - android:layout_marginEnd="26dp" - android:layout_marginBottom="@dimen/spacing_small" - android:letterSpacing="0.08" + android:layout_marginTop="24dp" + android:layout_marginEnd="8dp" + android:layout_marginBottom="8dp" android:text="@string/duration_dialog_ok_button" - android:textColor="@color/colorTextTint" + android:textColor="@color/colorAccent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/minutes" /> diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_overview_fragment.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_fragment.xml index f3fcf6ff7ae6c678d7ab130f34a86075b8638b16..140a4c3982e094a187e809252263df3147963cd3 100644 --- a/Corona-Warn-App/src/main/res/layout/contact_diary_overview_fragment.xml +++ b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_fragment.xml @@ -1,65 +1,27 @@ <?xml version="1.0" encoding="utf-8"?> -<layout xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools"> + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/content_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:contentDescription="@string/contact_diary_overview_title" + android:orientation="vertical"> - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/content_container" + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar" android:layout_width="match_parent" - android:layout_height="match_parent" - android:contentDescription="@string/contact_diary_overview_title"> + android:layout_height="wrap_content" + android:background="@color/colorBackground" + app:popupTheme="@style/CWAToolbar.Menu" + app:title="@string/contact_diary_overview_title" /> - <androidx.appcompat.widget.Toolbar - android:id="@+id/toolbar" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:background="@color/colorBackground" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:popupTheme="@style/CWAToolbar.Menu" - app:title="@string/contact_diary_overview_title" /> - - <TextView - android:id="@+id/contact_diary_overview_subtitle" - style="@style/subtitleMedium" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_small" - android:focusable="true" - android:text="@string/contact_diary_overview_subtitle" - app:layout_constraintEnd_toEndOf="@id/guideline_end" - app:layout_constraintStart_toStartOf="@id/guideline_start" - app:layout_constraintTop_toBottomOf="@id/toolbar" - tools:text="Tragen Sie ein, mit wem Sie sich getroffen haben und wo Sie gewesen sind." /> - - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/contact_diary_overview_recyclerview" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_marginTop="@dimen/spacing_small" - android:layout_marginBottom="@dimen/spacing_mega_tiny" - app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="@id/guideline_end" - app:layout_constraintHorizontal_bias="0.0" - app:layout_constraintStart_toStartOf="@+id/guideline_start" - app:layout_constraintTop_toBottomOf="@+id/contact_diary_overview_subtitle" - tools:listitem="@layout/contact_diary_overview_list_item" /> - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guideline_start" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical" - app:layout_constraintGuide_begin="@dimen/guideline_start" /> - - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guideline_end" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical" - app:layout_constraintGuide_end="@dimen/guideline_end" /> - - </androidx.constraintlayout.widget.ConstraintLayout> + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/contact_diary_overview_recyclerview" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + tools:listitem="@layout/contact_diary_overview_list_item" /> -</layout> +</LinearLayout> diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_overview_list_item.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_list_item.xml index ee6ea381df3b131608f7b6ad74af1fd75c765b77..6082e367f537a3a4bacfa1a5aae22919e5d5f5d4 100644 --- a/Corona-Warn-App/src/main/res/layout/contact_diary_overview_list_item.xml +++ b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_list_item.xml @@ -1,94 +1,92 @@ <?xml version="1.0" encoding="utf-8"?> -<layout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools"> + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/contact_diary_overview_element_body" + style="@style/contactDiaryCardRipple" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="24dp" + android:layout_marginEnd="24dp" + android:layout_marginBottom="@dimen/spacing_tiny" + android:focusable="true"> - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/contact_diary_overview_element_body" - style="@style/contactDiaryCardRipple" - android:layout_width="match_parent" + <TextView + android:id="@+id/contact_diary_overview_element_name" + style="@style/contactDiaryListItem" + android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/spacing_tiny" - android:focusable="true"> - - <TextView - android:id="@+id/contact_diary_overview_element_name" - style="@style/contactDiaryListItem" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="@dimen/spacing_small" - android:focusable="false" - app:layout_constraintBottom_toTopOf="@id/contact_diary_overview_element_guideline" - app:layout_constraintEnd_toStartOf="@+id/contact_diary_overview_element_right_arrow" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - tools:text="Donnerstag, 01.12.2020" /> - - <ImageView - android:id="@+id/contact_diary_overview_element_right_arrow" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginVertical="@dimen/spacing_tiny" - android:layout_marginEnd="@dimen/spacing_small" - android:importantForAccessibility="no" - android:scaleType="centerInside" - android:src="@drawable/ic_contact_diary_right_arrow" - app:layout_constraintBottom_toTopOf="@id/contact_diary_overview_element_guideline" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + android:layout_marginStart="@dimen/spacing_small" + android:focusable="false" + app:layout_constraintBottom_toTopOf="@id/contact_diary_overview_element_guideline" + app:layout_constraintEnd_toStartOf="@+id/contact_diary_overview_element_right_arrow" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:text="Donnerstag, 01.12.2020" /> - <androidx.constraintlayout.widget.Guideline - android:id="@+id/contact_diary_overview_element_guideline" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="horizontal" - app:layout_constraintGuide_begin="@dimen/contact_diary_list_item" /> + <ImageView + android:id="@+id/contact_diary_overview_element_right_arrow" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginVertical="@dimen/spacing_tiny" + android:layout_marginEnd="@dimen/spacing_small" + android:importantForAccessibility="no" + android:scaleType="centerInside" + android:src="@drawable/ic_contact_diary_right_arrow" + app:layout_constraintBottom_toTopOf="@id/contact_diary_overview_element_guideline" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> - <include - android:id="@+id/contact_diary_overview_nested_list_item_risk" - layout="@layout/contact_diary_overview_nested_list_item_risk" - android:layout_width="match_parent" - android:focusable="false" - android:layout_height="wrap_content" - app:layout_constraintTop_toBottomOf="@id/contact_diary_overview_element_guideline" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toEndOf="parent" /> + <androidx.constraintlayout.widget.Guideline + android:id="@+id/contact_diary_overview_element_guideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_begin="@dimen/contact_diary_list_item" /> - <androidx.constraintlayout.widget.Barrier - android:id="@+id/contact_diary_overview_barrier" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:barrierDirection="bottom" - app:barrierAllowsGoneWidgets="false" - app:constraint_referenced_ids="contact_diary_overview_element_guideline, contact_diary_overview_nested_list_item_risk"/> + <include + android:id="@+id/contact_diary_overview_nested_list_item_risk" + layout="@layout/contact_diary_overview_nested_list_item_risk" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:focusable="false" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/contact_diary_overview_element_guideline" /> - <View - android:id="@+id/contact_diary_overview_element_divider" - android:layout_width="match_parent" - android:layout_height="@dimen/card_divider" - android:background="?android:attr/listDivider" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/contact_diary_overview_barrier"/> + <androidx.constraintlayout.widget.Barrier + android:id="@+id/contact_diary_overview_barrier" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="bottom" + app:constraint_referenced_ids="contact_diary_overview_element_guideline, contact_diary_overview_nested_list_item_risk" /> - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/contact_diary_overview_nested_recycler_view" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:nestedScrollingEnabled="false" - android:paddingVertical="@dimen/spacing_tiny" - app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toBottomOf="@id/contact_diary_overview_element_divider" /> + <View + android:id="@+id/contact_diary_overview_element_divider" + android:layout_width="match_parent" + android:layout_height="@dimen/card_divider" + android:background="?android:attr/listDivider" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/contact_diary_overview_barrier" /> - <androidx.constraintlayout.widget.Group - android:id="@+id/contact_diary_overview_nested_element_group" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:constraint_referenced_ids="contact_diary_overview_element_divider,contact_diary_overview_nested_recycler_view"/> + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/contact_diary_overview_nested_recycler_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:nestedScrollingEnabled="false" + android:paddingVertical="@dimen/spacing_tiny" + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/contact_diary_overview_element_divider" /> - </androidx.constraintlayout.widget.ConstraintLayout> + <androidx.constraintlayout.widget.Group + android:id="@+id/contact_diary_overview_nested_element_group" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:constraint_referenced_ids="contact_diary_overview_element_divider,contact_diary_overview_nested_recycler_view" /> -</layout> +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/Corona-Warn-App/src/main/res/layout/contact_diary_overview_list_subheader.xml b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_list_subheader.xml new file mode 100644 index 0000000000000000000000000000000000000000..50ff8857dc420ebdc3684d2c25dc76ce27043b72 --- /dev/null +++ b/Corona-Warn-App/src/main/res/layout/contact_diary_overview_list_subheader.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + xmlns:tools="http://schemas.android.com/tools"> + + + <TextView + android:id="@+id/contact_diary_overview_subtitle" + style="@style/subtitleMedium" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="24dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="24dp" + android:layout_marginBottom="16dp" + android:focusable="true" + android:text="@string/contact_diary_overview_subtitle" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:text="Tragen Sie ein, mit wem Sie sich getroffen haben und wo Sie gewesen sind." /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/navigation/nav_graph_onboarding.xml b/Corona-Warn-App/src/main/res/navigation/nav_graph_onboarding.xml index 3c128a61f3a3f9b98e3b3efcd31e7167af410cf7..e4bcb9b60551fbc18d62f7ac4e364b71fc604136 100644 --- a/Corona-Warn-App/src/main/res/navigation/nav_graph_onboarding.xml +++ b/Corona-Warn-App/src/main/res/navigation/nav_graph_onboarding.xml @@ -135,4 +135,4 @@ android:name="de.rki.coronawarnapp.ui.information.InformationTermsFragment" android:label="@layout/fragment_information_terms" tools:layout="@layout/fragment_information_terms" /> -</navigation> \ No newline at end of file +</navigation> diff --git a/Corona-Warn-App/src/main/res/values-bg/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-bg/contact_diary_strings.xml index 7b9a7397daa1aebab0d499105fe5c82e02457ee4..07fcab5029d5c3969a433ff62e10985f97908bea 100644 --- a/Corona-Warn-App/src/main/res/values-bg/contact_diary_strings.xml +++ b/Corona-Warn-App/src/main/res/values-bg/contact_diary_strings.xml @@ -11,7 +11,9 @@ <string name="contact_diary_person_list_no_items_title">"Ð’Ñе още нÑма въведени лица"</string> <string name="contact_diary_person_list_no_items_subtitle">"Създайте лице и го добавете към Ð’Ð°ÑˆÐ¸Ñ Ð´Ð½ÐµÐ²Ð½Ð¸Ðº на контактите."</string> <string name="contact_diary_add_person_title">"Лице"</string> - <string name="contact_diary_add_person_text_input_name_hint">"Име"</string> + <string name="contact_diary_add_person_text_input_name_hint">"Име, фамилиÑ"</string> + <string name="contact_diary_add_text_input_phone_hint">"Телефон"</string> + <string name="contact_diary_add_text_input_email_hint">"Имейл"</string> <string name="contact_diary_add_person_save_button">"Запазване"</string> <string name="contact_diary_add_location_title">"ÐœÑÑто"</string> <string name="contact_diary_add_location_text_input_hint">"ОпиÑание"</string> @@ -70,8 +72,10 @@ <string name="contact_diary_low_risk_title">"ÐиÑък риÑк"</string> <!-- XTXT: Body for contact diary overview screen risk information --> <string name="contact_diary_risk_body">"въз оÑнова на оценените от приложението контакти."</string> + <!-- XTXT: Body for contact diary overview screen risk information when high risk due to low risk encounters--> + <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"въз оÑнова на повече от едно излагане на ниÑък риÑк."</string> <!-- XTXT: Extended Body for contact diary overview screen risk information --> - <string name="contact_diary_risk_body_extended">"въз оÑнова на оценените от приложението контакти. Ðе е задължително те да Ñа Ñвързани Ñ Ð¾Ñ‚Ð±ÐµÐ»Ñзаните от Ð’Ð°Ñ Ñ…Ð¾Ñ€Ð° и меÑта."</string> + <string name="contact_diary_risk_body_extended">"Ðе е задължително те да Ñа Ñвързани Ñ Ð¾Ñ‚Ð±ÐµÐ»Ñзаните от Ð’Ð°Ñ Ñ…Ð¾Ñ€Ð° и меÑта."</string> <!-- XTXT: content description of contact journal image on home screen --> @@ -111,6 +115,13 @@ <!-- XHED: Title for the contact diary dialog to delete delete a single person --> <string name="contact_diary_delete_person_title">"ÐаиÑтина ли иÑкате да изтриете това лице?"</string> + <!-- XHED: Title for the contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_title">"Бележка"</string> + <!-- XTXT: Description for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_description">"Тук можете да въведете бележки, които ще ви помогнат да оцените по-добре ÑÐ²Ð¾Ñ Ñ€Ð¸Ñк от заразÑване."</string> + <!-- XTXT: Body for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_body">"Опишете обÑтоÑтелÑтвата, които биха могли да доведат до повишаване на вашето ниво на риÑк, например в каква близоÑÑ‚ Ñте били до други хора и каква дейноÑÑ‚ Ñ Ð¿Ð¾Ñ‚ÐµÐ½Ñ†Ð¸Ð°Ð»Ð½Ð¾ влиÑние върху качеÑтвото на въздуха Ñте извършвали (напр. „ÑедÑхме близо един до друг“, „Ñпортувахме“, „проÑтранÑтвото беше малко“ или „пÑхме“).\n\nÐко Ñе заразите, тази Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶Ðµ да помогне на Ñлужбата за общеÑтвено здравеопазване да проÑледи потенциалните вериги на заразÑване."</string> + <!-- XTXT: location (description for screen readers) --> <string name="accessibility_location">"ÐœÑÑто %s"</string> <!-- XTXT: person (description for screen readers) --> @@ -133,4 +144,29 @@ <!-- XTXT: Edit (description for screen readers) --> <string name="accessibility_edit">"Редактиране"</string> + <!-- XACT: Add Person Button (description for screen readers) --> + <string name="accessibility_day_add_person">"ДобавÑне на лице"</string> + <!-- XACT: Add Location Button (description for screen readers) --> + <string name="accessibility_day_add_location">"ДобавÑне на мÑÑто"</string> + + <!-- XBUT: Option - person encounter - below 15 Min --> + <string name="contact_diary_person_encounter_duration_below_15_min">"По-малко от 15 мин"</string> + <!-- XBUT: Option - person encounter - above 15 Min --> + <string name="contact_diary_person_encounter_duration_above_15_min">"Повече от 15 мин"</string> + <!-- XBUT: Option - person encounter - with mask --> + <string name="contact_diary_person_encounter_mask_with">"С маÑка"</string> + <!-- XBUT: Option - person encounter - without mask --> + <string name="contact_diary_person_encounter_mask_without">"Без маÑка"</string> + <!-- XBUT: Option - person encounter - outside --> + <string name="contact_diary_person_encounter_environment_outside">"Ðа открито"</string> + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_person_encounter_environment_inside">"Ðа закрито"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_person_encounter_circumstances_hint">"Забележка (напр. близко разÑтоÑние)"</string> + + + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_location_visit_duration_label">"ПродължителноÑÑ‚"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_location_visit_circumstances_hint">"Забележка (напр. препълнено)"</string> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-bg/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-bg/release_info_strings.xml index 22bc2a703de4e25aa7f6b5b9da3e47385ea552b3..ad038d586b9f7aea1e7a6d21cf2406c00009ffb2 100644 --- a/Corona-Warn-App/src/main/res/values-bg/release_info_strings.xml +++ b/Corona-Warn-App/src/main/res/values-bg/release_info_strings.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?><resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" tools:ignore="MissingTranslation"> <!-- #################################### - Release Info Screen 1.12 + Release Info Screen 1.14 ###################################### --> <!-- XHED: Title for the release info screen --> @@ -16,42 +16,34 @@ <!-- XHED: Titles for the release info screen bullet points --> <string-array name="new_release_title"> - <item>"Връзка към анкетата на инÑтитута “Роберт Кохâ€"</item> - <item>"СъглаÑие за ÑподелÑне на данни (незадължително)"</item> - <item>"Промени в плочките за риÑк"</item> - <item>"Продължаване на региÑтрирането на Ð¸Ð·Ð»Ð°Ð³Ð°Ð½Ð¸Ñ Ð½Ð° риÑк Ñлед ÑподелÑнето на Вашите Ñлучайно генерирани ИД кодове"</item> - <item>"ВнедрÑване на табове"</item> - <item>"Допълнителна Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ð½Ð¾Ñно процедурата за теÑтване"</item> + <item>"Допълнителни функции в дневника на контактите"</item> + <item>"Директен доÑтъп до дневника на контактите"</item> + <item>"Повече подробноÑти отноÑно вашето ниво на риÑк"</item> + <item>"Екранни Ñнимки на приложението Corona-Warn-App"</item> </string-array> <!-- XTXT: Text bodies for the release info screen bullet points --> <string-array name="new_release_body"> - <item>"Ðко Вашето ниво на риÑк от заразÑване е повишено, можете да отворите и попълните анкетата на инÑтитута “Роберт Кох†от Ñамото приложение."</item> - <item>"Вече имате възможноÑÑ‚ да ÑподелÑте Ñвоите данни за използването на приложението. Това ще ни помогне да го подобрим."</item> - <item>"Малки промени в текÑтовете на плочките за риÑк."</item> - <item>"След като Ñподелите Вашите Ñлучайно генерирани ИД кодове, можете да решите дали и кога бихте желали да включите пак региÑтрирането на излаганиÑта на риÑк."</item> - <item>"Вече има отделен таб за Ð’Ð°ÑˆÐ¸Ñ Ð´Ð½ÐµÐ²Ð½Ð¸Ðº на контактите. Така имате бърз доÑтъп до дневника и можете леÑно да преминавате от него към Ð½Ð°Ñ‡Ð°Ð»Ð½Ð¸Ñ ÐµÐºÑ€Ð°Ð½ на приложението."</item> - <item>"Ð’ приложението вече има по-подробна Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ð½Ð¾Ñно процедурата за теÑтване."</item> + <item>"Вече можете да въвеждате Ñпецифични обÑтоÑтелÑтва за вÑеки контакт. Можете да избирате от предварително зададени опции (напр. продължителноÑÑ‚ на контакта, използвана ли е маÑка, или не), както и да въвеждате кратка бележка, в коÑто да отбележите други обÑтоÑтелÑтва, които биха могли да доведат да повишен риÑк. Ðко Ñе заразите, тази Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶Ðµ да помогне на Ñлужбата за общеÑтвено здравеопазване да проÑледи потенциалните вериги на заразÑване."</item> + <item>"Вече можете да добавите Ð·Ð°Ð¿Ð¸Ñ Ð² дневника на контактите Ñи, без да е необходимо първо да отварÑте приложението. За да направите това, докоÑнете и задръжте иконата на приложението Corona-Warn-App в продължение на 2 Ñекунди, докато Ñе поÑви меню, и Ñлед това изберете „ДобавÑне на Ð·Ð°Ð¿Ð¸Ñ Ñ Ð´Ð½ÐµÑˆÐ½Ð° дата в дневника“."</item> + <item>"Ðко приложението указва, че вашиÑÑ‚ риÑк от заразÑване е повишен, вече можете да видите дали това Ñе дължи на едно или повече Ð¸Ð·Ð»Ð°Ð³Ð°Ð½Ð¸Ñ Ñ Ð¿Ð¾Ð²Ð¸ÑˆÐµÐ½ риÑк, или на такива Ñ Ð½Ð¸Ñък риÑк."</item> + <item>"Ð’Ñички екранни Ñнимки на приложението вече Ñа доÑтъпни в уебÑайта https://www.coronawarn.app. Така ще можете да научавате например какви нови функции Ñе планират."</item> </string-array> <!-- XTXT: Text labels that will be converted to Links --> <string-array name="new_release_linkified_labels"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app"</item> </string-array> <!-- XTXT: URL destinations for the lables in new_release_linkified_labels --> <string-array name="new_release_target_urls"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app/en/screenshots"</item> </string-array> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-bg/strings.xml b/Corona-Warn-App/src/main/res/values-bg/strings.xml index fbdda0b02b459d441f2450af2e29f76ea66c72ca..658893e14fd24cd4e11d9b2f9a559d01d22910e6 100644 --- a/Corona-Warn-App/src/main/res/values-bg/strings.xml +++ b/Corona-Warn-App/src/main/res/values-bg/strings.xml @@ -322,7 +322,7 @@ <string name="risk_details_behavior_body_stay_away">"Спазвайте диÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð¾Ñ‚ поне 1,5 м от околните."</string> <!-- XMSG: risk details - link to faq, something like a bullet point --> - <string name="risk_details_increased_risk_faq_link_text">"Ðко Ñе теÑтвате, ще получите допълнителна Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ð½Ð¾Ñно процедурата за теÑтване в ЧЗВ."</string> + <string name="risk_details_increased_risk_faq_link_text">"Ðко Ñе теÑтвате, вижте Процедура за теÑтване в ЧЗВ, за да получите допълнителна информациÑ."</string> <!-- XTXT: Explanation screen increased risk level link label - HAS TO MATCH the link text above --> <string name="risk_details_increased_risk_faq_link_label">"ЧЗВ"</string> <!-- XTXT: Explains user about increased risk level: URL, has to be "translated" into english (relevant for all languages except german) - https://www.coronawarn.app/en/faq/#further_details --> @@ -537,11 +537,11 @@ <!-- XTXT: onboarding privacy preserving analytics (ppa) - regional evaluation text --> <string name="onboarding_ppa_regional_evaluation_text">"Ðко поÑочите федерална Ð¿Ñ€Ð¾Ð²Ð¸Ð½Ñ†Ð¸Ñ Ð¸ регион, ще можем да правим и регионални анализи."</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - age title --> - <string name="onboarding_ppa_age_title">"Вашата възраÑÑ‚ (незадължително)"</string> + <string name="onboarding_ppa_age_title">"Вашата възраÑтова група (незадължително)"</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - consent title --> <string name="onboarding_ppa_more_info_title">"Подробна Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ð½Ð¾Ñно обработката на тези данни и риÑковете отноÑно защитата на данните в СÐЩ и други държави."</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - donate button --> - <string name="onboarding_ppa_consent_donate_button">"СподелÑне на данни"</string> + <string name="onboarding_ppa_consent_donate_button">"Приемам"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - dont donate button --> <string name="onboarding_ppa_consent_not_donate_button">"Без ÑподелÑне на данни"</string> @@ -1754,6 +1754,9 @@ <!-- XBUT: Abort button for test result positive no consent screen --> <string name="submission_test_result_positive_no_consent_button_abort">"Отказ"</string> + <!-- XHED: Title of contact diary app shortcut --> + <string name="app_shortcut_contact_diary_title">"ДобавÑне на запиÑ"</string> + <!-- XTXT: Statistics information (Accessibilty) --> <string name="statistics_info_button">"Още информациÑ"</string> <!-- XHED: Title for statistics reproduction card --> @@ -1830,7 +1833,7 @@ <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_UNSPECIFIED --> <string name="analytics_userinput_agegroup_unspecified">"Без отговор"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_0_TO_29 --> - <string name="analytics_userinput_agegroup_0_to_29">"0-29 години"</string> + <string name="analytics_userinput_agegroup_0_to_29">"До 29 години"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_30_TO_59 --> <string name="analytics_userinput_agegroup_30_to_59">"30-59 години"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_FROM_60 --> @@ -1877,4 +1880,17 @@ <string name="analytics_userinput_district_title">"Ð’ кой окръг Ñе намирате"</string> <!-- XTXT: Analytics voluntary user input, district: UNSPECIFIED --> <string name="analytics_userinput_district_unspecified">"Без отговор"</string> -</resources> + + <!-- #################################### + Duration dialog + ###################################### --> + + <!-- XHED: Duration dialog title --> + <string name="duration_dialog_title">"ПродължителноÑÑ‚"</string> + <!-- XBUT: Duration dialog cancel button --> + <string name="duration_dialog_cancel_button">"Отказ"</string> + <!-- XBUT: Duration dialog ok button --> + <string name="duration_dialog_ok_button">"OK"</string> + <!-- NOTR --> + <string name="duration_dialog_default_value">"00:00"</string> +</resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-en/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-en/contact_diary_strings.xml index 4590f73acfddedd5dcddbf5dbe74a2b8e330aa8f..67d81f0efc1f1469fdb4bfba79a26f3cd3a55d34 100644 --- a/Corona-Warn-App/src/main/res/values-en/contact_diary_strings.xml +++ b/Corona-Warn-App/src/main/res/values-en/contact_diary_strings.xml @@ -11,7 +11,9 @@ <string name="contact_diary_person_list_no_items_title">"No people defined yet"</string> <string name="contact_diary_person_list_no_items_subtitle">"Create a person and add them to your contact journal."</string> <string name="contact_diary_add_person_title">"Person"</string> - <string name="contact_diary_add_person_text_input_name_hint">"Name"</string> + <string name="contact_diary_add_person_text_input_name_hint">"First name, last name"</string> + <string name="contact_diary_add_text_input_phone_hint">"Phone"</string> + <string name="contact_diary_add_text_input_email_hint">"e-mail"</string> <string name="contact_diary_add_person_save_button">"Save"</string> <string name="contact_diary_add_location_title">"Place"</string> <string name="contact_diary_add_location_text_input_hint">"Description"</string> @@ -70,8 +72,10 @@ <string name="contact_diary_low_risk_title">"Low Risk"</string> <!-- XTXT: Body for contact diary overview screen risk information --> <string name="contact_diary_risk_body">"based on the encounters evaluated by the app."</string> + <!-- XTXT: Body for contact diary overview screen risk information when high risk due to low risk encounters--> + <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"based on multiple exposures with low risk."</string> <!-- XTXT: Extended Body for contact diary overview screen risk information --> - <string name="contact_diary_risk_body_extended">"based on the encounters evaluated by the app. They are not necessarily related to the people and places you have recorded."</string> + <string name="contact_diary_risk_body_extended">"They are not necessarily related to the people and places you have recorded."</string> <!-- XTXT: content description of contact journal image on home screen --> @@ -111,6 +115,13 @@ <!-- XHED: Title for the contact diary dialog to delete delete a single person --> <string name="contact_diary_delete_person_title">"Do you really want to remove this person?"</string> + <!-- XHED: Title for the contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_title">"Note"</string> + <!-- XTXT: Description for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_description">"You can enter notes here that will help you to better estimate your risk of infection."</string> + <!-- XTXT: Body for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_body">"Write down the circumstances that could result in an increased risk, for example, how close you were to other people or things you did that could affect the air quality (examples: “sat close togetherâ€, “played sportsâ€, “little spaceâ€, “we sangâ€).\n\nIf you become infected, this information can also help the public health authority trace potential chains of infection."</string> + <!-- XTXT: location (description for screen readers) --> <string name="accessibility_location">"Place %s"</string> <!-- XTXT: person (description for screen readers) --> @@ -133,4 +144,29 @@ <!-- XTXT: Edit (description for screen readers) --> <string name="accessibility_edit">"Edit"</string> + <!-- XACT: Add Person Button (description for screen readers) --> + <string name="accessibility_day_add_person">"Add Person"</string> + <!-- XACT: Add Location Button (description for screen readers) --> + <string name="accessibility_day_add_location">"Add Place"</string> + + <!-- XBUT: Option - person encounter - below 15 Min --> + <string name="contact_diary_person_encounter_duration_below_15_min">"Less than 15 min"</string> + <!-- XBUT: Option - person encounter - above 15 Min --> + <string name="contact_diary_person_encounter_duration_above_15_min">"More than 15 min"</string> + <!-- XBUT: Option - person encounter - with mask --> + <string name="contact_diary_person_encounter_mask_with">"With mask"</string> + <!-- XBUT: Option - person encounter - without mask --> + <string name="contact_diary_person_encounter_mask_without">"Without mask"</string> + <!-- XBUT: Option - person encounter - outside --> + <string name="contact_diary_person_encounter_environment_outside">"Outdoors"</string> + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_person_encounter_environment_inside">"Indoors"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_person_encounter_circumstances_hint">"Note (e.g. close distance)"</string> + + + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_location_visit_duration_label">"Duration"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_location_visit_circumstances_hint">"Note (e.g. very full)"</string> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-en/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-en/release_info_strings.xml index 16bcc281c37b95b523da1f13f0944c8bd5f65fc9..97db0a2ff3c673927a356ef88cb27e6801fab66b 100644 --- a/Corona-Warn-App/src/main/res/values-en/release_info_strings.xml +++ b/Corona-Warn-App/src/main/res/values-en/release_info_strings.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?><resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" tools:ignore="MissingTranslation"> <!-- #################################### - Release Info Screen 1.12 + Release Info Screen 1.14 ###################################### --> <!-- XHED: Title for the release info screen --> @@ -16,42 +16,34 @@ <!-- XHED: Titles for the release info screen bullet points --> <string-array name="new_release_title"> - <item>"Link to RKI survey"</item> - <item>"Consent to Share Data (optional)"</item> - <item>"Changes to the Risk Tiles"</item> - <item>"Continuation of Exposure Logging after Sharing Your Random IDs"</item> - <item>"Implementation of Tabs"</item> - <item>"More Information about the Testing Procedure"</item> + <item>"Additional Features in the Contact Journal"</item> + <item>"Direct Access to Contact Journal"</item> + <item>"More Details about Your Risk Status"</item> + <item>"Screenshots for the Corona-Warn-App"</item> </string-array> <!-- XTXT: Text bodies for the release info screen bullet points --> <string-array name="new_release_body"> - <item>"If you have an increased risk, you can start and take a survey conducted by the Robert Koch Institute from within the app."</item> - <item>"You now have the option of sharing your usage data, which will help us to improve the app."</item> - <item>"Minor changes to the texts on the risk tiles."</item> - <item>"After you have shared your encrypted random IDs, you can decide whether and when you want to switch exposure logging back on."</item> - <item>"There is now a separate tab page for your contact journal. This lets you access your journal and switch from the contact journal back to the home screen of the app more quickly."</item> - <item>"The app now contains more detailed information about the testing procedure."</item> + <item>"You can now enter the specific circumstances of each encounter. You can select from the predefined options (such as duration of the encounter, with or without mask) and also enter a brief note to record other circumstances that might result in an increased risk. If you become infected, this information can help the public health authority trace potential chains of infection."</item> + <item>"You can now add an entry to your contact journal directly, without having to open the app first. To do so, tap and hold the icon for the Corona-Warn-App for approximately 2 seconds, until a menu appears, and then tap “Add Journal Entry for Todayâ€."</item> + <item>"If the app indicates that you have an increased risk, you can now see whether the risk status is displayed based on one or more exposures with an increased risk or one or more exposures with a low risk."</item> + <item>"The website https://www.coronawarn.app now contains all the screenshots for the app, so you can find out about planned features, for example."</item> </string-array> <!-- XTXT: Text labels that will be converted to Links --> <string-array name="new_release_linkified_labels"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app"</item> </string-array> <!-- XTXT: URL destinations for the lables in new_release_linkified_labels --> <string-array name="new_release_target_urls"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app/en/screenshots"</item> </string-array> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-en/strings.xml b/Corona-Warn-App/src/main/res/values-en/strings.xml index 0330f3c7b7f0bab25bccdc3ad621f791477b9178..d8c0ec6c58b8f6db20d394c7eb2a9318fe9bb08a 100644 --- a/Corona-Warn-App/src/main/res/values-en/strings.xml +++ b/Corona-Warn-App/src/main/res/values-en/strings.xml @@ -537,11 +537,11 @@ <!-- XTXT: onboarding privacy preserving analytics (ppa) - regional evaluation text --> <string name="onboarding_ppa_regional_evaluation_text">"If you also specify your federal state and region, we can conduct regional analyses."</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - age title --> - <string name="onboarding_ppa_age_title">"Your age (optional)"</string> + <string name="onboarding_ppa_age_title">"Your age group (optional)"</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - consent title --> <string name="onboarding_ppa_more_info_title">"Detailed Information about This Data Processing and Data Protection Risks in the U.S. and Other Third Countries"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - donate button --> - <string name="onboarding_ppa_consent_donate_button">"Share Data"</string> + <string name="onboarding_ppa_consent_donate_button">"Accept"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - dont donate button --> <string name="onboarding_ppa_consent_not_donate_button">"Do Not Share"</string> @@ -1754,6 +1754,9 @@ <!-- XBUT: Abort button for test result positive no consent screen --> <string name="submission_test_result_positive_no_consent_button_abort">"Cancel"</string> + <!-- XHED: Title of contact diary app shortcut --> + <string name="app_shortcut_contact_diary_title">"Add Entry"</string> + <!-- XTXT: Statistics information (Accessibilty) --> <string name="statistics_info_button">"Further information"</string> <!-- XHED: Title for statistics reproduction card --> @@ -1830,7 +1833,7 @@ <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_UNSPECIFIED --> <string name="analytics_userinput_agegroup_unspecified">"No answer"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_0_TO_29 --> - <string name="analytics_userinput_agegroup_0_to_29">"0-29 years old"</string> + <string name="analytics_userinput_agegroup_0_to_29">"Up to 29"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_30_TO_59 --> <string name="analytics_userinput_agegroup_30_to_59">"30-59 years old"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_FROM_60 --> @@ -1877,4 +1880,17 @@ <string name="analytics_userinput_district_title">"Your District (County)"</string> <!-- XTXT: Analytics voluntary user input, district: UNSPECIFIED --> <string name="analytics_userinput_district_unspecified">"No answer"</string> + + <!-- #################################### + Duration dialog + ###################################### --> + + <!-- XHED: Duration dialog title --> + <string name="duration_dialog_title">"Duration"</string> + <!-- XBUT: Duration dialog cancel button --> + <string name="duration_dialog_cancel_button">"Cancel"</string> + <!-- XBUT: Duration dialog ok button --> + <string name="duration_dialog_ok_button">"OK"</string> + <!-- NOTR --> + <string name="duration_dialog_default_value">"00:00"</string> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-pl/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-pl/contact_diary_strings.xml index 38df500cf588e0f9c76fc2d46671d4d9ac3affb0..def8dbd37cbf58ecb39050b2a2c6ed1f712005d3 100644 --- a/Corona-Warn-App/src/main/res/values-pl/contact_diary_strings.xml +++ b/Corona-Warn-App/src/main/res/values-pl/contact_diary_strings.xml @@ -11,7 +11,9 @@ <string name="contact_diary_person_list_no_items_title">"Nie zdefiniowano jeszcze żadnych osób"</string> <string name="contact_diary_person_list_no_items_subtitle">"Utwórz osobÄ™ i dodaj jÄ… do dziennika kontaktów."</string> <string name="contact_diary_add_person_title">"Osoba"</string> - <string name="contact_diary_add_person_text_input_name_hint">"ImiÄ™ i nazwisko"</string> + <string name="contact_diary_add_person_text_input_name_hint">"ImiÄ™, nazwisko"</string> + <string name="contact_diary_add_text_input_phone_hint">"Telefon"</string> + <string name="contact_diary_add_text_input_email_hint">"E-mail"</string> <string name="contact_diary_add_person_save_button">"Zapisz"</string> <string name="contact_diary_add_location_title">"Miejsce"</string> <string name="contact_diary_add_location_text_input_hint">"Opis"</string> @@ -70,8 +72,10 @@ <string name="contact_diary_low_risk_title">"Niskie ryzyko"</string> <!-- XTXT: Body for contact diary overview screen risk information --> <string name="contact_diary_risk_body">"na podstawie kontaktów ocenionych przez aplikacjÄ™."</string> + <!-- XTXT: Body for contact diary overview screen risk information when high risk due to low risk encounters--> + <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"na podstawie wielu narażeÅ„ o niskim ryzyku."</string> <!-- XTXT: Extended Body for contact diary overview screen risk information --> - <string name="contact_diary_risk_body_extended">"na podstawie kontaktów ocenionych przez aplikacjÄ™. Niekoniecznie sÄ… one zwiÄ…zane z zarejestrowanymi przez Ciebie osobami i miejscami."</string> + <string name="contact_diary_risk_body_extended">"Niekoniecznie sÄ… one zwiÄ…zane z zarejestrowanymi przez Ciebie osobami i miejscami."</string> <!-- XTXT: content description of contact journal image on home screen --> @@ -111,6 +115,13 @@ <!-- XHED: Title for the contact diary dialog to delete delete a single person --> <string name="contact_diary_delete_person_title">"Czy na pewno chcesz usunąć tÄ™ osobÄ™?"</string> + <!-- XHED: Title for the contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_title">"Uwaga"</string> + <!-- XTXT: Description for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_description">"Możesz tu wpisać uwagi, które pomogÄ… Ci lepiej oszacować ryzyko zakażenia."</string> + <!-- XTXT: Body for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_body">"Zapisz okolicznoÅ›ci, które mogÅ‚y zwiÄ™kszyć ryzyko, np. odlegÅ‚ość od innych osób lub wykonywane czynnoÅ›ci, które mogÅ‚y mieć wpÅ‚yw na jakość powietrza (przykÅ‚ady: „siedzieliÅ›my blisko siebieâ€, „uprawialiÅ›my sportâ€, „maÅ‚o miejscaâ€, „śpiewaliÅ›myâ€).\n\nW przypadku Twojego zakażenia informacje te bÄ™dÄ… mogÅ‚y zostać wykorzystane przez organy ds. zdrowia publicznego do przeÅ›ledzenia potencjalnych Å‚aÅ„cuchów zakażenia."</string> + <!-- XTXT: location (description for screen readers) --> <string name="accessibility_location">"Miejsce %s"</string> <!-- XTXT: person (description for screen readers) --> @@ -133,4 +144,29 @@ <!-- XTXT: Edit (description for screen readers) --> <string name="accessibility_edit">"Edytuj"</string> + <!-- XACT: Add Person Button (description for screen readers) --> + <string name="accessibility_day_add_person">"Dodaj osobÄ™"</string> + <!-- XACT: Add Location Button (description for screen readers) --> + <string name="accessibility_day_add_location">"Dodaj miejsce"</string> + + <!-- XBUT: Option - person encounter - below 15 Min --> + <string name="contact_diary_person_encounter_duration_below_15_min">"Mniej niż 15 min"</string> + <!-- XBUT: Option - person encounter - above 15 Min --> + <string name="contact_diary_person_encounter_duration_above_15_min">"WiÄ™cej niż 15 min"</string> + <!-- XBUT: Option - person encounter - with mask --> + <string name="contact_diary_person_encounter_mask_with">"Z maseczkÄ…"</string> + <!-- XBUT: Option - person encounter - without mask --> + <string name="contact_diary_person_encounter_mask_without">"Bez maseczki"</string> + <!-- XBUT: Option - person encounter - outside --> + <string name="contact_diary_person_encounter_environment_outside">"Na zewnÄ…trz"</string> + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_person_encounter_environment_inside">"W pomieszczeniu"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_person_encounter_circumstances_hint">"Uwaga (np. bliska odlegÅ‚ość)"</string> + + + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_location_visit_duration_label">"Czas trwania"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_location_visit_circumstances_hint">"Uwaga (np. bardzo peÅ‚ny)"</string> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-pl/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-pl/release_info_strings.xml index 1c663f6e74a37130ee3b1b89307408beeec10b4a..f04a4e4705434e19155807dc01b3b52898a4fc11 100644 --- a/Corona-Warn-App/src/main/res/values-pl/release_info_strings.xml +++ b/Corona-Warn-App/src/main/res/values-pl/release_info_strings.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?><resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" tools:ignore="MissingTranslation"> <!-- #################################### - Release Info Screen 1.12 + Release Info Screen 1.14 ###################################### --> <!-- XHED: Title for the release info screen --> @@ -16,42 +16,34 @@ <!-- XHED: Titles for the release info screen bullet points --> <string-array name="new_release_title"> - <item>"Link do ankiety RKI"</item> - <item>"Zgoda na udostÄ™pnianie danych (opcjonalnie)"</item> - <item>"Zmiany w kafelkach ryzyka"</item> - <item>"Kontynuacja rejestrowania narażenia po udostÄ™pnieniu losowych identyfikatorów"</item> - <item>"Implementacja kart"</item> - <item>"WiÄ™cej informacji o procedurze testowania"</item> + <item>"Dodatkowe funkcje w dzienniku kontaktów"</item> + <item>"BezpoÅ›redni dostÄ™p do dziennika kontaktów"</item> + <item>"WiÄ™cej szczegółów na temat Twojego statusu ryzyka"</item> + <item>"Zrzuty ekranu dla Corona-Warn-App"</item> </string-array> <!-- XTXT: Text bodies for the release info screen bullet points --> <string-array name="new_release_body"> - <item>"JeÅ›li masz podwyższone ryzyko, możesz rozpocząć i wypeÅ‚nić ankietÄ™ przeprowadzanÄ… przez Instytut Roberta Kocha z poziomu aplikacji."</item> - <item>"Masz teraz możliwość udostÄ™pnienia swoich danych na temat użytkowania, co pomoże nam ulepszyć aplikacjÄ™."</item> - <item>"Niewielkie zmiany w tekstach na kafelkach ryzyka."</item> - <item>"Po udostÄ™pnieniu zaszyfrowanych losowych identyfikatorów możesz zdecydować, czy i kiedy chcesz ponownie wÅ‚Ä…czyć rejestrowanie narażenia."</item> - <item>"DostÄ™pna jest teraz oddzielna karta dla Twojego dziennika kontaktów. DziÄ™ki niej uzyskasz dostÄ™p do swojego dziennika i szybciej przeÅ‚Ä…czysz siÄ™ z dziennika kontaktów z powrotem na ekran główny aplikacji."</item> - <item>"Aplikacja zawiera teraz bardziej szczegółowe informacje na temat procedury testowania."</item> + <item>"Teraz możesz wprowadzić szczegółowe okolicznoÅ›ci każdego kontaktu. Możesz dokonać wyboru spoÅ›ród predefiniowanych opcji (takich jak czas trwania kontaktu, z maseczkÄ… lub bez), a także wprowadzić krótkÄ… notatkÄ™ w celu zapisania innych okolicznoÅ›ci, które mogÄ… zwiÄ™kszać ryzyko. W przypadku Twojego zakażenia informacje te bÄ™dÄ… mogÅ‚y zostać wykorzystane przez organy ds. zdrowia publicznego do przeÅ›ledzenia potencjalnych Å‚aÅ„cuchów zakażenia."</item> + <item>"Możesz teraz bezpoÅ›rednio dodać wpis do dziennika kontaktów bez koniecznoÅ›ci otwierania aplikacji. Aby to zrobić, dotknij i przytrzymaj ikonÄ™ aplikacji Corona-Warn-App przez okoÅ‚o 2 sekundy, aż pojawi siÄ™ menu, a nastÄ™pnie dotknij opcji „Dodaj wpis do dziennika na dziÅ›\"."</item> + <item>"JeÅ›li aplikacja wskaże podwyższone ryzyko, możesz sprawdzić, czy status ryzyka jest wyÅ›wietlany na podstawie jednego lub wiÄ™kszej liczby narażeÅ„ o podwyższonym ryzyku czy jednego lub wiÄ™kszej liczby o niskim ryzyku."</item> + <item>"Witryna https://www.coronawarn.app zawiera teraz wszystkie zrzuty ekranu aplikacji, dziÄ™ki czemu możesz uzyskać informacji na przykÅ‚ad o planowanych funkcjach."</item> </string-array> <!-- XTXT: Text labels that will be converted to Links --> <string-array name="new_release_linkified_labels"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app"</item> </string-array> <!-- XTXT: URL destinations for the lables in new_release_linkified_labels --> <string-array name="new_release_target_urls"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app/en/screenshots"</item> </string-array> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-pl/strings.xml b/Corona-Warn-App/src/main/res/values-pl/strings.xml index 51bc65f9f9367f7eb5203b610216feb3ef871ec3..eaa9f8c595946d738be2cbd181342b4cd91328fb 100644 --- a/Corona-Warn-App/src/main/res/values-pl/strings.xml +++ b/Corona-Warn-App/src/main/res/values-pl/strings.xml @@ -537,11 +537,11 @@ <!-- XTXT: onboarding privacy preserving analytics (ppa) - regional evaluation text --> <string name="onboarding_ppa_regional_evaluation_text">"JeÅ›li podasz również swój kraj zwiÄ…zkowy i region, bÄ™dziemy mogli przeprowadzić analizy regionalne."</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - age title --> - <string name="onboarding_ppa_age_title">"Twój wiek (opcjonalnie)"</string> + <string name="onboarding_ppa_age_title">"Twoja grupa wiekowa (opcjonalnie)"</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - consent title --> <string name="onboarding_ppa_more_info_title">"Szczegółowe informacje o ryzyku zwiÄ…zanym z przetwarzaniem i ochronÄ… danych w USA i innych krajach trzecich"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - donate button --> - <string name="onboarding_ppa_consent_donate_button">"UdostÄ™pnij dane"</string> + <string name="onboarding_ppa_consent_donate_button">"Akceptuj"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - dont donate button --> <string name="onboarding_ppa_consent_not_donate_button">"Nie udostÄ™pniaj"</string> @@ -1754,6 +1754,9 @@ <!-- XBUT: Abort button for test result positive no consent screen --> <string name="submission_test_result_positive_no_consent_button_abort">"Anuluj"</string> + <!-- XHED: Title of contact diary app shortcut --> + <string name="app_shortcut_contact_diary_title">"Dodaj wpis"</string> + <!-- XTXT: Statistics information (Accessibilty) --> <string name="statistics_info_button">"WiÄ™cej informacji"</string> <!-- XHED: Title for statistics reproduction card --> @@ -1830,7 +1833,7 @@ <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_UNSPECIFIED --> <string name="analytics_userinput_agegroup_unspecified">"Brak odpowiedzi"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_0_TO_29 --> - <string name="analytics_userinput_agegroup_0_to_29">"0-29 lat"</string> + <string name="analytics_userinput_agegroup_0_to_29">"Do 29 lat"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_30_TO_59 --> <string name="analytics_userinput_agegroup_30_to_59">"30-59 lat"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_FROM_60 --> @@ -1877,4 +1880,17 @@ <string name="analytics_userinput_district_title">"Twój okrÄ™g (powiat)"</string> <!-- XTXT: Analytics voluntary user input, district: UNSPECIFIED --> <string name="analytics_userinput_district_unspecified">"Brak odpowiedzi"</string> + + <!-- #################################### + Duration dialog + ###################################### --> + + <!-- XHED: Duration dialog title --> + <string name="duration_dialog_title">"Czas trwania"</string> + <!-- XBUT: Duration dialog cancel button --> + <string name="duration_dialog_cancel_button">"Anuluj"</string> + <!-- XBUT: Duration dialog ok button --> + <string name="duration_dialog_ok_button">"OK"</string> + <!-- NOTR --> + <string name="duration_dialog_default_value">"00:00"</string> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-ro/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-ro/contact_diary_strings.xml index 90539612e53b315e2e8674688e51d65ae34521da..322b6dc22bc51d3c16219331c408eb3c83820acd 100644 --- a/Corona-Warn-App/src/main/res/values-ro/contact_diary_strings.xml +++ b/Corona-Warn-App/src/main/res/values-ro/contact_diary_strings.xml @@ -11,7 +11,9 @@ <string name="contact_diary_person_list_no_items_title">"Nicio persoană definită deocamdată"</string> <string name="contact_diary_person_list_no_items_subtitle">"CreaÈ›i o persoană È™i adăugaÈ›i-o la jurnalul dvs. de contacte."</string> <string name="contact_diary_add_person_title">"Persoană"</string> - <string name="contact_diary_add_person_text_input_name_hint">"Nume"</string> + <string name="contact_diary_add_person_text_input_name_hint">"Prenume, nume"</string> + <string name="contact_diary_add_text_input_phone_hint">"Telefon"</string> + <string name="contact_diary_add_text_input_email_hint">"e-mail"</string> <string name="contact_diary_add_person_save_button">"Salvare"</string> <string name="contact_diary_add_location_title">"Loc"</string> <string name="contact_diary_add_location_text_input_hint">"Descriere"</string> @@ -70,8 +72,10 @@ <string name="contact_diary_low_risk_title">"Risc redus"</string> <!-- XTXT: Body for contact diary overview screen risk information --> <string name="contact_diary_risk_body">"pe baza întâlnirilor evaluate de aplicaÈ›ie."</string> + <!-- XTXT: Body for contact diary overview screen risk information when high risk due to low risk encounters--> + <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"pe baza mai multor expuneri cu risc redus."</string> <!-- XTXT: Extended Body for contact diary overview screen risk information --> - <string name="contact_diary_risk_body_extended">"pe baza întâlnirilor evaluate de aplicaÈ›ie. Acestea nu sunt legate neapărat de persoanele È™i locurile pe care le-aÈ›i înregistrat."</string> + <string name="contact_diary_risk_body_extended">"Acestea nu sunt legate neapărat de persoanele È™i locurile pe care le-aÈ›i înregistrat."</string> <!-- XTXT: content description of contact journal image on home screen --> @@ -111,6 +115,13 @@ <!-- XHED: Title for the contact diary dialog to delete delete a single person --> <string name="contact_diary_delete_person_title">"Sigur doriÈ›i să eliminaÈ›i această persoană?"</string> + <!-- XHED: Title for the contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_title">"Notă"</string> + <!-- XTXT: Description for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_description">"Acum puteÈ›i introduce aici note care vă vor ajuta să estimaÈ›i mai bine riscul dvs. de infectare."</string> + <!-- XTXT: Body for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_body">"NotaÈ›i circumstanÈ›ele care ar putea avea drept efect un risc crescut, de exemplu, cât de aproape vă aflaÈ›i față de alte persoane È™i ce făceaÈ›i (exemple: „am stat aproape unul de altulâ€, „am făcut sportâ€, „spaÈ›iu puÈ›inâ€, „am cântatâ€).\n\nDacă vă infectaÈ›i, aceste informaÈ›ii pot ajuta autoritatea de sănătate publică să urmărească posibilele lanÈ›uri de infectare."</string> + <!-- XTXT: location (description for screen readers) --> <string name="accessibility_location">"Locul %s"</string> <!-- XTXT: person (description for screen readers) --> @@ -133,4 +144,29 @@ <!-- XTXT: Edit (description for screen readers) --> <string name="accessibility_edit">"Editare"</string> + <!-- XACT: Add Person Button (description for screen readers) --> + <string name="accessibility_day_add_person">"Adăugare persoană"</string> + <!-- XACT: Add Location Button (description for screen readers) --> + <string name="accessibility_day_add_location">"Adăugare loc"</string> + + <!-- XBUT: Option - person encounter - below 15 Min --> + <string name="contact_diary_person_encounter_duration_below_15_min">"Mai puÈ›in de 15 min."</string> + <!-- XBUT: Option - person encounter - above 15 Min --> + <string name="contact_diary_person_encounter_duration_above_15_min">"Mai mult de 15 min."</string> + <!-- XBUT: Option - person encounter - with mask --> + <string name="contact_diary_person_encounter_mask_with">"Cu mască"</string> + <!-- XBUT: Option - person encounter - without mask --> + <string name="contact_diary_person_encounter_mask_without">"Fără mască"</string> + <!-- XBUT: Option - person encounter - outside --> + <string name="contact_diary_person_encounter_environment_outside">"ÃŽn exterior"</string> + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_person_encounter_environment_inside">"ÃŽn interior"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_person_encounter_circumstances_hint">"Notă (de ex., distanță mică)"</string> + + + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_location_visit_duration_label">"Durată"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_location_visit_circumstances_hint">"Notă (de ex., foarte plin)"</string> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-ro/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-ro/release_info_strings.xml index ab72df625c9f8d4eddcd4860a9a8944b1735ee0a..7015d94907b8d2201d60cd8c67aba2414efc3737 100644 --- a/Corona-Warn-App/src/main/res/values-ro/release_info_strings.xml +++ b/Corona-Warn-App/src/main/res/values-ro/release_info_strings.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?><resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" tools:ignore="MissingTranslation"> <!-- #################################### - Release Info Screen 1.12 + Release Info Screen 1.14 ###################################### --> <!-- XHED: Title for the release info screen --> @@ -16,42 +16,34 @@ <!-- XHED: Titles for the release info screen bullet points --> <string-array name="new_release_title"> - <item>"Legătură la chestionarul RKI"</item> - <item>"Consimțământ pentru partajarea datelor (opÈ›ional)"</item> - <item>"Modificări la mozaicurile riscului"</item> - <item>"Continuarea înregistrării în jurnal a expunerilor după partajarea ID-urilor dvs. aleatorii"</item> - <item>"Implementarea taburilor"</item> - <item>"Mai multe informaÈ›ii despre procedura de testare"</item> + <item>"Caracteristici suplimentare în jurnalul de contacte"</item> + <item>"Acces direct la jurnalul de contacte"</item> + <item>"Mai multe detalii despre starea riscului dvs."</item> + <item>"Capturi de ecran ale aplicaÈ›iei Corona-Warn"</item> </string-array> <!-- XTXT: Text bodies for the release info screen bullet points --> <string-array name="new_release_body"> - <item>"Dacă aveÈ›i risc crescut, puteÈ›i începe cu participarea la un chestionar desfășurat de Institutul Robert Koch în aplicaÈ›ie."</item> - <item>"Acum aveÈ›i opÈ›iunea de partajare a datelor de utilizare, ceea ce ne va ajuta să îmbunătățim aplicaÈ›ia."</item> - <item>"Modificări minore ale textelor de pe mozaicurile riscului."</item> - <item>"După ce aÈ›i partajat ID-urile dvs. aleatorii criptate, puteÈ›i decide dacă È™i când doriÈ›i să activaÈ›i din nou înregistrarea în jurnal a expunerilor."</item> - <item>"Acum există o pagină de tab separată pentru jurnalul dvs. de contacte. Acesta vă permite să accesaÈ›i jurnalul dvs. È™i să comutaÈ›i de la jurnalul de contacte înapoi la ecranul iniÈ›ial al aplicaÈ›iei mai rapid."</item> - <item>"AplicaÈ›ia conÈ›ine acum informaÈ›ii mai detaliate despre procedura de testare."</item> + <item>"Acum puteÈ›i introduce circumstanÈ›ele specifice ale fiecărei întâlniri. PuteÈ›i selecta din opÈ›iunile predefinite (precum durata întâlnirii, cu mască sau fără mască) È™i puteÈ›i, de asemenea, introduce o notă scurtă pentru a înregistra alte circumstanÈ›e care pot duce la un risc crescut. Dacă vă infectaÈ›i, aceste informaÈ›ii pot ajuta autoritatea de sănătate publică să urmărească posibilele lanÈ›uri de infectare."</item> + <item>"Acum puteÈ›i adăuga o intrare direct la jurnalul dvs. de contacte, fără a mai fi nevoie să deschideÈ›i mai întâi aplicaÈ›ia. Pentru aceasta, atingeÈ›i È™i menÈ›ineÈ›i apăsată pictograma pentru aplicaÈ›ia Corona-Warn timp de aproximativ 2 secunde, până apare un meniu, apoi apăsaÈ›i pe „Adăugare intrare în jurnal pentru astăziâ€."</item> + <item>"Dacă aplicaÈ›ia indică un risc crescut pentru dvs., acum puteÈ›i vedea dacă starea riscului este afiÈ™ată pe baza uneia sau mai multor expuneri cu un risc crescut sau pe baza mai multor expuneri cu risc redus."</item> + <item>"Site-ul web https://www.coronawarn.app conÈ›ine acum toate capturile de ecran ale aplicaÈ›iei, pentru a găsi, de exemplu, caracteristicile planificate."</item> </string-array> <!-- XTXT: Text labels that will be converted to Links --> <string-array name="new_release_linkified_labels"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app"</item> </string-array> <!-- XTXT: URL destinations for the lables in new_release_linkified_labels --> <string-array name="new_release_target_urls"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app/en/screenshots"</item> </string-array> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-ro/strings.xml b/Corona-Warn-App/src/main/res/values-ro/strings.xml index e29be8d41f483ea294dcf04f97dcbd3e28617c81..9e673a7e8cc46fbe9cfa00d71a655f6d0819e36b 100644 --- a/Corona-Warn-App/src/main/res/values-ro/strings.xml +++ b/Corona-Warn-App/src/main/res/values-ro/strings.xml @@ -537,11 +537,11 @@ <!-- XTXT: onboarding privacy preserving analytics (ppa) - regional evaluation text --> <string name="onboarding_ppa_regional_evaluation_text">"Dacă specificaÈ›i, de asemenea, statul federal È™i regiunea dvs., putem efectua analize regionale."</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - age title --> - <string name="onboarding_ppa_age_title">"Vârsta dvs. (opÈ›ional)"</string> + <string name="onboarding_ppa_age_title">"Grupul dvs. de vârstă (opÈ›ional)"</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - consent title --> <string name="onboarding_ppa_more_info_title">"InformaÈ›ii detaliate despre prelucrarea acestor date È™i riscurile privind prelucrarea datelor din SUA È™i din alte țări terÈ›e"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - donate button --> - <string name="onboarding_ppa_consent_donate_button">"Partajare date"</string> + <string name="onboarding_ppa_consent_donate_button">"Accept"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - dont donate button --> <string name="onboarding_ppa_consent_not_donate_button">"Fără partajare"</string> @@ -1754,6 +1754,9 @@ <!-- XBUT: Abort button for test result positive no consent screen --> <string name="submission_test_result_positive_no_consent_button_abort">"Anulare"</string> + <!-- XHED: Title of contact diary app shortcut --> + <string name="app_shortcut_contact_diary_title">"Adăugare intrare"</string> + <!-- XTXT: Statistics information (Accessibilty) --> <string name="statistics_info_button">"InformaÈ›ii suplimentare"</string> <!-- XHED: Title for statistics reproduction card --> @@ -1830,7 +1833,7 @@ <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_UNSPECIFIED --> <string name="analytics_userinput_agegroup_unspecified">"Nu răspund"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_0_TO_29 --> - <string name="analytics_userinput_agegroup_0_to_29">"0-29 de ani"</string> + <string name="analytics_userinput_agegroup_0_to_29">"Sub 29 de ani"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_30_TO_59 --> <string name="analytics_userinput_agegroup_30_to_59">"30-59 de ani"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_FROM_60 --> @@ -1877,4 +1880,17 @@ <string name="analytics_userinput_district_title">"Districtul (judeÈ›ul) dvs."</string> <!-- XTXT: Analytics voluntary user input, district: UNSPECIFIED --> <string name="analytics_userinput_district_unspecified">"Nu răspund"</string> + + <!-- #################################### + Duration dialog + ###################################### --> + + <!-- XHED: Duration dialog title --> + <string name="duration_dialog_title">"Durată"</string> + <!-- XBUT: Duration dialog cancel button --> + <string name="duration_dialog_cancel_button">"Anulare"</string> + <!-- XBUT: Duration dialog ok button --> + <string name="duration_dialog_ok_button">"OK"</string> + <!-- NOTR --> + <string name="duration_dialog_default_value">"00:00"</string> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-tr/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values-tr/contact_diary_strings.xml index c8b833111fc2d158b4b355975f9dde90202d6968..eb4308ad5f45b4efc85cf53be6b9132b5bd60fb5 100644 --- a/Corona-Warn-App/src/main/res/values-tr/contact_diary_strings.xml +++ b/Corona-Warn-App/src/main/res/values-tr/contact_diary_strings.xml @@ -11,7 +11,9 @@ <string name="contact_diary_person_list_no_items_title">"Henüz hiçbir kiÅŸi tanımlanmadı"</string> <string name="contact_diary_person_list_no_items_subtitle">"Bir kiÅŸi oluÅŸturun ve temas güncenize ekleyin."</string> <string name="contact_diary_add_person_title">"KiÅŸi"</string> - <string name="contact_diary_add_person_text_input_name_hint">"Ad"</string> + <string name="contact_diary_add_person_text_input_name_hint">"Ad, soyadı"</string> + <string name="contact_diary_add_text_input_phone_hint">"Telefon"</string> + <string name="contact_diary_add_text_input_email_hint">"e-posta"</string> <string name="contact_diary_add_person_save_button">"Kaydet"</string> <string name="contact_diary_add_location_title">"Yer"</string> <string name="contact_diary_add_location_text_input_hint">"Tanım"</string> @@ -70,8 +72,10 @@ <string name="contact_diary_low_risk_title">"Düşük Risk"</string> <!-- XTXT: Body for contact diary overview screen risk information --> <string name="contact_diary_risk_body">"uygulama tarafından deÄŸerlendirilen karşılaÅŸmalar temel alınır."</string> + <!-- XTXT: Body for contact diary overview screen risk information when high risk due to low risk encounters--> + <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"(düşük riskli birden fazla maruz kalmaya göre)."</string> <!-- XTXT: Extended Body for contact diary overview screen risk information --> - <string name="contact_diary_risk_body_extended">"uygulama tarafından deÄŸerlendirilen karşılaÅŸmalar temel alınır. KaydettiÄŸiniz kiÅŸilerle ve yerlerle ilgili olmaları ÅŸart deÄŸildir."</string> + <string name="contact_diary_risk_body_extended">"KaydettiÄŸiniz kiÅŸilerle ve yerlerle ilgili olmaları ÅŸart deÄŸildir."</string> <!-- XTXT: content description of contact journal image on home screen --> @@ -111,6 +115,13 @@ <!-- XHED: Title for the contact diary dialog to delete delete a single person --> <string name="contact_diary_delete_person_title">"Bu kiÅŸiyi gerçekten kaldırmak istiyor musunuz?"</string> + <!-- XHED: Title for the contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_title">"Not"</string> + <!-- XTXT: Description for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_description">"Enfeksiyon riskinizi daha iyi tahmin etmenize yardımcı olacak notları bu bölüme girebilirsiniz."</string> + <!-- XTXT: Body for contact diary comment info screen --> + <string name="contact_diary_comment_info_screen_body">"BaÅŸka insanlara ne kadar yakın olduÄŸunuz ya da yaptığınız ÅŸeyler gibi hava kalitesini etkileyebilecek ve riskin artmasına neden olabilecek koÅŸulları yazın (örnekler: “yakın bir ÅŸekilde birlikte oturdukâ€, “spor yaptıkâ€, “az alan vardıâ€, “şarkı söyledikâ€).\n\nEnfekte olmanız halinde bu bilgiler, kamu saÄŸlığı yetkilisinin potansiyel enfeksiyon zincirlerini takip etmesine de yardımcı olabilir."</string> + <!-- XTXT: location (description for screen readers) --> <string name="accessibility_location">"Yer %s"</string> <!-- XTXT: person (description for screen readers) --> @@ -133,4 +144,29 @@ <!-- XTXT: Edit (description for screen readers) --> <string name="accessibility_edit">"Düzenle"</string> + <!-- XACT: Add Person Button (description for screen readers) --> + <string name="accessibility_day_add_person">"KiÅŸi Ekle"</string> + <!-- XACT: Add Location Button (description for screen readers) --> + <string name="accessibility_day_add_location">"Yer Ekle"</string> + + <!-- XBUT: Option - person encounter - below 15 Min --> + <string name="contact_diary_person_encounter_duration_below_15_min">"15 dakikadan az"</string> + <!-- XBUT: Option - person encounter - above 15 Min --> + <string name="contact_diary_person_encounter_duration_above_15_min">"15 dakikadan fazla"</string> + <!-- XBUT: Option - person encounter - with mask --> + <string name="contact_diary_person_encounter_mask_with">"Maskeli"</string> + <!-- XBUT: Option - person encounter - without mask --> + <string name="contact_diary_person_encounter_mask_without">"Maskesiz"</string> + <!-- XBUT: Option - person encounter - outside --> + <string name="contact_diary_person_encounter_environment_outside">"Açık hava"</string> + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_person_encounter_environment_inside">"Kapalı ortam"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_person_encounter_circumstances_hint">"Not (ör. yakın mesafe)"</string> + + + <!-- XBUT: Option - person encounter - inside--> + <string name="contact_diary_location_visit_duration_label">"Süre"</string> + <!-- XTXT: Option - person encounter - circumstances hint--> + <string name="contact_diary_location_visit_circumstances_hint">"Not (ör. çok dolu)"</string> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-tr/release_info_strings.xml b/Corona-Warn-App/src/main/res/values-tr/release_info_strings.xml index 11084f58b7e4126e7ab7ffb8abef6168d3ffd899..c29b757bb969656b1dc0b0e1663ac93110bd1386 100644 --- a/Corona-Warn-App/src/main/res/values-tr/release_info_strings.xml +++ b/Corona-Warn-App/src/main/res/values-tr/release_info_strings.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?><resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" tools:ignore="MissingTranslation"> <!-- #################################### - Release Info Screen 1.12 + Release Info Screen 1.14 ###################################### --> <!-- XHED: Title for the release info screen --> @@ -16,42 +16,34 @@ <!-- XHED: Titles for the release info screen bullet points --> <string-array name="new_release_title"> - <item>"RKI anketi baÄŸlantısı"</item> - <item>"Veri PaylaÅŸma Ä°zni (isteÄŸe baÄŸlı)"</item> - <item>"Risk Kutucuklarındaki DeÄŸiÅŸiklikler"</item> - <item>"Rastgele Kimliklerinizi PaylaÅŸtıktan Sonra Maruz Kalma Günlüğüne Devam Etme"</item> - <item>"Sekmelerin Uygulanması"</item> - <item>"Test Prosedürü Hakkında Daha Fazla Bilgi"</item> + <item>"Temas Güncesindeki Ek Özellikler"</item> + <item>"Temas Güncesine DoÄŸrudan EriÅŸim"</item> + <item>"Risk Durumunuz Hakkında Daha Ayrıntılı Bilgi"</item> + <item>"Corona-Warn-App Ekran Görüntüleri"</item> </string-array> <!-- XTXT: Text bodies for the release info screen bullet points --> <string-array name="new_release_body"> - <item>"Yüksek risk altındaysanız Robert Koch Institute tarafından sunulan bir anketi uygulamadan yanıtlayabilirsiniz."</item> - <item>"Kullanım verilerinizi paylaÅŸarak uygulamayı iyileÅŸtirmemize yardımcı olma seçeneÄŸine sahipsiniz."</item> - <item>"Risk kutucuklarındaki metinler üzerinde ufak deÄŸiÅŸiklikler."</item> - <item>"ÅžifrelenmiÅŸ rastgele kimliklerinizi paylaÅŸtıktan sonra maruz kalma günlüğünü yeniden açmak isteyip istemediÄŸinize ve ne zaman yeniden açacağınıza karar verebilirsiniz."</item> - <item>"Temas günceniz için ayrı bir sekme sayfası eklenmiÅŸtir. Bu sayede, daha hızlı bir ÅŸekilde güncenize eriÅŸebilir ve temas güncenizden uygulamanızın ana ekranına geri dönebilirsiniz."</item> - <item>"Uygulama artık test prosedürü hakkında daha ayrıntılı bilgiler içermektedir."</item> + <item>"Artık her bir karşılaÅŸma için belirli koÅŸullar girebilirsiniz. Önceden tanımlanmış seçenekler (örneÄŸin karşılaÅŸmanın süresi, maske takılı olup olmadığı) arasından seçim yapabilir ve yüksek riske neden olabilecek diÄŸer koÅŸulları kaydetmek için kısa bir not da ekleyebilirsiniz. Enfekte olmanız halinde bu bilgiler kamu saÄŸlığı yetkilisinin potansiyel enfeksiyon zincirlerini takip etmesine yardımcı olabilir."</item> + <item>"Artık önce uygulamayı açmanız gerekmeden doÄŸrudan temas güncenize giriÅŸ ekleyebilirsiniz. Bunun için, bir menü görüntülenene dek yaklaşık 2 saniye süreyle Corona-Warn-App simgesine basılı tutun ve ardından “Bugün için Günce GiriÅŸi Ekle†seçeneÄŸine dokunun."</item> + <item>"Uygulama, yüksek risk altında olduÄŸunuzu belirtiyorsa artık risk durumunun, yüksek riskli bir veya daha fazla maruz kalmaya göre mi yoksa düşük riskli bir veya daha fazla maruz kalmaya göre mi görüntülendiÄŸini görebilirsiniz."</item> + <item>"https://www.coronawarn.app adresindeki web sitesinde uygulamanın tüm ekran görüntüleri sunulmaktadır. Bu sayede, planlanan özellikler gibi çeÅŸitli bilgileri edinebilirsiniz."</item> </string-array> <!-- XTXT: Text labels that will be converted to Links --> <string-array name="new_release_linkified_labels"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app"</item> </string-array> <!-- XTXT: URL destinations for the lables in new_release_linkified_labels --> <string-array name="new_release_target_urls"> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> - <item></item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app/en/screenshots"</item> </string-array> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values-tr/strings.xml b/Corona-Warn-App/src/main/res/values-tr/strings.xml index dbb190211959b7022cf7bb1981658c5c2c0bca48..771a2ed84e25fd8f224652461450881497960131 100644 --- a/Corona-Warn-App/src/main/res/values-tr/strings.xml +++ b/Corona-Warn-App/src/main/res/values-tr/strings.xml @@ -323,8 +323,8 @@ <!-- XMSG: risk details - link to faq, something like a bullet point --> <string name="risk_details_increased_risk_faq_link_text">"Test yaptırırsanız SSS bölümünde test prosedürü hakkında ek bilgi bulabilirsiniz."</string> - <!-- XTXT: Explanation screen increased risk level link label --> - <string name="risk_details_increased_risk_faq_link_label">"SSS: Test Prosedürü"</string> + <!-- XTXT: Explanation screen increased risk level link label - HAS TO MATCH the link text above --> + <string name="risk_details_increased_risk_faq_link_label">"SSS"</string> <!-- XTXT: Explains user about increased risk level: URL, has to be "translated" into english (relevant for all languages except german) - https://www.coronawarn.app/en/faq/#further_details --> <string name="risk_details_increased_risk_faq_url">"https://www.coronawarn.app/en/faq/#red_card_how_to_test"</string> @@ -537,11 +537,11 @@ <!-- XTXT: onboarding privacy preserving analytics (ppa) - regional evaluation text --> <string name="onboarding_ppa_regional_evaluation_text">"Federal eyalet ve bölge bilgilerinizi de paylaşırsanız bölgesel analizler yapabiliriz."</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - age title --> - <string name="onboarding_ppa_age_title">"Yaşınız (isteÄŸe baÄŸlı)"</string> + <string name="onboarding_ppa_age_title">"YaÅŸ grubunuz (isteÄŸe baÄŸlı)"</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - consent title --> <string name="onboarding_ppa_more_info_title">"ABD’de ve DiÄŸer Üçüncü Ãœlkelerde Veri Ä°ÅŸleme ve Veri Koruma Riskleri Hakkında Ayrıntılı Bilgiler"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - donate button --> - <string name="onboarding_ppa_consent_donate_button">"Verileri PaylaÅŸ"</string> + <string name="onboarding_ppa_consent_donate_button">"Kabul Et"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - dont donate button --> <string name="onboarding_ppa_consent_not_donate_button">"PaylaÅŸma"</string> @@ -1754,6 +1754,9 @@ <!-- XBUT: Abort button for test result positive no consent screen --> <string name="submission_test_result_positive_no_consent_button_abort">"Ä°ptal"</string> + <!-- XHED: Title of contact diary app shortcut --> + <string name="app_shortcut_contact_diary_title">"GiriÅŸ Ekle"</string> + <!-- XTXT: Statistics information (Accessibilty) --> <string name="statistics_info_button">"Daha fazla bilgi"</string> <!-- XHED: Title for statistics reproduction card --> @@ -1830,7 +1833,7 @@ <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_UNSPECIFIED --> <string name="analytics_userinput_agegroup_unspecified">"Bilgi yok"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_0_TO_29 --> - <string name="analytics_userinput_agegroup_0_to_29">"0-29 yaÅŸ"</string> + <string name="analytics_userinput_agegroup_0_to_29">"29 yaÅŸa kadar"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_30_TO_59 --> <string name="analytics_userinput_agegroup_30_to_59">"30-59 yaÅŸ"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_FROM_60 --> @@ -1877,4 +1880,17 @@ <string name="analytics_userinput_district_title">"Bölgeniz (Ä°lçe)"</string> <!-- XTXT: Analytics voluntary user input, district: UNSPECIFIED --> <string name="analytics_userinput_district_unspecified">"Bilgi yok"</string> + + <!-- #################################### + Duration dialog + ###################################### --> + + <!-- XHED: Duration dialog title --> + <string name="duration_dialog_title">"Süre"</string> + <!-- XBUT: Duration dialog cancel button --> + <string name="duration_dialog_cancel_button">"Ä°ptal Et"</string> + <!-- XBUT: Duration dialog ok button --> + <string name="duration_dialog_ok_button">"Tamam"</string> + <!-- NOTR --> + <string name="duration_dialog_default_value">"00:00"</string> </resources> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml index b7276c4c7e70bbcdae399d81b0bc44473134dfad..5a610c20973298353c67e836344802a78111b1b0 100644 --- a/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml +++ b/Corona-Warn-App/src/main/res/values/contact_diary_strings.xml @@ -12,9 +12,9 @@ <string name="contact_diary_person_list_no_items_title">"No people defined yet"</string> <string name="contact_diary_person_list_no_items_subtitle">"Create a person and add them to your contact journal."</string> <string name="contact_diary_add_person_title">"Person"</string> - <string name="contact_diary_add_person_text_input_name_hint">"Name"</string> - <string name="contact_diary_add_text_input_phone_hint" /> - <string name="contact_diary_add_text_input_email_hint"/> + <string name="contact_diary_add_person_text_input_name_hint">"First name, last name"</string> + <string name="contact_diary_add_text_input_phone_hint">"Phone"</string> + <string name="contact_diary_add_text_input_email_hint">"e-mail"</string> <string name="contact_diary_add_person_save_button">"Save"</string> <string name="contact_diary_add_location_title">"Place"</string> <string name="contact_diary_add_location_text_input_hint">"Description"</string> @@ -74,7 +74,7 @@ <!-- XTXT: Body for contact diary overview screen risk information --> <string name="contact_diary_risk_body">"based on the encounters evaluated by the app."</string> <!-- XTXT: Body for contact diary overview screen risk information when high risk due to low risk encounters--> - <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"based on several encounters with low risk."</string> + <string name="contact_diary_risk_body_high_risk_due_to_low_risk_encounters">"based on multiple exposures with low risk."</string> <!-- XTXT: Extended Body for contact diary overview screen risk information --> <string name="contact_diary_risk_body_extended">"They are not necessarily related to the people and places you have recorded."</string> @@ -146,11 +146,11 @@ <string name="contact_diary_overview_location_duration_suffix" translatable="false">"Std."</string> <!-- XHED: Title for the contact diary comment info screen --> - <string name="contact_diary_comment_info_screen_title">"Notiz"</string> + <string name="contact_diary_comment_info_screen_title">"Note"</string> <!-- XTXT: Description for contact diary comment info screen --> - <string name="contact_diary_comment_info_screen_description">"Hier können Sie Notizen machen, die Ihnen helfen, das Risiko einer Infektion besser einzuschätzen."</string> + <string name="contact_diary_comment_info_screen_description">"You can enter notes here that will help you to better estimate your risk of infection."</string> <!-- XTXT: Body for contact diary comment info screen --> - <string name="contact_diary_comment_info_screen_body">"Notieren Sie Umstände, die zu einem erhöhten Risiko führen könnten, z.B. räumliche Nähe zu anderen Personen oder die Ausübung einer Tätigkeit, die sich auf die Luftqualität auswirkt (Beispiele: „saßen nah beieinander“, „es wurde Sport getrieben“, „wir haben gesungen“).\n\nSollten Sie sich tatsächlich anstecken, können diese Notizen auch dem Gesundheitsamt bei der Nachverfolgung möglicher Infektionsketten helfen."</string> + <string name="contact_diary_comment_info_screen_body">"Write down the circumstances that could result in an increased risk, for example, how close you were to other people or things you did that could affect the air quality (examples: “sat close togetherâ€, “played sportsâ€, “little spaceâ€, “we sangâ€).\n\nIf you become infected, this information can also help the public health authority trace potential chains of infection."</string> <!-- XTXT: location (description for screen readers) --> <string name="accessibility_location">"Place %s"</string> @@ -175,28 +175,28 @@ <string name="accessibility_edit">"Edit"</string> <!-- XACT: Add Person Button (description for screen readers) --> - <string name="accessibility_day_add_person">""</string> + <string name="accessibility_day_add_person">"Add Person"</string> <!-- XACT: Add Location Button (description for screen readers) --> - <string name="accessibility_day_add_location">""</string> + <string name="accessibility_day_add_location">"Add Place"</string> <!-- XBUT: Option - person encounter - below 15 Min --> - <string name="contact_diary_person_encounter_duration_below_15_min">unter 15 Min</string> + <string name="contact_diary_person_encounter_duration_below_15_min">"Less than 15 min"</string> <!-- XBUT: Option - person encounter - above 15 Min --> - <string name="contact_diary_person_encounter_duration_above_15_min">über 15 Min</string> + <string name="contact_diary_person_encounter_duration_above_15_min">"More than 15 min"</string> <!-- XBUT: Option - person encounter - with mask --> - <string name="contact_diary_person_encounter_mask_with">mit Maske</string> + <string name="contact_diary_person_encounter_mask_with">"With mask"</string> <!-- XBUT: Option - person encounter - without mask --> - <string name="contact_diary_person_encounter_mask_without">ohne Maske</string> + <string name="contact_diary_person_encounter_mask_without">"Without mask"</string> <!-- XBUT: Option - person encounter - outside --> - <string name="contact_diary_person_encounter_environment_outside">im Freien</string> + <string name="contact_diary_person_encounter_environment_outside">"Outdoors"</string> <!-- XBUT: Option - person encounter - inside--> - <string name="contact_diary_person_encounter_environment_inside">drinnen</string> + <string name="contact_diary_person_encounter_environment_inside">"Indoors"</string> <!-- XTXT: Option - person encounter - circumstances hint--> - <string name="contact_diary_person_encounter_circumstances_hint">Notiz (z.B. geringer Abstand)</string> + <string name="contact_diary_person_encounter_circumstances_hint">"Note (e.g. close distance)"</string> <!-- XBUT: Option - person encounter - inside--> - <string name="contact_diary_location_visit_duration_label">Dauer</string> + <string name="contact_diary_location_visit_duration_label">"Duration"</string> <!-- XTXT: Option - person encounter - circumstances hint--> - <string name="contact_diary_location_visit_circumstances_hint">Notiz (z.B. sehr voll)</string> + <string name="contact_diary_location_visit_circumstances_hint">"Note (e.g. very full)"</string> </resources> diff --git a/Corona-Warn-App/src/main/res/values/release_info_strings.xml b/Corona-Warn-App/src/main/res/values/release_info_strings.xml index 16d097b510a3ae8c0cf7f16b6c28ef2fc5cbc221..b8c27c66cf82e2b01ffe02bc9f8c4ac4ee88356d 100644 --- a/Corona-Warn-App/src/main/res/values/release_info_strings.xml +++ b/Corona-Warn-App/src/main/res/values/release_info_strings.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" tools:ignore="MissingTranslation"> <!-- #################################### - Release Info Screen 1.12 + Release Info Screen 1.14 ###################################### --> <!-- XHED: Title for the release info screen --> @@ -9,7 +9,7 @@ <!-- XHED: Version title for the release info screen --> <string name="release_info_version_title">Release %1$s</string> <!-- XTXT: Description for the release info screen --> - <string name="release_info_version_body" /> + <string name="release_info_version_body">"Along with bug fixes, this update also includes new and enhanced features."</string> <!-- XBUT: Continue button for the release info screen --> <string name="release_info_continue_button">"Next"</string> <!-- XTXT: New release info footer --> @@ -17,34 +17,34 @@ <!-- XHED: Titles for the release info screen bullet points --> <string-array name="new_release_title"> - <item>EN: Zusatzfunktionen im Kontakt-Tagebuch</item> - <item>Direkter Zugriff auf Kontakt-Tagebuch</item> - <item>Mehr Details zum Risikostatus</item> - <item>Screenshots zur Corona-Warn-App</item> + <item>"Additional Features in the Contact Journal"</item> + <item>"Direct Access to Contact Journal"</item> + <item>"More Details about Your Risk Status"</item> + <item>"Screenshots for the Corona-Warn-App"</item> </string-array> <!-- XTXT: Text bodies for the release info screen bullet points --> <string-array name="new_release_body"> - <item>EN: Sie können zu jedem Eintrag angeben, unter welchen Umständen die Begegnung stattfand. Sie können aus vorgegebenen Optionen auswählen (z.B. Dauer der Begegnung, mit oder ohne Maske) sowie zusätzlich in einer kurzen Notiz weitere Umstände erfassen, die zu einem erhöhten Risiko führen könnten. Sollten Sie sich tatsächlich anstecken, können diese Angaben dem Gesundheitsamt bei der Nachverfolgung möglicher Infektionsketten helfen.</item> - <item>Sie können nun direkt einen Eintrag im Kontakt-Tagebuch hinzufügen, ohne erst die App öffnen zu müssen. Tippen Sie dazu etwa 2 Sekunden lang auf das Icon der Corona-Warn-App bis ein Menü erscheint und tippen Sie dann auf "Tagebuch-Eintrag für heute hinzufügen“.</item> - <item>Wenn Ihnen in der App ein erhöhtes Risiko angezeigt wird, können Sie nun sehen, ob der Risikostatus aufgrund einer bzw. mehrerer Begegnungen mit erhöhtem Risiko angezeigt wird, oder aufgrund von mehreren Begegnungen mit niedrigem Risiko.</item> - <item>Auf https://www.coronawarn.app stehen nun alle Screenshots der App zu Verfügung. So können Sie sich nun auch über geplante Funktionen der App informieren.</item> + <item>"You can now enter the specific circumstances of each encounter. You can select from the predefined options (such as duration of the encounter, with or without mask) and also enter a brief note to record other circumstances that might result in an increased risk. If you become infected, this information can help the public health authority trace potential chains of infection."</item> + <item>"You can now add an entry to your contact journal directly, without having to open the app first. To do so, tap and hold the icon for the Corona-Warn-App for approximately 2 seconds, until a menu appears, and then tap “Add Journal Entry for Todayâ€."</item> + <item>"If the app indicates that you have an increased risk, you can now see whether the risk status is displayed based on one or more exposures with an increased risk or one or more exposures with a low risk."</item> + <item>"The website https://www.coronawarn.app now contains all the screenshots for the app, so you can find out about planned features, for example."</item> </string-array> <!-- XTXT: Text labels that will be converted to Links --> <string-array name="new_release_linkified_labels"> - <item></item> - <item></item> - <item></item> - <item>https://www.coronawarn.app</item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app"</item> </string-array> <!-- XTXT: URL destinations for the lables in new_release_linkified_labels --> <string-array name="new_release_target_urls"> - <item></item> - <item></item> - <item></item> - <item>https://www.coronawarn.app/en/screenshots</item> + <item/> + <item/> + <item/> + <item>"https://www.coronawarn.app/en/screenshots"</item> </string-array> </resources> diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index de77c976edb37749ce346df5532e89ab9d307def..0ad1b02f4a76ef9b9514663baddd37633f5dad15 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -549,11 +549,11 @@ <!-- XTXT: onboarding privacy preserving analytics (ppa) - regional evaluation text --> <string name="onboarding_ppa_regional_evaluation_text">"If you also specify your federal state and region, we can conduct regional analyses."</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - age title --> - <string name="onboarding_ppa_age_title">"Your age (optional)"</string> + <string name="onboarding_ppa_age_title">"Your age group (optional)"</string> <!-- XTXT: onboarding privacy preserving analytics (ppa) - consent title --> <string name="onboarding_ppa_more_info_title">"Detailed Information about This Data Processing and Data Protection Risks in the U.S. and Other Third Countries"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - donate button --> - <string name="onboarding_ppa_consent_donate_button">"Share Data"</string> + <string name="onboarding_ppa_consent_donate_button">"Accept"</string> <!-- XBUT: onboarding privacy preserving analytics (ppa) - dont donate button --> <string name="onboarding_ppa_consent_not_donate_button">"Do Not Share"</string> @@ -1771,7 +1771,7 @@ <string name="submission_test_result_positive_no_consent_button_abort">"Cancel"</string> <!-- XHED: Title of contact diary app shortcut --> - <string name="app_shortcut_contact_diary_title">"Eintrag hinzufügen"</string> + <string name="app_shortcut_contact_diary_title">"Add Entry"</string> <!-- XTXT: Statistics information (Accessibilty) --> <string name="statistics_info_button">"Further information"</string> @@ -1849,7 +1849,7 @@ <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_UNSPECIFIED --> <string name="analytics_userinput_agegroup_unspecified">"No answer"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_0_TO_29 --> - <string name="analytics_userinput_agegroup_0_to_29">"0-29 years old"</string> + <string name="analytics_userinput_agegroup_0_to_29">"Up to 29"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_30_TO_59 --> <string name="analytics_userinput_agegroup_30_to_59">"30-59 years old"</string> <!-- XTXT: Analytics voluntary user input, age group: AGE_GROUP_FROM_60 --> @@ -1902,11 +1902,11 @@ ###################################### --> <!-- XHED: Duration dialog title --> - <string name="duration_dialog_title">Dauer</string> + <string name="duration_dialog_title">"Duration"</string> <!-- XBUT: Duration dialog cancel button --> - <string name="duration_dialog_cancel_button">Cancel</string> + <string name="duration_dialog_cancel_button">"Cancel"</string> <!-- XBUT: Duration dialog ok button --> - <string name="duration_dialog_ok_button">OK</string> + <string name="duration_dialog_ok_button">"OK"</string> <!-- NOTR --> - <string name="duration_dialog_default_value">00:00</string> + <string name="duration_dialog_default_value">"00:00"</string> </resources> diff --git a/Corona-Warn-App/src/main/res/values/styles.xml b/Corona-Warn-App/src/main/res/values/styles.xml index 246bcd8c0ff714441dc65d8b46af7f69909a1f5e..d1fc93e477682fd469efb0b74369d1b656953e38 100644 --- a/Corona-Warn-App/src/main/res/values/styles.xml +++ b/Corona-Warn-App/src/main/res/values/styles.xml @@ -477,8 +477,6 @@ <item name="boxCornerRadiusTopStart">@dimen/spacing_mega_tiny</item> <item name="boxStrokeWidth">0dp</item> <item name="boxStrokeWidthFocused">0dp</item> - <item name="counterTextAppearance">@color/colorTransparent</item> - <item name="android:maxLength">5</item> </style> <style name="DefaultNumberPickerTheme" parent="AppTheme"> diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/durationpicker/DurationExtensionKtTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/durationpicker/DurationExtensionKtTest.kt index 4bfa961ca21dcfff47bb170e56e8c2441ee99680..84d647ea27cf50a0499fb23ca5d15a87d889d365 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/durationpicker/DurationExtensionKtTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/durationpicker/DurationExtensionKtTest.kt @@ -54,4 +54,4 @@ internal class DurationExtensionKtTest { val suffix: String?, val expectedReadableDuration: String ) -} \ No newline at end of file +} diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt index a751d47446c7bd0fc5101c48c542e06ec0a65e6f..a9cab888e37c5c3870194c9da386a7dcbbcf3da4 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/contactdiary/ui/overview/ContactDiaryOverviewViewModelTest.kt @@ -8,7 +8,8 @@ import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryPerson import de.rki.coronawarnapp.contactdiary.model.DefaultContactDiaryPersonEncounter import de.rki.coronawarnapp.contactdiary.storage.repo.ContactDiaryRepository import de.rki.coronawarnapp.contactdiary.ui.exporter.ContactDiaryExporter -import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.ListItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.day.DayOverviewItem +import de.rki.coronawarnapp.contactdiary.ui.overview.adapter.subheader.OverviewSubHeaderItem import de.rki.coronawarnapp.contactdiary.util.ContactDiaryData import de.rki.coronawarnapp.contactdiary.util.mockStringsForContactDiaryExporterTests import de.rki.coronawarnapp.risk.result.AggregatedRiskPerDateResult @@ -109,9 +110,14 @@ open class ContactDiaryOverviewViewModelTest { verify(exactly = 1) { taskController.submit(any()) } } + @Test + fun `first item is subheader`() { + createInstance().listItems.getOrAwaitValue().first() is OverviewSubHeaderItem + } + @Test fun `overview list lists all days as expected`() { - with(createInstance().listItems.getOrAwaitValue()) { + with(createInstance().listItems.getOrAwaitValue().filterIsInstance<DayOverviewItem>()) { size shouldBe ContactDiaryOverviewViewModel.DAY_COUNT var days = 0 @@ -129,7 +135,11 @@ open class ContactDiaryOverviewViewModelTest { @Test fun `navigate to day fragment with correct day`() { - val listItem = ListItem(date) + val listItem = DayOverviewItem( + date = date, + data = emptyList(), + risk = null + ) {} with(createInstance()) { onItemPress(listItem) @@ -148,7 +158,11 @@ open class ContactDiaryOverviewViewModelTest { every { contactDiaryRepository.locationVisits } returns flowOf(listOf(locationVisit)) every { riskLevelStorage.aggregatedRiskPerDateResults } returns flowOf(listOf(aggregatedRiskPerDateResultLowRisk)) - with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) { + val item = createInstance().listItems.getOrAwaitValue().first { + it is DayOverviewItem && it.date == date + } as DayOverviewItem + + with(item) { data.validate( hasPerson = true, hasLocation = true @@ -166,7 +180,11 @@ open class ContactDiaryOverviewViewModelTest { fun `low risk without person or location`() { every { riskLevelStorage.aggregatedRiskPerDateResults } returns flowOf(listOf(aggregatedRiskPerDateResultLowRisk)) - with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) { + val item = createInstance().listItems.getOrAwaitValue().first { + it is DayOverviewItem && it.date == date + } as DayOverviewItem + + with(item) { data.validate( hasPerson = false, hasLocation = false @@ -190,7 +208,11 @@ open class ContactDiaryOverviewViewModelTest { ) ) - with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) { + val item = createInstance().listItems.getOrAwaitValue().first { + it is DayOverviewItem && it.date == date + } as DayOverviewItem + + with(item) { data.validate( hasPerson = true, hasLocation = true @@ -212,7 +234,11 @@ open class ContactDiaryOverviewViewModelTest { ) ) - with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) { + val item = createInstance().listItems.getOrAwaitValue().first { + it is DayOverviewItem && it.date == date + } as DayOverviewItem + + with(item) { data.validate( hasPerson = false, hasLocation = false @@ -236,7 +262,11 @@ open class ContactDiaryOverviewViewModelTest { ) ) - with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) { + val item = createInstance().listItems.getOrAwaitValue().first { + it is DayOverviewItem && it.date == date + } as DayOverviewItem + + with(item) { data.validate( hasPerson = true, hasLocation = true @@ -258,7 +288,11 @@ open class ContactDiaryOverviewViewModelTest { ) ) - with(createInstance().listItems.getOrAwaitValue().first { it.date == date }) { + val item = createInstance().listItems.getOrAwaitValue().first { + it is DayOverviewItem && it.date == date + } as DayOverviewItem + + with(item) { data.validate( hasPerson = false, hasLocation = false @@ -298,7 +332,7 @@ open class ContactDiaryOverviewViewModelTest { } } - private fun List<ListItem.Data>.validate(hasPerson: Boolean, hasLocation: Boolean) { + private fun List<DayOverviewItem.Data>.validate(hasPerson: Boolean, hasLocation: Boolean) { var count = 0 if (hasPerson) count++ if (hasLocation) count++ @@ -306,17 +340,21 @@ open class ContactDiaryOverviewViewModelTest { size shouldBe count forEach { when (it.type) { - ListItem.Type.PERSON -> { + DayOverviewItem.Type.PERSON -> { it.drawableId shouldBe R.drawable.ic_contact_diary_person_item } - ListItem.Type.LOCATION -> { + DayOverviewItem.Type.LOCATION -> { it.drawableId shouldBe R.drawable.ic_contact_diary_location_item } } } } - private fun ListItem.Risk.validate(highRisk: Boolean, dueToLowEncounters: Boolean, hasPersonOrLocation: Boolean) { + private fun DayOverviewItem.Risk.validate( + highRisk: Boolean, + dueToLowEncounters: Boolean, + hasPersonOrLocation: Boolean + ) { when (highRisk) { true -> { title shouldBe R.string.contact_diary_high_risk_title diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionCollectorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionCollectorTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..ac0144363e0d88499e81d547406dfd63295e2f59 --- /dev/null +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionCollectorTest.kt @@ -0,0 +1,3 @@ +package de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission + +class AnalyticsKeySubmissionCollectorTest diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionDonorTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionDonorTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..252fa5d3b015fc6d749f9c1188bfe66fce6d568b --- /dev/null +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/datadonation/analytics/modules/keysubmission/AnalyticsKeySubmissionDonorTest.kt @@ -0,0 +1,3 @@ +package de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission + +class AnalyticsKeySubmissionDonorTest diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/release/NewReleaseInfoFragmentTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/release/NewReleaseInfoFragmentTest.kt index 4e8a58260c50bdb7856b437d526c9aa1feefbaf0..a010e57352bade4d619e8f758aac8388a88196e9 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/release/NewReleaseInfoFragmentTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/release/NewReleaseInfoFragmentTest.kt @@ -53,6 +53,10 @@ class NewReleaseInfoFragmentTest : BaseTest() { @Test fun `ensure TURKISH new release info arrays are of equal length`() = loadAndCompareStringArrayResources() + @Config(qualifiers = "bg") + @Test + fun `ensure BULGARIAN new release info arrays are of equal length`() = loadAndCompareStringArrayResources() + @Config(qualifiers = "fr") @Test fun `ensure DEFAULT aka FRENCH new release info arrays are of equal length`() = loadAndCompareStringArrayResources() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/release/NewReleaseInfoViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/release/NewReleaseInfoViewModelTest.kt index f9ae8c5c3879e6d6417e0ee3c51ecd8fa41c555f..04d9af9abf9d1e52c2f65fa2a6388a23d5a48704 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/release/NewReleaseInfoViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/release/NewReleaseInfoViewModelTest.kt @@ -1,6 +1,8 @@ package de.rki.coronawarnapp.release +import de.rki.coronawarnapp.datadonation.analytics.storage.AnalyticsSettings import de.rki.coronawarnapp.main.CWASettings +import de.rki.coronawarnapp.util.preferences.FlowPreference import io.kotest.matchers.shouldBe import io.mockk.MockKAnnotations import io.mockk.Runs @@ -10,29 +12,49 @@ import io.mockk.just import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith +import testhelpers.BaseTest import testhelpers.TestDispatcherProvider import testhelpers.extensions.InstantExecutorExtension +import testhelpers.preferences.mockFlowPreference @ExtendWith(InstantExecutorExtension::class) -class NewReleaseInfoViewModelTest { +class NewReleaseInfoViewModelTest : BaseTest() { - @MockK lateinit var settings: CWASettings + @MockK lateinit var appSettings: CWASettings + @MockK lateinit var analyticsSettings: AnalyticsSettings + private lateinit var lastOnboardingVersionCode: FlowPreference<Long> lateinit var viewModel: NewReleaseInfoViewModel @BeforeEach fun setUp() { MockKAnnotations.init(this) - every { settings.lastChangelogVersion.update(any()) } just Runs + lastOnboardingVersionCode = mockFlowPreference(0L) + every { analyticsSettings.lastOnboardingVersionCode } returns lastOnboardingVersionCode + + every { appSettings.lastChangelogVersion.update(any()) } just Runs viewModel = NewReleaseInfoViewModel( TestDispatcherProvider(), - settings + appSettings, + analyticsSettings ) } @Test - fun testOnNextButtonClick() { + fun `if analytics onboarding has not yet been done, navigate to it`() { + lastOnboardingVersionCode.value shouldBe 0L + + viewModel.onNextButtonClick() + viewModel.routeToScreen.value shouldBe NewReleaseInfoNavigationEvents.NavigateToOnboardingDeltaAnalyticsFragment + } + + @Test + fun `if analytics onboarding is done, just close the release screen`() { + lastOnboardingVersionCode.update { 1130000L } + viewModel.onNextButtonClick() viewModel.routeToScreen.value shouldBe NewReleaseInfoNavigationEvents.CloseScreen + + lastOnboardingVersionCode.value shouldBe 1130000L } @Test diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/SubmissionRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/SubmissionRepositoryTest.kt index cd1f01845abb25bdb5a2c12a4e7a07d27731a23d..e78e650721b97d777d8d9409d12eca30d09271ea 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/SubmissionRepositoryTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/storage/SubmissionRepositoryTest.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.storage +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.deadman.DeadmanNotificationScheduler import de.rki.coronawarnapp.playbook.BackgroundNoise import de.rki.coronawarnapp.service.submission.SubmissionService @@ -51,6 +52,7 @@ class SubmissionRepositoryTest : BaseTest() { @MockK lateinit var encryptedPreferencesFactory: EncryptedPreferencesFactory @MockK lateinit var encryptionErrorResetTool: EncryptionErrorResetTool @MockK lateinit var deadmanNotificationScheduler: DeadmanNotificationScheduler + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector private val guid = "123456-12345678-1234-4DA7-B166-B86D85475064" private val tan = "123456-12345678-1234-4DA7-B166-B86D85475064" @@ -94,7 +96,8 @@ class SubmissionRepositoryTest : BaseTest() { submissionService = submissionService, timeStamper = timeStamper, tekHistoryStorage = tekHistoryStorage, - deadmanNotificationScheduler = deadmanNotificationScheduler + deadmanNotificationScheduler = deadmanNotificationScheduler, + analyticsKeySubmissionCollector = analyticsKeySubmissionCollector ) @Test @@ -106,6 +109,7 @@ class SubmissionRepositoryTest : BaseTest() { every { LocalData.isAllowedToSubmitDiagnosisKeys(any()) } just Runs every { LocalData.isTestResultAvailableNotificationSent(any()) } just Runs every { LocalData.numberOfSuccessfulSubmissions(any()) } just Runs + every { analyticsKeySubmissionCollector.reset() } just Runs submissionRepository.removeTestFromDevice() @@ -123,6 +127,7 @@ class SubmissionRepositoryTest : BaseTest() { @Test fun registrationWithGUIDSucceeds() = runBlockingTest { coEvery { submissionService.asyncRegisterDeviceViaGUID(guid) } returns registrationData + coEvery { analyticsKeySubmissionCollector.reportTestRegistered() } just Runs val submissionRepository = createInstance(scope = this) @@ -139,6 +144,8 @@ class SubmissionRepositoryTest : BaseTest() { @Test fun registrationWithTeleTANSucceeds() = runBlockingTest { coEvery { submissionService.asyncRegisterDeviceViaTAN(tan) } returns registrationData + coEvery { analyticsKeySubmissionCollector.reportTestRegistered() } just Runs + every { analyticsKeySubmissionCollector.reportRegisteredWithTeleTAN() } just Runs val submissionRepository = createInstance(scope = this) diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt index fdcb70d740fe07a8e7996a7d984c498a3980e6a9..f5e67e1b5f43d10e8739f91da62534ef7b022aaa 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt @@ -3,6 +3,7 @@ package de.rki.coronawarnapp.submission.task import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey import de.rki.coronawarnapp.appconfig.AppConfigProvider import de.rki.coronawarnapp.appconfig.ConfigData +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException import de.rki.coronawarnapp.notification.ShareTestResultNotificationService import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService @@ -56,10 +57,9 @@ class SubmissionTaskTest : BaseTest() { @MockK lateinit var tek: TemporaryExposureKey @MockK lateinit var userSymptoms: Symptoms @MockK lateinit var transformedKey: TemporaryExposureKeyExportOuterClass.TemporaryExposureKey - @MockK lateinit var appConfigData: ConfigData - @MockK lateinit var timeStamper: TimeStamper + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector private lateinit var settingSymptomsPreference: FlowPreference<Symptoms?> @@ -101,6 +101,9 @@ class SubmissionTaskTest : BaseTest() { coEvery { playbook.submit(any()) } just Runs + every { analyticsKeySubmissionCollector.reportSubmitted() } just Runs + every { analyticsKeySubmissionCollector.reportSubmittedInBackground() } just Runs + every { shareTestResultNotificationService.cancelSharePositiveTestResultNotification() } just Runs every { testResultAvailableNotificationService.cancelTestResultAvailableNotification() } just Runs @@ -118,7 +121,8 @@ class SubmissionTaskTest : BaseTest() { shareTestResultNotificationService = shareTestResultNotificationService, timeStamper = timeStamper, autoSubmission = autoSubmission, - testResultAvailableNotificationService = testResultAvailableNotificationService + testResultAvailableNotificationService = testResultAvailableNotificationService, + analyticsKeySubmissionCollector = analyticsKeySubmissionCollector ) @Test @@ -148,6 +152,9 @@ class SubmissionTaskTest : BaseTest() { ) ) + analyticsKeySubmissionCollector.reportSubmitted() + analyticsKeySubmissionCollector.reportSubmittedInBackground() + tekHistoryStorage.clear() settingSymptomsPreference.update(match { it.invoke(mockk()) == null }) diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsViewModelTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..7c07b541dc8e7355c3eb832482cc7099623cf2d1 --- /dev/null +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/onboarding/OnboardingAnalyticsViewModelTest.kt @@ -0,0 +1,84 @@ +package de.rki.coronawarnapp.ui.onboarding + +import de.rki.coronawarnapp.datadonation.analytics.Analytics +import de.rki.coronawarnapp.datadonation.analytics.common.Districts +import de.rki.coronawarnapp.datadonation.analytics.storage.AnalyticsSettings +import de.rki.coronawarnapp.environment.BuildConfigWrap +import de.rki.coronawarnapp.server.protocols.internal.ppdd.PpaData.PPAAgeGroup +import de.rki.coronawarnapp.server.protocols.internal.ppdd.PpaData.PPAFederalState +import de.rki.coronawarnapp.util.preferences.FlowPreference +import io.kotest.matchers.shouldBe +import io.mockk.MockKAnnotations +import io.mockk.Runs +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.just +import io.mockk.mockkObject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.test.runBlockingTest +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import testhelpers.BaseTest +import testhelpers.TestDispatcherProvider +import testhelpers.extensions.InstantExecutorExtension +import testhelpers.preferences.mockFlowPreference + +@ExtendWith(InstantExecutorExtension::class) +class OnboardingAnalyticsViewModelTest : BaseTest() { + + @MockK lateinit var settings: AnalyticsSettings + @MockK lateinit var analytics: Analytics + @MockK lateinit var districts: Districts + private lateinit var lastOnboardingVersionCode: FlowPreference<Long> + + @BeforeEach + fun setUp() { + MockKAnnotations.init(this) + lastOnboardingVersionCode = mockFlowPreference(0L) + + every { settings.lastOnboardingVersionCode } returns lastOnboardingVersionCode + every { settings.userInfoAgeGroup } returns mockFlowPreference(PPAAgeGroup.AGE_GROUP_UNSPECIFIED) + every { settings.userInfoDistrict } returns mockFlowPreference(0) + every { settings.userInfoFederalState } returns mockFlowPreference(PPAFederalState.FEDERAL_STATE_UNSPECIFIED) + + coEvery { analytics.setAnalyticsEnabled(any()) } just Runs + + mockkObject(BuildConfigWrap) + every { BuildConfigWrap.VERSION_CODE } returns 1234567890L + } + + private fun createInstance(scope: CoroutineScope) = OnboardingAnalyticsViewModel( + appScope = scope, + dispatcherProvider = TestDispatcherProvider(), + analytics = analytics, + districts = districts, + settings = settings + ) + + @Test + fun `accepting ppa updates versioncode and state `() { + lastOnboardingVersionCode.value shouldBe 0L + + runBlockingTest { + createInstance(scope = this).onProceed(true) + } + + coVerify { analytics.setAnalyticsEnabled(true) } + lastOnboardingVersionCode.value shouldBe 1234567890L + } + + @Test + fun `declining ppa updates versioncode and state`() { + lastOnboardingVersionCode.value shouldBe 0L + + runBlockingTest { + createInstance(scope = this).onProceed(false) + } + + coVerify { analytics.setAnalyticsEnabled(false) } + lastOnboardingVersionCode.value shouldBe 1234567890L + } +} diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModelTest.kt index 2467d7099a012f4b09496e9165e2e8f9dc39415c..5e1f894d73b3e3296a5664e021376872cef265b7 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/qrcode/consent/SubmissionConsentViewModelTest.kt @@ -1,6 +1,7 @@ package de.rki.coronawarnapp.ui.submission.qrcode.consent import com.google.android.gms.common.api.ApiException +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.nearby.modules.tekhistory.TEKHistoryProvider import de.rki.coronawarnapp.storage.interoperability.InteroperabilityRepository import de.rki.coronawarnapp.submission.SubmissionRepository @@ -30,6 +31,7 @@ class SubmissionConsentViewModelTest { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var interoperabilityRepository: InteroperabilityRepository @MockK lateinit var tekHistoryProvider: TEKHistoryProvider + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector lateinit var viewModel: SubmissionConsentViewModel @@ -40,11 +42,13 @@ class SubmissionConsentViewModelTest { MockKAnnotations.init(this) every { interoperabilityRepository.countryList } returns MutableStateFlow(countryList) every { submissionRepository.giveConsentToSubmission() } just Runs + every { analyticsKeySubmissionCollector.reportAdvancedConsentGiven() } just Runs viewModel = SubmissionConsentViewModel( submissionRepository, interoperabilityRepository, dispatcherProvider = TestDispatcherProvider(), - tekHistoryProvider + tekHistoryProvider, + analyticsKeySubmissionCollector = analyticsKeySubmissionCollector ) } @@ -74,6 +78,7 @@ class SubmissionConsentViewModelTest { @Test fun `giveGoogleConsentResult when user Allows routes to QR Code scan`() { + every { analyticsKeySubmissionCollector.reportAdvancedConsentGiven() } just Runs viewModel.giveGoogleConsentResult(true) viewModel.routeToScreen.value shouldBe SubmissionNavigationEvents.NavigateToQRCodeScan } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModelTest.kt index 05498c26cd671904a1907733501eb9f9c218d45d..835ce668dbbfcd9ec40525b1576bbdb0f722fd56 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/calendar/SubmissionSymptomCalendarViewModelTest.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.ui.submission.symptoms.calendar +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.Symptoms import de.rki.coronawarnapp.submission.auto.AutoSubmission @@ -29,6 +30,7 @@ class SubmissionSymptomCalendarViewModelTest : BaseTest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var autoSubmission: AutoSubmission + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector private lateinit var currentSymptoms: FlowPreference<Symptoms?> @BeforeEach @@ -48,7 +50,8 @@ class SubmissionSymptomCalendarViewModelTest : BaseTest() { symptomIndication = indication, dispatcherProvider = TestDispatcherProvider(), submissionRepository = submissionRepository, - autoSubmission = autoSubmission + autoSubmission = autoSubmission, + analyticsKeySubmissionCollector = analyticsKeySubmissionCollector ) @Test diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModelTest.kt index f067783b3477bc21e9bf2bfad233924ee2f3016f..250cb3f5c117bd403c560b54938e46396fd053fa 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/symptoms/introduction/SubmissionSymptomIntroductionViewModelTest.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.ui.submission.symptoms.introduction +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.Symptoms import de.rki.coronawarnapp.submission.auto.AutoSubmission @@ -28,6 +29,7 @@ class SubmissionSymptomIntroductionViewModelTest : BaseTest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var autoSubmission: AutoSubmission + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector private val currentSymptoms = mockFlowPreference<Symptoms?>(null) @BeforeEach @@ -42,7 +44,8 @@ class SubmissionSymptomIntroductionViewModelTest : BaseTest() { private fun createViewModel() = SubmissionSymptomIntroductionViewModel( dispatcherProvider = TestDispatcherProvider(), submissionRepository = submissionRepository, - autoSubmission = autoSubmission + autoSubmission = autoSubmission, + analyticsKeySubmissionCollector = analyticsKeySubmissionCollector ) @Test diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testavailable/SubmissionTestResultAvailableViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testavailable/SubmissionTestResultAvailableViewModelTest.kt index d6e16b3112e83ec35603db00d2ab694844e3ba21..f06833355235b74b2ecc8746f09cd475bf9fa929 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testavailable/SubmissionTestResultAvailableViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testavailable/SubmissionTestResultAvailableViewModelTest.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.ui.submission.testavailable +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.auto.AutoSubmission import de.rki.coronawarnapp.submission.data.tekhistory.TEKHistoryUpdater @@ -29,6 +30,7 @@ class SubmissionTestResultAvailableViewModelTest : BaseTest() { @MockK lateinit var autoSubmission: AutoSubmission @MockK lateinit var tekHistoryUpdater: TEKHistoryUpdater @MockK lateinit var tekHistoryUpdaterFactory: TEKHistoryUpdater.Factory + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector @BeforeEach fun setUp() { @@ -46,7 +48,8 @@ class SubmissionTestResultAvailableViewModelTest : BaseTest() { submissionRepository = submissionRepository, dispatcherProvider = TestDispatcherProvider(), tekHistoryUpdaterFactory = tekHistoryUpdaterFactory, - autoSubmission = autoSubmission + autoSubmission = autoSubmission, + analyticsKeySubmissionCollector = analyticsKeySubmissionCollector ) @Test @@ -94,6 +97,7 @@ class SubmissionTestResultAvailableViewModelTest : BaseTest() { @Test fun `go to test result without updating TEK history if NO consent is given`() { every { submissionRepository.hasGivenConsentToSubmission } returns flowOf(false) + every { analyticsKeySubmissionCollector.reportConsentWithdrawn() } just Runs val viewModel = createViewModel() viewModel.proceed() diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt index c84ea408def3e5f45cba933fdcde2aaf483b497c..757497cea3cf68b9202ee6aa258789c4940c54ad 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/testresult/SubmissionTestResultConsentGivenViewModelTest.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.ui.submission.testresult +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.notification.TestResultAvailableNotificationService import de.rki.coronawarnapp.submission.SubmissionRepository import de.rki.coronawarnapp.submission.auto.AutoSubmission @@ -20,6 +21,7 @@ class SubmissionTestResultConsentGivenViewModelTest : BaseTest() { @MockK lateinit var submissionRepository: SubmissionRepository @MockK lateinit var autoSubmission: AutoSubmission @MockK lateinit var testResultAvailableNotificationService: TestResultAvailableNotificationService + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector lateinit var viewModel: SubmissionTestResultConsentGivenViewModel @BeforeEach @@ -31,7 +33,8 @@ class SubmissionTestResultConsentGivenViewModelTest : BaseTest() { submissionRepository = submissionRepository, dispatcherProvider = TestDispatcherProvider(), autoSubmission = autoSubmission, - testResultAvailableNotificationService = testResultAvailableNotificationService + testResultAvailableNotificationService = testResultAvailableNotificationService, + analyticsKeySubmissionCollector = analyticsKeySubmissionCollector ) @Test diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModelTest.kt index eb91b4fafd41603c8c62dd43b8f3d65fdb411589..6b3e2fdc42a2b7829f254c762b2bf1e682637b0d 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModelTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/warnothers/SubmissionResultPositiveOtherWarningNoConsentViewModelTest.kt @@ -1,5 +1,6 @@ package de.rki.coronawarnapp.ui.submission.warnothers +import de.rki.coronawarnapp.datadonation.analytics.modules.keysubmission.AnalyticsKeySubmissionCollector import de.rki.coronawarnapp.nearby.ENFClient import de.rki.coronawarnapp.storage.interoperability.InteroperabilityRepository import de.rki.coronawarnapp.submission.SubmissionRepository @@ -31,6 +32,7 @@ class SubmissionResultPositiveOtherWarningNoConsentViewModelTest : BaseTest() { @MockK lateinit var tekHistoryUpdaterFactory: TEKHistoryUpdater.Factory @MockK lateinit var interoperabilityRepository: InteroperabilityRepository @MockK lateinit var enfClient: ENFClient + @MockK lateinit var analyticsKeySubmissionCollector: AnalyticsKeySubmissionCollector @BeforeEach fun setUp() { @@ -50,7 +52,8 @@ class SubmissionResultPositiveOtherWarningNoConsentViewModelTest : BaseTest() { autoSubmission = autoSubmission, enfClient = enfClient, interoperabilityRepository = interoperabilityRepository, - submissionRepository = submissionRepository + submissionRepository = submissionRepository, + analyticsKeySubmissionCollector = analyticsKeySubmissionCollector ) @Test diff --git a/gradle.properties b/gradle.properties index 9b0279b18b450e889f22c4827e04be18cfda289b..dd26c8008b0a8c7eee720e9465a64cb40e3df128 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,4 +20,4 @@ org.gradle.dependency.verification.console=verbose VERSION_MAJOR=1 VERSION_MINOR=15 VERSION_PATCH=0 -VERSION_BUILD=2 +VERSION_BUILD=4