diff --git a/Corona-Warn-App/build.gradle b/Corona-Warn-App/build.gradle index 58d5fd5c02e869c3a4be36ba6cdf39b2ffed957e..3ad809646f4c48e689d121f8b6754bef13a89528 100644 --- a/Corona-Warn-App/build.gradle +++ b/Corona-Warn-App/build.gradle @@ -32,8 +32,8 @@ android { applicationId 'de.rki.coronawarnapp' minSdkVersion 23 targetSdkVersion 29 - versionCode 15 - versionName "0.8.8" + versionCode 16 + versionName "0.8.9" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" buildConfigField "String", "DOWNLOAD_CDN_URL", "\"$DOWNLOAD_CDN_URL\"" diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/WebRequestBuilder.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/WebRequestBuilder.kt index b33fa710367e3862882a3c9996551f5da374c2db..c7f8960056aa00d84f1b9f8631136a0ab23ba381 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/WebRequestBuilder.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/WebRequestBuilder.kt @@ -27,6 +27,9 @@ import de.rki.coronawarnapp.exception.ApplicationConfigurationInvalidException import de.rki.coronawarnapp.http.requests.RegistrationTokenRequest import de.rki.coronawarnapp.http.requests.ReqistrationRequest import de.rki.coronawarnapp.http.requests.TanRequestBody +import de.rki.coronawarnapp.http.service.DistributionService +import de.rki.coronawarnapp.http.service.SubmissionService +import de.rki.coronawarnapp.http.service.VerificationService import de.rki.coronawarnapp.server.protocols.ApplicationConfigurationOuterClass.ApplicationConfiguration import de.rki.coronawarnapp.service.diagnosiskey.DiagnosisKeyConstants import de.rki.coronawarnapp.service.submission.SubmissionConstants @@ -41,19 +44,36 @@ import java.io.File import java.util.Date import java.util.UUID -object WebRequestBuilder { - private val TAG: String? = WebRequestBuilder::class.simpleName - - private const val EXPORT_BINARY_FILE_NAME = "export.bin" - private const val EXPORT_SIGNATURE_FILE_NAME = "export.sig" - - private val serviceFactory = ServiceFactory() - - private val distributionService by lazy { serviceFactory.distributionService() } - private val verificationService by lazy { serviceFactory.verificationService() } - private val submissionService by lazy { serviceFactory.submissionService() } +class WebRequestBuilder( + private val distributionService: DistributionService, + private val verificationService: VerificationService, + private val submissionService: SubmissionService, + private val verificationKeys: VerificationKeys +) { + companion object { + private val TAG: String? = WebRequestBuilder::class.simpleName + private const val EXPORT_BINARY_FILE_NAME = "export.bin" + private const val EXPORT_SIGNATURE_FILE_NAME = "export.sig" + + @Volatile + private var instance: WebRequestBuilder? = null + + fun getInstance(): WebRequestBuilder { + return instance ?: synchronized(this) { + instance ?: buildWebRequestBuilder().also { instance = it } + } + } - private val verificationKeys = VerificationKeys() + private fun buildWebRequestBuilder(): WebRequestBuilder { + val serviceFactory = ServiceFactory() + return WebRequestBuilder( + serviceFactory.distributionService(), + serviceFactory.verificationService(), + serviceFactory.submissionService(), + VerificationKeys() + ) + } + } suspend fun asyncGetDateIndex(): List<String> = withContext(Dispatchers.IO) { return@withContext distributionService diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationHelper.kt index 4a1b47a284fb813af686f2ef71935ad612b1acfc..5501bad178d7a87a4504fd41bcee2074b2a38d7b 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/notification/NotificationHelper.kt @@ -92,7 +92,7 @@ object NotificationHelper { private fun buildNotification(title: String, content: String, visibility: Int): Notification? { val builder = NotificationCompat.Builder(CoronaWarnApplication.getAppContext(), channelId) .setSmallIcon(NotificationConstants.NOTIFICATION_SMALL_ICON) - .setPriority(NotificationCompat.PRIORITY_HIGH) + .setPriority(NotificationCompat.PRIORITY_MAX) .setVisibility(visibility) .setContentIntent(createPendingIntentToMainActivity()) .setAutoCancel(true) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/applicationconfiguration/ApplicationConfigurationService.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/applicationconfiguration/ApplicationConfigurationService.kt index 596ba0925338015533e0c50a5fd8e82cd3e1365a..137dc448bf064e38c726e9db5766356aa3b58265 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/applicationconfiguration/ApplicationConfigurationService.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/service/applicationconfiguration/ApplicationConfigurationService.kt @@ -6,8 +6,7 @@ import de.rki.coronawarnapp.server.protocols.ApplicationConfigurationOuterClass object ApplicationConfigurationService { suspend fun asyncRetrieveApplicationConfiguration(): ApplicationConfigurationOuterClass.ApplicationConfiguration { - return WebRequestBuilder - .asyncGetApplicationConfigurationFromServer() + return WebRequestBuilder.getInstance().asyncGetApplicationConfigurationFromServer() } suspend fun asyncRetrieveExposureConfiguration(): ExposureConfiguration = 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 fc4cc03daa3f1b55fb7581869329283a6973a5bf..bf03586ffb9c53deec91b86317f40047bf3a4471 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 @@ -48,7 +48,7 @@ object DiagnosisKeyService { */ suspend fun asyncSubmitKeys(authCode: String, keysToReport: List<KeyExportFormat.TemporaryExposureKey>) { Log.d(TAG, "Diagnosis Keys will be submitted.") - WebRequestBuilder.asyncSubmitKeysToServer( + WebRequestBuilder.getInstance().asyncSubmitKeysToServer( authCode, false, keysToReport 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 6cdd39fee0dc016c5cc81b382fc8a3da92d809f8..1f8f64b59edf6dbf3a5b9ed94a8d24de4a8bd004 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 @@ -24,7 +24,7 @@ object SubmissionService { private suspend fun asyncRegisterDeviceViaGUID(guid: String) { val registrationToken = - WebRequestBuilder.asyncGetRegistrationToken( + WebRequestBuilder.getInstance().asyncGetRegistrationToken( guid, QR_CODE_KEY_TYPE ) @@ -35,7 +35,7 @@ object SubmissionService { private suspend fun asyncRegisterDeviceViaTAN(tan: String) { val registrationToken = - WebRequestBuilder.asyncGetRegistrationToken( + WebRequestBuilder.getInstance().asyncGetRegistrationToken( tan, TELE_TAN_KEY_TYPE ) @@ -45,7 +45,7 @@ object SubmissionService { } suspend fun asyncRequestAuthCode(registrationToken: String): String { - return WebRequestBuilder.asyncGetTan(registrationToken) + return WebRequestBuilder.getInstance().asyncGetTan(registrationToken) } suspend fun asyncSubmitExposureKeys() { @@ -58,7 +58,7 @@ object SubmissionService { val registrationToken = LocalData.registrationToken() ?: throw NoRegistrationTokenSetException() return TestResult.fromInt( - WebRequestBuilder.asyncGetTestResult(registrationToken) + WebRequestBuilder.getInstance().asyncGetTestResult(registrationToken) ) } 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 3634469bef86a8e221bf079ddb0826aa109edc7e..e699c28da94d9565327d4eae0485f0fe0dc79378 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 @@ -77,25 +77,28 @@ class MainFragment : BaseFragment() { } private fun setButtonOnClickListener() { - binding.mainTest.submissionStatusCardFetching.submissionStatusCardFetchingButton.setOnClickListener { - doNavigate( - MainFragmentDirections.actionMainFragmentToSubmissionResultFragment() - ) + binding.mainTestUnregistered.submissionStatusCardUnregistered.setOnClickListener { + toSubmissionIntro() } - binding.mainTest.submissionStatusCardContent.submissionStatusCardContentButton.setOnClickListener { - doNavigate( - MainFragmentDirections.actionMainFragmentToSubmissionResultFragment() - ) + binding.mainTestUnregistered.submissionStatusCardUnregisteredButton.setOnClickListener { + toSubmissionIntro() } - binding.mainTestPositive.submissionStatusCardPositiveResultShowButton.setOnClickListener { + binding.mainTestDone.submissionStatusCardDone.setOnClickListener { doNavigate( - MainFragmentDirections.actionMainFragmentToSubmissionResultFragment() + MainFragmentDirections.actionMainFragmentToSubmissionDoneFragment() ) } - binding.mainTest.submissionStatusCardUnregistered.submissionStatusCardUnregisteredButton.setOnClickListener { - doNavigate( - MainFragmentDirections.actionMainFragmentToSubmissionIntroFragment() - ) + binding.mainTestResult.submissionStatusCardContent.setOnClickListener { + toSubmissionResult() + } + binding.mainTestResult.submissionStatusCardContentButton.setOnClickListener { + toSubmissionResult() + } + binding.mainTestPositive.submissionStatusCardPositive.setOnClickListener { + toSubmissionResult() + } + binding.mainTestPositive.submissionStatusCardPositiveButton.setOnClickListener { + toSubmissionResult() } binding.mainTracing.setOnClickListener { doNavigate(MainFragmentDirections.actionMainFragmentToSettingsTracingFragment()) @@ -122,6 +125,18 @@ class MainFragment : BaseFragment() { } } + private fun toSubmissionResult() { + doNavigate( + MainFragmentDirections.actionMainFragmentToSubmissionResultFragment() + ) + } + + private fun toSubmissionIntro() { + doNavigate( + MainFragmentDirections.actionMainFragmentToSubmissionIntroFragment() + ) + } + private fun showPopup(view: View) { val popup = PopupMenu(requireContext(), view) popup.inflate(R.menu.menu_main) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt index c18d49a015360e7b4747526b6a323afe69dd88cc..cae07743b57a1c5431a917d6a582d03244178564 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Transformations import androidx.lifecycle.ViewModel import de.rki.coronawarnapp.storage.SubmissionRepository +import de.rki.coronawarnapp.util.TanHelper class SubmissionTanViewModel : ViewModel() { @@ -16,7 +17,21 @@ class SubmissionTanViewModel : ViewModel() { val isValidTanFormat = Transformations.map(tan) { - it != null && it.length == TanConstants.MAX_LENGTH + it != null && + it.length == TanConstants.MAX_LENGTH && + TanHelper.isChecksumValid(it) && + TanHelper.allCharactersValid(it) + } + + val tanChecksumValid = + Transformations.map(tan) { + ((it !== null && it.trim().length == TanConstants.MAX_LENGTH) && + TanHelper.isChecksumValid(it).not()).not() + } + + val tanCharactersValid = + Transformations.map(tan) { + !((it != null) && TanHelper.allCharactersValid(it).not()) } fun storeTeletan() { diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt index b6be13be81def6ec21f396f0b89f278cdeb9fd6a..644cf1ee0f3aca6bb52e87b0fcca899b24065220 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanConstants.kt @@ -1,6 +1,6 @@ package de.rki.coronawarnapp.ui.submission object TanConstants { - const val MAX_LENGTH = 7 + const val MAX_LENGTH = 10 val ALPHA_NUMERIC_CHARS = ('a'..'z').plus('A'..'Z').plus('0'..'9') } diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt index 70cc48b6833364f5303cc7d9d7549f2962e58e7f..b7b02a82572a39e6528fb9ab183137028892fae2 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/submission/TanInput.kt @@ -8,6 +8,9 @@ import android.view.inputmethod.InputMethodManager import android.widget.FrameLayout import androidx.core.widget.doOnTextChanged import de.rki.coronawarnapp.R +import de.rki.coronawarnapp.ui.submission.TanConstants.MAX_LENGTH +import de.rki.coronawarnapp.util.TanHelper +import java.util.Locale import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_edittext import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_textview_1 import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_textview_2 @@ -16,6 +19,11 @@ import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_textview_4 import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_textview_5 import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_textview_6 import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_textview_7 +import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_textview_8 +import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_textview_9 +import kotlinx.android.synthetic.main.view_tan_input.view.tan_input_textview_10 +import kotlinx.android.synthetic.main.view_tan_input.view.dash_view_1 +import kotlinx.android.synthetic.main.view_tan_input.view.dash_view_2 class TanInput(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs) { @@ -30,7 +38,7 @@ class TanInput(context: Context, attrs: AttributeSet) : FrameLayout(context, att TanConstants.ALPHA_NUMERIC_CHARS.contains(it) } } - private val lengthFilter = InputFilter.LengthFilter(TanConstants.MAX_LENGTH) + private var lengthFilter = InputFilter.LengthFilter(MAX_LENGTH) var listener: ((String?) -> Unit)? = null @@ -41,6 +49,9 @@ class TanInput(context: Context, attrs: AttributeSet) : FrameLayout(context, att tan_input_edittext.filters = arrayOf(whitespaceFilter, alphaNumericFilter, lengthFilter) + dash_view_1.text = "-" + dash_view_2.text = "-" + // register listener tan_input_edittext.doOnTextChanged { text, _, _, _ -> updateTan(text) } setOnClickListener { showKeyboard() } @@ -56,9 +67,20 @@ class TanInput(context: Context, attrs: AttributeSet) : FrameLayout(context, att } } + private fun limitLength(length: Int?) { + lengthFilter = InputFilter.LengthFilter(if (length != null) length else MAX_LENGTH) + tan_input_edittext.filters = arrayOf(whitespaceFilter, alphaNumericFilter, lengthFilter) + } + private fun updateTan(text: CharSequence?) { - this.tan = text?.toString() + this.tan = text?.toString()?.toUpperCase(Locale.ROOT) updateDigits() + tan?.let { + limitLength( + if (TanHelper.allCharactersValid(it)) null + else it.length + ) + } notifyListener() } @@ -71,9 +93,24 @@ class TanInput(context: Context, attrs: AttributeSet) : FrameLayout(context, att tan_input_textview_4, tan_input_textview_5, tan_input_textview_6, - tan_input_textview_7 + tan_input_textview_7, + tan_input_textview_8, + tan_input_textview_9, + tan_input_textview_10 ).forEachIndexed { i, tanDigit -> tanDigit.text = digitAtIndex(i) + tanDigit.background = + if (digitAtIndex(i) == "") + resources.getDrawable(R.drawable.tan_input_digit, null) + else if (TanHelper.isTanCharacterValid(digitAtIndex(i))) + resources.getDrawable(R.drawable.tan_input_digit_entered, null) + else resources.getDrawable(R.drawable.tan_input_digit_error, null) + + tanDigit.setTextColor( + if (TanHelper.isTanCharacterValid(digitAtIndex(i))) + resources.getColor(R.color.colorTextSemanticNeutral, null) + else resources.getColor(R.color.colorTextSemanticRed, null) + ) } private fun digitAtIndex(index: Int): String = tan?.getOrNull(index)?.toString() ?: "" diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/CachedKeyFileHolder.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/CachedKeyFileHolder.kt index 9fe260c58c70dbc7a58117c63594756fba8d38ef..64b71b742bb75f97ab49e500079c237bd73b8c49 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/CachedKeyFileHolder.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/CachedKeyFileHolder.kt @@ -76,7 +76,7 @@ object CachedKeyFileHolder { return@withContext getLast3Hours(currentDate) .map { getURLForHour(currentDate.toServerFormat(), it) } .map { url -> async { - return@async WebRequestBuilder.asyncGetKeyFilesFromServer(url) + return@async WebRequestBuilder.getInstance().asyncGetKeyFilesFromServer(url) } }.awaitAll() } else { throw IllegalStateException( @@ -152,7 +152,7 @@ object CachedKeyFileHolder { */ private suspend fun String.createDayEntryForUrl() = keyCache.createEntry( this.generateCacheKeyFromString(), - WebRequestBuilder.asyncGetKeyFilesFromServer(this).toURI(), + WebRequestBuilder.getInstance().asyncGetKeyFilesFromServer(this).toURI(), DAY ) @@ -183,13 +183,13 @@ object CachedKeyFileHolder { * Get all dates from server based as formatted dates */ private suspend fun getDatesFromServer() = - WebRequestBuilder.asyncGetDateIndex() + WebRequestBuilder.getInstance().asyncGetDateIndex() /** * Get all hours from server based as formatted dates */ private suspend fun getHoursFromServer(day: Date) = - WebRequestBuilder.asyncGetHourIndex(day) + WebRequestBuilder.getInstance().asyncGetHourIndex(day) /** * TODO remove before release diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/TanHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/TanHelper.kt new file mode 100644 index 0000000000000000000000000000000000000000..7fa1562c70e11f15ba92758f2e813d96a15127a4 --- /dev/null +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/TanHelper.kt @@ -0,0 +1,35 @@ +package de.rki.coronawarnapp.util + +import de.rki.coronawarnapp.ui.submission.TanConstants.MAX_LENGTH +import java.nio.charset.StandardCharsets +import java.security.MessageDigest +import java.util.Locale + +object TanHelper { + private const val VALID_CHARACTERS = "23456789ABCDEFGHJKMNPQRSTUVWXYZ" + + fun isChecksumValid(tan: String): Boolean { + if (tan.trim().length != MAX_LENGTH) + return false + val subTan = tan.substring(0, MAX_LENGTH - 1).toUpperCase(Locale.ROOT) + val tanDigest = MessageDigest.getInstance("SHA-256") + .digest(subTan.toByteArray(StandardCharsets.US_ASCII)) + var checkChar = "%02x".format(tanDigest[0])[0] + if (checkChar == '0') checkChar = 'G' + if (checkChar == '1') checkChar = 'H' + + return checkChar.toUpperCase() == tan.last().toUpperCase() + } + + fun allCharactersValid(tan: String): Boolean { + for (character in tan) { + if (!isTanCharacterValid(character.toString())) + return false + } + return true + } + + fun isTanCharacterValid(character: String): Boolean { + return VALID_CHARACTERS.contains(character) + } +} diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt index 9b0914336fa973c0bbe8d948a6e3720b247d45d5..85b2671eb3bd01f9214bc2cb5c5c55eeb0da9f19 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/util/formatter/FormatterRiskHelper.kt @@ -2,12 +2,13 @@ package de.rki.coronawarnapp.util.formatter +import android.content.Context import android.content.res.ColorStateList import android.graphics.drawable.Drawable +import android.text.format.DateUtils import de.rki.coronawarnapp.CoronaWarnApplication import de.rki.coronawarnapp.R import de.rki.coronawarnapp.risk.RiskLevelConstants -import java.text.DateFormat import java.util.Date /*Texter*/ @@ -190,6 +191,15 @@ fun formatRiskActiveTracingDaysInRetentionPeriod( } } +fun formatRelativeDateTimeString(appContext: Context, date: Date): CharSequence? = + DateUtils.getRelativeDateTimeString( + appContext, + date.time, + DateUtils.DAY_IN_MILLIS, + DateUtils.DAY_IN_MILLIS * 2, + 0 + ) + /** * Formats the risk card text display of the last time diagnosis keys were * successfully fetched from the server @@ -211,9 +221,7 @@ fun formatTimeFetched( if (lastTimeDiagnosisKeysFetched != null) { appContext.getString( R.string.risk_card_body_time_fetched, - DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM).format( - lastTimeDiagnosisKeysFetched - ) + formatRelativeDateTimeString(appContext, lastTimeDiagnosisKeysFetched) ) } else { appContext.getString(R.string.risk_card_body_not_yet_fetched) @@ -228,10 +236,7 @@ fun formatTimeFetched( if (lastTimeDiagnosisKeysFetched != null) { appContext.getString( R.string.risk_card_body_time_fetched, - DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM) - .format( - lastTimeDiagnosisKeysFetched - ) + formatRelativeDateTimeString(appContext, lastTimeDiagnosisKeysFetched) ) } else { appContext.getString(R.string.risk_card_body_not_yet_fetched) 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 dbe3e29ed71c9d4c6116f0044da2aaf72f51bb13..7f16f3ed7ff0c62f1254e8213738e1b539fb6da7 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 @@ -74,7 +74,7 @@ fun formatTestStatusIcon(uiState: DeviceUIState?): Drawable? { 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_NEGATIVE -> appContext.getDrawable(R.drawable.ic_test_result_illustration_negative) DeviceUIState.PAIRED_ERROR -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid) else -> appContext.getDrawable(R.drawable.ic_test_result_illustration_invalid) } @@ -166,17 +166,17 @@ fun formatSubmissionStatusCardFetchingVisible( uiStateState == ApiRequestState.FAILED) ) -fun formatSubmissionStatusCardContentVisible( - deviceRegistered: Boolean?, - uiStateState: ApiRequestState? -): Int = formatVisibility(deviceRegistered == true && uiStateState == ApiRequestState.SUCCESS) +fun formatSubmissionStatusCardUnregisteredVisible( + deviceRegistered: Boolean? +): Int = formatVisibility(deviceRegistered == false) -fun formatShowSubmissionStatusCard(deviceUiState: DeviceUIState?): Int = - formatVisibility( - deviceUiState != DeviceUIState.PAIRED_POSITIVE && - deviceUiState != DeviceUIState.PAIRED_POSITIVE_TELETAN && - deviceUiState != DeviceUIState.SUBMITTED_FINAL - ) +fun formatSubmissionStatusCardContentVisible( + deviceUiState: DeviceUIState? +): Int = formatVisibility( + deviceUiState == DeviceUIState.PAIRED_ERROR || + deviceUiState == DeviceUIState.PAIRED_NEGATIVE || + deviceUiState == DeviceUIState.PAIRED_NO_RESULT +) fun formatShowSubmissionStatusPositiveCard(deviceUiState: DeviceUIState?): Int = formatVisibility( @@ -193,3 +193,8 @@ fun formatShowRiskStatusCard(deviceUiState: DeviceUIState?): Int = deviceUiState != DeviceUIState.PAIRED_POSITIVE_TELETAN && deviceUiState != DeviceUIState.SUBMITTED_FINAL ) + +fun formatShowTanCharacterError( + charactersValid: Boolean, + checksumValid: Boolean +): Int = formatVisibility(checksumValid && !charactersValid) diff --git a/Corona-Warn-App/src/main/res/color/card_dark.xml b/Corona-Warn-App/src/main/res/color/card_dark.xml new file mode 100644 index 0000000000000000000000000000000000000000..e20c80f49945275bf4f6a02fbd4ab89dca3185de --- /dev/null +++ b/Corona-Warn-App/src/main/res/color/card_dark.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@color/colorSurface2Pressed" android:state_pressed="true" /> <!-- pressed --> + <item android:color="@color/colorSurface2" /> <!-- default --> +</selector> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/drawable/card_dark.xml b/Corona-Warn-App/src/main/res/drawable/card_dark.xml new file mode 100644 index 0000000000000000000000000000000000000000..b09174ef0a833117701f490f245eb9423718c393 --- /dev/null +++ b/Corona-Warn-App/src/main/res/drawable/card_dark.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item> + <shape android:shape="rectangle"> + <corners android:radius="@dimen/radius_card" /> + <solid android:color="@color/card_dark" /> + </shape> + </item> +</selector> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/drawable/ic_icon_drilldowncard_dark.xml b/Corona-Warn-App/src/main/res/drawable/ic_icon_drilldowncard_dark.xml deleted file mode 100644 index ee2dcdb3abf857a3f3ef8eac1370af459a56d168..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/res/drawable/ic_icon_drilldowncard_dark.xml +++ /dev/null @@ -1,13 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="40dp" - android:height="44dp" - android:viewportWidth="40" - android:viewportHeight="44"> - <path - android:fillAlpha="0.6" - android:fillColor="#17191A" - android:fillType="evenOdd" - android:pathData="M32.9572,14.0808l-1.4942,1.5686l4.5525,4.7793l-14.0156,0l-0,2.0915l14.0156,0l-4.5525,4.7793l1.4942,1.5686l7.0428,-7.3937z" - android:strokeWidth="1" - android:strokeColor="#00000000" /> -</vector> diff --git a/Corona-Warn-App/src/main/res/drawable/ic_step_1.xml b/Corona-Warn-App/src/main/res/drawable/ic_step_1.xml deleted file mode 100644 index 45b7619813715d86a2674a15dd04062a07af6232..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/res/drawable/ic_step_1.xml +++ /dev/null @@ -1,6 +0,0 @@ -<vector android:height="40dp" android:viewportHeight="24" - android:viewportWidth="24" android:width="40dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillColor="#007FAD" android:fillType="nonZero" - android:pathData="M13,17C12.45,17 12,16.55 12,16L12,9L11,9C10.45,9 10,8.55 10,8C10,7.45 10.45,7 11,7L13,7C13.55,7 14,7.45 14,8L14,16C14,16.55 13.55,17 13,17Z" - android:strokeColor="#00000000" android:strokeWidth="1"/> -</vector> diff --git a/Corona-Warn-App/src/main/res/drawable/ic_step_2.xml b/Corona-Warn-App/src/main/res/drawable/ic_step_2.xml deleted file mode 100644 index 64729728a7d9d365bbc6e967176bfe02a05dce39..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/res/drawable/ic_step_2.xml +++ /dev/null @@ -1,6 +0,0 @@ -<vector android:height="40dp" android:viewportHeight="24" - android:viewportWidth="24" android:width="40dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillColor="#007FAD" android:fillType="nonZero" - android:pathData="M15,11C15,12.1 14.1,13 13,13L11,13L11,15L14,15C14.55,15 15,15.45 15,16C15,16.55 14.55,17 14,17L10,17C9.45,17 9,16.55 9,16L9,13C9,11.9 9.9,11 11,11L13,11L13,9L10,9C9.45,9 9,8.55 9,8C9,7.45 9.45,7 10,7L13,7C14.1,7 15,7.9 15,9L15,11Z" - android:strokeColor="#00000000" android:strokeWidth="1"/> -</vector> diff --git a/Corona-Warn-App/src/main/res/drawable/ic_step_background.xml b/Corona-Warn-App/src/main/res/drawable/ic_step_background.xml deleted file mode 100644 index b1270b99fb04d28dc7e525f7c0d7b14771236fab..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/res/drawable/ic_step_background.xml +++ /dev/null @@ -1,19 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="40dp" - android:height="40dp" - android:viewportWidth="40" - android:viewportHeight="40"> - <path - android:fillAlpha="0.1" - android:fillColor="#17191A" - android:fillType="evenOdd" - android:pathData="M20,32L20,32A0.5,0.5 0,0 1,20.5 32.5L20.5,151.5A0.5,0.5 0,0 1,20 152L20,152A0.5,0.5 0,0 1,19.5 151.5L19.5,32.5A0.5,0.5 0,0 1,20 32z" - android:strokeWidth="1" - android:strokeColor="#00000000" /> - <path - android:fillColor="#F5F5F5" - android:fillType="evenOdd" - android:pathData="M20,20m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0" - android:strokeWidth="1" - android:strokeColor="#00000000" /> -</vector> diff --git a/Corona-Warn-App/src/main/res/drawable/ic_test_result_illustration_positive_card.xml b/Corona-Warn-App/src/main/res/drawable/ic_test_result_illustration_positive_card.xml new file mode 100644 index 0000000000000000000000000000000000000000..f7af213827d95ff139dfe5c7fd87cf7d98e0df52 --- /dev/null +++ b/Corona-Warn-App/src/main/res/drawable/ic_test_result_illustration_positive_card.xml @@ -0,0 +1,130 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="80dp" + android:height="113dp" + android:viewportWidth="80" + android:viewportHeight="113"> + <group> + <clip-path + android:pathData="M0,0.5h80v112h-80z"/> + <path + android:pathData="M8.222,17.925l0,94.575l71.203,0l0,-76.558l-17.097,-18.017z" + android:strokeWidth="1" + android:fillColor="#EFEFEF" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M62.374,35.942l16.996,0l-16.996,-18.003z" + android:strokeWidth="1" + android:fillColor="#657888" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M35.774,99.55L29.286,99.55C28.18,99.55 27.284,98.654 27.284,97.548L27.284,91.06C27.284,89.953 28.18,89.058 29.286,89.058L35.774,89.058C36.88,89.058 37.776,89.953 37.776,91.06L37.776,97.548C37.776,98.654 36.88,99.55 35.774,99.55" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M61.111,99.55L54.62,99.55C53.515,99.55 52.619,98.654 52.619,97.549L52.619,91.058C52.619,89.953 53.515,89.058 54.62,89.058L61.111,89.058C62.216,89.058 63.112,89.953 63.112,91.058L63.112,97.549C63.112,98.654 62.216,99.55 61.111,99.55" + android:strokeWidth="1" + android:fillColor="#657888" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M25.409,59.165L64.443,59.165C65.209,59.225 65.689,59.762 65.689,60.498C65.689,61.145 65.209,61.865 64.443,61.831L25.409,61.831C24.404,61.865 23.924,61.234 23.924,60.498C23.924,59.762 24.404,59.225 25.409,59.165" + android:strokeWidth="1" + android:fillColor="#657888" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M25.409,44.764L64.443,44.764C65.209,44.824 65.689,45.361 65.689,46.097C65.689,46.743 65.209,47.464 64.443,47.429L25.409,47.429C24.404,47.464 23.924,46.832 23.924,46.097C23.924,45.361 24.404,44.824 25.409,44.764" + android:strokeWidth="1" + android:fillColor="#657888" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M25.409,73.327L64.443,73.327C65.209,73.387 65.689,73.924 65.689,74.66C65.689,75.306 65.209,76.027 64.443,75.992L25.409,75.992C24.404,76.027 23.924,75.395 23.924,74.66C23.924,73.924 24.404,73.387 25.409,73.327" + android:strokeWidth="1" + android:fillColor="#657888" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M35.713,91.303C35.593,91.295 35.476,91.347 35.402,91.442L31.466,96.284L29.464,94.155C29.38,94.046 29.241,93.995 29.107,94.023C28.973,94.049 28.865,94.149 28.828,94.281C28.792,94.413 28.832,94.554 28.934,94.647L31.223,97.085C31.295,97.16 31.396,97.201 31.5,97.197C31.605,97.193 31.702,97.143 31.767,97.062L35.97,91.901C36.06,91.795 36.081,91.649 36.026,91.522C35.972,91.396 35.851,91.311 35.713,91.303" + android:strokeWidth="1" + android:fillColor="#FFFFFF" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M35.741,90.804L35.625,90.804C35.384,90.822 35.158,90.941 35.008,91.134L31.438,95.524L29.828,93.812C29.659,93.589 29.327,93.466 29.005,93.533C28.692,93.594 28.434,93.832 28.347,94.146C28.271,94.423 28.335,94.713 28.514,94.929L30.858,97.427C31.033,97.609 31.272,97.706 31.519,97.696C31.769,97.687 32.001,97.569 32.157,97.374L36.358,92.216C36.564,91.973 36.615,91.624 36.485,91.323C36.373,91.061 36.138,90.874 35.862,90.819L35.741,90.804Z" + android:strokeWidth="1" + android:fillColor="#FFFFFF" + android:fillType="nonZero" + android:strokeColor="#00000000"/> + <path + android:pathData="M27.587,24.429C24.556,30.195 17.425,32.411 11.66,29.38C5.894,26.35 3.677,19.219 6.708,13.453C9.739,7.688 16.87,5.471 22.635,8.501C28.401,11.533 30.618,18.663 27.587,24.429" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M29.423,29.537C29.151,29.952 28.23,31.41 27.57,29.629C26.709,27.304 24.884,27.811 24.884,27.811L23.194,28.05L26.746,24.04C26.746,24.04 26.66,25.648 27.185,26.452C27.449,26.857 28.001,27.45 28.695,27.466C29.39,27.482 30.734,27.533 29.423,29.537" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M10.055,34.432C9.59,34.26 7.965,33.684 9.555,32.646C11.633,31.292 11.015,29.063 11.015,29.063L10.409,27.467L15.105,30.043C15.105,30.043 13.518,30.316 12.85,31.005C12.513,31.353 11.776,32.583 11.914,33.264C12.052,33.945 12.3,35.268 10.055,34.432" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M22.029,28.466C22.029,28.466 21.084,28.957 21.379,31.083C21.554,32.352 22.414,34.297 22.536,34.7C22.615,34.961 22.773,35.037 22.994,35.195C23.54,35.583 24.367,36.417 22.405,36.967C20.76,37.428 20.014,37.273 20.346,36.294C20.515,35.794 20.595,35.423 20.538,34.899C20.413,33.746 19.597,30.95 18.514,30.195C16.883,29.059 17.432,29.407 17.432,29.407L20.932,26.764L22.029,28.466Z" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M13.707,3.644C14.349,3.553 15.065,3.335 14.759,4.45C14.652,4.837 14.633,5.212 14.665,5.557C14.749,6.457 15.052,6.951 15.754,7.521L16.293,7.959L12.697,8.28C12.697,8.28 13.337,7.724 13.162,6.801C13.089,6.416 13.03,5.564 12.596,5.247C12.198,4.955 11.37,3.977 13.707,3.644" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M8.06,14.767C7.777,14.568 7.635,14.22 7.704,13.88C7.824,13.288 8.079,12.381 6.905,11.334C5.562,10.136 3.635,9.222 3.475,9.205C2.251,9.069 1.466,9.017 2.81,7.122C4.082,5.329 4.823,5.401 4.946,6.79C4.973,7.091 5.082,7.378 5.261,7.622C5.897,8.491 8.312,10.851 9.951,10.88C10.452,10.891 9.889,13.469 9.889,13.469C9.794,14.122 8.06,14.767 8.06,14.767" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M0.018,17.834C0.178,16.363 0.796,15.658 2.107,16.569C4.374,18.146 6.958,15.837 6.958,15.837L7.453,14.48L6.925,20.86C6.925,20.86 5.912,19.505 4.884,19.017C4.385,18.779 2.852,18.565 2.107,18.87C1.301,19.199 -0.182,19.669 0.018,17.834" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M9.977,26.272C9.977,26.272 8.532,24.837 6.559,26.335C4.586,27.834 4.198,28.251 4.198,28.251C4.198,28.251 2.587,31.521 0.896,28.929C-0.795,26.336 0.596,25.722 2.445,26.152C2.445,26.152 6.276,25.076 6.914,23.001C7.553,20.926 7.21,21.458 7.21,21.458L11.67,24.943L9.977,26.272Z" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M31.533,10.598C31.811,11.009 32.8,12.422 30.902,12.342C28.424,12.24 27.632,14.411 27.632,14.411L27.198,16.063L24.873,11.238C24.873,11.238 26.323,11.938 27.267,11.766C27.742,11.679 29.058,11.103 29.342,10.469C29.625,9.835 30.191,8.615 31.533,10.598" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M28.1,17.67C28.1,17.67 28.345,19.441 30.618,19.403C31.898,19.382 32.66,19.404 33.081,19.428C33.352,19.443 34.361,19.437 34.585,19.282C35.138,18.902 36.205,18.413 36.048,20.444C35.916,22.148 35.514,22.795 34.708,22.148C34.297,21.816 33.093,21.5 32.581,21.373C31.455,21.095 29.599,20.808 28.518,21.566C26.891,22.708 27.406,22.312 27.406,22.312L26.125,18.116L28.1,17.67Z" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + <path + android:pathData="M18.622,7.998C18.622,7.998 20.516,8.511 21.453,6.225C21.901,5.132 22.254,3.876 22.406,3.445C22.521,3.117 22.568,2.77 22.54,2.424C22.491,1.799 22.657,0.764 24.601,1.78C26.856,2.96 26.144,3.524 25.395,3.823C25.092,3.944 24.825,4.141 24.607,4.385C23.856,5.225 22.258,7.71 22.603,9.31C23.059,11.423 23.092,10.793 23.092,10.793L18.304,10.281L18.622,7.998Z" + android:strokeWidth="1" + android:fillColor="#C00F2D" + android:fillType="evenOdd" + android:strokeColor="#00000000"/> + </group> +</vector> diff --git a/Corona-Warn-App/src/main/res/drawable/tan_input_digit.xml b/Corona-Warn-App/src/main/res/drawable/tan_input_digit.xml index d06cdb9200e0e17be9a2d49cbc16c86faf412081..48e3d0c51a82c6484dfaad67960e18c39a9fa341 100644 --- a/Corona-Warn-App/src/main/res/drawable/tan_input_digit.xml +++ b/Corona-Warn-App/src/main/res/drawable/tan_input_digit.xml @@ -1,11 +1,20 @@ <?xml version="1.0" encoding="utf-8"?> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <corners android:radius="@dimen/submission_tan_input_digit_radius" /> - <gradient - android:angle="90" - android:centerColor="@color/colorSurface2" - android:centerX="0.02" - android:endColor="@color/colorSurface2" - android:startColor="@color/colorTextSemanticNeutral" /> -</shape> \ No newline at end of file +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> +<item> + <shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="@dimen/submission_tan_input_digit_radius" /> + <solid android:color="@color/colorSurface2" /> + </shape> +</item> +<item + android:height="1.5dp" + android:gravity="bottom"> + <shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:bottomLeftRadius="@dimen/submission_tan_input_digit_radius" /> + <corners android:bottomRightRadius="@dimen/submission_tan_input_digit_radius" /> + <solid android:color="@color/colorTextSemanticNeutral" /> + </shape> +</item> +</layer-list> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/drawable/tan_input_digit_entered.xml b/Corona-Warn-App/src/main/res/drawable/tan_input_digit_entered.xml new file mode 100644 index 0000000000000000000000000000000000000000..0550164c034b36b235de59a69df0cf69b5088316 --- /dev/null +++ b/Corona-Warn-App/src/main/res/drawable/tan_input_digit_entered.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="@dimen/submission_tan_input_digit_radius" /> + <solid android:color="@color/colorSurface2" /> +</shape> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/drawable/tan_input_digit_error.xml b/Corona-Warn-App/src/main/res/drawable/tan_input_digit_error.xml new file mode 100644 index 0000000000000000000000000000000000000000..01780eeb09b0b18076cb5bd414e1a2274c3d4015 --- /dev/null +++ b/Corona-Warn-App/src/main/res/drawable/tan_input_digit_error.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item> + <shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="@dimen/submission_tan_input_digit_radius" /> + <solid android:color="@color/colorSurface2" /> + </shape> + </item> + <item + android:height="1.5dp" + android:gravity="bottom"> + <shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:bottomLeftRadius="@dimen/submission_tan_input_digit_radius" /> + <corners android:bottomRightRadius="@dimen/submission_tan_input_digit_radius" /> + <solid android:color="@color/colorTextSemanticRed" /> + </shape> + </item> +</layer-list> 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 1e6f774901339bd616240f36550a57cc00b8ed2d..27b5cd78e5965d6071df2dca5602fb10e907befe 100644 --- a/Corona-Warn-App/src/main/res/layout/fragment_main.xml +++ b/Corona-Warn-App/src/main/res/layout/fragment_main.xml @@ -131,56 +131,70 @@ app:showDetails="@{false}" app:tracingViewModel="@{tracingViewModel}" /> + <!-- submission status cards --> <include - android:id="@+id/main_test_positive" - layout="@layout/include_submission_status_card_positive" + android:id="@+id/main_test_unregistered" + layout="@layout/include_submission_status_card_unregistered" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:visibility="@{FormatterSubmissionHelper.formatShowSubmissionStatusPositiveCard(submissionViewModel.deviceUiState)}" + android:layout_marginTop="@dimen/spacing_normal" + android:visibility="@{FormatterSubmissionHelper.formatSubmissionStatusCardUnregisteredVisible(submissionViewModel.deviceRegistered)}" app:layout_constraintEnd_toStartOf="@+id/guideline_end" app:layout_constraintStart_toStartOf="@+id/guideline_start" - app:layout_constraintTop_toBottomOf="@+id/main_tracing_divider" - app:registerDate="@{submissionViewModel.testResultReceivedDate}" /> + app:layout_constraintTop_toBottomOf="@id/main_risk" /> - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/main_test_done" - style="@style/card" - android:padding="0dp" + <include + android:id="@+id/main_test_result" + layout="@layout/include_submission_status_card_content" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:visibility="@{FormatterSubmissionHelper.formatShowSubmissionDoneCard(submissionViewModel.deviceUiState)}" + android:layout_marginTop="@dimen/spacing_normal" + android:visibility="@{FormatterSubmissionHelper.formatSubmissionStatusCardContentVisible(submissionViewModel.deviceUiState)}" + app:deviceUIState="@{submissionViewModel.deviceUiState}" app:layout_constraintEnd_toStartOf="@+id/guideline_end" app:layout_constraintStart_toStartOf="@+id/guideline_start" - app:layout_constraintTop_toBottomOf="@+id/main_tracing_divider"> + app:layout_constraintTop_toBottomOf="@id/main_test_unregistered" /> - <include - layout="@layout/include_submission_done_card" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - </androidx.constraintlayout.widget.ConstraintLayout> + <include + android:id="@+id/main_test_fetching" + layout="@layout/include_submission_status_card_fetching" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_normal" + android:visibility="@{FormatterSubmissionHelper.formatSubmissionStatusCardFetchingVisible(submissionViewModel.deviceRegistered, submissionViewModel.uiStateState)}" + app:layout_constraintEnd_toStartOf="@+id/guideline_end" + app:layout_constraintStart_toStartOf="@+id/guideline_start" + app:layout_constraintTop_toBottomOf="@id/main_test_result" /> <include - android:id="@+id/main_test" - layout="@layout/include_submission_status_card" - android:layout_width="0dp" + android:id="@+id/main_test_positive" + layout="@layout/include_submission_status_card_positive" + android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" android:layout_marginTop="@dimen/spacing_normal" - android:visibility="@{FormatterSubmissionHelper.formatShowSubmissionStatusCard(submissionViewModel.deviceUiState)}" + android:visibility="@{FormatterSubmissionHelper.formatShowSubmissionStatusPositiveCard(submissionViewModel.deviceUiState)}" + app:layout_constraintEnd_toStartOf="@+id/guideline_end" + app:layout_constraintStart_toStartOf="@+id/guideline_start" + app:layout_constraintTop_toBottomOf="@+id/main_test_fetching" + app:registerDate="@{submissionViewModel.testResultReceivedDate}" /> + + <include + android:id="@+id/main_test_done" + layout="@layout/include_submission_status_card_done" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_normal" + android:visibility="@{FormatterSubmissionHelper.formatShowSubmissionDoneCard(submissionViewModel.deviceUiState)}" app:layout_constraintEnd_toStartOf="@+id/guideline_end" app:layout_constraintStart_toStartOf="@+id/guideline_start" - app:layout_constraintTop_toBottomOf="@+id/main_risk" - app:submissionViewModel="@{submissionViewModel}" /> + app:layout_constraintTop_toBottomOf="@+id/main_test_positive" /> <androidx.constraintlayout.widget.Barrier android:id="@+id/main_barrier" android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierDirection="bottom" - app:constraint_referenced_ids="main_test, main_test_done, main_test_positive, main_risk" /> + app:constraint_referenced_ids="main_test_done, main_risk" /> <include android:id="@+id/main_about" @@ -199,12 +213,7 @@ app:layout_constraintTop_toBottomOf="@+id/main_barrier" app:tracingViewModel="@{tracingViewModel}" /> - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guideline_start" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical" - app:layout_constraintGuide_begin="@dimen/spacing_small" /> + <include layout="@layout/merge_guidelines_side" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline_bottom" @@ -213,20 +222,6 @@ android:orientation="horizontal" app:layout_constraintGuide_end="@dimen/spacing_small" /> - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guideline_end" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical" - app:layout_constraintGuide_end="@dimen/spacing_small" /> - - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guideline_top" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="horizontal" - app:layout_constraintGuide_begin="@dimen/spacing_small" /> - </androidx.constraintlayout.widget.ConstraintLayout> </ScrollView> diff --git a/Corona-Warn-App/src/main/res/layout/fragment_submission_tan.xml b/Corona-Warn-App/src/main/res/layout/fragment_submission_tan.xml index c940d7044756bbc18ba88d9b6393936436795151..4337a0b5e99b2d44ccadf2aea29579f74a14fcf1 100644 --- a/Corona-Warn-App/src/main/res/layout/fragment_submission_tan.xml +++ b/Corona-Warn-App/src/main/res/layout/fragment_submission_tan.xml @@ -5,6 +5,7 @@ <data> + <import type="de.rki.coronawarnapp.util.formatter.FormatterHelper" /> <import type="de.rki.coronawarnapp.util.formatter.FormatterSubmissionHelper" /> <variable @@ -54,6 +55,33 @@ app:layout_constraintStart_toStartOf="@+id/guideline_start" app:layout_constraintTop_toBottomOf="@+id/submission_tan_body" /> + <TextView + android:id="@+id/submission_tan_character_error" + style="@style/subtitle" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_small" + android:visibility="@{FormatterSubmissionHelper.formatShowTanCharacterError(viewmodel.tanCharactersValid, viewmodel.tanChecksumValid)}" + android:text="@string/submission_tan_character_error" + android:textColor="@color/colorTextSemanticRed" + app:layout_constraintEnd_toStartOf="@+id/guideline_end" + app:layout_constraintStart_toStartOf="@+id/guideline_start" + app:layout_constraintTop_toBottomOf="@id/submission_tan_input" /> + + <TextView + android:id="@+id/submission_tan_error" + style="@style/subtitle" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_small" + android:visibility="@{FormatterHelper.formatVisibility(!viewmodel.tanChecksumValid)}" + android:text="@string/submission_tan_error" + android:textColor="@color/colorTextSemanticRed" + app:layout_constraintEnd_toStartOf="@+id/guideline_end" + app:layout_constraintStart_toStartOf="@+id/guideline_start" + app:layout_constraintTop_toBottomOf="@id/submission_tan_input" /> + + <Button android:id="@+id/submission_tan_button_enter" style="@style/buttonPrimary" diff --git a/Corona-Warn-App/src/main/res/layout/fragment_submission_test_result.xml b/Corona-Warn-App/src/main/res/layout/fragment_submission_test_result.xml index 3db21c4784a6f2f63500dcb1c75683fa63d7b190..a7368ab3d12339aa4500e9338f04970d3fafa398 100644 --- a/Corona-Warn-App/src/main/res/layout/fragment_submission_test_result.xml +++ b/Corona-Warn-App/src/main/res/layout/fragment_submission_test_result.xml @@ -38,94 +38,102 @@ app:layout_constraintTop_toTopOf="parent" /> <include - android:id="@+id/include" layout="@layout/include_submission_test_result" android:layout_width="@dimen/match_constraint" android:layout_height="@dimen/match_constraint" + android:layout_marginBottom="@dimen/button_padding_top_bottom" android:visibility="@{FormatterSubmissionHelper.formatTestResultVisible(submissionViewModel.uiStateState)}" - app:layout_constraintBottom_toTopOf="@+id/submission_test_result_button_container" + app:layout_constraintBottom_toTopOf="@+id/include_submission_test_result_buttons" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/submission_test_result_header" app:submissionViewModel="@{submissionViewModel}" /> - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/submission_test_result_button_container" - android:layout_width="match_parent" + <androidx.constraintlayout.widget.Barrier + android:id="@+id/include_submission_test_result_buttons" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:visibility="@{FormatterSubmissionHelper.formatTestResultVisible(submissionViewModel.uiStateState)}" + + app:barrierAllowsGoneWidgets="false" + app:barrierDirection="top" + app:constraint_referenced_ids="submission_test_result_button_pending_refresh,submission_test_result_button_invalid_remove_test,submission_test_result_button_positive_continue,submission_test_result_button_negative_remove_test" /> + + <Button + android:id="@+id/submission_test_result_button_pending_refresh" + style="@style/buttonPrimary" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:text="@string/submission_test_result_pending_refresh_button" + android:visibility="@{FormatterSubmissionHelper.formatTestResultPendingStepsVisible(submissionViewModel.deviceUiState)}" + app:layout_constraintBottom_toTopOf="@+id/submission_test_result_button_pending_remove_test" + app:layout_constraintEnd_toStartOf="@+id/guideline_end" + app:layout_constraintStart_toStartOf="@id/guideline_start" + app:layout_constraintTop_toBottomOf="@+id/guideline_action_large" /> + + <Button + android:id="@+id/submission_test_result_button_pending_remove_test" + style="@style/buttonLight" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:text="@string/submission_test_result_pending_remove_test_button" + android:visibility="@{FormatterSubmissionHelper.formatTestResultPendingStepsVisible(submissionViewModel.deviceUiState)}" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent"> - - <Button - android:id="@+id/submission_test_result_button_pending_refresh" - style="@style/buttonPrimary" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginHorizontal="@dimen/spacing_normal" - android:layout_marginVertical="@dimen/spacing_small" - android:text="@string/submission_test_result_pending_refresh_button" - android:visibility="@{FormatterSubmissionHelper.formatTestResultPendingStepsVisible(submissionViewModel.deviceUiState)}" - app:layout_constraintBottom_toTopOf="@+id/submission_test_result_button_pending_remove_test" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - <Button - android:id="@+id/submission_test_result_button_pending_remove_test" - style="@style/buttonLight" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginHorizontal="@dimen/spacing_normal" - android:layout_marginVertical="@dimen/spacing_small" - android:text="@string/submission_test_result_pending_remove_test_button" - android:visibility="@{FormatterSubmissionHelper.formatTestResultPendingStepsVisible(submissionViewModel.deviceUiState)}" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - <Button - android:id="@+id/submission_test_result_button_invalid_remove_test" - style="@style/buttonPrimary" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginHorizontal="@dimen/spacing_normal" - android:layout_marginVertical="@dimen/spacing_small" - android:text="@string/submission_test_result_invalid_remove_test_button" - android:visibility="@{FormatterSubmissionHelper.formatTestResultInvalidStepsVisible(submissionViewModel.deviceUiState)}" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - <Button - android:id="@+id/submission_test_result_button_positive_continue" - style="@style/buttonPrimary" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginHorizontal="@dimen/spacing_normal" - android:layout_marginVertical="@dimen/spacing_small" - android:text="@string/submission_test_result_positive_continue_button" - android:visibility="@{FormatterSubmissionHelper.formatTestResultPositiveStepsVisible(submissionViewModel.deviceUiState)}" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - <Button - android:id="@+id/submission_test_result_button_negative_remove_test" - style="@style/buttonPrimary" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginHorizontal="@dimen/spacing_normal" - android:layout_marginVertical="@dimen/spacing_small" - android:text="@string/submission_test_result_negative_remove_test_button" - android:visibility="@{FormatterSubmissionHelper.formatTestResultNegativeStepsVisible(submissionViewModel.deviceUiState)}" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - </androidx.constraintlayout.widget.ConstraintLayout> + app:layout_constraintEnd_toStartOf="@+id/guideline_end" + app:layout_constraintStart_toStartOf="@id/guideline_start" + app:layout_constraintTop_toBottomOf="@+id/submission_test_result_button_pending_refresh" /> + + <Button + android:id="@+id/submission_test_result_button_invalid_remove_test" + style="@style/buttonPrimary" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:text="@string/submission_test_result_invalid_remove_test_button" + android:visibility="@{FormatterSubmissionHelper.formatTestResultInvalidStepsVisible(submissionViewModel.deviceUiState)}" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/guideline_end" + app:layout_constraintStart_toStartOf="@id/guideline_start" + app:layout_constraintTop_toTopOf="@id/guideline_action" /> + + <Button + android:id="@+id/submission_test_result_button_positive_continue" + style="@style/buttonPrimary" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:text="@string/submission_test_result_positive_continue_button" + android:visibility="@{FormatterSubmissionHelper.formatTestResultPositiveStepsVisible(submissionViewModel.deviceUiState)}" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/guideline_end" + app:layout_constraintStart_toStartOf="@id/guideline_start" + app:layout_constraintTop_toTopOf="@id/guideline_action" /> + + <Button + android:id="@+id/submission_test_result_button_negative_remove_test" + style="@style/buttonPrimary" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:text="@string/submission_test_result_negative_remove_test_button" + android:visibility="@{FormatterSubmissionHelper.formatTestResultNegativeStepsVisible(submissionViewModel.deviceUiState)}" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/guideline_end" + app:layout_constraintStart_toStartOf="@id/guideline_start" + app:layout_constraintTop_toTopOf="@id/guideline_action" /> <include layout="@layout/merge_guidelines_side" /> + <androidx.constraintlayout.widget.Guideline + android:id="@+id/guideline_action_large" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_end="@dimen/guideline_action_large" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/guideline_action" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_end="@dimen/guideline_action" /> + + </androidx.constraintlayout.widget.ConstraintLayout> </layout> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/layout/include_dispatcher_card.xml b/Corona-Warn-App/src/main/res/layout/include_dispatcher_card.xml index 99b7cac0cbf5bb4de5cb9192852d10522a772c61..12f0a35429ef3567af232925be8daf22253d25f8 100644 --- a/Corona-Warn-App/src/main/res/layout/include_dispatcher_card.xml +++ b/Corona-Warn-App/src/main/res/layout/include_dispatcher_card.xml @@ -47,7 +47,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/spacing_small" android:layout_marginEnd="@dimen/spacing_normal" - app:icon="@{@drawable/ic_icon_drilldowncard_dark}" + app:icon="@{@drawable/ic_forward}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -60,7 +60,6 @@ android:layout_marginTop="@dimen/spacing_normal" android:layout_marginBottom="@dimen/spacing_normal" android:text="@{body}" - app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/dispatcher_card_illustration" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/dispatcher_card_title" diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_contact.xml b/Corona-Warn-App/src/main/res/layout/include_submission_contact.xml index 70a040bcc2f9775f7acc02257d3705cbd1c40e7b..6fde2a8fc1502370f74a0cf74db1608233b2fca9 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_contact.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_contact.xml @@ -35,7 +35,7 @@ style="@style/headline5" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" + android:layout_marginTop="@dimen/spacing_medium" android:text="@string/submission_contact_headline" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="@id/guideline_start" @@ -51,7 +51,7 @@ app:layout_constraintStart_toStartOf="@+id/guideline_start" app:layout_constraintTop_toBottomOf="@id/submission_contact_headline" app:step_entry_final="false" - app:step_entry_icon="@drawable/ic_step_1"> + app:step_entry_icon="@drawable/ic_main_overview_1"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" @@ -104,7 +104,7 @@ app:layout_constraintStart_toStartOf="@+id/guideline_start" app:layout_constraintTop_toBottomOf="@+id/submission_contact_step_1" app:step_entry_final="true" - app:step_entry_icon="@drawable/ic_step_2"> + app:step_entry_icon="@drawable/ic_main_overview_2"> <TextView style="@style/subtitle" diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_status_card.xml b/Corona-Warn-App/src/main/res/layout/include_submission_status_card.xml deleted file mode 100644 index 41a1af9439eccd1765de70043dc9cfea65fe8c55..0000000000000000000000000000000000000000 --- a/Corona-Warn-App/src/main/res/layout/include_submission_status_card.xml +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<layout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto"> - - <data> - - <import type="de.rki.coronawarnapp.util.formatter.FormatterHelper" /> - - <import type="de.rki.coronawarnapp.util.formatter.FormatterSubmissionHelper" /> - - <variable - name="submissionViewModel" - type="de.rki.coronawarnapp.ui.viewmodel.SubmissionViewModel" /> - </data> - - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/submission_status_card" - style="@style/card" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <include - android:id="@+id/submission_status_card_content" - layout="@layout/include_submission_status_card_content" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:visibility="@{FormatterSubmissionHelper.formatSubmissionStatusCardContentVisible(submissionViewModel.deviceRegistered, submissionViewModel.uiStateState)}" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:deviceUIState="@{submissionViewModel.deviceUiState}" /> - - <include - android:id="@+id/submission_status_card_unregistered" - layout="@layout/include_submission_status_card_unregistered" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:visibility="@{FormatterHelper.formatVisibility(!submissionViewModel.deviceRegistered)}" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <include - android:id="@+id/submission_status_card_fetching" - layout="@layout/include_submission_status_card_fetching" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:visibility="@{FormatterSubmissionHelper.formatSubmissionStatusCardFetchingVisible(submissionViewModel.deviceRegistered, submissionViewModel.uiStateState)}" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - </androidx.constraintlayout.widget.ConstraintLayout> -</layout> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_content.xml b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_content.xml index 4a9eec4551092f6fd4288f17319c55c0401e67de..bc18df4e3b790df01d1516559c42ff4a174ea4a2 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_content.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_content.xml @@ -13,17 +13,19 @@ </data> <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/submission_status_card" + android:id="@+id/submission_status_card_content" + style="@style/cardNoPadding" android:layout_width="match_parent" android:layout_height="wrap_content"> - <TextView android:id="@+id/submission_status_card_content_title" style="@style/headline5" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/spacing_tiny" + android:layout_marginStart="@dimen/card_padding" + android:layout_marginTop="@dimen/card_padding" + android:layout_marginEnd="@dimen/spacing_small" android:text="@{FormatterSubmissionHelper.formatSubmissionStatusCardContentTitleText(deviceUIState)}" app:layout_constraintEnd_toStartOf="@+id/submission_status_card_content_icon" app:layout_constraintStart_toStartOf="parent" @@ -35,23 +37,25 @@ style="@style/subtitleMedium" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/card_padding" android:layout_marginTop="@dimen/spacing_normal" - android:layout_marginEnd="@dimen/spacing_tiny" + android:layout_marginEnd="@dimen/spacing_small" android:text="@{FormatterSubmissionHelper.formatSubmissionStatusCardSubtitleText(deviceUIState)}" android:textColor="@{FormatterSubmissionHelper.formatSubmissionStatusCardSubtitleColor(deviceUIState)}" android:visibility="@{FormatterSubmissionHelper.formatSubmissionStatusCardContentStatusTextVisible(deviceUIState)}" app:layout_constraintEnd_toStartOf="@+id/submission_status_card_content_icon" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/submission_status_card_content_title" - tools:text="@string/test_result_card_status_positive" /> + tools:text="@string/test_result_card_status_negative" /> <TextView android:id="@+id/submission_status_card_content_body" style="@style/subtitle" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/card_padding" android:layout_marginTop="@dimen/spacing_tiny" - android:layout_marginEnd="@dimen/spacing_tiny" + android:layout_marginEnd="@dimen/spacing_small" android:text="@{FormatterSubmissionHelper.formatSubmissionStatusCardContentBodyText(deviceUIState)}" app:layout_constraintEnd_toStartOf="@+id/submission_status_card_content_icon" app:layout_constraintStart_toStartOf="parent" @@ -70,8 +74,12 @@ style="@style/buttonPrimary" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/card_padding" android:layout_marginTop="@dimen/spacing_normal" + android:layout_marginEnd="@dimen/card_padding" + android:layout_marginBottom="@dimen/card_padding" android:text="@string/submission_status_card_button_show_results" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/submission_status_card_content_barrier" /> @@ -82,7 +90,7 @@ android:layout_height="wrap_content" android:background="@{FormatterSubmissionHelper.formatSubmissionStatusCardContentIcon(deviceUIState)}" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" + app:layout_constraintTop_toTopOf="@id/submission_status_card_content_title" tools:src="@drawable/ic_main_illustration_negative" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_done_card.xml b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_done.xml similarity index 84% rename from Corona-Warn-App/src/main/res/layout/include_submission_done_card.xml rename to Corona-Warn-App/src/main/res/layout/include_submission_status_card_done.xml index 929d2201aaf477886d56a758edce09e8899b94a2..eca173050e305c53903e2ea624b2483d9afb6922 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_done_card.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_done.xml @@ -3,8 +3,11 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/submission_status_card_done" + style="@style/card" android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + android:padding="0dp"> <TextView android:id="@+id/submission_done_card_title" @@ -15,20 +18,20 @@ android:layout_marginTop="@dimen/spacing_normal" android:layout_marginEnd="@dimen/spacing_small" android:text="@string/submission_done_title" - app:layout_constraintEnd_toStartOf="@+id/submission_done_card__icon" + app:layout_constraintEnd_toStartOf="@+id/submission_done_card_icon" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <include - android:id="@+id/submission_done_card__icon" + android:id="@+id/submission_done_card_icon" layout="@layout/include_button_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" android:layout_marginEnd="@dimen/spacing_normal" - app:icon="@{@drawable/ic_icon_drilldowncard_dark}" + app:icon="@{@drawable/ic_forward}" + app:layout_constraintBottom_toBottomOf="@+id/submission_done_card_title" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="@+id/submission_done_card_title" /> <ImageView android:id="@+id/submission_done_card_illustration" @@ -48,8 +51,8 @@ layout="@layout/include_submission_done_content" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - app:illustrationDescription="@{@string/submission_done_illustration_description}" android:layout_marginTop="@dimen/spacing_normal" + app:illustrationDescription="@{@string/submission_done_illustration_description}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/submission_done_card_illustration" /> diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_fetching.xml b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_fetching.xml index 3a60545b633e8732001ba19e10314861727f4ca6..9b8209f5db50b9edc98a257481037139ca7f6c84 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_fetching.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_fetching.xml @@ -3,7 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/submission_status_card" + android:id="@+id/submission_status_card_fetching" + style="@style/card" android:layout_width="match_parent" android:layout_height="wrap_content"> @@ -31,9 +32,9 @@ <TextView android:id="@+id/submission_status_card_fetching_body" style="@style/subtitle" + android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" android:layout_marginStart="@dimen/spacing_normal" - android:layout_width="@dimen/match_constraint" android:text="@string/submission_status_card_body_fetching" app:layout_constraintBottom_toBottomOf="@+id/submission_status_card_fetching_spinner" app:layout_constraintEnd_toEndOf="parent" @@ -42,11 +43,12 @@ <Button android:id="@+id/submission_status_card_fetching_button" - style="@style/buttonLight" + style="@style/buttonPrimary" + android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" android:layout_marginTop="@dimen/spacing_normal" - android:layout_width="@dimen/match_constraint" - android:text="@string/submission_status_card_button_show_details" + android:enabled="false" + android:text="@string/submission_status_card_button_show_results" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/submission_status_card_fetching_spinner" /> diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_positive.xml b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_positive.xml index e936138ad75d97656aa8fa1e423a4319ac4628df..1d97e1b8b431826c8cb6008c693b13260cbf7330 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_positive.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_positive.xml @@ -19,107 +19,108 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/submission_status_card_positive_container" + <TextView + android:id="@+id/submission_status_card_positive_title" + style="@style/headline5" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/spacing_small" + android:text="@string/submission_status_card_title_positive" + app:layout_constraintEnd_toStartOf="@id/submission_status_card_positive_next" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <include + android:id="@+id/submission_status_card_positive_next" + layout="@layout/include_button_icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:icon="@{@drawable/ic_forward}" + app:layout_constraintBottom_toBottomOf="@+id/submission_status_card_positive_title" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@+id/submission_status_card_positive_title" /> + + <include + android:id="@+id/submission_status_card_positive_result_card" + layout="@layout/include_test_result_card_positive" android:layout_width="match_parent" android:layout_height="wrap_content" - app:layout_constraintBottom_toBottomOf="parent" + android:layout_marginTop="@dimen/spacing_normal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_title" /> + + <include + android:id="@+id/divider" + layout="@layout/include_divider" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_normal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_card" /> + + <TextView + android:id="@+id/submission_status_card_positive_result_subtitle" + style="@style/headline5" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_normal" + android:text="@string/submission_status_card_positive_result_subtitle" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/divider" /> + + <include + android:id="@+id/submission_status_card_positive_result_contact" + layout="@layout/include_risk_details_behavior_row" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_normal" + app:body="@{@string/submission_status_card_positive_result_contact}" + app:icon="@{@drawable/ic_risk_details_contact}" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_subtitle" + app:riskLevel="@{RiskLevelConstants.INCREASED_RISK}" /> + + <include + android:id="@+id/submission_status_card_positive_result_contagious" + layout="@layout/include_risk_details_behavior_row" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_normal" + app:body="@{@string/submission_status_card_positive_result_contagious}" + app:icon="@{@drawable/ic_submission_home}" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_contact" + app:riskLevel="@{RiskLevelConstants.INCREASED_RISK}" /> + + <include + android:id="@+id/submission_status_card_positive_result_share" + layout="@layout/include_risk_details_behavior_row" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_normal" + app:body="@{@string/submission_status_card_positive_result_share}" + app:icon="@{@drawable/ic_submission_share}" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_contagious" + app:riskLevel="@{RiskLevelConstants.INCREASED_RISK}" /> + + <Button + android:id="@+id/submission_status_card_positive_button" + style="@style/buttonPrimary" + android:layout_width="@dimen/match_constraint" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/spacing_normal" + android:text="@string/submission_test_result_positive_continue_button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent"> - - <TextView - android:id="@+id/submission_status_card_positive_title" - style="@style/headline5" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:text="@string/submission_status_card_title_positive" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <include - android:id="@+id/submission_status_card_positive_result_card" - layout="@layout/include_test_result_card_positive" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_title" /> - - <include - android:id="@+id/divider" - layout="@layout/include_divider" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_card" /> - - <TextView - android:id="@+id/submission_status_card_positive_result_subtitle" - style="@style/headline5" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" - android:text="@string/submission_status_card_positive_result_subtitle" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/divider" /> - - <include - android:id="@+id/submission_status_card_positive_result_contact" - layout="@layout/include_risk_details_behavior_row" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" - app:body="@{@string/submission_status_card_positive_result_contact}" - app:icon="@{@drawable/ic_risk_details_contact}" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_subtitle" - app:riskLevel="@{RiskLevelConstants.INCREASED_RISK}" /> - - <include - android:id="@+id/submission_status_card_positive_result_contagious" - layout="@layout/include_risk_details_behavior_row" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" - app:body="@{@string/submission_status_card_positive_result_contagious}" - app:icon="@{@drawable/ic_submission_home}" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_contact" - app:riskLevel="@{RiskLevelConstants.INCREASED_RISK}" /> - - <include - android:id="@+id/submission_status_card_positive_result_share" - layout="@layout/include_risk_details_behavior_row" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" - app:body="@{@string/submission_status_card_positive_result_share}" - app:icon="@{@drawable/ic_submission_share}" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_contagious" - app:riskLevel="@{RiskLevelConstants.INCREASED_RISK}" /> - - <Button - android:id="@+id/submission_status_card_positive_result_show_button" - style="@style/buttonPrimary" - android:layout_width="@dimen/match_constraint" - android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" - android:text="@string/submission_test_result_positive_continue_button" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_share" /> - - - </androidx.constraintlayout.widget.ConstraintLayout> + app:layout_constraintTop_toBottomOf="@+id/submission_status_card_positive_result_share" /> + + </androidx.constraintlayout.widget.ConstraintLayout> </layout> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_unregistered.xml b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_unregistered.xml index 27465e371f13281c8dd7bc28bd6c2b49e10f1525..8c60e26477cf6f6db3eac9f342cdf937d6cac0d4 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_status_card_unregistered.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_status_card_unregistered.xml @@ -3,7 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/submission_status_card" + android:id="@+id/submission_status_card_unregistered" + style="@style/cardNoPadding" android:layout_width="match_parent" android:layout_height="wrap_content"> @@ -13,6 +14,8 @@ style="@style/headline5" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/card_padding" + android:layout_marginTop="@dimen/card_padding" android:layout_marginEnd="@dimen/spacing_small" android:text="@string/submission_status_card_title_unregistered" app:layout_constraintEnd_toStartOf="@+id/submission_status_card_unregistered_icon" @@ -22,9 +25,10 @@ <TextView android:id="@+id/submission_status_card_unregistered_body" - style="@style/subtitle" + style="@style/subtitleMedium" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/card_padding" android:layout_marginTop="@dimen/spacing_normal" android:layout_marginEnd="@dimen/spacing_small" android:text="@string/submission_status_card_body_unregistered" @@ -37,8 +41,12 @@ style="@style/buttonPrimary" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/card_padding" android:layout_marginTop="@dimen/spacing_normal" + android:layout_marginEnd="@dimen/card_padding" + android:layout_marginBottom="@dimen/card_padding" android:text="@string/submission_status_card_button_unregistered" + app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/submission_status_card_unregistered_barrier" /> diff --git a/Corona-Warn-App/src/main/res/layout/include_submission_test_result.xml b/Corona-Warn-App/src/main/res/layout/include_submission_test_result.xml index b08af9be3c17131c05fb2d5102f44d28b667a71c..74da81201130872368b74de59042186a4884399f 100644 --- a/Corona-Warn-App/src/main/res/layout/include_submission_test_result.xml +++ b/Corona-Warn-App/src/main/res/layout/include_submission_test_result.xml @@ -27,8 +27,8 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/spacing_small" app:deviceUIState="@{submissionViewModel.deviceUiState}" - app:layout_constraintEnd_toEndOf="@+id/guideline_end" - app:layout_constraintStart_toStartOf="@+id/guideline_start" + app:layout_constraintEnd_toEndOf="@+id/guideline_card_end" + app:layout_constraintStart_toStartOf="@+id/guideline_card_start" app:layout_constraintTop_toTopOf="parent" app:registerDate="@{submissionViewModel.testResultReceivedDate}" /> @@ -37,7 +37,7 @@ style="@style/headline5" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/spacing_normal" + android:layout_marginTop="@dimen/spacing_medium" android:text="@string/submission_test_result_subtitle" app:layout_constraintEnd_toEndOf="@+id/guideline_end" app:layout_constraintStart_toStartOf="@+id/guideline_start" @@ -89,6 +89,8 @@ <include layout="@layout/merge_guidelines_side" /> + <include layout="@layout/merge_guidelines_card" /> + </androidx.constraintlayout.widget.ConstraintLayout> </ScrollView> </layout> \ No newline at end of file diff --git a/Corona-Warn-App/src/main/res/layout/include_test_result_card.xml b/Corona-Warn-App/src/main/res/layout/include_test_result_card.xml index ef96da3c6c78e720043dee63e49bd127ee985d4a..c42ec74bda640b65c7abe629c544296be830f24d 100644 --- a/Corona-Warn-App/src/main/res/layout/include_test_result_card.xml +++ b/Corona-Warn-App/src/main/res/layout/include_test_result_card.xml @@ -17,7 +17,7 @@ <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@color/colorSurface2" + android:background="@drawable/card_dark" android:padding="@dimen/card_padding"> <TextView @@ -25,7 +25,7 @@ style="@style/body2" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/spacing_tiny" + android:layout_marginEnd="@dimen/spacing_small" android:text="@string/test_result_card_headline" app:layout_constraintEnd_toStartOf="@id/test_result_card_status_icon" app:layout_constraintStart_toStartOf="parent" @@ -36,7 +36,7 @@ style="@style/headline5" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/spacing_tiny" + android:layout_marginEnd="@dimen/spacing_small" android:text="@{FormatterSubmissionHelper.formatTestResultCardContent(deviceUIState)}" app:layout_constraintEnd_toStartOf="@id/test_result_card_status_icon" app:layout_constraintStart_toStartOf="parent" @@ -50,7 +50,7 @@ android:background="@{FormatterSubmissionHelper.formatTestStatusIcon(deviceUIState)}" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" - tools:src="@drawable/ic_main_illustration_negative" /> + tools:src="@drawable/ic_test_result_illustration_negative" /> <TextView android:id="@+id/test_result_card_registered_at_text" @@ -58,7 +58,7 @@ android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" android:layout_marginTop="@dimen/spacing_normal" - android:layout_marginEnd="@dimen/spacing_tiny" + android:layout_marginEnd="@dimen/spacing_small" android:text="@{FormatterSubmissionHelper.formatTestResultRegisteredAtText(registerDate)}" app:layout_constraintEnd_toStartOf="@id/test_result_card_status_icon" app:layout_constraintStart_toStartOf="parent" diff --git a/Corona-Warn-App/src/main/res/layout/include_test_result_card_positive.xml b/Corona-Warn-App/src/main/res/layout/include_test_result_card_positive.xml index 86fb1d367f36b6a6585e9e3f2c8ca70e57f8c80d..e6f3bf2a7d2cd37c7515d69cb4ba2bbee12685da 100644 --- a/Corona-Warn-App/src/main/res/layout/include_test_result_card_positive.xml +++ b/Corona-Warn-App/src/main/res/layout/include_test_result_card_positive.xml @@ -12,7 +12,7 @@ style="@style/headline6" android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/spacing_tiny" + android:layout_marginEnd="@dimen/spacing_small" android:text="@string/submission_test_result_card_positive_title" app:layout_constraintEnd_toStartOf="@id/test_result_card_positive_icon" app:layout_constraintStart_toStartOf="parent" @@ -22,7 +22,7 @@ android:id="@+id/test_result_card_positive_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@drawable/ic_test_result_illustration_positive" + android:background="@drawable/ic_test_result_illustration_positive_card" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" tools:src="@drawable/ic_test_result_illustration_positive" /> @@ -33,7 +33,7 @@ android:layout_width="@dimen/match_constraint" android:layout_height="wrap_content" android:layout_marginTop="@dimen/spacing_normal" - android:layout_marginEnd="@dimen/spacing_tiny" + android:layout_marginEnd="@dimen/spacing_small" android:text="@string/submission_test_result_card_positive_body" app:layout_constraintEnd_toStartOf="@id/test_result_card_positive_icon" app:layout_constraintStart_toStartOf="parent" diff --git a/Corona-Warn-App/src/main/res/layout/view_step_entry.xml b/Corona-Warn-App/src/main/res/layout/view_step_entry.xml index ffaaca906aab9c234ff17e92dfded7e547111243..ee490f1cbdd737c30333923efa14efdaa45d5bea 100644 --- a/Corona-Warn-App/src/main/res/layout/view_step_entry.xml +++ b/Corona-Warn-App/src/main/res/layout/view_step_entry.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto"> + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" @@ -10,10 +11,9 @@ android:id="@+id/step_entry_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:background="@drawable/ic_step_background" - android:src="@drawable/ic_step_1" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintTop_toTopOf="parent" + tools:src="@drawable/ic_main_overview_1" /> <FrameLayout android:id="@+id/step_entry_wrapper_children" diff --git a/Corona-Warn-App/src/main/res/layout/view_tan_input.xml b/Corona-Warn-App/src/main/res/layout/view_tan_input.xml index 213e9ff71c18e439291b5c0443c14ff26fff0ae2..9083b562845012532d3bc66852b9b20a93ee1ffa 100644 --- a/Corona-Warn-App/src/main/res/layout/view_tan_input.xml +++ b/Corona-Warn-App/src/main/res/layout/view_tan_input.xml @@ -36,17 +36,26 @@ android:id="@+id/tan_input_textview_3" style="@style/tanInputDigit" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintEnd_toStartOf="@+id/tan_input_textview_4" + app:layout_constraintEnd_toStartOf="@+id/dash_view_1" app:layout_constraintStart_toEndOf="@+id/tan_input_textview_2" app:layout_constraintTop_toTopOf="parent" tools:text="X" /> + <TextView + android:id="@+id/dash_view_1" + style="@style/tanInputDash" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/tan_input_textview_4" + app:layout_constraintStart_toEndOf="@+id/tan_input_textview_3" + app:layout_constraintTop_toTopOf="parent" + tools:text="-" /> + <TextView android:id="@+id/tan_input_textview_4" style="@style/tanInputDigit" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@+id/tan_input_textview_5" - app:layout_constraintStart_toEndOf="@+id/tan_input_textview_3" + app:layout_constraintStart_toEndOf="@+id/dash_view_1" app:layout_constraintTop_toTopOf="parent" tools:text="X" /> @@ -63,19 +72,54 @@ android:id="@+id/tan_input_textview_6" style="@style/tanInputDigit" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintEnd_toStartOf="@+id/tan_input_textview_7" + app:layout_constraintEnd_toStartOf="@+id/dash_view_2" app:layout_constraintStart_toEndOf="@+id/tan_input_textview_5" app:layout_constraintTop_toTopOf="parent" tools:text="X" /> + <TextView + android:id="@+id/dash_view_2" + style="@style/tanInputDash" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/tan_input_textview_7" + app:layout_constraintStart_toEndOf="@+id/tan_input_textview_6" + app:layout_constraintTop_toTopOf="parent" + tools:text="-" /> + <TextView android:id="@+id/tan_input_textview_7" style="@style/tanInputDigit" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@+id/tan_input_textview_6" + app:layout_constraintEnd_toStartOf="@+id/tan_input_textview_8" + app:layout_constraintStart_toEndOf="@+id/dash_view_2" app:layout_constraintTop_toTopOf="parent" tools:text="X" /> + <TextView + android:id="@+id/tan_input_textview_8" + style="@style/tanInputDigit" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/tan_input_textview_9" + app:layout_constraintStart_toEndOf="@+id/tan_input_textview_7" + app:layout_constraintTop_toTopOf="parent" + tools:text="X" /> + + <TextView + android:id="@+id/tan_input_textview_9" + style="@style/tanInputDigit" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintEnd_toStartOf="@+id/tan_input_textview_10" + app:layout_constraintStart_toEndOf="@+id/tan_input_textview_8" + app:layout_constraintTop_toTopOf="parent" + tools:text="X" /> + + <TextView + android:id="@+id/tan_input_textview_10" + style="@style/tanInputDigit" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/tan_input_textview_9" + app:layout_constraintTop_toTopOf="parent" + tools:text="X" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout> 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 e0b293bc802d037cc8ebb189da1553815a767e56..53903c9abd0f56315687d73798fbcb96de85d7b7 100644 --- a/Corona-Warn-App/src/main/res/navigation/nav_graph.xml +++ b/Corona-Warn-App/src/main/res/navigation/nav_graph.xml @@ -35,6 +35,9 @@ <action android:id="@+id/action_mainFragment_to_submissionResultFragment" app:destination="@id/submissionResultFragment" /> + <action + android:id="@+id/action_mainFragment_to_submissionDoneFragment" + app:destination="@id/submissionDoneFragment" /> <action android:id="@+id/action_mainFragment_to_mainOverviewFragment" app:destination="@id/mainOverviewFragment" /> diff --git a/Corona-Warn-App/src/main/res/values-de/strings.xml b/Corona-Warn-App/src/main/res/values-de/strings.xml index d123afa1ab84c8074dd4d93326af91141f48e2d7..9555649d9518546120c31b7c82d5c0d0e3a8ed2a 100644 --- a/Corona-Warn-App/src/main/res/values-de/strings.xml +++ b/Corona-Warn-App/src/main/res/values-de/strings.xml @@ -591,7 +591,7 @@ <!-- XHED: Page title for TAN submission pge --> <string name="submission_tan_title">"TAN-Eingabe"</string> <!-- YTXT: Body text for the tan submission page --> - <string name="submission_tan_body">"Die TAN ist 7-stellig und Groß- und Kleinschreibung muss nicht beachtet werden.\n\nGeben Sie bitte die Ihnen mitgeteilte TAN ein:"</string> + <string name="submission_tan_body">"Geben Sie bitte die 10 Stellen der TAN ein, die Ihnen mitgeteilt wurde."</string> <!-- XBUT: Submit TAN button --> <string name="submission_tan_button_text">"Weiter"</string> @@ -729,8 +729,6 @@ <string name="submission_status_card_button_unregistered">"Informieren & mitmachen"</string> <!-- XBUT: submission status card show results button --> <string name="submission_status_card_button_show_results">"Ergebnis anzeigen"</string> - <!-- XBUT: submission status card show details button --> - <string name="submission_status_card_button_show_details">"Details anzeigen"</string> <!-- XHED: submission status card positive result title --> <string name="submission_status_card_positive_result_title">"Positives Ergebnis"</string> <!-- XHED: submission status card positive result subtitle --> diff --git a/Corona-Warn-App/src/main/res/values-en/strings.xml b/Corona-Warn-App/src/main/res/values-en/strings.xml index 3746e6810ddfdbc68811bfc0fb6ac479b663861e..139deb4061106861b72cf1bf9181212a220a075f 100644 --- a/Corona-Warn-App/src/main/res/values-en/strings.xml +++ b/Corona-Warn-App/src/main/res/values-en/strings.xml @@ -593,7 +593,7 @@ <!-- XHED: Page title for TAN submission pge --> <string name="submission_tan_title">"TAN entry"</string> <!-- YTXT: Body text for the tan submission page --> - <string name="submission_tan_body">"The TAN has 7 characters and is case-insensitive.\n\nPlease enter the TAN you were given:"</string> + <string name="submission_tan_body">"Please enter the 10 characters of the TAN you were given:"</string> <!-- XBUT: Submit TAN button --> <string name="submission_tan_button_text">"Next"</string> @@ -731,8 +731,6 @@ <string name="submission_status_card_button_unregistered">"Notify and Help"</string> <!-- XBUT: submission status card show results button --> <string name="submission_status_card_button_show_results">"Display Result"</string> - <!-- XBUT: submission status card show details button --> - <string name="submission_status_card_button_show_details">"Display Details"</string> <!-- XHED: submission status card positive result title --> <string name="submission_status_card_positive_result_title">"Positive Result"</string> <!-- XHED: submission status card positive result subtitle --> diff --git a/Corona-Warn-App/src/main/res/values-night/colors.xml b/Corona-Warn-App/src/main/res/values-night/colors.xml index aa86c95574cd0fbfc80a6d6fdca97aeb377ebe52..d3440a0be4c68276e3f5028a33a7b7a4142f0135 100644 --- a/Corona-Warn-App/src/main/res/values-night/colors.xml +++ b/Corona-Warn-App/src/main/res/values-night/colors.xml @@ -11,6 +11,7 @@ <color name="colorSurface1">#232324</color> <color name="colorSurface1Pressed">#39393A</color> <color name="colorSurface2">#434445</color> + <color name="colorSurface2Pressed">#565757</color> <color name="colorHairline">#4DFFFFFF</color> <!-- Text --> diff --git a/Corona-Warn-App/src/main/res/values/colors.xml b/Corona-Warn-App/src/main/res/values/colors.xml index 8996a7170adbdb1d970a9be70c01317fd6bbcdb5..d8624761e63ba2c52c3708f1ef23c6f2439abc41 100644 --- a/Corona-Warn-App/src/main/res/values/colors.xml +++ b/Corona-Warn-App/src/main/res/values/colors.xml @@ -11,6 +11,7 @@ <color name="colorSurface1">#FFFFFF</color> <color name="colorSurface1Pressed">#E7E8E8</color> <color name="colorSurface2">#F5F5F5</color> + <color name="colorSurface2Pressed">#D7D7D7</color> <color name="colorHairline">#3317191A</color> <!-- Text --> diff --git a/Corona-Warn-App/src/main/res/values/dimens.xml b/Corona-Warn-App/src/main/res/values/dimens.xml index fc63f4a940f10742447a32c4465b622bc5b8ebc4..5b3c0277c6fbe5197046ffa0f2750da31c16a28f 100644 --- a/Corona-Warn-App/src/main/res/values/dimens.xml +++ b/Corona-Warn-App/src/main/res/values/dimens.xml @@ -1,6 +1,7 @@ <resources> <!-- spacing, used as reference for everything else --> <dimen name="spacing_large">48dp</dimen> + <dimen name="spacing_medium">32dp</dimen> <dimen name="spacing_normal">24dp</dimen> <dimen name="spacing_small">16dp</dimen> <dimen name="spacing_tiny">8dp</dimen> @@ -81,10 +82,14 @@ <!-- Submission Tan Input --> <dimen name="submission_tan_input_edittext_size">1dp</dimen> <dimen name="submission_tan_input_digit_radius">2dp</dimen> - <dimen name="submission_tan_input_digit_width">24dp</dimen> - <dimen name="submission_tan_input_digit_height">32dp</dimen> + <dimen name="submission_tan_input_digit_width">22dp</dimen> + <dimen name="submission_tan_input_digit_height">40dp</dimen> + <dimen name="submission_tan_input_dash_width">11dp</dimen> + <dimen name="submission_tan_input_dash_height">40dp</dimen> <!-- Submission QR Code Scan --> <dimen name="submission_scan_qr_code_viewfinder_size">240dp</dimen> <dimen name="submission_scan_qr_code_viewfinder_center_offset">120dp</dimen> + + <dimen name="no_padding">0dp</dimen> </resources> diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml index c0fce7d608a567e3d241203cca74db7e634cbc15..ead09a21a67e7e23db4be012b3d41b13b9d862fa 100644 --- a/Corona-Warn-App/src/main/res/values/strings.xml +++ b/Corona-Warn-App/src/main/res/values/strings.xml @@ -2664,9 +2664,13 @@ as modifying the License. <!-- XHED: Page title for TAN submission pge --> <string name="submission_tan_title">TAN Eingabe</string> <!-- YTXT: Body text for the tan submission page --> - <string name="submission_tan_body">Die TAN ist 7-stellig und Groß- und Kleinschreibung muss beachtet werden.\n\nGeben Sie bitte die Ihnen mitgeteilte TAN ein:</string> + <string name="submission_tan_body">Geben Sie bitte die 10 Stellen der TAN ein, die Ihnen mitgeteilt wurde.</string> <!-- XBUT: Submit TAN button --> <string name="submission_tan_button_text">Weiter</string> + <!-- YTXT: Error text for the tan submission page --> + <string name="submission_tan_error">Ungültige TAN, bitte überprüfen Sie Ihre Eingabe.</string> + <!-- YTXT: Error text for the tan submission page (wrong characters) --> + <string name="submission_tan_character_error">Ungültige Eingabe, bitte überprüfen Sie das Zeichen.</string> <!-- Submission Intro --> <!-- XHED: Page title for menu at the start of the submission process --> @@ -2814,8 +2818,6 @@ as modifying the License. <string name="submission_status_card_button_unregistered">Informieren & mitmachen</string> <!-- XBUT: submission status card show results button --> <string name="submission_status_card_button_show_results">Test anzeigen</string> - <!-- XBUT: submission status card show details button --> - <string name="submission_status_card_button_show_details">Details anzeigen</string> <!-- XHED: submission status card positive result title --> <string name="submission_status_card_positive_result_title">Positives Ergebnis</string> <!-- XHED: submission status card positive result subtitle --> diff --git a/Corona-Warn-App/src/main/res/values/styles.xml b/Corona-Warn-App/src/main/res/values/styles.xml index 263640fb389abd0f4ffd0dbe1a0bf5555229e387..4039163558da94eb9bb6de99666ac759738af23f 100644 --- a/Corona-Warn-App/src/main/res/values/styles.xml +++ b/Corona-Warn-App/src/main/res/values/styles.xml @@ -99,6 +99,10 @@ <item name="android:elevation">@dimen/elevation_strong</item> </style> + <style name="cardNoPadding" parent="card"> + <item name="android:padding">@dimen/no_padding</item> + </style> + <style name="cardTracing"> <item name="android:padding">@dimen/card_padding</item> <item name="android:background">@drawable/card</item> @@ -106,8 +110,7 @@ </style> <style name="cardGrey"> - <item name="android:background">@drawable/card</item> - <item name="android:backgroundTint">@color/colorSurface2</item> + <item name="android:background">@drawable/card_dark</item> </style> @@ -216,6 +219,13 @@ <item name="android:gravity">center</item> </style> + <style name="tanInputDash" parent="headline6"> + <item name="android:layout_width">@dimen/submission_tan_input_dash_width</item> + <item name="android:layout_height">@dimen/submission_tan_input_dash_height</item> + <item name="android:background">@null</item> + <item name="android:gravity">center</item> + </style> + <style name="tanInputEdittext"> <item name="android:layout_width">@dimen/submission_tan_input_edittext_size</item> <item name="android:layout_height">@dimen/submission_tan_input_edittext_size</item> diff --git a/Corona-Warn-App/src/main/res/xml/network_security_config.xml b/Corona-Warn-App/src/main/res/xml/network_security_config.xml index 6ec4e91c1f8786782c2f4b604509eebea660dbd3..16b3be10f24fdeca65ff00264843dc4ae67fbd17 100644 --- a/Corona-Warn-App/src/main/res/xml/network_security_config.xml +++ b/Corona-Warn-App/src/main/res/xml/network_security_config.xml @@ -4,7 +4,7 @@ <domain-config cleartextTrafficPermitted="false"> <!-- TODO Add Production Domain for Verification Service--> <domain includeSubdomains="true">submission.coronawarn.app</domain> - <domain includeSubdomains="true">prodVerify.com</domain> + <domain includeSubdomains="true">verification.coronawarn.app</domain> <pin-set expiration="2024-02-12" tools:ignore="MissingBackupPin"> <pin digest="SHA-256">c3jf+L8VIAFQnJJDM6Mfb4MtI1JnhVS8JwZHMwJj28M=</pin> </pin-set> diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/WebRequestBuilderTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/WebRequestBuilderTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..305daf8a9ee5ecf9aa965165964ee2591a01a067 --- /dev/null +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/http/WebRequestBuilderTest.kt @@ -0,0 +1,78 @@ +package de.rki.coronawarnapp.http + +import de.rki.coronawarnapp.http.service.DistributionService +import de.rki.coronawarnapp.http.service.SubmissionService +import de.rki.coronawarnapp.http.service.VerificationService +import de.rki.coronawarnapp.service.diagnosiskey.DiagnosisKeyConstants +import de.rki.coronawarnapp.util.TimeAndDateExtensions.toServerFormat +import de.rki.coronawarnapp.util.security.VerificationKeys +import io.mockk.MockKAnnotations +import io.mockk.clearAllMocks +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.mockkObject +import io.mockk.unmockkAll +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import java.util.Date + +class WebRequestBuilderTest { + @MockK private lateinit var verificationService: VerificationService + @MockK private lateinit var distributionService: DistributionService + @MockK private lateinit var submissionService: SubmissionService + @MockK private lateinit var verificationKeys: VerificationKeys + + private lateinit var webRequestBuilder: WebRequestBuilder + + @Before + fun setUp() = run { + MockKAnnotations.init(this) + webRequestBuilder = WebRequestBuilder( + distributionService, + verificationService, + submissionService, + verificationKeys + ) + } + + @After + fun tearDown() = unmockkAll() + + @Test + fun retrievingDateIndexIsSuccessful() { + val urlString = DiagnosisKeyConstants.AVAILABLE_DATES_URL + coEvery { distributionService.getDateIndex(urlString) } + .returns(listOf("1900-01-01", "2000-01-01")) + + runBlocking { + val expectedResult = listOf("1900-01-01", "2000-01-01") + Assert.assertEquals(webRequestBuilder.asyncGetDateIndex(), expectedResult) + coVerify { + distributionService.getDateIndex(urlString) + } + } + } + + @Test + fun asyncGetHourIndex() { + val day = Date() + val urlString = DiagnosisKeyConstants.AVAILABLE_DATES_URL + + "/${day.toServerFormat()}/${DiagnosisKeyConstants.HOUR}" + + coEvery { distributionService.getHourIndex(urlString) } + .returns(listOf("1", "2")) + + runBlocking { + val expectedResult = listOf("1", "2") + Assert.assertEquals(webRequestBuilder.asyncGetHourIndex(day), expectedResult) + coVerify { + distributionService.getHourIndex(urlString) + } + } + } +} \ No newline at end of file diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModelTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModelTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..fe08e5de2a9d974e1c13b4d11111cee9b0cd84d2 --- /dev/null +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/ui/submission/SubmissionTanViewModelTest.kt @@ -0,0 +1,61 @@ +package de.rki.coronawarnapp.ui.submission + +import com.google.android.gms.nearby.exposurenotification.ExposureSummary +import de.rki.coronawarnapp.storage.SubmissionRepository +import de.rki.coronawarnapp.util.TanHelper +import io.mockk.* +import org.junit.Assert.* +import org.junit.Test + +class SubmissionTanViewModelTest { + private var viewModel: SubmissionTanViewModel = SubmissionTanViewModel() + + @Test + fun allCharactersValid() { + viewModel.tan.postValue("ABCD") + viewModel.tanCharactersValid.value?.let { assertTrue(it) } + + viewModel.tan.postValue("ABCD0") + viewModel.tanCharactersValid.value?.let { assertFalse(it) } + + } + + @Test + fun tanFormatValid() { + viewModel.tan.postValue("ZWFPC7NG47") + viewModel.isValidTanFormat.value?.let { assertTrue(it) } + + viewModel.tan.postValue("ABC") + viewModel.isValidTanFormat.value?.let { assertFalse(it) } + + viewModel.tan.postValue("ZWFPC7NG48") + viewModel.isValidTanFormat.value?.let { assertFalse(it) } + + viewModel.tan.postValue("ZWFPC7NG4A") + viewModel.isValidTanFormat.value?.let { assertFalse(it) } + } + + @Test + fun checksumValid() { + viewModel.tan.postValue("ZWFPC7NG47") + viewModel.tanChecksumValid.value?.let { assertTrue(it) } + + viewModel.tan.postValue("ZWFPC7NG48") + viewModel.tanChecksumValid.value?.let { assertFalse(it) } + } + + @Test + fun testTanStorage() { + val sr = mockk<SubmissionRepository> { + every { setTeletan(any()) } just Runs + } + val tan = "ZWFPC7NG47"; + sr.setTeletan(tan) + + verify (exactly = 1) { sr.setTeletan( + withArg { + assertEquals(it, tan) + }) + } + } +} \ No newline at end of file diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/TanHelperTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/TanHelperTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..d3c4a11201a9d5db9e242e35ff16964a7ba130ce --- /dev/null +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/util/TanHelperTest.kt @@ -0,0 +1,88 @@ +package de.rki.coronawarnapp.util + +import de.rki.coronawarnapp.service.submission.SubmissionService +import org.hamcrest.CoreMatchers +import org.hamcrest.MatcherAssert +import org.junit.Test + +class TanHelperTest { + + @Test + fun isValidCharacter() { + // valid + val validCharacters = arrayOf( + "2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H", + "J","K","M","N","P","Q","R","S","T","U","V","W","X","Y","Z" + ) + for (character in validCharacters) { + MatcherAssert.assertThat( + TanHelper.isTanCharacterValid(character), + CoreMatchers.equalTo(true) + ) + } + + // invalid + val invalidCharacters = arrayOf( + "0","1","O","L","I","Ö","*","&","-","a","b", + "c","ö","ß","é","."," ","€","(",")",";","," + ) + for (character in invalidCharacters) { + MatcherAssert.assertThat( + TanHelper.isTanCharacterValid(character), + CoreMatchers.equalTo(false) + ) + } + } + + @Test + fun areCharactersValid() { + // valid input strings (not necessarily valid TANs) + val validStrings = arrayOf( + "ABCD", "2345", "PTPHM35RP4", "AAAAAAAAAA", "BBBBB") + for (text in validStrings) { + MatcherAssert.assertThat( + TanHelper.allCharactersValid(text), + CoreMatchers.equalTo(true) + ) + } + + // invalid input strings + val invalidStrings = arrayOf( + "ABCDÖ", "01234", "PTPHM15RP4", "AAAAAA AAA", "BB.BBB") + for (text in invalidStrings) { + MatcherAssert.assertThat( + TanHelper.allCharactersValid(text), + CoreMatchers.equalTo(false) + ) + } + } + + @Test + fun isChecksumValid() { + // valid + val validTans = arrayOf( + "9A3B578UMG", "DEU7TKSV3H", "PTPHM35RP4", "V923D59AT8", "H9NC5CQ34E") + for (tan in validTans) { + MatcherAssert.assertThat( + TanHelper.isChecksumValid(tan), + CoreMatchers.equalTo(true) + ) + } + + // invalid + val invalidTans = arrayOf( + "DEU7TKSV32", "DEU7TKSV33", "DEU7TKSV34", "DEU7TKSV35", + "DEU7TKSV36", "DEU7TKSV37", "DEU7TKSV38", "DEU7TKSV39", + "DEU7TKSV3A", "DEU7TKSV3B", "DEU7TKSV3C", "DEU7TKSV3D", + "DEU7TKSV3E", "DEU7TKSV3F", "DEU7TKSV3G", + " QV5FQ38MA", + "9A3B578UM0", "DEU7TKSV31", "Q4XBJCB43", "929B96CA8" + ) + for (tan in invalidTans) { + MatcherAssert.assertThat( + TanHelper.isChecksumValid(tan), + CoreMatchers.equalTo(false) + ) + } + } +} \ No newline at end of file