diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/SubmissionTanInvalidException.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/SubmissionTanInvalidException.kt new file mode 100644 index 0000000000000000000000000000000000000000..55b2acb7cdec3cf93d9a5984555c4fa8ff330afe --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/SubmissionTanInvalidException.kt @@ -0,0 +1,28 @@ +/****************************************************************************** + * Corona-Warn-App * + * * + * SAP SE and all other contributors / * + * copyright owners license this file to you under the Apache * + * License, Version 2.0 (the "License"); you may not use this * + * file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ******************************************************************************/ + +package de.rki.coronawarnapp.exception + +/** + * An Exception thrown when an error occurs inside the [de.rki.coronawarnapp.http.WebRequestBuilder] + * + * @param message an Exception thrown inside the WebRequestBuilder + * @param cause the cause of the error + */ +class SubmissionTanInvalidException(message: String, cause: Throwable) : Exception(message, cause) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/TestAlreadyPairedException.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/TestAlreadyPairedException.kt new file mode 100644 index 0000000000000000000000000000000000000000..b2af0b017dc78c66307862b0fb7486ab61ba77dc --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/TestAlreadyPairedException.kt @@ -0,0 +1,28 @@ +/****************************************************************************** + * Corona-Warn-App * + * * + * SAP SE and all other contributors / * + * copyright owners license this file to you under the Apache * + * License, Version 2.0 (the "License"); you may not use this * + * file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ******************************************************************************/ + +package de.rki.coronawarnapp.exception + +/** + * An Exception thrown when an error occurs inside the [de.rki.coronawarnapp.http.WebRequestBuilder] + * + * @param message an Exception thrown inside the WebRequestBuilder + * @param cause the cause of the error + */ +class TestAlreadyPairedException(message: String, cause: Throwable) : Exception(message, cause) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/TestPairingInvalidException.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/TestPairingInvalidException.kt new file mode 100644 index 0000000000000000000000000000000000000000..77619440763a0013c56848bdeb4267ea0bda7f26 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/TestPairingInvalidException.kt @@ -0,0 +1,28 @@ +/****************************************************************************** + * Corona-Warn-App * + * * + * SAP SE and all other contributors / * + * copyright owners license this file to you under the Apache * + * License, Version 2.0 (the "License"); you may not use this * + * file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ******************************************************************************/ + +package de.rki.coronawarnapp.exception + +/** + * An Exception thrown when an error occurs inside the [de.rki.coronawarnapp.http.WebRequestBuilder] + * + * @param message an Exception thrown inside the WebRequestBuilder + * @param cause the cause of the error + */ +class TestPairingInvalidException(message: String, cause: Throwable) : Exception(message, cause) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstants.kt index beef25125312cb51f5bde31a23a251ba8588ad63..f7a653b72680251ebde926dfa2add83cbc7a771e 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstants.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyConstants.kt @@ -77,4 +77,6 @@ object DiagnosisKeyConstants { /** Available Dates URL built from CDN URL's and REST resources */ val AVAILABLE_DATES_URL = "$DIAGNOSIS_KEYS_DOWNLOAD_URL/$COUNTRY/$CURRENT_COUNTRY/$DATE" + + const val SERVER_ERROR_CODE_403 = 403 } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyService.kt index 24682d27e24334a78c12e7e8438a41656be37b80..e30de86ea5638e506f54bbe7e1fa17af954907ae 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyService.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/diagnosiskey/DiagnosisKeyService.kt @@ -23,7 +23,10 @@ import KeyExportFormat import android.util.Log import de.rki.coronawarnapp.exception.DiagnosisKeyRetrievalException import de.rki.coronawarnapp.exception.DiagnosisKeySubmissionException +import de.rki.coronawarnapp.exception.SubmissionTanInvalidException import de.rki.coronawarnapp.http.WebRequestBuilder +import de.rki.coronawarnapp.service.diagnosiskey.DiagnosisKeyConstants.SERVER_ERROR_CODE_403 +import retrofit2.HttpException /** * The Diagnosis Key Service is used to interact with the Server to submit and retrieve keys through @@ -54,8 +57,14 @@ object DiagnosisKeyService { false, keysToReport ) - } catch (e: Exception) { - throw DiagnosisKeySubmissionException(e) + } catch (e: HttpException) { + if (e.code() == SERVER_ERROR_CODE_403) { + throw SubmissionTanInvalidException( + "the test paring to the device is invalid", + e + ) + } + throw e } } } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt index a99128c90139e6e25660ee52dcda1740142288d6..4150a275b99715addd407de02bd75a9ce8801416 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/submission/SubmissionConstants.kt @@ -20,4 +20,6 @@ object SubmissionConstants { const val MAX_QR_CODE_LENGTH = 150 const val MAX_GUID_LENGTH = 80 const val GUID_SEPARATOR = '?' + + const val SERVER_ERROR_CODE_400 = 400 } 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 c50399d451d64d9d6df4c21c22525e09ef3cf362..efbbe6e5adb8c12eb209fada488c292634c0f44d 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 @@ -2,24 +2,38 @@ package de.rki.coronawarnapp.service.submission import de.rki.coronawarnapp.exception.NoGUIDOrTANSetException import de.rki.coronawarnapp.exception.NoRegistrationTokenSetException +import de.rki.coronawarnapp.exception.TestAlreadyPairedException +import de.rki.coronawarnapp.exception.TestPairingInvalidException import de.rki.coronawarnapp.http.WebRequestBuilder import de.rki.coronawarnapp.service.submission.SubmissionConstants.QR_CODE_KEY_TYPE +import de.rki.coronawarnapp.service.submission.SubmissionConstants.SERVER_ERROR_CODE_400 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 +import retrofit2.HttpException object SubmissionService { suspend fun asyncRegisterDevice() { - val testGUID = LocalData.testGUID() - val testTAN = LocalData.teletan() - - when { - testGUID != null -> asyncRegisterDeviceViaGUID(testGUID) - testTAN != null -> asyncRegisterDeviceViaTAN(testTAN) - else -> throw NoGUIDOrTANSetException() + try { + val testGUID = LocalData.testGUID() + val testTAN = LocalData.teletan() + + when { + testGUID != null -> asyncRegisterDeviceViaGUID(testGUID) + testTAN != null -> asyncRegisterDeviceViaTAN(testTAN) + else -> throw NoGUIDOrTANSetException() + } + LocalData.devicePairingSuccessfulTimestamp(System.currentTimeMillis()) + } catch (err: HttpException) { + if (err.code() == SERVER_ERROR_CODE_400) { + throw TestAlreadyPairedException( + "the test was already paired to a different device", + err + ) + } + throw err } - LocalData.devicePairingSuccessfulTimestamp(System.currentTimeMillis()) } private suspend fun asyncRegisterDeviceViaGUID(guid: String) { @@ -45,8 +59,17 @@ object SubmissionService { } suspend fun asyncRequestAuthCode(registrationToken: String): String { - val authCode = WebRequestBuilder.asyncGetTan(registrationToken) - return authCode + try { + return WebRequestBuilder.asyncGetTan(registrationToken) + } catch (err: HttpException) { + if (err.code() == SERVER_ERROR_CODE_400) { + throw TestPairingInvalidException( + "the test paring to the device is invalid", + err + ) + } + throw err + } } suspend fun asyncSubmitExposureKeys() { @@ -88,10 +111,6 @@ object SubmissionService { LocalData.devicePairingSuccessfulTimestamp(0L) } - private fun deleteAuthCode() { - LocalData.authCode(null) - } - private fun deleteTeleTAN() { LocalData.teletan(null) } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionRegisterDeviceFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionRegisterDeviceFragment.kt index de5655f4a419e237b74ca1f6c6cdea45f6cad8cb..6a49eba8ca92c452b53d07b1110b19a20566f39d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionRegisterDeviceFragment.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionRegisterDeviceFragment.kt @@ -6,9 +6,13 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.activityViewModels import androidx.lifecycle.Observer +import de.rki.coronawarnapp.R import de.rki.coronawarnapp.databinding.FragmentSubmissionRegisterDeviceBinding +import de.rki.coronawarnapp.exception.TestAlreadyPairedException import de.rki.coronawarnapp.ui.BaseFragment import de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel +import de.rki.coronawarnapp.util.DialogHelper +import retrofit2.HttpException class SubmissionRegisterDeviceFragment : BaseFragment() { private val viewModel: SubmissionViewModel by activityViewModels() @@ -30,6 +34,46 @@ class SubmissionRegisterDeviceFragment : BaseFragment() { _binding = null } + private fun navigateToDispatchScreen() = doNavigate( + SubmissionRegisterDeviceFragmentDirections + .actionSubmissionRegisterDeviceFragmentToSubmissionDispatcherFragment() + ) + + private fun buildErrorDialog(exception: Exception): DialogHelper.DialogInstance { + return when (exception) { + is TestAlreadyPairedException -> DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_test_paired_title, + R.string.submission_error_dialog_web_test_paired_body, + R.string.submission_error_dialog_web_test_paired_button_positive, + null, + true, + ::navigateToDispatchScreen + ) + is HttpException -> DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_generic_error_title, + getString( + R.string.submission_error_dialog_web_generic_network_error_body, + exception.code() + ), + R.string.submission_error_dialog_web_generic_error_button_positive, + null, + true, + ::navigateToDispatchScreen + ) + else -> DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_generic_error_title, + R.string.submission_error_dialog_web_generic_error_body, + R.string.submission_error_dialog_web_generic_error_button_positive, + null, + true, + ::navigateToDispatchScreen + ) + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -41,6 +85,12 @@ class SubmissionRegisterDeviceFragment : BaseFragment() { ) } }) + + viewModel.registrationError.observe(viewLifecycleOwner, Observer { + if (it != null) { + DialogHelper.showDialog(buildErrorDialog(it)) + } + }) } override fun onResume() { 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 7fc0b62982dad204ebd94c0cc3b84db311d32972..2322c093d30d091e4c13cca61a2faa745ccfdbca 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 @@ -9,11 +9,14 @@ 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.exception.SubmissionTanInvalidException +import de.rki.coronawarnapp.exception.TestPairingInvalidException 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 +import retrofit2.HttpException class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), InternalExposureNotificationPermissionHelper.Callback { @@ -66,10 +69,60 @@ class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), _binding = null } + private fun buildErrorDialog(exception: Exception): DialogHelper.DialogInstance { + return when (exception) { + is TestPairingInvalidException -> DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_paring_invalid_title, + R.string.submission_error_dialog_web_paring_invalid_body, + R.string.submission_error_dialog_web_paring_invalid_button_positive, + null, + true, + ::navigateToSubmissionResultFragment + ) + is SubmissionTanInvalidException -> DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_tan_invalid_title, + R.string.submission_error_dialog_web_tan_invalid_body, + R.string.submission_error_dialog_web_tan_invalid_button_positive, + null, + true, + ::navigateToSubmissionResultFragment + ) + is HttpException -> DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_generic_error_title, + getString( + R.string.submission_error_dialog_web_generic_network_error_body, + exception.code() + ), + R.string.submission_error_dialog_web_generic_error_button_positive, + null, + true, + ::navigateToSubmissionResultFragment + ) + else -> DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_generic_error_title, + R.string.submission_error_dialog_web_generic_error_body, + R.string.submission_error_dialog_web_generic_error_button_positive, + null, + true, + ::navigateToSubmissionResultFragment + ) + } + } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() + submissionViewModel.submissionError.observe(viewLifecycleOwner, Observer { + if (it != null) { + DialogHelper.showDialog(buildErrorDialog(it)) + } + }) + submissionViewModel.submissionState.observe(viewLifecycleOwner, Observer { if (it == ApiRequestState.SUCCESS) { doNavigate( @@ -85,13 +138,16 @@ class SubmissionResultPositiveOtherWarningFragment : BaseFragment(), initiateWarningOthers() } binding.submissionPositiveOtherWarningHeader.headerButtonBack.buttonIcon.setOnClickListener { - doNavigate( - SubmissionResultPositiveOtherWarningFragmentDirections - .actionSubmissionResultPositiveOtherWarningFragmentToSubmissionResultFragment() - ) + navigateToSubmissionResultFragment() } } + private fun navigateToSubmissionResultFragment() = + doNavigate( + SubmissionResultPositiveOtherWarningFragmentDirections + .actionSubmissionResultPositiveOtherWarningFragmentToSubmissionResultFragment() + ) + private fun initiateWarningOthers() { if (tracingViewModel.isTracingEnabled.value != true) { val tracingRequiredDialog = DialogHelper.DialogInstance( 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 553ce28b902a44cac9b0d6cbf27c9251de4b9862..737e8f6e38a1b7bcd29260d52a91378d8dab725a 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,12 +5,14 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Observer 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 +import retrofit2.HttpException /** * A simple [BaseFragment] subclass. @@ -39,6 +41,35 @@ class SubmissionTestResultFragment : BaseFragment() { return binding.root } + private fun navigateToMainScreen() = + doNavigate(SubmissionTestResultFragmentDirections.actionSubmissionResultFragmentToMainFragment()) + + private fun buildErrorDialog(exception: Exception): DialogHelper.DialogInstance { + return when (exception) { + is HttpException -> DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_generic_error_title, + getString( + R.string.submission_error_dialog_web_generic_network_error_body, + exception.code() + ), + R.string.submission_error_dialog_web_generic_error_button_positive, + null, + true, + ::navigateToMainScreen + ) + else -> DialogHelper.DialogInstance( + requireActivity(), + R.string.submission_error_dialog_web_generic_error_title, + R.string.submission_error_dialog_web_generic_error_body, + R.string.submission_error_dialog_web_generic_error_button_positive, + null, + true, + ::navigateToMainScreen + ) + } + } + override fun onDestroyView() { super.onDestroyView() _binding = null @@ -47,6 +78,12 @@ class SubmissionTestResultFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setButtonOnClickListener() + + submissionViewModel.uiStateError.observe(viewLifecycleOwner, Observer { + if (it != null) { + DialogHelper.showDialog(buildErrorDialog(it)) + } + }) } override fun onResume() { 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 de2bb9f5066be22b2fe90cd43af268fde93c8df7..bac24dc8dee99b1908a20fca81357b852e2654db 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 @@ -17,14 +17,26 @@ import java.util.Date class SubmissionViewModel : ViewModel() { private val _scanStatus = MutableLiveData(ScanStatus.STARTED) + private val _registrationState = MutableLiveData(ApiRequestState.IDLE) + private val _registrationError = MutableLiveData<Exception?>(null) + private val _uiStateState = MutableLiveData(ApiRequestState.IDLE) + private val _uiStateError = MutableLiveData<Exception?>(null) + private val _submissionState = MutableLiveData(ApiRequestState.IDLE) + private val _submissionError = MutableLiveData<Exception?>(null) val scanStatus: LiveData<ScanStatus> = _scanStatus + val registrationState: LiveData<ApiRequestState> = _registrationState + val registrationError: LiveData<Exception?> = _registrationError + val uiStateState: LiveData<ApiRequestState> = _uiStateState + val uiStateError: LiveData<Exception?> = _uiStateError + val submissionState: LiveData<ApiRequestState> = _submissionState + val submissionError: LiveData<Exception?> = _submissionError val deviceRegistered get() = LocalData.registrationToken() != null @@ -34,13 +46,25 @@ class SubmissionViewModel : ViewModel() { SubmissionRepository.deviceUIState fun submitDiagnosisKeys() = - executeRequestWithState(SubmissionService::asyncSubmitExposureKeys, _submissionState) + executeRequestWithState( + SubmissionService::asyncSubmitExposureKeys, + _submissionState, + _submissionError + ) fun doDeviceRegistration() = - executeRequestWithState(SubmissionService::asyncRegisterDevice, _registrationState) + executeRequestWithState( + SubmissionService::asyncRegisterDevice, + _registrationState, + _registrationError + ) fun refreshDeviceUIState() = - executeRequestWithState(SubmissionRepository::refreshUIState, _uiStateState) + executeRequestWithState( + SubmissionRepository::refreshUIState, + _uiStateState, + _uiStateError + ) fun validateAndStoreTestGUID(scanResult: String) { if (SubmissionService.containsValidGUID(scanResult)) { @@ -65,7 +89,8 @@ class SubmissionViewModel : ViewModel() { private fun executeRequestWithState( apiRequest: suspend () -> Unit, - state: MutableLiveData<ApiRequestState> + state: MutableLiveData<ApiRequestState>, + exceptionLiveData: MutableLiveData<Exception?>? = null ) { state.value = ApiRequestState.STARTED viewModelScope.launch { @@ -73,6 +98,7 @@ class SubmissionViewModel : ViewModel() { apiRequest() state.value = ApiRequestState.SUCCESS } catch (err: Exception) { + exceptionLiveData?.value = err state.value = ApiRequestState.FAILED err.report(ExceptionCategory.INTERNAL) } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt index 5c07fbd3315290a9e792a23e696fe4533a595747..70bcbddee65cd6034ad29ec7c16e3b0ae9673625 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/DialogHelper.kt @@ -34,6 +34,26 @@ object DialogHelper { positiveButtonFunction, negativeButtonFunction ) + + constructor( + activity: Activity, + title: Int, + message: String, + positiveButton: Int, + negativeButton: Int? = null, + cancelable: Boolean? = true, + positiveButtonFunction: () -> Unit? = {}, + negativeButtonFunction: () -> Unit? = {} + ) : this( + activity, + activity.resources.getString(title), + message, + activity.resources.getString(positiveButton), + negativeButton?.let { activity.resources.getString(it) }, + cancelable, + positiveButtonFunction, + negativeButtonFunction + ) } fun showDialog( diff --git a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml index 3cae79a5ca3ee633dfbeeb4d0cc5fd30826d8314..c62db62a70fb78a82e4c3a3878014a3be5f14a48 100644 --- a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml +++ b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml @@ -293,6 +293,11 @@ android:id="@+id/action_submissionRegisterDeviceFragment_to_submissionResultFragment" app:destination="@id/submissionResultFragment" app:popUpTo="@id/mainFragment" /> + <action + android:id="@+id/action_submissionRegisterDeviceFragment_to_submissionDispatcherFragment" + app:destination="@id/submissionDispatcherFragment" + app:popUpTo="@id/submissionDispatcherFragment" + app:popUpToInclusive="true" /> </fragment> <fragment android:id="@+id/submissionDoneFragment" diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index bd8cd1b5a5d8c6bbea7abbdf92a81f01f71f5de8..6474fed1f768505b1c588fafb9540005d4825b9e 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -543,6 +543,36 @@ Submission ###################################### --> + <!-- XHED: Dialog title for generic web request error --> + <string name="submission_error_dialog_web_generic_error_title">Fehler</string> + <!-- XMSG: Dialog body for generic web request network error with status code --> + <string name="submission_error_dialog_web_generic_network_error_body">Es ist ein Verbindungsfehler aufgetreten (%1$d). Bitte versuchen Sie es erneut.</string> + <!-- XMSG: Dialog body for generic web request error without status code --> + <string name="submission_error_dialog_web_generic_error_body">Es ist ein Verbindungsfehler aufgetreten. Bitte versuchen Sie es erneut.</string> + <!-- XBUT: Positive button for generic web request error --> + <string name="submission_error_dialog_web_generic_error_button_positive">Zurück</string> + + <!-- XHED: Dialog title for already paired test error --> + <string name="submission_error_dialog_web_test_paired_title">Fehler</string> + <!-- XMSG: Dialog body for already paired test error --> + <string name="submission_error_dialog_web_test_paired_body">Der QR-Code / Die TAN ist ungültig oder wurde schon verwendet. Bitte versuchen Sie es erneut oder kontaktieren Sie die technische Hotline über App-Informationen → Kontakt.</string> + <!-- XBUT: Positive button for already paired test error --> + <string name="submission_error_dialog_web_test_paired_button_positive">Zurück</string> + + <!-- XHED: Dialog title for could not create submission tan --> + <string name="submission_error_dialog_web_paring_invalid_title">Fehler</string> + <!-- XMSG: Dialog body for could not create submission tan --> + <string name="submission_error_dialog_web_paring_invalid_body">Es konnte keine Übermittlungs-TAN erstellt werden. Bitte kontaktieren Sie die technische Hotline über App-Informationen → Kontakt.</string> + <!-- XBUT: Positive button for could not create submission tan --> + <string name="submission_error_dialog_web_paring_invalid_button_positive">Zurück</string> + + <!-- XHED: Dialog title for submission tan invalid --> + <string name="submission_error_dialog_web_tan_invalid_title">Fehler</string> + <!-- XMSG: Dialog body for submission tan invalid --> + <string name="submission_error_dialog_web_tan_invalid_body">Es konnte keine Übermittlungs-TAN erstellt werden. Bitte kontaktieren Sie die technische Hotline über App-Informationen → Kontakt.</string> + <!-- XBUT: Positive button for submission tan invalid --> + <string name="submission_error_dialog_web_tan_invalid_button_positive">Zurück</string> + <!-- Permission Rationale Dialog --> <string name="submission_qr_code_scan_permission_rationale_dialog_headline">Kamera Berechtigung benötigt</string> <string name="submission_qr_code_scan_permission_rationale_dialog_body">Bitte erlauben Sie die Autorisierung der Kamera für das Scannen von QR-Codes.</string> diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelCalculationTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelCalculationTest.kt index b4dd3853f5bdd59d5866577ef98ea18b02bd64ec..3a17562f085cf105e1e5822a365318e610f53712 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelCalculationTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/risk/RiskLevelCalculationTest.kt @@ -99,4 +99,4 @@ class RiskLevelCalculationTest { .setAttenuationDurations(intArray) .build() } -} \ No newline at end of file +} diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/VerificationServiceTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/VerificationServiceTest.kt index 4d0c06f803f98f441e216e1e6ddaf9723c6c54bf..16f069c15ba8d80bfbe487d13fa58ac088362843 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/VerificationServiceTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/service/submission/VerificationServiceTest.kt @@ -21,7 +21,7 @@ class VerificationServiceTest { equalTo(false) ) } - + @Test fun extractGUID() { val guid = "123456-12345678-1234-4DA7-B166-B86D85475064"