From 5b344e60f2f40ee414d547cfe94665e5be6d3e2d Mon Sep 17 00:00:00 2001 From: Fabian-K Date: Wed, 3 Jun 2020 18:21:05 +0200 Subject: [PATCH 01/20] Require tracing for upload (#137) * submission: require tracing enabled when navigating from "Test Result" via "Weiter" * submission: require tracing enabled when navigating from "Andere warnen" via "Weiter" * fix required formatting of SubmissionViewModel.kt * remove isTracingEnabled from SubmissionViewModel.kt and instead include TracingViewModel into fragments to match remaining repository --- ...ssionResultPositiveOtherWarningFragment.kt | 31 ++++++++++--- .../SubmissionTestResultFragment.kt | 43 ++++++++++++++----- .../ui/viewmodel/SubmissionViewModel.kt | 5 ++- .../src/main/res/values/strings.xml | 5 +++ 4 files changed, 67 insertions(+), 17 deletions(-) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt index 14f0a914b67..b94a5e620ba 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt @@ -7,10 +7,13 @@ import android.view.ViewGroup import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer import com.google.android.gms.nearby.exposurenotification.TemporaryExposureKey +import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentSubmissionPositiveOtherWarningBinding import de.rki.coronawarnapp.nearby.InternalExposureNotificationPermissionHelper import de.rki.coronawarnapp.ui.BaseFragment import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel +import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel +import de.rki.coronawarnapp.util.DialogHelper class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), InternalExposureNotificationPermissionHelper.Callback { @@ -19,7 +22,9 @@ class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), private val TAG: String? = SubmissionResultPositiveOtherWarningFragment::class.simpleName } - private val viewModel: SubmissionViewModel by activityViewModels() + private val submissionViewModel: SubmissionViewModel by activityViewModels() + private val tracingViewModel: TracingViewModel by activityViewModels() + private lateinit var binding: FragmentSubmissionPositiveOtherWarningBinding private var submissionRequested = false private var submissionFailed = false @@ -28,6 +33,7 @@ class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), override fun onResume() { super.onResume() + tracingViewModel.refreshIsTracingEnabled() if (submissionRequested && !submissionFailed) { internalExposureNotificationPermissionHelper.requestPermissionToShareKeys() } @@ -35,7 +41,7 @@ class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), override fun onKeySharePermissionGranted(keys: List) { super.onKeySharePermissionGranted(keys) - viewModel.submitDiagnosisKeys() + submissionViewModel.submitDiagnosisKeys() } override fun onFailure(exception: Exception?) { @@ -58,7 +64,7 @@ class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() - viewModel.submissionState.observe(viewLifecycleOwner, Observer { + submissionViewModel.submissionState.observe(viewLifecycleOwner, Observer { if (it == ApiRequestState.SUCCESS) { doNavigate( SubmissionResultPositiveOtherWarningFragmentDirections @@ -70,8 +76,7 @@ class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), private fun setButtonOnClickListener() { binding.submissionPositiveOtherWarningButton.setOnClickListener { - submissionRequested = true - internalExposureNotificationPermissionHelper.requestPermissionToShareKeys() + initiateWarningOthers() } binding.submissionPositiveOtherWarningHeader .informationHeader.headerButtonBack.buttonIcon.setOnClickListener { @@ -81,4 +86,20 @@ class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), ) } } + + private fun initiateWarningOthers() { + if (tracingViewModel.isTracingEnabled.value != true) { + val tracingRequiredDialog = DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_test_result_dialog_tracing_required_title, + R.string.submission_test_result_dialog_tracing_required_message, + R.string.submission_test_result_dialog_tracing_required_button + ) + DialogHelper.showDialog(tracingRequiredDialog) + return + } + + submissionRequested = true + internalExposureNotificationPermissionHelper.requestPermissionToShareKeys() + } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt index aed4b341efc..9b04678d913 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt @@ -5,9 +5,12 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.activityViewModels +import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentSubmissionTestResultBinding import de.rki.coronawarnapp.ui.BaseFragment import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel +import de.rki.coronawarnapp.ui.viewmodel.TracingViewModel +import de.rki.coronawarnapp.util.DialogHelper /** * A simple [BaseFragment] subclass. @@ -17,7 +20,9 @@ class SubmissionTestResultFragment : BaseFragment() { private val TAG: String? = SubmissionTanFragment::class.simpleName } - private val viewModel: SubmissionViewModel by activityViewModels() + private val submissionViewModel: SubmissionViewModel by activityViewModels() + private val tracingViewModel: TracingViewModel by activityViewModels() + private lateinit var binding: FragmentSubmissionTestResultBinding override fun onCreateView( @@ -27,7 +32,7 @@ class SubmissionTestResultFragment : BaseFragment() { ): View? { // get the binding reference by inflating it with the current layout binding = FragmentSubmissionTestResultBinding.inflate(inflater) - binding.submissionViewModel = viewModel + binding.submissionViewModel = submissionViewModel binding.lifecycleOwner = this // Inflate the layout for this fragment return binding.root @@ -40,37 +45,35 @@ class SubmissionTestResultFragment : BaseFragment() { override fun onResume() { super.onResume() - viewModel.refreshTestResult() + submissionViewModel.refreshTestResult() + tracingViewModel.refreshIsTracingEnabled() } private fun setButtonOnClickListener() { binding.submissionTestResultButtonPendingRefresh.setOnClickListener { - viewModel.refreshTestResult() + submissionViewModel.refreshTestResult() } binding.submissionTestResultButtonPendingRemoveTest.setOnClickListener { - viewModel.deregisterTestFromDevice() + submissionViewModel.deregisterTestFromDevice() doNavigate( SubmissionTestResultFragmentDirections.actionSubmissionResultFragmentToMainFragment() ) } binding.submissionTestResultButtonNegativeRemoveTest.setOnClickListener { - viewModel.deregisterTestFromDevice() + submissionViewModel.deregisterTestFromDevice() doNavigate( SubmissionTestResultFragmentDirections.actionSubmissionResultFragmentToMainFragment() ) } binding.submissionTestResultButtonPositiveContinue.setOnClickListener { - doNavigate( - SubmissionTestResultFragmentDirections - .actionSubmissionResultFragmentToSubmissionResultPositiveOtherWarningFragment() - ) + continueIfTracingEnabled() } binding.submissionTestResultButtonInvalidRemoveTest.setOnClickListener { - viewModel.deregisterTestFromDevice() + submissionViewModel.deregisterTestFromDevice() doNavigate( SubmissionTestResultFragmentDirections.actionSubmissionResultFragmentToMainFragment() ) @@ -82,4 +85,22 @@ class SubmissionTestResultFragment : BaseFragment() { ) } } + + private fun continueIfTracingEnabled() { + if (tracingViewModel.isTracingEnabled.value != true) { + val tracingRequiredDialog = DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_test_result_dialog_tracing_required_title, + R.string.submission_test_result_dialog_tracing_required_message, + R.string.submission_test_result_dialog_tracing_required_button + ) + DialogHelper.showDialog(tracingRequiredDialog) + return + } + + doNavigate( + SubmissionTestResultFragmentDirections + .actionSubmissionResultFragmentToSubmissionResultPositiveOtherWarningFragment() + ) + } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt index d32a6100167..7baf40e1213 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt @@ -64,7 +64,10 @@ class SubmissionViewModel : ViewModel() { LocalData.inititalTestResultReceivedTimestamp(0L) } - private fun executeRequestWithState(apiRequest: suspend () -> Unit, state: MutableLiveData) { + private fun executeRequestWithState( + apiRequest: suspend () -> Unit, + state: MutableLiveData + ) { state.value = ApiRequestState.STARTED viewModelScope.launch { try { diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index 582e3296cd3..e6a73261ca1 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -412,6 +412,11 @@ Ihr Test-Ergebnis Es gab ein Problem bei der Auswertung Ihres Tests. Bitte kontaktieren Sie das Gesundheitsamt um Information zum weiteren Vorgehen zu erhalten. Bitte entfernen Sie den Test wieder aus der Corona-Warn-App, damit Sie bei Bedarf einen neuen Test hinterlegen können. Test entfernen + + Risiko-Ermittlung erforderlich + Bitte aktivieren Sie die Risiko-Ermittlung um andere zu warnen. + OK + TAN Eingabe Die TAN ist 7-stellig und Groß- und Kleinschreibung muss nicht beachtet werden. From 47a13b82f3351b2741c7a07751397a0b9de46ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Wed, 3 Jun 2020 18:39:28 +0200 Subject: [PATCH 02/20] Circle Hotfix For Build (#142) Signed-off-by: d067928 --- .circleci/config.yml | 4 ++-- Corona-Warn-App/build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2a7aa1d2d8a..7d0ae9878ca 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,8 +11,8 @@ jobs: steps: - checkout - install-ndk: - ndk-sha: "c81a5bcb4672a18d3647bf6898cd4dbcb978d0e8" - ndk-version: "android-ndk-r21c" + ndk-sha: "50250fcba479de477b45801e2699cca47f7e1267" + ndk-version: "android-ndk-r21b" - restore-build-cache - restore_cache: key: jars-{{ checksum "build.gradle" }}-{{ checksum "Corona-Warn-App/build.gradle" }}-{{ checksum "Server-Protocol-Buffer/build.gradle" }} diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle index ab1083da7e6..42d44254931 100644 --- a/Corona-Warn-App/build.gradle +++ b/Corona-Warn-App/build.gradle @@ -25,7 +25,7 @@ apply plugin: "androidx.navigation.safeargs.kotlin" apply plugin: 'jacoco' android { - ndkVersion "21.2.6472646" + ndkVersion "21.1.6352462" compileSdkVersion 29 buildToolsVersion "29.0.3" From 46f291a220256090486de1887e63450c3fa58a4d Mon Sep 17 00:00:00 2001 From: Thomas Klingbeil <64434904+tklingbeil@users.noreply.github.com> Date: Wed, 3 Jun 2020 19:35:45 +0200 Subject: [PATCH 03/20] Reuse already present registration token (#145) * use registration token passed to transaction * remove unexpected space before : --- .../coronawarnapp/service/submission/SubmissionService.kt | 5 +---- .../transaction/SubmitDiagnosisKeysTransaction.kt | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt index ad23d8a0d3b..d7cb8b6c8f0 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt @@ -47,10 +47,7 @@ object SubmissionService { deleteTeleTAN() } - suspend fun asyncRequestAuthCode(): String { - val registrationToken = - LocalData.registrationToken() ?: throw NoRegistrationTokenSetException() - + suspend fun asyncRequestAuthCode(registrationToken: String): String { val authCode = WebRequestBuilder.asyncGetTan(TAN_REQUEST_URL, registrationToken) return authCode } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransaction.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransaction.kt index f998b199a8d..d7cc02559b5 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransaction.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/transaction/SubmitDiagnosisKeysTransaction.kt @@ -52,7 +52,7 @@ object SubmitDiagnosisKeysTransaction : Transaction() { * RETRIEVE TAN ****************************************************/ val authCode = executeState(RETRIEVE_TAN) { - SubmissionService.asyncRequestAuthCode() + SubmissionService.asyncRequestAuthCode(registrationToken) } /**************************************************** * RETRIEVE TEMPORARY EXPOSURE KEY HISTORY From 9da617ec10b4269a0e1eeb04e5ba8dced8e27619 Mon Sep 17 00:00:00 2001 From: harambasicluka <64483219+harambasicluka@users.noreply.github.com> Date: Wed, 3 Jun 2020 22:18:08 +0200 Subject: [PATCH 04/20] Feature: Strings (#148) * rechecked some strings, added translation tags, completion check * shared pref comments - not translatable * removed unused "m_" from preferences * menu items * comments for risk details and test fragment * more comments Co-authored-by: Muschko --- .../de/rki/coronawarnapp/storage/LocalData.kt | 30 +- .../src/main/res/values/strings.xml | 332 +++++++++++------- 2 files changed, 214 insertions(+), 148 deletions(-) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt index 1988d0d4d7a..734d06ac111 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt @@ -160,7 +160,7 @@ object LocalData { fun lastTimeDiagnosisKeysFromServerFetch(): Date? { val time = getSharedPreferenceInstance().getLong( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_timestamp_diagnosis_keys_fetch), + .getString(R.string.preference_timestamp_diagnosis_keys_fetch), 0L ) // TODO need this for nullable ref, shout not be goto for nullable storage @@ -180,7 +180,7 @@ object LocalData { getSharedPreferenceInstance().edit(true) { putLong( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_timestamp_diagnosis_keys_fetch), + .getString(R.string.preference_timestamp_diagnosis_keys_fetch), value?.time ?: 0L ) } @@ -193,7 +193,7 @@ object LocalData { */ fun lastTimeManualDiagnosisKeysRetrieved(): Long = getSharedPreferenceInstance().getLong( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_timestamp_manual_diagnosis_keys_retrieval), + .getString(R.string.preference_timestamp_manual_diagnosis_keys_retrieval), 0L ) @@ -204,7 +204,7 @@ object LocalData { getSharedPreferenceInstance().edit(true) { putLong( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_timestamp_manual_diagnosis_keys_retrieval), + .getString(R.string.preference_timestamp_manual_diagnosis_keys_retrieval), value ) } @@ -220,7 +220,7 @@ object LocalData { */ fun googleApiToken(): String? = getSharedPreferenceInstance().getString( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_string_google_api_token), + .getString(R.string.preference_string_google_api_token), null ) @@ -232,7 +232,7 @@ object LocalData { fun googleApiToken(value: String?) = getSharedPreferenceInstance().edit(true) { putString( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_string_google_api_token), + .getString(R.string.preference_string_google_api_token), value ) } @@ -333,7 +333,7 @@ object LocalData { */ fun registrationToken(): String? = getSharedPreferenceInstance().getString( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_registration_token), + .getString(R.string.preference_registration_token), null ) @@ -346,7 +346,7 @@ object LocalData { getSharedPreferenceInstance().edit(true) { putString( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_registration_token), + .getString(R.string.preference_registration_token), value ) } @@ -410,7 +410,7 @@ object LocalData { fun testGUID(): String? = getSharedPreferenceInstance().getString( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_test_guid), + .getString(R.string.preference_test_guid), null ) @@ -418,7 +418,7 @@ object LocalData { getSharedPreferenceInstance().edit(true) { putString( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_test_guid), + .getString(R.string.preference_test_guid), value ) } @@ -426,7 +426,7 @@ object LocalData { fun authCode(): String? = getSharedPreferenceInstance().getString( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_auth_code), + .getString(R.string.preference_auth_code), null ) @@ -434,7 +434,7 @@ object LocalData { getSharedPreferenceInstance().edit(true) { putString( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_auth_code), + .getString(R.string.preference_auth_code), value ) } @@ -444,7 +444,7 @@ object LocalData { getSharedPreferenceInstance().edit(true) { putBoolean( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_is_allowed_to_submit_diagnosis_keys), + .getString(R.string.preference_is_allowed_to_submit_diagnosis_keys), isAllowedToSubmitDiagnosisKeys ) } @@ -453,7 +453,7 @@ object LocalData { fun isAllowedToSubmitDiagnosisKeys(): Boolean? { return getSharedPreferenceInstance().getBoolean( CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_is_allowed_to_submit_diagnosis_keys), + .getString(R.string.preference_is_allowed_to_submit_diagnosis_keys), false ) } @@ -482,5 +482,5 @@ object LocalData { fun getLastFetchDatePreference() = CoronaWarnApplication.getAppContext() - .getString(R.string.preference_m_timestamp_diagnosis_keys_fetch) + .getString(R.string.preference_timestamp_diagnosis_keys_fetch) } diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index e6a73261ca1..0f79f4f3b55 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -4,81 +4,106 @@ Preference Keys ###################################### TODO: Check what is needed --> + shared_preferences_cwa + preference_onboarding_completed + preference_reset_app + preference_only_wifi + preference_tracing - - preference_m_timestamp_diagnosis_keys_fetch + + + preference_timestamp_diagnosis_keys_fetch - - preference_m_timestamp_manual_diagnosis_keys_retrieval + + + preference_timestamp_manual_diagnosis_keys_retrieval - + + preference_m_string_google_api_token + preference_notifications_enabled + preference_notifications_risk_enabled + preference_notifications_test_enabled + preference_background_job_enabled + preference_mobile_data_enabled - - preference_m_registration_token + + + preference_registration_token preference_device_pairing_successful_time + preference_initial_tracing_activation_time + preference_initial_result_received_time + preference_risk_level_score - - preference_m_test_guid + + + preference_test_guid - - preference_m_is_allowed_to_submit_diagnosis_keys + + + preference_is_allowed_to_submit_diagnosis_keys - - preference_m_auth_code + + + preference_auth_code + preference_database_password + preference_total_non_active_tracing + preference_last_non_active_tracing_timestamp + preference_number_successful_submissions + preference_teletan @@ -86,20 +111,23 @@ - - Überblick - App-Informationen - Einstellungen + + Überblick + + App-Informationen + + Einstellungen + ###################################### --> + de.rki.coronawarnapp.notification.exposureNotificationChannelId + 1 @@ -109,55 +137,72 @@ Es gibt Neuigkeiten von Ihrer Corona-Warn-App - - Bisher keine Risiko-Begegnungen + + + Bisher keine Risiko-Begegnungen %1$s Risikobegegnungen - %1$s von 14 Tagen aktiv + + %1$s von 14 Tagen aktiv Kontakte wurden noch nicht überprüft. Aktualisiert: %1$s Nächste Aktualisierung in: %1$s - Aktualisieren + + Aktualisieren Aktualisierung in %1$s - Risiko-Ermittlung einschalten - Aktivieren Sie die Risiko-Ermittlung, um Ihre heutige Risiko-Einschätzung zu berechnen. - - Niedriges Risiko - - Erhöhtes Risiko + + Risiko-Ermittlung einschalten + + Aktivieren Sie die Risiko-Ermittlung, um Ihre heutige Risiko-Einschätzung zu berechnen. + + Niedriges Risiko + + Erhöhtes Risiko %1$s Tage seit der letzten Begegnung - - Unbekanntes Risiko - Da Sie die Risiko-Ermittlung noch nicht lange genug aktiviert haben, konnten wir für Sie kein Infektionsrisiko berechnen. - - Risiko-Ermittlung gestoppt + + Unbekanntes Risiko + + Da Sie die Risiko-Ermittlung noch nicht lange genug aktiviert haben, konnten wir für Sie kein Infektionsrisiko berechnen. + + Risiko-Ermittlung gestoppt Letzte Ermittlung:\n%1$s - - Risiko-Ermittlung nicht möglich - Ihre Risiko-Berechnung konnte seit mehr als 24 Stunden nicht aktualisiert werden. - - Prüfung läuft… - Es werden aktuelle Daten heruntergeladen und geprüft. Dies kann mehrere Minuten dauern. + + Risiko-Ermittlung nicht möglich + + Ihre Risiko-Berechnung konnte seit mehr als 24 Stunden nicht aktualisiert werden. + + Prüfung läuft… + + Es werden aktuelle Daten heruntergeladen und geprüft. Dies kann mehrere Minuten dauern. - Häufige Fragen - Hier finden Sie Antworten auf häufig gestellte Fragen rund um die Corona-Warn-App. + + + Häufige Fragen + + Hier finden Sie Antworten auf häufig gestellte Fragen rund um die Corona-Warn-App. - Corona-Warn-App teilen - Gemeinsam Corona bekämpfen - Je mehr Menschen mitmachen, desto besser durchbrechen wir Infektionsketten. Laden Sie Familie, Freunde und Bekannte ein! - Download-Link versenden - Gemeinsam Corona bekämpfen\nIch bin dabei. Du auch?\nhttps://www.coronawarn.app/\n - OK + + + Corona-Warn-App teilen + + Gemeinsam Corona bekämpfen + + Je mehr Menschen mitmachen, desto besser durchbrechen wir Infektionsketten. Laden Sie Familie, Freunde und Bekannte ein! + + Download-Link versenden + + Gemeinsam Corona bekämpfen\nIch bin dabei. Du auch?\nhttps://www.coronawarn.app/\n + Überblick Risiko-Ermittlung @@ -185,21 +230,38 @@ - Verhalten - So verhalten Sie sich richtig - Begeben Sie sich umgehend nach Hause bzw. bleiben Sie zu Hause. - Für Fragen zu auftretenden Symptomen, Testmöglichkeiten und weiteren Isolationsmaßnahmen wenden Sie sich bitte an eine der folgenden Stellen: - Waschen Sie Ihre Hände regelmäßig. - Tragen Sie einen Mundschutz bei Kontakt mit anderen Personen. - Halten Sie mindestens 1,5 Meter Abstand zu anderen Personen. - Niesen oder husten Sie in die Armbeuge oder in ein Taschentuch. - - Ihre Hausärztin/Ihren Hausarzt - - Den Kassenärztlichen Bereitschaftsdienst unter der Telefonnummer: 116117 - - Ihr Gesundheitsamt - Infektionsrisiko - So wurde Ihr Risiko ermittelt - So wird Ihr Risiko ermittelt - Da Sie die Risiko-Ermittlung noch nicht lange genug aktiviert haben, konnten wir für Sie kein Infektionsrisiko berechnen. + + + Verhalten + + So verhalten Sie sich richtig + + Begeben Sie sich umgehend nach Hause bzw. bleiben Sie zu Hause. + + Für Fragen zu auftretenden Symptomen, Testmöglichkeiten und weiteren Isolationsmaßnahmen wenden Sie sich bitte an eine der folgenden Stellen: + + Waschen Sie Ihre Hände regelmäßig. + + Tragen Sie einen Mundschutz bei Kontakt mit anderen Personen. + + Halten Sie mindestens 1,5 Meter Abstand zu anderen Personen. + + Niesen oder husten Sie in die Armbeuge oder in ein Taschentuch. + + - Ihre Hausärztin/Ihren Hausarzt + + - Den Kassenärztlichen Bereitschaftsdienst unter der Telefonnummer: 116117 + + - Ihr Gesundheitsamt + + Infektionsrisiko + + So wurde Ihr Risiko ermittelt + + So wird Ihr Risiko ermittelt + + Da Sie die Risiko-Ermittlung noch nicht lange genug aktiviert haben, konnten wir für Sie kein Infektionsrisiko berechnen. + Ihre Risiko-Berechnung konnte seit mehr als 24 Stunden nicht aktualisiert werden. Sie haben ein niedriges Infektionsrisiko, da keine Begegnung mit nachweislich Coronapositiv getesteten Personen aufgezeichnet wurde oder sich Ihre Begegnung auf kurze Zeit und einen größeren Abstand beschränkt hat. Sie haben ein erhöhtes Infektionsrisiko, da Sie zuletzt vor %1$s Tagen mindestens einer- Corona positiv-getesteten Person über einen längeren Zeitraum und mit einem geringen Abstand begegnet sind. @@ -213,54 +275,51 @@ IS MISSING Nicht aktivieren - Weiter + Weiter - Los Geht\'s + Los geht\'s + Zurück - - Gemeinsam Corona bekämpfen + Gemeinsam Corona bekämpfen - Mehr Schutz für Sie und uns alle. Mit der Corona-Warn-App durchbrechen wir Infektionsketten schneller. + Mehr Schutz für Sie und uns alle. Mit der Corona-Warn-App durchbrechen wir Infektionsketten schneller. - Machen Sie Ihr Smartphone zum Corona-Warn-System. Überblicken Sie Ihren Risikostatus und erfahren Sie, ob in den letzten 14 Tagen infizierte Personen in ihrer Nähe waren. + Machen Sie Ihr Smartphone zum Corona-Warn-System. Überblicken Sie Ihren Risikostatus und erfahren Sie, ob in den letzten 14 Tagen infizierte Personen in ihrer Nähe waren. - Die App merkt sich Begegnungen zwischen Menschen, indem ihre Smartphones verschlüsselte Zufallscodes austauschen. Und zwar ohne dabei auf persönliche Daten zuzugreifen. - + Die App merkt sich Begegnungen zwischen Menschen, indem ihre Smartphones verschlüsselte Zufallscodes austauschen. Und zwar ohne dabei auf persönliche Daten zuzugreifen. Datenschutz Verantwortliche Stelle im Sinne des Art. 4 Abs. 7 DSGVO: \n \n Robert Koch-Institut\nNordufer 20\n13353 Berlin @string/lorem_ipsum @string/lorem_ipsum - - Wie Sie die Risiko-Ermittlung ermöglichen + Wie Sie die Risiko-Ermittlung ermöglichen - Um zu erkennen, ob für Sie ein Ansteckungsrisiko vorliegt, müssen Sie die Risiko-Ermittlung aktivieren. + Um zu erkennen, ob für Sie ein Ansteckungsrisiko vorliegt, müssen Sie die Risiko-Ermittlung aktivieren. - Die Risiko-Ermittlung funktioniert, indem Ihr Handy per Bluetooth verschlüsselte Zufallscodes anderer Nutzerinnen und Nutzer empfängt und Ihren eigenen Zufallscode an deren Smartphones weitergibt. Die Funktion lässt sich jederzeit wieder deaktivieren. + Die Risiko-Ermittlung funktioniert, indem Ihr Handy per Bluetooth verschlüsselte Zufallscodes anderer Nutzerinnen und Nutzer empfängt und Ihren eigenen Zufallscode an deren Smartphones weitergibt. Die Funktion lässt sich jederzeit wieder deaktivieren. - Die verschlüsselten Zufallscodes geben nur Auskunft über das Datum, die Dauer und die anhand der Signalstärke berechnete Entfernung zu Ihren Mitmenschen. Persönliche Daten wie Name, Adresse oder Aufenthaltsort werden zu keiner Zeit erfasst. Konkrete Rückschlüsse auf Personen sind nicht möglich. + Die verschlüsselten Zufallscodes geben nur Auskunft über das Datum, die Dauer und die anhand der Signalstärke berechnete Entfernung zu Ihren Mitmenschen. Persönliche Daten wie Name, Adresse oder Aufenthaltsort werden zu keiner Zeit erfasst. Konkrete Rückschlüsse auf Personen sind nicht möglich. + Berechtigung - Corona-Warn-App kann dadurch keine Benachrichtigungen zum COVID-19-Risikostatus versenden und empfangen. Sie können die Funktion jederzeit ausschalten. + Corona-Warn-App kann dadurch keine Benachrichtigungen zum COVID-19-Risikostatus versenden und empfangen. Sie können die Funktion jederzeit ausschalten. - Nicht aktivieren - - Zurück - - - Falls Sie positiv getestet werden … + Nicht aktivieren + + Zurück + + Falls Sie positiv getestet werden … - … teilen Sie es bitte über die Corona-Warn-App mit. Freiwillig und sicher. Für die Gesundheit aller. + … teilen Sie es bitte über die Corona-Warn-App mit. Freiwillig und sicher. Für die Gesundheit aller. - Ihre Mitteilung wird zuverlässig verschlüsselt über einen sicheren Server weiterverarbeitet. Die Personen, deren verschlüsselte Zufallscodes Sie gesammelt haben, erhalten nun eine Warnung und Informationen darüber, wie sie weiter vorgehen sollen. - - - Warnungen erhalten, Risiken erkennen + Ihre Mitteilung wird zuverlässig verschlüsselt über einen sicheren Server weiterverarbeitet. Die Personen, deren verschlüsselte Zufallscodes Sie gesammelt haben, erhalten nun eine Warnung und Informationen darüber, wie sie weiter vorgehen sollen. + + Warnungen erhalten, Risiken erkennen - Die App kann Sie automatisch über Ihren Risikostatus informieren und bei Neuinfektionen von Menschen, denen Sie begegnet sind, warnen. Erlauben Sie der App jetzt, Sie zu benachrichtigen. + Die App kann Sie automatisch über Ihren Risikostatus informieren und bei Neuinfektionen von Menschen, denen Sie begegnet sind, warnen. Erlauben Sie der App jetzt, Sie zu benachrichtigen. - Auf diese Weise können Sie sich zum Schutz Ihrer Mitmenschen in Isolation begeben und nach entsprechender Abklärung testen lassen. + Auf diese Weise können Sie sich zum Schutz Ihrer Mitmenschen in Isolation begeben und nach entsprechender Abklärung testen lassen. + Risiko-Ermittlung - Aktivieren Sie die Aufzeichnung Ihrer Begegnungen + So funktioniert die Aufzeichnung Ihrer Begegnungen Erlauben Sie Erfassung und Weitergabe von Covid-19-Zufalls-IDs. Risiko-Ermittlung Aktiv Risiko-Ermittlung Gestoppt @@ -316,69 +376,68 @@ + - App-Informationen + App-Informationen + Version: %1s - Über die App + Über die App - Gemeinsam Corona bekämpfen + Gemeinsam Corona bekämpfen - Das Robert Koch-Institut (RKI) als zentrale Einrichtung des Bundes im Bereich der Öffentlichen Gesundheit und als nationalesPublic-Health-Institut veröffentlicht die Corona-Warn-App für die gesamte Bundesregierung. Die App ist die digitale Ergänzung zu Abstandhalten, Hygiene und Alltagsmaske. + Das Robert Koch-Institut (RKI) als zentrale Einrichtung des Bundes im Bereich der Öffentlichen Gesundheit und als nationalesPublic-Health-Institut veröffentlicht die Corona-Warn-App für die gesamte Bundesregierung. Die App ist die digitale Ergänzung zu Abstandhalten, Hygiene und Alltagsmaske. - Wer sie nutzt, hilft, Infektionsketten schnell nachzuverfolgen und zu durchbrechen. Die App speichert dezentral – auf Ihrem Smartphone – Begegnungen mit anderen.Sie werden informiert, wenn Sie Kontakt mit nachweislich infizierten Personen hatten.Ihre Privatsphärebleibt dabeibestens geschützt. + Wer sie nutzt, hilft, Infektionsketten schnell nachzuverfolgen und zu durchbrechen. Die App speichert dezentral – auf Ihrem Smartphone – Begegnungen mit anderen.Sie werden informiert, wenn Sie Kontakt mit nachweislich infizierten Personen hatten.Ihre Privatsphärebleibt dabeibestens geschützt. - Datenschutzinformation + Datenschutzinformation @string/lorem_ipsum - Nutzungsbedingungen + Nutzungsbedingungen @string/lorem_ipsum - Technische Hotline + Technische Hotline - Wie können wir Ihnen helfen? + Wie können wir Ihnen helfen? - Für technische Fragen rund um die Corona-Warn-App können Sie sich direkt an unsere technische Hotline wenden. + Für technische Fragen rund um die Corona-Warn-App können Sie sich direkt an unsere technische Hotline wenden. - Technische Hotline: + Technische Hotline: - +49 (0)800 7540001 + +49 (0)800 7540001 - Unser Kundenservice ist für Sie da. + Unser Kundenservice ist für Sie da. - Unsere Öffnungszeiten:\nMo – Fr: 08:00 – 22:00 Uhr\nSa – So: 10:00 – 22:00 Uhr\nEs gelten die Preise Ihres Telefonanbieters. + Unsere Öffnungszeiten:\nMo – Fr: 08:00 – 22:00 Uhr\nSa – So: 10:00 – 22:00 Uhr\nEs gelten die Preise Ihres Telefonanbieters. - Für gesundheitliche Fragen, wenden Sie sich bitte an Ihre Hausarztpraxis oder die Hotline des ärztlichen Bereitschaftsdienstes 116 117. + Für gesundheitliche Fragen, wenden Sie sich bitte an Ihre Hausarztpraxis oder die Hotline des ärztlichen Bereitschaftsdienstes 116 117. - Häufige Fragen + Häufige Fragen - Rechtliche Hinweise + Rechtliche Hinweise FTP/SFTP/FTPS client uses libs - Impressum + Impressum Herausgeber SAP Deutschland SE & Co. KG \n \nHauptsitz: \nSAP Deutschland SE & Co. KG \nHasso-Plattner-Ring 7 \n69190 Walldorf + Kamera Berechtigung benötigt Bitte erlauben Sie die Autorisierung der Kamera für das Scannen von QR-Codes. - Erlauben Nicht erlauben - Scan erfolgreich Der QR-Code wurde erfolgreich gescannt - Registrieren Abbrechen Falscher QR Code Es scheint, dass der falsche QR-Code gescannt wurde - Erneut versuchen Abbrechen @@ -390,33 +449,26 @@ Test-Ergebnis Info zum Ablauf: Abschließen - Test erfolgreich hinzugefügt Ihr Test wurde in der Corona-Warn-App hinterlegt. - Test-Ergebnis noch nicht verfügbar Ihr Test-Ergebnis steht noch nicht zur Verfügung. Aktualisieren Test entfernen - Ihr Test-Ergebnis Der Labortest hat keinen Nachweis für das Coronavirus SARS-CoV-2 bei Ihnen ergeben. \n\nBitte entfernen Sie den Test wieder aus der Corona-Warn-App, damit Sie bei Bedarf einen neuen Test hinterlegen können. Test entfernen - Ihr Test-Ergebnis Ihr Test-Ergebnis wurde erfolgreich als “Positiv” verifiziert. Andere warnen Ihre Zufallscodes der letzten 14 Tage teilen, um andere zu schützen und die Infektionskette zu unterbrechen. Weiter - Ihr Test-Ergebnis Es gab ein Problem bei der Auswertung Ihres Tests. Bitte kontaktieren Sie das Gesundheitsamt um Information zum weiteren Vorgehen zu erhalten. Bitte entfernen Sie den Test wieder aus der Corona-Warn-App, damit Sie bei Bedarf einen neuen Test hinterlegen können. Test entfernen - Risiko-Ermittlung erforderlich Bitte aktivieren Sie die Risiko-Ermittlung um andere zu warnen. OK - TAN Eingabe Die TAN ist 7-stellig und Groß- und Kleinschreibung muss nicht beachtet werden. @@ -430,25 +482,19 @@ Danke für die Mithilfe! Ihr verifizierter Befund wurde anonym übertragen. - Auswahl - Welche Informationen liegen Ihnen vor? Dokument mit QR-Code Registrieren Sie Ihren Test, indem Sie den QR-Code ihres Test-Dokument scannen - Datenschutz @string/lorem_ipsum Erlauben Nicht Erlauben - TAN-Code Registrieren Sie Ihren Test per manuekker TAN Eingabe - Noch keine TAN? Bitte rufen Sie uns an, falls Sie Positiv getestet wurden - Andere warnen Helfen Sie mit! @@ -459,7 +505,6 @@ Deine zufälligen IDs der letzten 14 Tage werden dazu genutzt, andere darüber zu informieren, dass du in ihrer Nähe gewesen bist und sie daher möglicherweise in Kontakt mit COVID-19 gekommen sind. Erlauben Nicht erlauben - Vielen Dank! Sie haben einen wichtigen Beitrag geleistet! @@ -507,32 +552,53 @@ Ergebnis liegt noch nicht vor + OK + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + Test API + Test Notification + Android API Test(Manual Test) + Start (Broadcast/Receive Bluetooth) + Get Exposure keys (my keys history from api) + Share my keys via Email + Submit Exposure Key + Show QR Code + Submit keys to Server + Scan Exposure Key + Check Exposure Summary + Exposure summary + Days since last exposure: %1$s + Attenuation Durations in Minutes: %1$s + Summation Risk Score: %1$s + Matched key count: %1$s + Maximum risk score %1$s + My keys (count: %1$d) + Other key + Calculate Risk Level - - - Hello blank fragment From f0ea5d63c326f58efe3039f6faed7c6424bfe4c9 Mon Sep 17 00:00:00 2001 From: Thomas Klingbeil <64434904+tklingbeil@users.noreply.github.com> Date: Wed, 3 Jun 2020 22:56:45 +0200 Subject: [PATCH 05/20] Set diagnosis key risk level based on day (#146) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * apply risk level to diagnosis keys based on day from static vector * day 0 is „today“, which is not available right away from the framework. --- .../util/ProtoFormatConverterExtensions.kt | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ProtoFormatConverterExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ProtoFormatConverterExtensions.kt index 80325f9529a..7b0d6754b28 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ProtoFormatConverterExtensions.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ProtoFormatConverterExtensions.kt @@ -9,18 +9,44 @@ object ProtoFormatConverterExtensions { private const val ROLLING_PERIOD = 144 private const val DEFAULT_TRANSMISSION_RISK_LEVEL = 1 + private const val TRANSMISSION_RISK_DAY_0 = 5 + private const val TRANSMISSION_RISK_DAY_1 = 6 + private const val TRANSMISSION_RISK_DAY_2 = 7 + private const val TRANSMISSION_RISK_DAY_3 = 8 + private const val TRANSMISSION_RISK_DAY_4 = 7 + private const val TRANSMISSION_RISK_DAY_5 = 5 + private const val TRANSMISSION_RISK_DAY_6 = 3 + private const val TRANSMISSION_RISK_DAY_7 = 2 + private val DEFAULT_TRANSMISSION_RISK_VECTOR = intArrayOf( + TRANSMISSION_RISK_DAY_0, + TRANSMISSION_RISK_DAY_1, + TRANSMISSION_RISK_DAY_2, + TRANSMISSION_RISK_DAY_3, + TRANSMISSION_RISK_DAY_4, + TRANSMISSION_RISK_DAY_5, + TRANSMISSION_RISK_DAY_6, + TRANSMISSION_RISK_DAY_7) private const val MAXIMUM_KEYS = 14 fun List.limitKeyCount() = - this.sortedWith(compareBy({ it.rollingStartIntervalNumber })).asReversed().take(MAXIMUM_KEYS) + this.sortedWith(compareBy { it.rollingStartIntervalNumber }).asReversed().take(MAXIMUM_KEYS) - fun List.transformKeyHistoryToExternalFormat() = this.map { - KeyExportFormat.TemporaryExposureKey.newBuilder() - .setKeyData(ByteString.readFrom(it.keyData.inputStream())) - .setRollingStartIntervalNumber(it.rollingStartIntervalNumber) - .setRollingPeriod(ROLLING_PERIOD) - .setTransmissionRiskLevel(DEFAULT_TRANSMISSION_RISK_LEVEL) - .build() + fun List.transformKeyHistoryToExternalFormat() = + this.sortedWith(compareBy { it.rollingStartIntervalNumber }) + .mapIndexed { index, it -> + // The earliest key we receive is from yesterday (i.e. 1 day ago), + // thus we need use index+1 + val riskValue = + if (index + 1 <= DEFAULT_TRANSMISSION_RISK_VECTOR.lastIndex) + DEFAULT_TRANSMISSION_RISK_VECTOR[index + 1] + else + DEFAULT_TRANSMISSION_RISK_LEVEL + KeyExportFormat.TemporaryExposureKey.newBuilder() + .setKeyData(ByteString.readFrom(it.keyData.inputStream())) + .setRollingStartIntervalNumber(it.rollingStartIntervalNumber) + .setRollingPeriod(ROLLING_PERIOD) + .setTransmissionRiskLevel(riskValue) + .build() } fun AppleLegacyKeyExchange.Key.convertToGoogleKey(): KeyExportFormat.TemporaryExposureKey = From be2858666fc03b157439188b088acd282cd859da Mon Sep 17 00:00:00 2001 From: Kolya Opahle Date: Thu, 4 Jun 2020 11:10:01 +0200 Subject: [PATCH 06/20] Submission thank you card and ui state integration (#150) * Made submission status card style more cross device friendly Signed-off-by: Kolya Opahle * Added the positive result submission status card Signed-off-by: Kolya Opahle * lint fix * Updated main fragment documentation * Added icon for sharing risk status Signed-off-by: Kolya Opahle * Updated positive result home screen card text and icons Signed-off-by: Kolya Opahle * added the ui state to the submission view model * Create a include for the submission done screen * Starting to add ui state based cards to homescreen * Added barrier for main screan layout to help with state change barrier in constraint layout will add barrier for about _card which will seperate it from whatever card is visible above it. (main_test, main_test_done, main_test_positive, main_risk) * Submission ui is now based on UIState which is calculated in ViewModel * Small changes to the thank you view. More design changes tomorrow * UI State now allows for failed fetch status again * Re-Added ?. that somehow got lost during the merge Co-authored-by: Oliver Zimmerman --- .../de/rki/coronawarnapp/http/OkHttp3Stack.kt | 4 +- .../ApplicationConfigurationRequest.kt | 3 +- .../service/submission/SubmissionService.kt | 12 ++ .../storage/SubmissionRepository.kt | 42 +++- .../rki/coronawarnapp/ui/main/MainFragment.kt | 4 +- .../ui/settings/SettingsResetFragment.kt | 2 +- .../ui/submission/SubmissionDoneFragment.kt | 7 +- ...ssionResultPositiveOtherWarningFragment.kt | 2 +- .../SubmissionTestResultFragment.kt | 4 +- .../coronawarnapp/ui/view/CircleProgress.kt | 3 +- .../ui/viewmodel/SubmissionViewModel.kt | 19 +- .../util/ProtoFormatConverterExtensions.kt | 5 +- .../rki/coronawarnapp/util/UiStateHelper.kt | 24 --- .../formatter/FormatterSubmissionHelper.kt | 179 ++++++++++-------- .../res/drawable/ic_main_overview_circle.xml | 12 +- .../res/drawable/ic_settings_reset_circle.xml | 44 ++--- .../src/main/res/layout/fragment_main.xml | 43 ++++- .../res/layout/fragment_settings_reset.xml | 4 +- .../res/layout/fragment_submission_done.xml | 50 +---- .../fragment_submission_test_result.xml | 26 +-- .../src/main/res/layout/include_risk_card.xml | 2 +- .../res/layout/include_submission_done.xml | 64 +++++++ .../layout/include_submission_status_card.xml | 6 +- ...include_submission_status_card_content.xml | 18 +- ...nclude_submission_status_card_positive.xml | 4 +- .../res/layout/include_test_result_card.xml | 18 +- 26 files changed, 348 insertions(+), 253 deletions(-) delete mode 100644 Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/UiStateHelper.kt create mode 100644 Corona-Warn-App/src/main/res/layout/include_submission_done.xml diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/OkHttp3Stack.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/OkHttp3Stack.kt index 0e60fa00b1f..c1e0dfc87d8 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/OkHttp3Stack.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/OkHttp3Stack.kt @@ -82,7 +82,9 @@ class OkHttp3Stack(context: Context, interceptors: List) : BaseHttp request: Request<*> ) { when (request.method) { - Request.Method.DEPRECATED_GET_OR_POST -> { throw IllegalArgumentException("deprecated.") } + Request.Method.DEPRECATED_GET_OR_POST -> { + throw IllegalArgumentException("deprecated.") + } Request.Method.GET -> builder.get() Request.Method.DELETE -> builder.delete(createRequestBody(request)) Request.Method.POST -> builder.post(createRequestBody(request)!!) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/request/ApplicationConfigurationRequest.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/request/ApplicationConfigurationRequest.kt index a12c88fed40..826df2c174f 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/request/ApplicationConfigurationRequest.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/request/ApplicationConfigurationRequest.kt @@ -24,7 +24,8 @@ class ApplicationConfigurationRequest( companion object { private val TAG: String? = ApplicationConfigurationRequest::class.simpleName - private const val SOFT_TTL = 5 * 60 * 1000 // in 5 minutes cache will be hit, but also refreshed on background + private const val SOFT_TTL = + 5 * 60 * 1000 // in 5 minutes cache will be hit, but also refreshed on background private const val TTL = 1 * 60 * 60 * 1000 // in 1 hours this cache entry expires completely } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt index d7cb8b6c8f0..d8f6e09debf 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionService.kt @@ -9,6 +9,7 @@ import de.rki.coronawarnapp.service.submission.SubmissionConstants.TAN_REQUEST_U import de.rki.coronawarnapp.service.submission.SubmissionConstants.TELE_TAN_KEY_TYPE import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.transaction.SubmitDiagnosisKeysTransaction +import de.rki.coronawarnapp.util.formatter.TestResult object SubmissionService { suspend fun asyncRegisterDevice() { @@ -58,6 +59,17 @@ object SubmissionService { SubmitDiagnosisKeysTransaction.start(registrationToken) } + suspend fun asyncRequestTestResult(): TestResult { + val registrationToken = + LocalData.registrationToken() ?: throw NoRegistrationTokenSetException() + return TestResult.fromInt( + WebRequestBuilder.asyncGetTestResult( + SubmissionConstants.TEST_RESULT_URL, + registrationToken + ) + ) + } + /** * extracts the GUID from [scanResult]. Returns null if it does not match the required pattern */ diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt index 5d3546d6034..31f3ac1520c 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/SubmissionRepository.kt @@ -1,27 +1,42 @@ package de.rki.coronawarnapp.storage import androidx.lifecycle.MutableLiveData -import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException -import de.rki.coronawarnapp.http.WebRequestBuilder -import de.rki.coronawarnapp.service.submission.SubmissionConstants.TEST_RESULT_URL +import de.rki.coronawarnapp.service.submission.SubmissionService +import de.rki.coronawarnapp.util.DeviceUIState import de.rki.coronawarnapp.util.formatter.TestResult import java.util.Date object SubmissionRepository { private val TAG: String? = SubmissionRepository::class.simpleName - val testResult = MutableLiveData(TestResult.INVALID) val testResultReceivedDate = MutableLiveData(Date()) + val deviceUIState = MutableLiveData(DeviceUIState.UNPAIRED) + + suspend fun refreshUIState() { + var uiState = DeviceUIState.UNPAIRED + + if (LocalData.numberOfSuccessfulSubmissions() == 1) { + uiState = DeviceUIState.SUBMITTED_FINAL + } else { + if (LocalData.registrationToken() != "") { + uiState = when { + LocalData.isAllowedToSubmitDiagnosisKeys() == true -> { + DeviceUIState.PAIRED_POSITIVE + } + else -> fetchTestResult() + } + } + } + deviceUIState.value = uiState + } + + private suspend fun fetchTestResult(): DeviceUIState { + val testResult = SubmissionService.asyncRequestTestResult() - suspend fun refreshTestResult() { - val registrationToken = - LocalData.registrationToken() ?: throw NoRegistrationTokenSetException() - val testResultValue = - WebRequestBuilder.asyncGetTestResult(TEST_RESULT_URL, registrationToken) - testResult.value = TestResult.fromInt(testResultValue) if (testResult == TestResult.POSITIVE) { LocalData.isAllowedToSubmitDiagnosisKeys(true) } + val initialTestResultReceivedTimestamp = LocalData.inititalTestResultReceivedTimestamp() if (initialTestResultReceivedTimestamp == null) { @@ -31,6 +46,13 @@ object SubmissionRepository { } else { testResultReceivedDate.value = Date(initialTestResultReceivedTimestamp) } + + return when (testResult) { + TestResult.NEGATIVE -> DeviceUIState.PAIRED_NEGATIVE + TestResult.POSITIVE -> DeviceUIState.PAIRED_POSITIVE + TestResult.PENDING -> DeviceUIState.PAIRED_NO_RESULT + TestResult.INVALID -> DeviceUIState.PAIRED_ERROR + } } fun setTeletan(teletan: String) { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt index 5d2606f2096..917504354a0 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/main/MainFragment.kt @@ -69,9 +69,7 @@ class MainFragment : BaseFragment() { tracingViewModel.refreshActiveTracingDaysInRetentionPeriod() settingsViewModel.refreshBackgroundJobEnabled() TimerHelper.checkManualKeyRetrievalTimer() - if (submissionViewModel.deviceRegistered) { - submissionViewModel.refreshTestResult() - } + submissionViewModel.refreshDeviceUIState() } private fun setButtonOnClickListener() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetFragment.kt index 33ec04776d2..9975bdcdd68 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/settings/SettingsResetFragment.kt @@ -90,7 +90,7 @@ class SettingsResetFragment : BaseFragment() { activity?.finish() } - private suspend fun deleteLocalAppContent() { + private fun deleteLocalAppContent() { DataRetentionHelper.clearAllLocalData(requireContext()) } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionDoneFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionDoneFragment.kt index a3841c8f6d5..af9ab63b466 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionDoneFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionDoneFragment.kt @@ -30,7 +30,12 @@ class SubmissionDoneFragment : BaseFragment() { } private fun setButtonOnClickListener() { - binding.submissionDoneHeader.informationHeader.headerButtonBack.buttonIcon.setOnClickListener { + binding + .submissionDoneInclude + .submissionDoneHeader + .informationHeader + .headerButtonBack.buttonIcon + .setOnClickListener { doNavigate( SubmissionDoneFragmentDirections.actionSubmissionDoneFragmentToMainFragment() ) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt index b94a5e620ba..527afa53285 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionResultPositiveOtherWarningFragment.kt @@ -29,7 +29,7 @@ class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), private var submissionRequested = false private var submissionFailed = false private lateinit var internalExposureNotificationPermissionHelper: - InternalExposureNotificationPermissionHelper + InternalExposureNotificationPermissionHelper override fun onResume() { super.onResume() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt index 9b04678d913..cdb2f61ca13 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTestResultFragment.kt @@ -45,13 +45,13 @@ class SubmissionTestResultFragment : BaseFragment() { override fun onResume() { super.onResume() - submissionViewModel.refreshTestResult() + submissionViewModel.refreshDeviceUIState() tracingViewModel.refreshIsTracingEnabled() } private fun setButtonOnClickListener() { binding.submissionTestResultButtonPendingRefresh.setOnClickListener { - submissionViewModel.refreshTestResult() + submissionViewModel.refreshDeviceUIState() } binding.submissionTestResultButtonPendingRemoveTest.setOnClickListener { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CircleProgress.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CircleProgress.kt index dc4e6a9af5e..bef8b354ff1 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CircleProgress.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/view/CircleProgress.kt @@ -89,7 +89,8 @@ class CircleProgress @JvmOverloads constructor( val progressColor = styleAttrs.getColor(R.styleable.CircleProgress_progressColor, ContextCompat.getColor(context, R.color.colorPrimary)) // attribute textColor; default = colorGrey - val textColor = styleAttrs.getColor(R.styleable.CircleProgress_textColor, + val textColor = styleAttrs.getColor( + R.styleable.CircleProgress_textColor, ContextCompat.getColor(context, R.color.textColorGrey) ) // attribute disableText; default = true diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt index 7baf40e1213..e11b0c577f2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/viewmodel/SubmissionViewModel.kt @@ -11,28 +11,27 @@ import de.rki.coronawarnapp.storage.LocalData import de.rki.coronawarnapp.storage.SubmissionRepository import de.rki.coronawarnapp.ui.submission.ApiRequestState import de.rki.coronawarnapp.ui.submission.ScanStatus -import de.rki.coronawarnapp.util.formatter.TestResult +import de.rki.coronawarnapp.util.DeviceUIState import kotlinx.coroutines.launch import java.util.Date class SubmissionViewModel : ViewModel() { private val _scanStatus = MutableLiveData(ScanStatus.STARTED) private val _registrationState = MutableLiveData(ApiRequestState.IDLE) - private val _testResultState = MutableLiveData(ApiRequestState.IDLE) - private val _authCodeState = MutableLiveData(ApiRequestState.IDLE) + private val _uiStateState = MutableLiveData(ApiRequestState.IDLE) private val _submissionState = MutableLiveData(ApiRequestState.IDLE) val scanStatus: LiveData = _scanStatus val registrationState: LiveData = _registrationState - val testResultState: LiveData = _testResultState - val authCodeState: LiveData = _authCodeState + val uiStateState: LiveData = _uiStateState val submissionState: LiveData = _submissionState val deviceRegistered get() = LocalData.registrationToken() != null - val testResult: LiveData = - SubmissionRepository.testResult - val testResultReceivedDate: LiveData = SubmissionRepository.testResultReceivedDate + val testResultReceivedDate: LiveData = + SubmissionRepository.testResultReceivedDate + val deviceUiState: LiveData = + SubmissionRepository.deviceUIState fun submitDiagnosisKeys() = executeRequestWithState(SubmissionService::asyncSubmitExposureKeys, _submissionState) @@ -40,8 +39,8 @@ class SubmissionViewModel : ViewModel() { fun doDeviceRegistration() = executeRequestWithState(SubmissionService::asyncRegisterDevice, _registrationState) - fun refreshTestResult() = - executeRequestWithState(SubmissionRepository::refreshTestResult, _testResultState) + fun refreshDeviceUIState() = + executeRequestWithState(SubmissionRepository::refreshUIState, _uiStateState) fun validateAndStoreTestGUID(scanResult: String) { val guid = SubmissionService.extractGUID(scanResult) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ProtoFormatConverterExtensions.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ProtoFormatConverterExtensions.kt index 7b0d6754b28..c81679e5d43 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ProtoFormatConverterExtensions.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/ProtoFormatConverterExtensions.kt @@ -25,7 +25,8 @@ object ProtoFormatConverterExtensions { TRANSMISSION_RISK_DAY_4, TRANSMISSION_RISK_DAY_5, TRANSMISSION_RISK_DAY_6, - TRANSMISSION_RISK_DAY_7) + TRANSMISSION_RISK_DAY_7 + ) private const val MAXIMUM_KEYS = 14 fun List.limitKeyCount() = @@ -47,7 +48,7 @@ object ProtoFormatConverterExtensions { .setRollingPeriod(ROLLING_PERIOD) .setTransmissionRiskLevel(riskValue) .build() - } + } fun AppleLegacyKeyExchange.Key.convertToGoogleKey(): KeyExportFormat.TemporaryExposureKey = KeyExportFormat.TemporaryExposureKey.newBuilder() diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/UiStateHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/UiStateHelper.kt deleted file mode 100644 index 3a3a5e0c412..00000000000 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/UiStateHelper.kt +++ /dev/null @@ -1,24 +0,0 @@ -package de.rki.coronawarnapp.util - -import de.rki.coronawarnapp.storage.LocalData -import de.rki.coronawarnapp.util.DeviceUIState.PAIRED_NO_RESULT -import de.rki.coronawarnapp.util.DeviceUIState.PAIRED_POSITIVE -import de.rki.coronawarnapp.util.DeviceUIState.SUBMITTED_FINAL -import de.rki.coronawarnapp.util.DeviceUIState.UNPAIRED - -object UiStateHelper { - private fun uiState(): DeviceUIState { - var uiState = UNPAIRED - if (LocalData.registrationToken() != "") { - if (LocalData.inititalTestResultReceivedTimestamp() == null) { - uiState = PAIRED_NO_RESULT - } else if (LocalData.isAllowedToSubmitDiagnosisKeys() == true) { - uiState = PAIRED_POSITIVE - } - } else if (LocalData.numberOfSuccessfulSubmissions() == 1) { - uiState = SUBMITTED_FINAL - } - - return uiState - } -} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt index 5d19352eef0..590f0cee20d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterSubmissionHelper.kt @@ -7,145 +7,160 @@ import android.view.View import de.rki.coronawarnapp.CoronaWarnApplication import de.rki.coronawarnapp.R import de.rki.coronawarnapp.ui.submission.ApiRequestState -import de.rki.coronawarnapp.util.formatter.TestResult.INVALID -import de.rki.coronawarnapp.util.formatter.TestResult.NEGATIVE -import de.rki.coronawarnapp.util.formatter.TestResult.PENDING -import de.rki.coronawarnapp.util.formatter.TestResult.POSITIVE +import de.rki.coronawarnapp.util.DeviceUIState import java.util.Date -fun formatTestResultSpinnerVisible(testResultStatus: ApiRequestState?): Int = - formatVisibility(testResultStatus != ApiRequestState.SUCCESS) +fun formatTestResultSpinnerVisible(uiStateState: ApiRequestState?): Int = + formatVisibility(uiStateState != ApiRequestState.SUCCESS) -fun formatTestResultVisible(testResultStatus: ApiRequestState?): Int = - formatVisibility(testResultStatus == ApiRequestState.SUCCESS) +fun formatTestResultVisible(uiStateState: ApiRequestState?): Int = + formatVisibility(uiStateState == ApiRequestState.SUCCESS) -fun formatTestResultVirusNameTextVisible(testResult: TestResult?): Int { - return when (testResult) { - POSITIVE, NEGATIVE -> View.VISIBLE +fun formatTestResultVirusNameTextVisible(uiState: DeviceUIState?): Int { + return when (uiState) { + DeviceUIState.PAIRED_POSITIVE, + DeviceUIState.PAIRED_POSITIVE_TELETAN, + DeviceUIState.PAIRED_NEGATIVE -> View.VISIBLE else -> View.GONE } } -fun formatTestResultStatusTextVisible(testResult: TestResult?): Int { - return when (testResult) { - POSITIVE, NEGATIVE -> View.VISIBLE +fun formatTestResultStatusTextVisible(uiState: DeviceUIState?): Int { + return when (uiState) { + DeviceUIState.PAIRED_POSITIVE, + DeviceUIState.PAIRED_POSITIVE_TELETAN, + DeviceUIState.PAIRED_NEGATIVE -> View.VISIBLE else -> View.GONE } } -fun formatTestResultStatusText(testResult: TestResult?): String { +fun formatTestResultStatusText(uiState: DeviceUIState?): String { val appContext = CoronaWarnApplication.getAppContext() - return when (testResult) { - NEGATIVE -> appContext.getString(R.string.test_result_card_status_negative) - POSITIVE -> appContext.getString(R.string.test_result_card_status_positive) + return when (uiState) { + DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.test_result_card_status_negative) + DeviceUIState.PAIRED_POSITIVE, + DeviceUIState.PAIRED_POSITIVE_TELETAN -> appContext.getString(R.string.test_result_card_status_positive) else -> appContext.getString(R.string.test_result_card_status_invalid) } } -fun formatTestResultStatusColor(testResult: TestResult?): Int { +fun formatTestResultStatusColor(uiState: DeviceUIState?): Int { val appContext = CoronaWarnApplication.getAppContext() - return when (testResult) { - NEGATIVE -> appContext.getColor(R.color.colorGreen) - POSITIVE -> appContext.getColor(R.color.colorRed) + return when (uiState) { + DeviceUIState.PAIRED_NEGATIVE -> appContext.getColor(R.color.colorGreen) + DeviceUIState.PAIRED_POSITIVE, + DeviceUIState.PAIRED_POSITIVE_TELETAN -> appContext.getColor(R.color.colorRed) else -> appContext.getColor(R.color.colorRed) } } -fun formatTestStatusIcon(testResult: TestResult?): Drawable? { +fun formatTestStatusIcon(uiState: DeviceUIState?): Drawable? { val appContext = CoronaWarnApplication.getAppContext() // TODO Replace with real drawables when design is finished - return when (testResult) { - PENDING -> appContext.getDrawable(R.drawable.ic_test_result_illustration_pending) - POSITIVE -> appContext.getDrawable(R.drawable.ic_test_result_illustration_positive) - NEGATIVE -> appContext.getDrawable(R.drawable.ic_main_illustration_negative) - INVALID -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid) + return when (uiState) { + DeviceUIState.PAIRED_NO_RESULT -> appContext.getDrawable(R.drawable.ic_test_result_illustration_pending) + DeviceUIState.PAIRED_POSITIVE_TELETAN, + DeviceUIState.PAIRED_POSITIVE -> appContext.getDrawable(R.drawable.ic_test_result_illustration_positive) + DeviceUIState.PAIRED_NEGATIVE -> appContext.getDrawable(R.drawable.ic_main_illustration_negative) + DeviceUIState.PAIRED_ERROR -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid) else -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid) } } -fun formatTestResultInvalidStatusTextVisible(testResult: TestResult?): Int = - formatVisibility(testResult == INVALID) +fun formatTestResultInvalidStatusTextVisible(uiState: DeviceUIState?): Int = + formatVisibility(uiState == DeviceUIState.PAIRED_ERROR) -fun formatTestResultPendingStatusTextVisible(testResult: TestResult?): Int = - formatVisibility(testResult == PENDING) +fun formatTestResultPendingStatusTextVisible(uiState: DeviceUIState?): Int = + formatVisibility(uiState == DeviceUIState.PAIRED_NO_RESULT) fun formatTestResultRegisteredAtText(registeredAt: Date?): String { val appContext = CoronaWarnApplication.getAppContext() return appContext.getString(R.string.test_result_card_registered_at_text).format(registeredAt) } -fun formatTestResultPendingStepsVisible(testResult: TestResult?): Int = - formatVisibility(testResult == PENDING) +fun formatTestResultPendingStepsVisible(uiState: DeviceUIState?): Int = + formatVisibility(uiState == DeviceUIState.PAIRED_NO_RESULT) -fun formatTestResultNegativeStepsVisible(testResult: TestResult?): Int = - formatVisibility(testResult == NEGATIVE) +fun formatTestResultNegativeStepsVisible(uiState: DeviceUIState?): Int = + formatVisibility(uiState == DeviceUIState.PAIRED_NEGATIVE) -fun formatTestResultPositiveStepsVisible(testResult: TestResult?): Int = - formatVisibility(testResult == POSITIVE) +fun formatTestResultPositiveStepsVisible(uiState: DeviceUIState?): Int = + formatVisibility(uiState == DeviceUIState.PAIRED_POSITIVE || uiState == DeviceUIState.PAIRED_POSITIVE_TELETAN) -fun formatTestResultInvalidStepsVisible(testResult: TestResult?): Int = - formatVisibility(testResult == INVALID) +fun formatTestResultInvalidStepsVisible(uiState: DeviceUIState?): Int = + formatVisibility(uiState == DeviceUIState.PAIRED_ERROR) -fun formatSubmissionStatusCardContentTitleText(testResult: TestResult?): String { +fun formatSubmissionStatusCardContentTitleText(uiState: DeviceUIState?): String { val appContext = CoronaWarnApplication.getAppContext() - return when (testResult) { - INVALID, NEGATIVE, POSITIVE -> appContext.getString(R.string.submission_status_card_title_available) - PENDING -> appContext.getString(R.string.submission_status_card_title_pending) + return when (uiState) { + DeviceUIState.PAIRED_ERROR, + DeviceUIState.PAIRED_NEGATIVE, + DeviceUIState.PAIRED_POSITIVE_TELETAN, + DeviceUIState.PAIRED_POSITIVE -> appContext.getString(R.string.submission_status_card_title_available) + DeviceUIState.PAIRED_NO_RESULT -> appContext.getString(R.string.submission_status_card_title_pending) else -> appContext.getString(R.string.submission_status_card_title_pending) } } -fun formatSubmissionStatusCardContentBodyText(testResult: TestResult?): String { +fun formatSubmissionStatusCardContentBodyText(uiState: DeviceUIState?): String { val appContext = CoronaWarnApplication.getAppContext() - return when (testResult) { - INVALID -> appContext.getString(R.string.submission_status_card_body_invalid) - NEGATIVE -> appContext.getString(R.string.submission_status_card_body_negative) - POSITIVE -> appContext.getString(R.string.submission_status_card_body_positive) - PENDING -> appContext.getString(R.string.submission_status_card_body_pending) + return when (uiState) { + DeviceUIState.PAIRED_ERROR -> appContext.getString(R.string.submission_status_card_body_invalid) + DeviceUIState.PAIRED_NEGATIVE -> appContext.getString(R.string.submission_status_card_body_negative) + DeviceUIState.PAIRED_POSITIVE, + DeviceUIState.PAIRED_POSITIVE_TELETAN -> appContext.getString(R.string.submission_status_card_body_positive) + DeviceUIState.PAIRED_NO_RESULT -> appContext.getString(R.string.submission_status_card_body_pending) else -> appContext.getString(R.string.submission_status_card_body_pending) } } -fun formatSubmissionStatusCardContentButtonText(testResult: TestResult?): String { +fun formatSubmissionStatusCardContentButtonText(uiState: DeviceUIState?): String { val appContext = CoronaWarnApplication.getAppContext() - return when (testResult) { - INVALID, NEGATIVE, POSITIVE -> appContext.getString(R.string.submission_status_card_button_show_results) + return when (uiState) { + DeviceUIState.PAIRED_ERROR, + DeviceUIState.PAIRED_NEGATIVE, + DeviceUIState.PAIRED_POSITIVE_TELETAN, + DeviceUIState.PAIRED_POSITIVE -> appContext.getString(R.string.submission_status_card_button_show_results) else -> appContext.getString(R.string.submission_status_card_button_show_details) } } -fun formatSubmissionStatusCardContentStatusTextVisible(testResult: TestResult?): Int { - return when (testResult) { - POSITIVE, NEGATIVE, INVALID -> View.VISIBLE +fun formatSubmissionStatusCardContentStatusTextVisible(uiState: DeviceUIState?): Int { + return when (uiState) { + DeviceUIState.PAIRED_POSITIVE, + DeviceUIState.PAIRED_POSITIVE_TELETAN, + DeviceUIState.PAIRED_NEGATIVE, + DeviceUIState.PAIRED_ERROR -> View.VISIBLE else -> View.GONE } } -fun formatSubmissionStatusCardContentIcon(testResult: TestResult?): Drawable? { +fun formatSubmissionStatusCardContentIcon(uiState: DeviceUIState?): Drawable? { val appContext = CoronaWarnApplication.getAppContext() // TODO Replace with real drawables when design is finished - return when (testResult) { - PENDING -> appContext.getDrawable(R.drawable.ic_main_illustration_pending) - POSITIVE -> appContext.getDrawable(R.drawable.ic_main_illustration_pending) - NEGATIVE -> appContext.getDrawable(R.drawable.ic_main_illustration_negative) - INVALID -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid) + return when (uiState) { + DeviceUIState.PAIRED_NO_RESULT -> appContext.getDrawable(R.drawable.ic_main_illustration_pending) + DeviceUIState.PAIRED_POSITIVE, + DeviceUIState.PAIRED_POSITIVE_TELETAN -> appContext.getDrawable(R.drawable.ic_main_illustration_pending) + DeviceUIState.PAIRED_NEGATIVE -> appContext.getDrawable(R.drawable.ic_main_illustration_negative) + DeviceUIState.PAIRED_ERROR -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid) else -> appContext.getDrawable(R.drawable.ic_main_illustration_invalid) } } fun formatSubmissionStatusCardFetchingVisible( deviceRegistered: Boolean?, - testResultState: ApiRequestState? + uiStateState: ApiRequestState? ): Int = formatVisibility( deviceRegistered == true && ( - testResultState == ApiRequestState.STARTED || - testResultState == ApiRequestState.FAILED) + uiStateState == ApiRequestState.STARTED || + uiStateState == ApiRequestState.FAILED) ) fun formatSubmissionStatusCardContentVisible( deviceRegistered: Boolean?, - testResultState: ApiRequestState? -): Int = formatVisibility(deviceRegistered == true && testResultState == ApiRequestState.SUCCESS) + uiStateState: ApiRequestState? +): Int = formatVisibility(deviceRegistered == true && uiStateState == ApiRequestState.SUCCESS) fun formatSubmissionTanButtonTint(isValidTanFormat: Boolean) = formatColor( isValidTanFormat, @@ -159,11 +174,25 @@ fun formatSubmissionTanButtonTextColor(isValidTanFormat: Boolean) = formatColor( R.color.colorGreyDisabled ) -fun formatShowSubmissionStatusCard(testResult: TestResult?): Int = - formatVisibility(testResult != POSITIVE) - -fun formatShowSubmissionStatusPositiveCard(testResult: TestResult?): Int = - formatVisibility(testResult == POSITIVE) - -fun formatShowRiskStatusCard(testResult: TestResult?): Int = - formatVisibility(testResult != POSITIVE) +fun formatShowSubmissionStatusCard(deviceUiState: DeviceUIState?): Int = + formatVisibility( + deviceUiState != DeviceUIState.PAIRED_POSITIVE && + deviceUiState != DeviceUIState.PAIRED_POSITIVE_TELETAN && + deviceUiState != DeviceUIState.SUBMITTED_FINAL + ) + +fun formatShowSubmissionStatusPositiveCard(deviceUiState: DeviceUIState?): Int = + formatVisibility( + deviceUiState == DeviceUIState.PAIRED_POSITIVE || + deviceUiState == DeviceUIState.PAIRED_POSITIVE_TELETAN + ) + +fun formatShowSubmissionDoneCard(deviceUiState: DeviceUIState?): Int = + formatVisibility(deviceUiState == DeviceUIState.SUBMITTED_FINAL) + +fun formatShowRiskStatusCard(deviceUiState: DeviceUIState?): Int = + formatVisibility( + deviceUiState != DeviceUIState.PAIRED_POSITIVE && + deviceUiState != DeviceUIState.PAIRED_POSITIVE_TELETAN && + deviceUiState != DeviceUIState.SUBMITTED_FINAL + ) diff --git a/Corona-Warn-App/src/main/res/drawable/ic_main_overview_circle.xml b/Corona-Warn-App/src/main/res/drawable/ic_main_overview_circle.xml index 84d7b629759..1aa46b8b109 100644 --- a/Corona-Warn-App/src/main/res/drawable/ic_main_overview_circle.xml +++ b/Corona-Warn-App/src/main/res/drawable/ic_main_overview_circle.xml @@ -3,10 +3,10 @@ android:height="42dp" android:viewportWidth="40" android:viewportHeight="42"> - + diff --git a/Corona-Warn-App/src/main/res/drawable/ic_settings_reset_circle.xml b/Corona-Warn-App/src/main/res/drawable/ic_settings_reset_circle.xml index ded4098d212..b9f5b384bcc 100644 --- a/Corona-Warn-App/src/main/res/drawable/ic_settings_reset_circle.xml +++ b/Corona-Warn-App/src/main/res/drawable/ic_settings_reset_circle.xml @@ -3,26 +3,26 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> - - - + + + diff --git a/Corona-Warn-App/src/main/res/layout/fragment_main.xml b/Corona-Warn-App/src/main/res/layout/fragment_main.xml index a9ab393c0b0..dfaba52e58a 100644 --- a/Corona-Warn-App/src/main/res/layout/fragment_main.xml +++ b/Corona-Warn-App/src/main/res/layout/fragment_main.xml @@ -126,10 +126,10 @@ + + + + + + + + app:layout_constraintTop_toBottomOf="@id/settings_reset_button_delete" + app:layout_constraintVertical_bias="0" /> - - - - - - + app:layout_constraintTop_toTopOf="@+id/guideline_top" />