From 738b4427f5541d7000e2b898263bab8c469045ee Mon Sep 17 00:00:00 2001 From: Mykhailo Nester Date: Mon, 11 Oct 2021 11:40:01 +0300 Subject: [PATCH] Improvement/code cleanup (#231) - fix lint warnings; - code cleanup in verification package; - remove empty spaces; - improve readability; - improve formatting; --- .idea/misc.xml | 16 ++ .../engine/data/source/local/RulesDaoTest.kt | 2 +- .../dgca/verifier/app/android/MainActivity.kt | 6 +- .../anonymization/AnonymizationManager.kt | 2 +- .../app/android/data/ConfigRepositoryImpl.kt | 9 +- .../android/data/VerifierRepositoryImpl.kt | 5 +- .../app/android/data/local/AppDatabase.kt | 1 + .../verifier/app/android/data/local/KeyDao.kt | 1 + .../data/local/countries/CountriesDao.kt | 1 + .../DefaultCountriesLocalDataSource.kt | 11 +- .../{countries => model}/CountryLocal.kt | 2 +- .../{rules => model}/DescriptionLocal.kt | 4 +- .../app/android/data/local/{ => model}/Key.kt | 2 +- .../{rules => model}/RuleIdentifierLocal.kt | 2 +- .../data/local/{rules => model}/RuleLocal.kt | 2 +- .../RuleWithDescriptionsLocal.kt | 4 +- .../ValueSetIdentifierLocal.kt | 2 +- .../{valuesets => model}/ValueSetLocal.kt | 2 +- .../android/data/local/rules/Converters.kt | 3 +- .../data/local/rules/EngineDatabase.kt | 9 +- .../local/rules/RuleIdentifierLocalMapper.kt | 27 +-- .../data/local/rules/RuleLocalMapper.kt | 93 ++++----- .../app/android/data/local/rules/RulesDao.kt | 4 + .../local/valuesets/ValueSetLocalMapper.kt | 42 ++-- .../data/local/valuesets/ValueSetsDao.kt | 2 + .../app/android/data/remote/ApiService.kt | 4 - .../DefaultCountriesRemoteDataSource.kt | 7 +- .../rules/DefaultRulesRemoteDataSource.kt | 6 +- .../DefaultValueSetsRemoteDataSource.kt | 7 +- .../verifier/app/android/di/EngineModule.kt | 5 +- .../verifier/app/android/di/NetworkModule.kt | 8 +- .../app/android/model/CertificateModel.kt | 5 + .../dgca/verifier/app/android/model/Mapper.kt | 70 ++++--- .../app/android/model/rules/RuleModel.kt | 12 +- .../RuleValidationResultModelsContainer.kt | 3 +- .../app/android/model/rules/RulesMapper.kt | 85 +++----- .../app/android/nfc/ParsedNdefRecord.kt | 1 + .../{ => reader}/CodeReaderFragment.kt | 73 ++++--- .../{ => reader}/CodeReaderViewModel.kt | 12 +- .../android/{ => reader}/CountriesAdapter.kt | 23 +-- .../security/DefaultKeyStoreCryptor.kt | 14 +- .../android/security/SecurityKeyWrapper.kt | 5 +- .../app/android/settings/SettingsFragment.kt | 16 +- .../app/android/settings/SettingsViewModel.kt | 5 +- .../settings/debug/mode/CountriesAdapter.kt | 36 ++-- .../debug/mode/CountriesSelectorFragment.kt | 16 +- .../debug/mode/DebugModeSettingsFragment.kt | 85 ++++---- .../debug/mode/DebugModeSettingsViewModel.kt | 9 +- .../settings/debug/mode/DebugModeState.kt | 5 +- .../android/{ => utils}/BackportUtils.java | 4 +- .../app/android/{ => utils}/DimensionExt.kt | 2 +- .../verifier/app/android/utils/Extenssions.kt | 1 - .../app/android/{ => utils}/TextUtils.kt | 4 +- .../app/android/{ => utils}/TimeExt.kt | 43 ++-- .../android/{ => utils}/ViewHolderUtils.kt | 2 +- .../BaseVerificationDialogFragment.kt | 23 ++- .../verification/VerificationFragment.kt | 2 + .../VerificationResultDialogFragment.kt | 187 ++++++++---------- .../verification/VerificationViewModel.kt | 37 ++-- .../verification/certs/RecoveryViewHolder.kt | 23 +-- .../verification/certs/TestViewHolder.kt | 15 +- .../certs/VaccinationViewHolder.kt | 17 +- .../detailed/CertificateContentAdapter.kt | 1 - .../detailed/CertificateContentView.kt | 3 +- ...DetailedBaseVerificationResultViewModel.kt | 2 +- .../detailed/DetailedCertificateRawView.kt | 4 +- .../detailed/DetailedCertificateView.kt | 40 ++-- ...etailedVerificationResultDialogFragment.kt | 5 +- .../DetailedVerificationResultHeaderView.kt | 4 +- .../DetailedVerificationResultView.kt | 10 +- .../detailed/qr/DefaultQrCodeConverter.kt | 1 + .../RuleValidationResultMapper.kt | 28 +-- .../{ => model}/InnerVerificationResult.kt | 2 +- .../model/QrCodeVerificationResult.kt | 39 ++++ .../RuleValidationResultCard.kt} | 16 +- .../StandardizedVerificationResult.kt | 4 +- .../rules/RuleValidationResultCard.kt | 53 ----- .../rules/RuleValidationResultsAdapter.kt | 49 ++--- .../main/res/color/btn_toggle_selector.xml | 26 --- app/src/main/res/drawable-hdpi/icon_check.png | Bin 1234 -> 0 bytes app/src/main/res/drawable-hdpi/icon_error.png | Bin 801 -> 0 bytes app/src/main/res/drawable-ldpi/icon_check.png | Bin 648 -> 0 bytes app/src/main/res/drawable-ldpi/icon_error.png | Bin 493 -> 0 bytes app/src/main/res/drawable-mdpi/icon_check.png | Bin 762 -> 0 bytes app/src/main/res/drawable-mdpi/icon_error.png | Bin 589 -> 0 bytes .../main/res/drawable-xhdpi/icon_check.png | Bin 1652 -> 0 bytes .../main/res/drawable-xhdpi/icon_error.png | Bin 1048 -> 0 bytes .../main/res/drawable-xxhdpi/icon_check.png | Bin 2446 -> 0 bytes .../main/res/drawable-xxhdpi/icon_error.png | Bin 2245 -> 0 bytes .../main/res/drawable-xxxhdpi/icon_check.png | Bin 3440 -> 0 bytes .../main/res/drawable-xxxhdpi/icon_error.png | Bin 3104 -> 0 bytes .../layout/fragment_countries_selector.xml | 3 +- .../res/layout/item_certificate_content.xml | 3 +- app/src/main/res/layout/item_country.xml | 4 +- .../layout/view_certificate_content_view.xml | 2 +- .../view_detailed_certificate_raw_view.xml | 2 +- .../layout/view_detailed_certificate_view.xml | 2 +- .../view_detailed_verification_result.xml | 8 +- app/src/main/res/navigation/nav_graph.xml | 8 +- app/src/main/res/values/colors.xml | 1 - app/src/main/res/values/styles.xml | 11 -- .../verifier/app/android/CertificateTests.kt | 23 +-- .../dgca/verifier/app/android/TimeExtTest.kt | 1 + .../BaseVerificationResultViewModelKtTest.kt | 12 +- 104 files changed, 658 insertions(+), 835 deletions(-) rename app/src/main/java/dgca/verifier/app/android/data/local/{countries => model}/CountryLocal.kt (94%) rename app/src/main/java/dgca/verifier/app/android/data/local/{rules => model}/DescriptionLocal.kt (92%) rename app/src/main/java/dgca/verifier/app/android/data/local/{ => model}/Key.kt (95%) rename app/src/main/java/dgca/verifier/app/android/data/local/{rules => model}/RuleIdentifierLocal.kt (95%) rename app/src/main/java/dgca/verifier/app/android/data/local/{rules => model}/RuleLocal.kt (96%) rename app/src/main/java/dgca/verifier/app/android/data/local/{rules => model}/RuleWithDescriptionsLocal.kt (91%) rename app/src/main/java/dgca/verifier/app/android/data/local/{valuesets => model}/ValueSetIdentifierLocal.kt (95%) rename app/src/main/java/dgca/verifier/app/android/data/local/{valuesets => model}/ValueSetLocal.kt (95%) rename app/src/main/java/dgca/verifier/app/android/{ => reader}/CodeReaderFragment.kt (92%) rename app/src/main/java/dgca/verifier/app/android/{ => reader}/CodeReaderViewModel.kt (98%) rename app/src/main/java/dgca/verifier/app/android/{ => reader}/CountriesAdapter.kt (71%) rename app/src/main/java/dgca/verifier/app/android/{ => utils}/BackportUtils.java (90%) rename app/src/main/java/dgca/verifier/app/android/{ => utils}/DimensionExt.kt (96%) rename app/src/main/java/dgca/verifier/app/android/{ => utils}/TextUtils.kt (92%) rename app/src/main/java/dgca/verifier/app/android/{ => utils}/TimeExt.kt (66%) rename app/src/main/java/dgca/verifier/app/android/{ => utils}/ViewHolderUtils.kt (97%) rename app/src/main/java/dgca/verifier/app/android/verification/{rules => mapper}/RuleValidationResultMapper.kt (53%) rename app/src/main/java/dgca/verifier/app/android/verification/{ => model}/InnerVerificationResult.kt (96%) create mode 100644 app/src/main/java/dgca/verifier/app/android/verification/model/QrCodeVerificationResult.kt rename app/src/main/java/dgca/verifier/app/android/verification/{VerificationResultResultViewModel.kt => model/RuleValidationResultCard.kt} (72%) rename app/src/main/java/dgca/verifier/app/android/verification/{ => model}/StandardizedVerificationResult.kt (97%) delete mode 100644 app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultCard.kt delete mode 100644 app/src/main/res/color/btn_toggle_selector.xml delete mode 100644 app/src/main/res/drawable-hdpi/icon_check.png delete mode 100644 app/src/main/res/drawable-hdpi/icon_error.png delete mode 100644 app/src/main/res/drawable-ldpi/icon_check.png delete mode 100644 app/src/main/res/drawable-ldpi/icon_error.png delete mode 100644 app/src/main/res/drawable-mdpi/icon_check.png delete mode 100644 app/src/main/res/drawable-mdpi/icon_error.png delete mode 100644 app/src/main/res/drawable-xhdpi/icon_check.png delete mode 100644 app/src/main/res/drawable-xhdpi/icon_error.png delete mode 100644 app/src/main/res/drawable-xxhdpi/icon_check.png delete mode 100644 app/src/main/res/drawable-xxhdpi/icon_error.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/icon_check.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/icon_error.png diff --git a/.idea/misc.xml b/.idea/misc.xml index bb68a0f6..92427fc3 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -8,12 +8,28 @@ + + + + + + diff --git a/app/src/androidTest/java/dgca/verifier/app/engine/data/source/local/RulesDaoTest.kt b/app/src/androidTest/java/dgca/verifier/app/engine/data/source/local/RulesDaoTest.kt index d35f2525..4ec44bf1 100644 --- a/app/src/androidTest/java/dgca/verifier/app/engine/data/source/local/RulesDaoTest.kt +++ b/app/src/androidTest/java/dgca/verifier/app/engine/data/source/local/RulesDaoTest.kt @@ -28,7 +28,7 @@ import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.fasterxml.jackson.databind.ObjectMapper import dgca.verifier.app.android.data.local.rules.EngineDatabase -import dgca.verifier.app.android.data.local.rules.RuleWithDescriptionsLocal +import dgca.verifier.app.android.data.local.model.RuleWithDescriptionsLocal import dgca.verifier.app.android.data.local.rules.RulesDao import dgca.verifier.app.android.data.local.rules.toRuleWithDescriptionLocal import dgca.verifier.app.engine.data.RuleCertificateType diff --git a/app/src/main/java/dgca/verifier/app/android/MainActivity.kt b/app/src/main/java/dgca/verifier/app/android/MainActivity.kt index 66a36e2d..e3efa1af 100644 --- a/app/src/main/java/dgca/verifier/app/android/MainActivity.kt +++ b/app/src/main/java/dgca/verifier/app/android/MainActivity.kt @@ -33,6 +33,7 @@ import androidx.navigation.NavController import androidx.navigation.fragment.NavHostFragment import dagger.hilt.android.AndroidEntryPoint import dgca.verifier.app.android.nfc.NdefParser +import dgca.verifier.app.android.reader.CodeReaderFragment import timber.log.Timber @AndroidEntryPoint @@ -43,7 +44,10 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE) + if (!BuildConfig.DEBUG) { + window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE) + } + setContentView(R.layout.activity_main) navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment diff --git a/app/src/main/java/dgca/verifier/app/android/anonymization/AnonymizationManager.kt b/app/src/main/java/dgca/verifier/app/android/anonymization/AnonymizationManager.kt index 67e82633..8e29bed7 100644 --- a/app/src/main/java/dgca/verifier/app/android/anonymization/AnonymizationManager.kt +++ b/app/src/main/java/dgca/verifier/app/android/anonymization/AnonymizationManager.kt @@ -90,7 +90,6 @@ class AnonymizationManager @Inject constructor() { dateOfBirth = dateOfBirth ) } - } fun String.anonymize(): String { @@ -143,5 +142,6 @@ fun String.anonymize(): String { fun String.anonymizeCi(): String { val ciPart = substring(lastIndexOf(":") + 1) val ciAnonymize = "[A-Za-z0-9]".toRegex().replace(ciPart, "X") + return replaceAfterLast(":", ciAnonymize) } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/data/ConfigRepositoryImpl.kt b/app/src/main/java/dgca/verifier/app/android/data/ConfigRepositoryImpl.kt index 49ca9f8e..307f8acf 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/ConfigRepositoryImpl.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/ConfigRepositoryImpl.kt @@ -32,15 +32,12 @@ class ConfigRepositoryImpl @Inject constructor( private val remoteConfigDataSource: RemoteConfigDataSource ) : ConfigRepository { - override fun local(): ConfigDataSource { - return localConfigDataSource - } + override fun local(): ConfigDataSource = localConfigDataSource - override fun getConfig(): Config { - return remoteConfigDataSource.getConfig( + override fun getConfig(): Config = + remoteConfigDataSource.getConfig( localConfigDataSource.getConfig().getContextUrl(BuildConfig.VERSION_NAME) ).apply { localConfigDataSource.setConfig(this) } - } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/data/VerifierRepositoryImpl.kt b/app/src/main/java/dgca/verifier/app/android/data/VerifierRepositoryImpl.kt index 51c8069a..bfde69d3 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/VerifierRepositoryImpl.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/VerifierRepositoryImpl.kt @@ -25,8 +25,8 @@ package dgca.verifier.app.android.data import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import dgca.verifier.app.android.data.local.AppDatabase -import dgca.verifier.app.android.data.local.Key import dgca.verifier.app.android.data.local.Preferences +import dgca.verifier.app.android.data.local.model.Key import dgca.verifier.app.android.data.remote.ApiService import dgca.verifier.app.android.security.KeyStoreCryptor import dgca.verifier.app.decoder.base64ToX509Certificate @@ -48,8 +48,7 @@ class VerifierRepositoryImpl @Inject constructor( private val validCertList = mutableListOf() private val mutex = Mutex() - private val lastSyncLiveData: MutableLiveData = - MutableLiveData(preferences.lastKeysSyncTimeMillis) + private val lastSyncLiveData: MutableLiveData = MutableLiveData(preferences.lastKeysSyncTimeMillis) override suspend fun fetchCertificates(statusUrl: String, updateUrl: String): Boolean? { mutex.withLock { diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/AppDatabase.kt b/app/src/main/java/dgca/verifier/app/android/data/local/AppDatabase.kt index 638aa53f..68136347 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/AppDatabase.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/AppDatabase.kt @@ -24,6 +24,7 @@ package dgca.verifier.app.android.data.local import androidx.room.Database import androidx.room.RoomDatabase +import dgca.verifier.app.android.data.local.model.Key @Database(entities = [Key::class], version = 1) abstract class AppDatabase : RoomDatabase() { diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/KeyDao.kt b/app/src/main/java/dgca/verifier/app/android/data/local/KeyDao.kt index 62154f20..a55056db 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/KeyDao.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/KeyDao.kt @@ -26,6 +26,7 @@ import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.Query +import dgca.verifier.app.android.data.local.model.Key @Dao interface KeyDao { diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/countries/CountriesDao.kt b/app/src/main/java/dgca/verifier/app/android/data/local/countries/CountriesDao.kt index ecba524d..17b5919e 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/countries/CountriesDao.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/countries/CountriesDao.kt @@ -25,6 +25,7 @@ package dgca.verifier.app.android.data.local.countries import androidx.room.Dao import androidx.room.Insert import androidx.room.Query +import dgca.verifier.app.android.data.local.model.CountryLocal import kotlinx.coroutines.flow.Flow @Dao diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/countries/DefaultCountriesLocalDataSource.kt b/app/src/main/java/dgca/verifier/app/android/data/local/countries/DefaultCountriesLocalDataSource.kt index 4d602281..a1a1ff7f 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/countries/DefaultCountriesLocalDataSource.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/countries/DefaultCountriesLocalDataSource.kt @@ -22,13 +22,14 @@ package dgca.verifier.app.android.data.local.countries +import dgca.verifier.app.android.data.local.model.CountryLocal import dgca.verifier.app.engine.data.source.local.countries.CountriesLocalDataSource import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import java.util.* -class DefaultCountriesLocalDataSource(private val countriesDao: CountriesDao) : - CountriesLocalDataSource { +class DefaultCountriesLocalDataSource(private val countriesDao: CountriesDao) : CountriesLocalDataSource { + override suspend fun updateCountries(countriesIsoCodes: List) { countriesDao.apply { deleteAll() @@ -37,9 +38,9 @@ class DefaultCountriesLocalDataSource(private val countriesDao: CountriesDao) : } override fun getCountries(): Flow> = - countriesDao.getAll().map { it.map { it.toCountry() } } + countriesDao.getAll().map { it.map { countryLocal -> countryLocal.toCountry() } } } -fun String.toCountryLocal(): CountryLocal = CountryLocal(isoCode = this.toLowerCase(Locale.ROOT)) +fun String.toCountryLocal(): CountryLocal = CountryLocal(isoCode = toLowerCase(Locale.ROOT)) -fun CountryLocal.toCountry(): String = this.isoCode \ No newline at end of file +fun CountryLocal.toCountry(): String = isoCode \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/countries/CountryLocal.kt b/app/src/main/java/dgca/verifier/app/android/data/local/model/CountryLocal.kt similarity index 94% rename from app/src/main/java/dgca/verifier/app/android/data/local/countries/CountryLocal.kt rename to app/src/main/java/dgca/verifier/app/android/data/local/model/CountryLocal.kt index 010e12b8..f49c20b0 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/countries/CountryLocal.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/model/CountryLocal.kt @@ -20,7 +20,7 @@ * Created by osarapulov on 7/26/21 11:56 AM */ -package dgca.verifier.app.android.data.local.countries +package dgca.verifier.app.android.data.local.model import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/rules/DescriptionLocal.kt b/app/src/main/java/dgca/verifier/app/android/data/local/model/DescriptionLocal.kt similarity index 92% rename from app/src/main/java/dgca/verifier/app/android/data/local/rules/DescriptionLocal.kt rename to app/src/main/java/dgca/verifier/app/android/data/local/model/DescriptionLocal.kt index 285bb24b..348dfb08 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/rules/DescriptionLocal.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/model/DescriptionLocal.kt @@ -17,10 +17,10 @@ * limitations under the License. * ---license-end * - * Created by osarapulov on 7/26/21 12:01 PM + * Created by mykhailo.nester on 10/10/2021, 10:51 */ -package dgca.verifier.app.android.data.local.rules +package dgca.verifier.app.android.data.local.model import androidx.room.Entity import androidx.room.ForeignKey diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/Key.kt b/app/src/main/java/dgca/verifier/app/android/data/local/model/Key.kt similarity index 95% rename from app/src/main/java/dgca/verifier/app/android/data/local/Key.kt rename to app/src/main/java/dgca/verifier/app/android/data/local/model/Key.kt index ee38b75a..9fa9f4f7 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/Key.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/model/Key.kt @@ -20,7 +20,7 @@ * Created by osarapulov on 4/29/21 11:32 PM */ -package dgca.verifier.app.android.data.local +package dgca.verifier.app.android.data.local.model import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleIdentifierLocal.kt b/app/src/main/java/dgca/verifier/app/android/data/local/model/RuleIdentifierLocal.kt similarity index 95% rename from app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleIdentifierLocal.kt rename to app/src/main/java/dgca/verifier/app/android/data/local/model/RuleIdentifierLocal.kt index 12bc9fc8..78eaebb9 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleIdentifierLocal.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/model/RuleIdentifierLocal.kt @@ -20,7 +20,7 @@ * Created by osarapulov on 7/26/21 12:04 PM */ -package dgca.verifier.app.android.data.local.rules +package dgca.verifier.app.android.data.local.model import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleLocal.kt b/app/src/main/java/dgca/verifier/app/android/data/local/model/RuleLocal.kt similarity index 96% rename from app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleLocal.kt rename to app/src/main/java/dgca/verifier/app/android/data/local/model/RuleLocal.kt index 23928a44..e646baec 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleLocal.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/model/RuleLocal.kt @@ -20,7 +20,7 @@ * Created by osarapulov on 7/26/21 12:05 PM */ -package dgca.verifier.app.android.data.local.rules +package dgca.verifier.app.android.data.local.model import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleWithDescriptionsLocal.kt b/app/src/main/java/dgca/verifier/app/android/data/local/model/RuleWithDescriptionsLocal.kt similarity index 91% rename from app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleWithDescriptionsLocal.kt rename to app/src/main/java/dgca/verifier/app/android/data/local/model/RuleWithDescriptionsLocal.kt index 1212eb1a..74d26030 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleWithDescriptionsLocal.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/model/RuleWithDescriptionsLocal.kt @@ -17,10 +17,10 @@ * limitations under the License. * ---license-end * - * Created by osarapulov on 7/26/21 12:06 PM + * Created by mykhailo.nester on 10/10/2021, 11:13 */ -package dgca.verifier.app.android.data.local.rules +package dgca.verifier.app.android.data.local.model import androidx.room.Embedded import androidx.room.Relation diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetIdentifierLocal.kt b/app/src/main/java/dgca/verifier/app/android/data/local/model/ValueSetIdentifierLocal.kt similarity index 95% rename from app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetIdentifierLocal.kt rename to app/src/main/java/dgca/verifier/app/android/data/local/model/ValueSetIdentifierLocal.kt index ef61ef1d..605a9e53 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetIdentifierLocal.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/model/ValueSetIdentifierLocal.kt @@ -20,7 +20,7 @@ * Created by mykhailo.nester on 21/09/2021, 22:19 */ -package dgca.verifier.app.android.data.local.valuesets +package dgca.verifier.app.android.data.local.model import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetLocal.kt b/app/src/main/java/dgca/verifier/app/android/data/local/model/ValueSetLocal.kt similarity index 95% rename from app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetLocal.kt rename to app/src/main/java/dgca/verifier/app/android/data/local/model/ValueSetLocal.kt index e7f20ac7..20abbfd1 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetLocal.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/model/ValueSetLocal.kt @@ -20,7 +20,7 @@ * Created by osarapulov on 7/26/21 12:08 PM */ -package dgca.verifier.app.android.data.local.valuesets +package dgca.verifier.app.android.data.local.model import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/rules/Converters.kt b/app/src/main/java/dgca/verifier/app/android/data/local/rules/Converters.kt index d4dd721e..6a814431 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/rules/Converters.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/rules/Converters.kt @@ -43,8 +43,7 @@ class Converters { @TypeConverter fun localDateToTimestamp(localDate: LocalDate?): Long { - return (localDate?.atStartOfDay(UTC_ZONE_ID) - ?: ZonedDateTime.now(UTC_ZONE_ID)).toInstant().toEpochMilli() + return (localDate?.atStartOfDay(UTC_ZONE_ID) ?: ZonedDateTime.now(UTC_ZONE_ID)).toInstant().toEpochMilli() } @TypeConverter diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/rules/EngineDatabase.kt b/app/src/main/java/dgca/verifier/app/android/data/local/rules/EngineDatabase.kt index b1d1088e..8e65be57 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/rules/EngineDatabase.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/rules/EngineDatabase.kt @@ -26,9 +26,12 @@ import androidx.room.Database import androidx.room.RoomDatabase import androidx.room.TypeConverters import dgca.verifier.app.android.data.local.countries.CountriesDao -import dgca.verifier.app.android.data.local.countries.CountryLocal -import dgca.verifier.app.android.data.local.valuesets.ValueSetIdentifierLocal -import dgca.verifier.app.android.data.local.valuesets.ValueSetLocal +import dgca.verifier.app.android.data.local.model.CountryLocal +import dgca.verifier.app.android.data.local.model.DescriptionLocal +import dgca.verifier.app.android.data.local.model.RuleIdentifierLocal +import dgca.verifier.app.android.data.local.model.RuleLocal +import dgca.verifier.app.android.data.local.model.ValueSetIdentifierLocal +import dgca.verifier.app.android.data.local.model.ValueSetLocal import dgca.verifier.app.android.data.local.valuesets.ValueSetsDao @Database( diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleIdentifierLocalMapper.kt b/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleIdentifierLocalMapper.kt index 6b6beeea..4043ab95 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleIdentifierLocalMapper.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleIdentifierLocalMapper.kt @@ -22,18 +22,21 @@ package dgca.verifier.app.android.data.local.rules +import dgca.verifier.app.android.data.local.model.RuleIdentifierLocal import dgca.verifier.app.engine.data.RuleIdentifier -fun RuleIdentifier.toRuleIdentifierLocal() = RuleIdentifierLocal( - identifier = this.identifier, - version = this.version, - country = this.country, - hash = this.hash -) +fun RuleIdentifier.toRuleIdentifierLocal() = + RuleIdentifierLocal( + identifier = identifier, + version = version, + country = country, + hash = hash + ) -fun RuleIdentifierLocal.toRuleIdentifier() = RuleIdentifier( - identifier = this.identifier, - version = this.version, - country = this.country, - hash = this.hash -) \ No newline at end of file +fun RuleIdentifierLocal.toRuleIdentifier() = + RuleIdentifier( + identifier = identifier, + version = version, + country = country, + hash = hash + ) \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleLocalMapper.kt b/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleLocalMapper.kt index 0d71296f..763c9a14 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleLocalMapper.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/rules/RuleLocalMapper.kt @@ -22,76 +22,63 @@ package dgca.verifier.app.android.data.local.rules +import dgca.verifier.app.android.data.local.model.DescriptionLocal +import dgca.verifier.app.android.data.local.model.RuleLocal +import dgca.verifier.app.android.data.local.model.RuleWithDescriptionsLocal import dgca.verifier.app.engine.UTC_ZONE_ID -import dgca.verifier.app.engine.data.Description import dgca.verifier.app.engine.data.Rule import java.util.* fun Rule.toRuleWithDescriptionLocal(): RuleWithDescriptionsLocal = - RuleWithDescriptionsLocal(this.toRuleLocal(), descriptions.toDescriptionsLocal()) + RuleWithDescriptionsLocal(toRuleLocal(), descriptions.toDescriptionsLocal()) -fun List.toRulesWithDescriptionLocal(): List { - val rulesWithDescriptionLocal = mutableListOf() - forEach { - rulesWithDescriptionLocal.add(it.toRuleWithDescriptionLocal()) - } - return rulesWithDescriptionLocal -} - -fun Rule.toRuleLocal(): RuleLocal = RuleLocal( - identifier = this.identifier, - type = this.type, - version = this.version, - schemaVersion = this.schemaVersion, - engine = this.engine, - engineVersion = this.engineVersion, - ruleCertificateType = this.ruleCertificateType, - validFrom = this.validFrom.withZoneSameInstant(UTC_ZONE_ID), - validTo = this.validTo.withZoneSameInstant(UTC_ZONE_ID), - affectedString = this.affectedString, - logic = this.logic, - countryCode = this.countryCode, - region = this.region -) - -fun Description.toDescriptionLocal(): DescriptionLocal = - DescriptionLocal(lang = this.lang, desc = this.desc) +fun Rule.toRuleLocal(): RuleLocal = + RuleLocal( + identifier = identifier, + type = type, + version = version, + schemaVersion = schemaVersion, + engine = engine, + engineVersion = engineVersion, + ruleCertificateType = ruleCertificateType, + validFrom = validFrom.withZoneSameInstant(UTC_ZONE_ID), + validTo = validTo.withZoneSameInstant(UTC_ZONE_ID), + affectedString = affectedString, + logic = logic, + countryCode = countryCode, + region = region + ) fun Map.toDescriptionsLocal(): List { val descriptionsLocal = mutableListOf() forEach { descriptionsLocal.add(DescriptionLocal(lang = it.key, desc = it.value)) } + return descriptionsLocal } -fun DescriptionLocal.toDescription(): Description = Description(lang = this.lang, desc = this.desc) - fun List.toDescriptions(): Map { val descriptions = mutableMapOf() forEach { descriptions[it.lang.toLowerCase(Locale.ROOT)] = it.desc } + return descriptions } -fun RuleWithDescriptionsLocal.toRule(): Rule = Rule( - identifier = this.rule.identifier, - type = this.rule.type, - version = this.rule.version, - schemaVersion = this.rule.schemaVersion, - engine = this.rule.engine, - engineVersion = this.rule.engineVersion, - ruleCertificateType = this.rule.ruleCertificateType, - validFrom = this.rule.validFrom.withZoneSameInstant(UTC_ZONE_ID), - validTo = this.rule.validTo.withZoneSameInstant(UTC_ZONE_ID), - affectedString = this.rule.affectedString, - logic = this.rule.logic, - countryCode = this.rule.countryCode, - descriptions = this.descriptions.toDescriptions(), - region = this.rule.region -) +fun RuleWithDescriptionsLocal.toRule(): Rule = + Rule( + identifier = rule.identifier, + type = rule.type, + version = rule.version, + schemaVersion = rule.schemaVersion, + engine = rule.engine, + engineVersion = rule.engineVersion, + ruleCertificateType = rule.ruleCertificateType, + validFrom = rule.validFrom.withZoneSameInstant(UTC_ZONE_ID), + validTo = rule.validTo.withZoneSameInstant(UTC_ZONE_ID), + affectedString = rule.affectedString, + logic = rule.logic, + countryCode = rule.countryCode, + descriptions = descriptions.toDescriptions(), + region = rule.region + ) -fun List.toRules(): List { - val rules = mutableListOf() - forEach { - rules.add(it.toRule()) - } - return rules -} \ No newline at end of file +fun List.toRules(): List = map { it.toRule() } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RulesDao.kt b/app/src/main/java/dgca/verifier/app/android/data/local/rules/RulesDao.kt index 53b7529e..636891f4 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/rules/RulesDao.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/rules/RulesDao.kt @@ -26,6 +26,10 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.Query import androidx.room.Transaction +import dgca.verifier.app.android.data.local.model.DescriptionLocal +import dgca.verifier.app.android.data.local.model.RuleIdentifierLocal +import dgca.verifier.app.android.data.local.model.RuleLocal +import dgca.verifier.app.android.data.local.model.RuleWithDescriptionsLocal import dgca.verifier.app.engine.data.RuleCertificateType import dgca.verifier.app.engine.data.Type import java.time.ZonedDateTime diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetLocalMapper.kt b/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetLocalMapper.kt index f401bb36..09be836e 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetLocalMapper.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetLocalMapper.kt @@ -22,27 +22,33 @@ package dgca.verifier.app.android.data.local.valuesets +import dgca.verifier.app.android.data.local.model.ValueSetIdentifierLocal +import dgca.verifier.app.android.data.local.model.ValueSetLocal import dgca.verifier.app.engine.data.ValueSet import dgca.verifier.app.engine.data.ValueSetIdentifier -fun ValueSet.toValueSetLocal(): ValueSetLocal = ValueSetLocal( - valueSetId = this.valueSetId, - valueSetDate = this.valueSetDate, - valueSetValues = this.valueSetValues -) +fun ValueSet.toValueSetLocal(): ValueSetLocal = + ValueSetLocal( + valueSetId = valueSetId, + valueSetDate = valueSetDate, + valueSetValues = valueSetValues + ) -fun ValueSetLocal.toValueSet(): ValueSet = ValueSet( - valueSetId = this.valueSetId, - valueSetDate = this.valueSetDate, - valueSetValues = this.valueSetValues -) +fun ValueSetLocal.toValueSet(): ValueSet = + ValueSet( + valueSetId = valueSetId, + valueSetDate = valueSetDate, + valueSetValues = valueSetValues + ) -fun ValueSetIdentifier.toValueSetIdentifierLocal(): ValueSetIdentifierLocal = ValueSetIdentifierLocal( - valueSetIdentifierId = id, - valueSetHash = hash -) +fun ValueSetIdentifier.toValueSetIdentifierLocal(): ValueSetIdentifierLocal = + ValueSetIdentifierLocal( + valueSetIdentifierId = id, + valueSetHash = hash + ) -fun ValueSetIdentifierLocal.toValueSetIdentifier(): ValueSetIdentifier = ValueSetIdentifier( - id = valueSetIdentifierId, - hash = valueSetHash -) \ No newline at end of file +fun ValueSetIdentifierLocal.toValueSetIdentifier(): ValueSetIdentifier = + ValueSetIdentifier( + id = valueSetIdentifierId, + hash = valueSetHash + ) \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetsDao.kt b/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetsDao.kt index 0e69762f..54a5dd75 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetsDao.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/local/valuesets/ValueSetsDao.kt @@ -26,6 +26,8 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.Query import androidx.room.Transaction +import dgca.verifier.app.android.data.local.model.ValueSetIdentifierLocal +import dgca.verifier.app.android.data.local.model.ValueSetLocal @Dao abstract class ValueSetsDao { diff --git a/app/src/main/java/dgca/verifier/app/android/data/remote/ApiService.kt b/app/src/main/java/dgca/verifier/app/android/data/remote/ApiService.kt index 6b15ef01..627aa5b8 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/remote/ApiService.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/remote/ApiService.kt @@ -23,7 +23,6 @@ package dgca.verifier.app.android.data.remote import dgca.verifier.app.android.data.Config -import dgca.verifier.app.engine.data.Rule import okhttp3.ResponseBody import retrofit2.Call import retrofit2.Response @@ -44,7 +43,4 @@ interface ApiService { @GET suspend fun getCertStatus(@Url url: String): Response> - - @GET - suspend fun getRules(@Url url: String): Response> } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/data/remote/countries/DefaultCountriesRemoteDataSource.kt b/app/src/main/java/dgca/verifier/app/android/data/remote/countries/DefaultCountriesRemoteDataSource.kt index 40d140ec..b30f3242 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/remote/countries/DefaultCountriesRemoteDataSource.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/remote/countries/DefaultCountriesRemoteDataSource.kt @@ -25,11 +25,10 @@ package dgca.verifier.app.android.data.remote.countries import dgca.verifier.app.engine.data.source.remote.countries.CountriesRemoteDataSrouce import retrofit2.Response -class DefaultCountriesRemoteDataSource(private val countriesApiService: CountriesApiService) : - CountriesRemoteDataSrouce { +class DefaultCountriesRemoteDataSource(private val countriesApiService: CountriesApiService) : CountriesRemoteDataSrouce { + override suspend fun getCountries(countriesUrl: String): List { - val countriesResponse: Response> = - countriesApiService.getCountries(countriesUrl) + val countriesResponse: Response> = countriesApiService.getCountries(countriesUrl) return countriesResponse.body() ?: listOf() } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/data/remote/rules/DefaultRulesRemoteDataSource.kt b/app/src/main/java/dgca/verifier/app/android/data/remote/rules/DefaultRulesRemoteDataSource.kt index acc43f9c..26c0806a 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/remote/rules/DefaultRulesRemoteDataSource.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/remote/rules/DefaultRulesRemoteDataSource.kt @@ -27,12 +27,10 @@ import dgca.verifier.app.engine.data.RuleIdentifier import dgca.verifier.app.engine.data.source.remote.rules.* import retrofit2.Response -class DefaultRulesRemoteDataSource(private val rulesApiService: RulesApiService) : - RulesRemoteDataSource { +class DefaultRulesRemoteDataSource(private val rulesApiService: RulesApiService) : RulesRemoteDataSource { override suspend fun getRuleIdentifiers(rulesUrl: String): List { - val rulesResponse: Response> = - rulesApiService.getRuleIdentifiers(rulesUrl) + val rulesResponse: Response> = rulesApiService.getRuleIdentifiers(rulesUrl) return rulesResponse.body()?.map { it.toRuleIdentifier() } ?: listOf() } diff --git a/app/src/main/java/dgca/verifier/app/android/data/remote/valuesets/DefaultValueSetsRemoteDataSource.kt b/app/src/main/java/dgca/verifier/app/android/data/remote/valuesets/DefaultValueSetsRemoteDataSource.kt index 58df5021..b68df074 100644 --- a/app/src/main/java/dgca/verifier/app/android/data/remote/valuesets/DefaultValueSetsRemoteDataSource.kt +++ b/app/src/main/java/dgca/verifier/app/android/data/remote/valuesets/DefaultValueSetsRemoteDataSource.kt @@ -27,11 +27,10 @@ import dgca.verifier.app.engine.data.source.remote.valuesets.ValueSetRemote import dgca.verifier.app.engine.data.source.remote.valuesets.ValueSetsRemoteDataSource import retrofit2.Response -class DefaultValueSetsRemoteDataSource(private val apiService: ValueSetsApiService) : - ValueSetsRemoteDataSource { +class DefaultValueSetsRemoteDataSource(private val apiService: ValueSetsApiService) : ValueSetsRemoteDataSource { + override suspend fun getValueSetsIdentifiers(url: String): List { - val response: Response> = - apiService.getValueSetsIdentifiers(url) + val response: Response> = apiService.getValueSetsIdentifiers(url) return response.body() ?: listOf() } diff --git a/app/src/main/java/dgca/verifier/app/android/di/EngineModule.kt b/app/src/main/java/dgca/verifier/app/android/di/EngineModule.kt index 4a15f45d..a1d6de48 100644 --- a/app/src/main/java/dgca/verifier/app/android/di/EngineModule.kt +++ b/app/src/main/java/dgca/verifier/app/android/di/EngineModule.kt @@ -117,7 +117,10 @@ object EngineModule { @Singleton @Provides - fun provideCertLogicEngine(affectedFieldsDataRetriever: AffectedFieldsDataRetriever, jsonLogicValidator: JsonLogicValidator): CertLogicEngine = + fun provideCertLogicEngine( + affectedFieldsDataRetriever: AffectedFieldsDataRetriever, + jsonLogicValidator: JsonLogicValidator + ): CertLogicEngine = DefaultCertLogicEngine(affectedFieldsDataRetriever, jsonLogicValidator) // Dependencies for countries. diff --git a/app/src/main/java/dgca/verifier/app/android/di/NetworkModule.kt b/app/src/main/java/dgca/verifier/app/android/di/NetworkModule.kt index af23f696..657e01a6 100644 --- a/app/src/main/java/dgca/verifier/app/android/di/NetworkModule.kt +++ b/app/src/main/java/dgca/verifier/app/android/di/NetworkModule.kt @@ -87,10 +87,7 @@ object NetworkModule { @Singleton @Provides - internal fun provideOkhttpClient( - cache: Cache, interceptor: Interceptor, - certificatePinner: CertificatePinner - ): OkHttpClient { + internal fun provideOkhttpClient(cache: Cache, interceptor: Interceptor, certificatePinner: CertificatePinner): OkHttpClient { val httpClient = getHttpClient(cache).apply { addInterceptor(HeaderInterceptor()) certificatePinner(certificatePinner) @@ -134,7 +131,8 @@ object NetworkModule { @Singleton @Provides - internal fun provideConverterFactory(objectMapper: ObjectMapper): Converter.Factory = JacksonConverterFactory.create(objectMapper) + internal fun provideConverterFactory(objectMapper: ObjectMapper): Converter.Factory = + JacksonConverterFactory.create(objectMapper) private fun createRetrofit(converterFactory: Converter.Factory, okHttpClient: Provider): Retrofit { return Retrofit.Builder() diff --git a/app/src/main/java/dgca/verifier/app/android/model/CertificateModel.kt b/app/src/main/java/dgca/verifier/app/android/model/CertificateModel.kt index c2da0ba0..e3a2fe14 100644 --- a/app/src/main/java/dgca/verifier/app/android/model/CertificateModel.kt +++ b/app/src/main/java/dgca/verifier/app/android/model/CertificateModel.kt @@ -33,6 +33,7 @@ data class CertificateModel( val tests: List?, val recoveryStatements: List? ) : Parcelable { + fun getFullName(): String { val givenName: String? = person.givenName?.trim() val familyName: String? = person.familyName?.trim() @@ -40,19 +41,23 @@ data class CertificateModel( if (givenName?.isNotEmpty() == true) { stringBuilder.append(givenName) } + if (familyName?.isNotEmpty() == true) { stringBuilder.append(" ").append(familyName) } + if (stringBuilder.isEmpty()) { val standardisedGivenName = person.standardisedGivenName if (standardisedGivenName?.isNotEmpty() == true) { stringBuilder.append(standardisedGivenName) } + val standardisedFamilyName = person.standardisedFamilyName if (standardisedFamilyName.isNotEmpty()) { stringBuilder.append(" ").append(standardisedFamilyName) } } + return stringBuilder.trim().toString() } } diff --git a/app/src/main/java/dgca/verifier/app/android/model/Mapper.kt b/app/src/main/java/dgca/verifier/app/android/model/Mapper.kt index a2026cc0..ffe1ab3b 100644 --- a/app/src/main/java/dgca/verifier/app/android/model/Mapper.kt +++ b/app/src/main/java/dgca/verifier/app/android/model/Mapper.kt @@ -24,18 +24,17 @@ package dgca.verifier.app.android.model import dgca.verifier.app.decoder.model.* -fun GreenCertificate.toCertificateModel(): CertificateModel { - return CertificateModel( +fun GreenCertificate.toCertificateModel(): CertificateModel = + CertificateModel( person = person.toPersonModel(), dateOfBirth = dateOfBirth, vaccinations = vaccinations?.map { it.toVaccinationModel() }, tests = tests?.map { it.toTestModel() }, recoveryStatements = recoveryStatements?.map { it.toRecoveryModel() } ) -} -fun RecoveryStatement.toRecoveryModel(): RecoveryModel { - return RecoveryModel( +fun RecoveryStatement.toRecoveryModel(): RecoveryModel = + RecoveryModel( disease = disease.toDiseaseCode().toDiseaseType(), dateOfFirstPositiveTest = dateOfFirstPositiveTest, countryOfVaccination = countryOfVaccination, @@ -44,10 +43,9 @@ fun RecoveryStatement.toRecoveryModel(): RecoveryModel { certificateValidUntil = certificateValidUntil, certificateIdentifier = certificateIdentifier ) -} -fun Test.toTestModel(): TestModel { - return TestModel( +fun Test.toTestModel(): TestModel = + TestModel( disease = disease.toDiseaseCode().toDiseaseType(), typeOfTest = typeOfTest.toTypeOfTestCode().toTypeOfTest(), testName = testName, @@ -61,28 +59,28 @@ fun Test.toTestModel(): TestModel { certificateIdentifier = certificateIdentifier, resultType = getTestResultType().toTestResult() ) -} -fun Test.TestResult.toTestResult(): TestResult { - return when (this) { +fun Test.TestResult.toTestResult(): TestResult = + when (this) { Test.TestResult.DETECTED -> TestResult.DETECTED Test.TestResult.NOT_DETECTED -> TestResult.NOT_DETECTED } -} -fun DiseaseCode.toDiseaseType(): DiseaseType = when (this) { - DiseaseCode.COVID_19 -> DiseaseType.COVID_19 - else -> DiseaseType.UNDEFINED -} +fun DiseaseCode.toDiseaseType(): DiseaseType = + when (this) { + DiseaseCode.COVID_19 -> DiseaseType.COVID_19 + else -> DiseaseType.UNDEFINED + } -fun TypeOfTestCode.toTypeOfTest(): TypeOfTest = when (this) { - TypeOfTestCode.NUCLEIC_ACID_AMPLIFICATION_WITH_PROBE_DETECTION -> TypeOfTest.NUCLEIC_ACID_AMPLIFICATION_WITH_PROBE_DETECTION - TypeOfTestCode.RAPID_IMMUNOASSAY -> TypeOfTest.RAPID_IMMUNOASSAY - else -> TypeOfTest.UNDEFINED -} +fun TypeOfTestCode.toTypeOfTest(): TypeOfTest = + when (this) { + TypeOfTestCode.NUCLEIC_ACID_AMPLIFICATION_WITH_PROBE_DETECTION -> TypeOfTest.NUCLEIC_ACID_AMPLIFICATION_WITH_PROBE_DETECTION + TypeOfTestCode.RAPID_IMMUNOASSAY -> TypeOfTest.RAPID_IMMUNOASSAY + else -> TypeOfTest.UNDEFINED + } -fun Vaccination.toVaccinationModel(): VaccinationModel { - return VaccinationModel( +fun Vaccination.toVaccinationModel(): VaccinationModel = + VaccinationModel( disease = disease.toDiseaseCode().toDiseaseType(), vaccine = vaccine, medicinalProduct = medicinalProduct, @@ -94,27 +92,27 @@ fun Vaccination.toVaccinationModel(): VaccinationModel { certificateIssuer = certificateIssuer, certificateIdentifier = certificateIdentifier ) -} -fun Person.toPersonModel(): PersonModel { - return PersonModel( +fun Person.toPersonModel(): PersonModel = + PersonModel( standardisedFamilyName = standardisedFamilyName, familyName = familyName, standardisedGivenName = standardisedGivenName, givenName = givenName ) -} -fun String.toDiseaseCode(): DiseaseCode = when (this) { - DiseaseCode.COVID_19.value -> DiseaseCode.COVID_19 - else -> DiseaseCode.UNDEFINED -} +fun String.toDiseaseCode(): DiseaseCode = + when (this) { + DiseaseCode.COVID_19.value -> DiseaseCode.COVID_19 + else -> DiseaseCode.UNDEFINED + } -fun String.toTypeOfTestCode(): TypeOfTestCode = when (this) { - TypeOfTestCode.NUCLEIC_ACID_AMPLIFICATION_WITH_PROBE_DETECTION.value -> TypeOfTestCode.NUCLEIC_ACID_AMPLIFICATION_WITH_PROBE_DETECTION - TypeOfTestCode.RAPID_IMMUNOASSAY.value -> TypeOfTestCode.RAPID_IMMUNOASSAY - else -> TypeOfTestCode.UNDEFINED -} +fun String.toTypeOfTestCode(): TypeOfTestCode = + when (this) { + TypeOfTestCode.NUCLEIC_ACID_AMPLIFICATION_WITH_PROBE_DETECTION.value -> TypeOfTestCode.NUCLEIC_ACID_AMPLIFICATION_WITH_PROBE_DETECTION + TypeOfTestCode.RAPID_IMMUNOASSAY.value -> TypeOfTestCode.RAPID_IMMUNOASSAY + else -> TypeOfTestCode.UNDEFINED + } enum class DiseaseCode(val value: String) { COVID_19("840539006"), diff --git a/app/src/main/java/dgca/verifier/app/android/model/rules/RuleModel.kt b/app/src/main/java/dgca/verifier/app/android/model/rules/RuleModel.kt index a1f3997c..524509db 100644 --- a/app/src/main/java/dgca/verifier/app/android/model/rules/RuleModel.kt +++ b/app/src/main/java/dgca/verifier/app/android/model/rules/RuleModel.kt @@ -45,10 +45,16 @@ data class RuleModel( val logic: String, val countryCode: String, val region: String? -): Parcelable { +) : Parcelable { + fun getDescriptionFor(languageCode: String): String { val description = descriptions[languageCode.toLowerCase(Locale.ROOT)] - return if (description?.isNotBlank() == true) description else descriptions[Locale.ENGLISH.language] - ?: "" + + return if (description?.isNotBlank() == true) { + description + } else { + descriptions[Locale.ENGLISH.language] + ?: "" + } } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/model/rules/RuleValidationResultModelsContainer.kt b/app/src/main/java/dgca/verifier/app/android/model/rules/RuleValidationResultModelsContainer.kt index b51d142f..ab357976 100644 --- a/app/src/main/java/dgca/verifier/app/android/model/rules/RuleValidationResultModelsContainer.kt +++ b/app/src/main/java/dgca/verifier/app/android/model/rules/RuleValidationResultModelsContainer.kt @@ -26,5 +26,4 @@ import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize -data class RuleValidationResultModelsContainer(val ruleValidationResultModels: List) : - Parcelable \ No newline at end of file +data class RuleValidationResultModelsContainer(val ruleValidationResultModels: List) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/model/rules/RulesMapper.kt b/app/src/main/java/dgca/verifier/app/android/model/rules/RulesMapper.kt index 6ffe8f53..2811edb7 100644 --- a/app/src/main/java/dgca/verifier/app/android/model/rules/RulesMapper.kt +++ b/app/src/main/java/dgca/verifier/app/android/model/rules/RulesMapper.kt @@ -22,71 +22,34 @@ package dgca.verifier.app.android.model.rules -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.ObjectMapper import dgca.verifier.app.engine.ValidationResult import dgca.verifier.app.engine.data.Rule -fun Rule.toRuleModel(): RuleModel { - return RuleModel( - identifier = this.identifier, - type = this.type, - version = this.version, - schemaVersion = this.schemaVersion, - engine = this.engine, - engineVersion = this.engineVersion, - ruleCertificateType = this.ruleCertificateType, - descriptions = this.descriptions, - validFrom = this.validFrom, - validTo = this.validTo, - affectedString = this.affectedString, - logic = this.logic.asText(), - countryCode = this.countryCode, - region = this.region +fun Rule.toRuleModel(): RuleModel = + RuleModel( + identifier = identifier, + type = type, + version = version, + schemaVersion = schemaVersion, + engine = engine, + engineVersion = engineVersion, + ruleCertificateType = ruleCertificateType, + descriptions = descriptions, + validFrom = validFrom, + validTo = validTo, + affectedString = affectedString, + logic = logic.asText(), + countryCode = countryCode, + region = region ) -} -fun RuleModel.toRule(objectMapper: ObjectMapper): Rule { - return Rule( - identifier = this.identifier, - type = this.type, - version = this.version, - schemaVersion = this.schemaVersion, - engine = this.engine, - engineVersion = this.engineVersion, - ruleCertificateType = this.ruleCertificateType, - descriptions = this.descriptions, - validFrom = this.validFrom, - validTo = this.validTo, - affectedString = this.affectedString, - logic = objectMapper.readValue(this.logic, JsonNode::class.java), - countryCode = this.countryCode, - region = this.region +fun ValidationResult.toRuleValidationResultModel(): RuleValidationResultModel = + RuleValidationResultModel( + rule = rule.toRuleModel(), + result = result, + current = current, + validationErrors = validationErrors ) -} -fun ValidationResult.toRuleValidationResultModel(): RuleValidationResultModel { - return RuleValidationResultModel( - rule = this.rule.toRuleModel(), - result = this.result, - current = this.current, - validationErrors = this.validationErrors - ) -} - -fun RuleValidationResultModel.toRuleValidationResult(objectMapper: ObjectMapper): ValidationResult { - return ValidationResult( - rule = this.rule.toRule(objectMapper), - result = this.result, - current = this.current, - validationErrors = this.validationErrors - ) -} - -fun List.toRuleValidationResultModels(): List { - return this.map { it.toRuleValidationResultModel() } -} - -fun List.toRuleValidationResults(objectMapper: ObjectMapper): List { - return this.map { it.toRuleValidationResult(objectMapper) } -} +fun List.toRuleValidationResultModels(): List = + map { it.toRuleValidationResultModel() } diff --git a/app/src/main/java/dgca/verifier/app/android/nfc/ParsedNdefRecord.kt b/app/src/main/java/dgca/verifier/app/android/nfc/ParsedNdefRecord.kt index a5b2a044..e97d9a66 100644 --- a/app/src/main/java/dgca/verifier/app/android/nfc/ParsedNdefRecord.kt +++ b/app/src/main/java/dgca/verifier/app/android/nfc/ParsedNdefRecord.kt @@ -23,5 +23,6 @@ package dgca.verifier.app.android.nfc interface ParsedNdefRecord { + fun str(): String } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/CodeReaderFragment.kt b/app/src/main/java/dgca/verifier/app/android/reader/CodeReaderFragment.kt similarity index 92% rename from app/src/main/java/dgca/verifier/app/android/CodeReaderFragment.kt rename to app/src/main/java/dgca/verifier/app/android/reader/CodeReaderFragment.kt index e5ecd69d..061878f6 100644 --- a/app/src/main/java/dgca/verifier/app/android/CodeReaderFragment.kt +++ b/app/src/main/java/dgca/verifier/app/android/reader/CodeReaderFragment.kt @@ -17,10 +17,10 @@ * limitations under the License. * ---license-end * - * Created by Mykhailo Nester on 4/23/21 9:48 AM + * Created by mykhailo.nester on 10/10/2021, 09:14 */ -package dgca.verifier.app.android +package dgca.verifier.app.android.reader import android.Manifest import android.content.pm.PackageManager @@ -46,11 +46,15 @@ import com.journeyapps.barcodescanner.BarcodeCallback import com.journeyapps.barcodescanner.BarcodeResult import com.journeyapps.barcodescanner.DefaultDecoderFactory import dagger.hilt.android.AndroidEntryPoint +import dgca.verifier.app.android.MainActivity +import dgca.verifier.app.android.R import dgca.verifier.app.android.base.BindingFragment import dgca.verifier.app.android.databinding.FragmentCodeReaderBinding import dgca.verifier.app.android.model.CertificateModel import dgca.verifier.app.android.model.rules.RuleValidationResultModelsContainer import dgca.verifier.app.android.verification.* +import dgca.verifier.app.android.verification.model.DebugData +import dgca.verifier.app.android.verification.model.StandardizedVerificationResult import dgca.verifier.app.engine.data.source.countries.COUNTRIES_MAP import timber.log.Timber import java.util.* @@ -58,8 +62,7 @@ import java.util.* private const val CAMERA_REQUEST_CODE = 1003 @AndroidEntryPoint -class CodeReaderFragment : BindingFragment(), - NavController.OnDestinationChangedListener { +class CodeReaderFragment : BindingFragment(), NavController.OnDestinationChangedListener { private val viewModel by viewModels() @@ -93,10 +96,7 @@ class CodeReaderFragment : BindingFragment(), adapter = CountriesAdapter(layoutInflater) } - override fun onCreateBinding( - inflater: LayoutInflater, - container: ViewGroup? - ): FragmentCodeReaderBinding = + override fun onCreateBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentCodeReaderBinding = FragmentCodeReaderBinding.inflate(inflater, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -115,9 +115,7 @@ class CodeReaderFragment : BindingFragment(), setFragmentResultListener(VERIFY_REQUEST_KEY) { _, bundle -> val standardizedVerificationResult: StandardizedVerificationResult? = - bundle.getSerializable( - STANDARDISED_VERIFICATION_RESULT_KEY - ) as StandardizedVerificationResult? + bundle.getSerializable(STANDARDISED_VERIFICATION_RESULT_KEY) as StandardizedVerificationResult? val certificateModel: CertificateModel? = bundle.getParcelable(CERTIFICATE_MODEL_KEY) val hcert: String? = bundle.getString(HCERT_KEY) val ruleValidationResultModelsContainer: RuleValidationResultModelsContainer? = bundle.getParcelable( @@ -140,12 +138,7 @@ class CodeReaderFragment : BindingFragment(), binding.countrySelector.adapter = adapter binding.countrySelector.onItemSelectedListener = object : OnItemSelectedListener { - override fun onItemSelected( - parentView: AdapterView<*>?, - selectedItemView: View?, - position: Int, - id: Long - ) { + override fun onItemSelected(parentView: AdapterView<*>?, selectedItemView: View?, position: Int, id: Long) { viewModel.selectCountry(adapter.getItem(position)) } @@ -169,6 +162,29 @@ class CodeReaderFragment : BindingFragment(), } } + override fun onResume() { + super.onResume() + findNavController().addOnDestinationChangedListener(this) + lastText = "" + } + + override fun onPause() { + super.onPause() + findNavController().removeOnDestinationChangedListener(this) + binding.barcodeScanner.pause() + } + + override fun onDestinationChanged( + controller: NavController, + destination: NavDestination, + arguments: Bundle? + ) { + if (destination.id == R.id.codeReaderFragment) { + binding.barcodeScanner.resume() + lastText = "" + } + } + private fun showVerificationResult( standardizedVerificationResult: StandardizedVerificationResult, certificateModel: CertificateModel?, @@ -197,18 +213,6 @@ class CodeReaderFragment : BindingFragment(), findNavController().navigate(action) } - override fun onResume() { - super.onResume() - findNavController().addOnDestinationChangedListener(this) - lastText = "" - } - - override fun onPause() { - super.onPause() - findNavController().removeOnDestinationChangedListener(this) - binding.barcodeScanner.pause() - } - private fun navigateToVerificationPage(text: String) { val action = CodeReaderFragmentDirections.actionCodeReaderFragmentToVerificationDialogFragment( @@ -230,17 +234,6 @@ class CodeReaderFragment : BindingFragment(), } } - override fun onDestinationChanged( - controller: NavController, - destination: NavDestination, - arguments: Bundle? - ) { - if (destination.id == R.id.codeReaderFragment) { - binding.barcodeScanner.resume() - lastText = "" - } - } - fun onNdefMessageReceived(qrCodeText: String) { val position = binding.countrySelector.selectedItemPosition if (position == -1 || refinedCountries.isEmpty()) { diff --git a/app/src/main/java/dgca/verifier/app/android/CodeReaderViewModel.kt b/app/src/main/java/dgca/verifier/app/android/reader/CodeReaderViewModel.kt similarity index 98% rename from app/src/main/java/dgca/verifier/app/android/CodeReaderViewModel.kt rename to app/src/main/java/dgca/verifier/app/android/reader/CodeReaderViewModel.kt index 9cb7ec7d..84e9fcf4 100644 --- a/app/src/main/java/dgca/verifier/app/android/CodeReaderViewModel.kt +++ b/app/src/main/java/dgca/verifier/app/android/reader/CodeReaderViewModel.kt @@ -20,7 +20,7 @@ * Created by mykhailo.nester on 4/24/21 2:54 PM */ -package dgca.verifier.app.android +package dgca.verifier.app.android.reader import androidx.lifecycle.* import dagger.hilt.android.lifecycle.HiltViewModel @@ -47,11 +47,6 @@ class CodeReaderViewModel @Inject constructor( emit(preferences.debugModeState?.let { DebugModeState.valueOf(it) } ?: DebugModeState.OFF) } - fun selectCountry(countryIsoCode: String) { - preferences.selectedCountryIsoCode = countryIsoCode - _selectedCountry.value = countryIsoCode - } - init { viewModelScope.launch { countriesRepository.getCountries().collectLatest { @@ -60,4 +55,9 @@ class CodeReaderViewModel @Inject constructor( } } } + + fun selectCountry(countryIsoCode: String) { + preferences.selectedCountryIsoCode = countryIsoCode + _selectedCountry.value = countryIsoCode + } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/CountriesAdapter.kt b/app/src/main/java/dgca/verifier/app/android/reader/CountriesAdapter.kt similarity index 71% rename from app/src/main/java/dgca/verifier/app/android/CountriesAdapter.kt rename to app/src/main/java/dgca/verifier/app/android/reader/CountriesAdapter.kt index 933f6115..1fb85406 100644 --- a/app/src/main/java/dgca/verifier/app/android/CountriesAdapter.kt +++ b/app/src/main/java/dgca/verifier/app/android/reader/CountriesAdapter.kt @@ -20,7 +20,7 @@ * Created by osarapulov on 7/8/21 12:01 AM */ -package dgca.verifier.app.android +package dgca.verifier.app.android.reader import android.view.LayoutInflater import android.view.View @@ -30,27 +30,6 @@ import android.widget.TextView import dgca.verifier.app.engine.data.source.countries.COUNTRIES_MAP import java.util.* -/*- - * ---license-start - * eu-digital-green-certificates / dgc-certlogic-android - * --- - * Copyright (C) 2021 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - * - * Created by osarapulov on 08.07.21 0:01 - */ class CountriesAdapter( private val layoutInflater: LayoutInflater ) : BaseAdapter() { diff --git a/app/src/main/java/dgca/verifier/app/android/security/DefaultKeyStoreCryptor.kt b/app/src/main/java/dgca/verifier/app/android/security/DefaultKeyStoreCryptor.kt index c50ad2d3..84cfa61e 100644 --- a/app/src/main/java/dgca/verifier/app/android/security/DefaultKeyStoreCryptor.kt +++ b/app/src/main/java/dgca/verifier/app/android/security/DefaultKeyStoreCryptor.kt @@ -26,12 +26,7 @@ import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyProperties import timber.log.Timber import java.io.IOException -import java.security.InvalidAlgorithmParameterException -import java.security.KeyStore -import java.security.KeyStoreException -import java.security.NoSuchAlgorithmException -import java.security.NoSuchProviderException -import java.security.UnrecoverableEntryException +import java.security.* import java.security.cert.CertificateException import javax.crypto.KeyGenerator import javax.inject.Inject @@ -94,11 +89,9 @@ class DefaultKeyStoreCryptor @Inject constructor() : KeyStoreCryptor { } catch (e: InvalidAlgorithmParameterException) { Timber.w(e) } + try { - val entry = keyStore.getEntry( - KEY_ALIAS, - null - ) as KeyStore.SecretKeyEntry + val entry = keyStore.getEntry(KEY_ALIAS, null) as KeyStore.SecretKeyEntry return SecurityKeyWrapper(entry.secretKey) } catch (e: KeyStoreException) { Timber.w(e) @@ -111,7 +104,6 @@ class DefaultKeyStoreCryptor @Inject constructor() : KeyStoreCryptor { } companion object { - const val ANDROID_KEY_STORE = "AndroidKeyStore" const val KEY_ALIAS = "KEY_ALIAS" } diff --git a/app/src/main/java/dgca/verifier/app/android/security/SecurityKeyWrapper.kt b/app/src/main/java/dgca/verifier/app/android/security/SecurityKeyWrapper.kt index 1734031d..9d8882e2 100644 --- a/app/src/main/java/dgca/verifier/app/android/security/SecurityKeyWrapper.kt +++ b/app/src/main/java/dgca/verifier/app/android/security/SecurityKeyWrapper.kt @@ -36,6 +36,7 @@ class SecurityKeyWrapper(private val secretKey: SecretKey) { fun encrypt(token: String?): String? { if (token == null) return null + try { val cipher = getCipher(Cipher.ENCRYPT_MODE) val encrypted = cipher.doFinal(token.toByteArray()) @@ -43,11 +44,13 @@ class SecurityKeyWrapper(private val secretKey: SecretKey) { } catch (e: GeneralSecurityException) { Timber.w(e) } + return null } fun decrypt(encryptedToken: String?): String? { if (encryptedToken == null) return null + try { val cipher = getCipher(Cipher.DECRYPT_MODE) val decoded = Base64.decode(encryptedToken, Base64.URL_SAFE) @@ -56,6 +59,7 @@ class SecurityKeyWrapper(private val secretKey: SecretKey) { } catch (e: GeneralSecurityException) { Timber.w(e) } + return null } @@ -69,7 +73,6 @@ class SecurityKeyWrapper(private val secretKey: SecretKey) { } companion object { - private const val AES_GCM_NO_PADDING = "AES/GCM/NoPadding" } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/settings/SettingsFragment.kt b/app/src/main/java/dgca/verifier/app/android/settings/SettingsFragment.kt index f94f1f5a..cdc171d6 100644 --- a/app/src/main/java/dgca/verifier/app/android/settings/SettingsFragment.kt +++ b/app/src/main/java/dgca/verifier/app/android/settings/SettingsFragment.kt @@ -35,13 +35,19 @@ import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import com.google.android.gms.oss.licenses.OssLicensesMenuActivity import dagger.hilt.android.AndroidEntryPoint -import dgca.verifier.app.android.* +import dgca.verifier.app.android.BuildConfig +import dgca.verifier.app.android.MainActivity +import dgca.verifier.app.android.R import dgca.verifier.app.android.base.BindingFragment import dgca.verifier.app.android.databinding.FragmentSettingsBinding import dgca.verifier.app.android.settings.debug.mode.DebugModeState +import dgca.verifier.app.android.utils.applyStyle +import dgca.verifier.app.android.utils.formatWith +import dgca.verifier.app.android.utils.toLocalDateTime @AndroidEntryPoint class SettingsFragment : BindingFragment() { + private val viewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { @@ -49,10 +55,7 @@ class SettingsFragment : BindingFragment() { lifecycle.addObserver(viewModel) } - override fun onCreateBinding( - inflater: LayoutInflater, - container: ViewGroup? - ): FragmentSettingsBinding = + override fun onCreateBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSettingsBinding = FragmentSettingsBinding.inflate(inflater, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -136,8 +139,7 @@ class SettingsFragment : BindingFragment() { } companion object { - const val PRIVACY_POLICY = - "https://op.europa.eu/en/web/about-us/legal-notices/eu-mobile-apps" + private const val PRIVACY_POLICY = "https://op.europa.eu/en/web/about-us/legal-notices/eu-mobile-apps" private const val LAST_UPDATE_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm" } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/settings/SettingsViewModel.kt b/app/src/main/java/dgca/verifier/app/android/settings/SettingsViewModel.kt index adf25895..fe0e833b 100644 --- a/app/src/main/java/dgca/verifier/app/android/settings/SettingsViewModel.kt +++ b/app/src/main/java/dgca/verifier/app/android/settings/SettingsViewModel.kt @@ -44,9 +44,10 @@ class SettingsViewModel @Inject constructor( private val _inProgress = MutableLiveData() val inProgress: LiveData = _inProgress + val lastSyncLiveData: LiveData = verifierRepository.getLastSyncTimeMillis() - private val _debugModeState: MutableLiveData = - MutableLiveData(DebugModeState.OFF) + + private val _debugModeState: MutableLiveData = MutableLiveData(DebugModeState.OFF) val debugModeState: LiveData = _debugModeState @OnLifecycleEvent(Lifecycle.Event.ON_START) diff --git a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/CountriesAdapter.kt b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/CountriesAdapter.kt index 9ddf4ea3..60f2c61b 100644 --- a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/CountriesAdapter.kt +++ b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/CountriesAdapter.kt @@ -31,34 +31,18 @@ import dgca.verifier.app.android.databinding.ItemCountryBinding import dgca.verifier.app.engine.data.source.countries.COUNTRIES_MAP import java.util.* - class CountriesAdapter(private val inflater: LayoutInflater, countriesData: CountriesData) : RecyclerView.Adapter() { + private val availableCountriesCodes = countriesData.availableCountriesCodes.sortedBy { Locale( "", COUNTRIES_MAP[it] ?: it ).displayCountry } - private val selectedCountriesCodes: MutableSet = - countriesData.selectedCountriesCodes.toMutableSet() - - fun getCountriesData() = CountriesData(availableCountriesCodes.toSet(), selectedCountriesCodes) - - inner class ViewHolder(val binding: ItemCountryBinding) : - RecyclerView.ViewHolder(binding.root) - - fun create(inflater: LayoutInflater, parent: ViewGroup) = - ViewHolder( - ItemCountryBinding.inflate( - inflater, - parent, - false - ) - ) + private val selectedCountriesCodes: MutableSet = countriesData.selectedCountriesCodes.toMutableSet() - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = - create(inflater, parent) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = create(inflater, parent) override fun onBindViewHolder(holder: ViewHolder, position: Int) { val countryCode = availableCountriesCodes[position] @@ -94,8 +78,20 @@ class CountriesAdapter(private val inflater: LayoutInflater, countriesData: Coun null ) } - } override fun getItemCount(): Int = availableCountriesCodes.size + + fun getCountriesData() = CountriesData(availableCountriesCodes.toSet(), selectedCountriesCodes) + + private fun create(inflater: LayoutInflater, parent: ViewGroup) = + ViewHolder( + ItemCountryBinding.inflate( + inflater, + parent, + false + ) + ) + + inner class ViewHolder(val binding: ItemCountryBinding) : RecyclerView.ViewHolder(binding.root) } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/CountriesSelectorFragment.kt b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/CountriesSelectorFragment.kt index 92a58eec..f62f741c 100644 --- a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/CountriesSelectorFragment.kt +++ b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/CountriesSelectorFragment.kt @@ -37,15 +37,12 @@ import dgca.verifier.app.android.MainActivity import dgca.verifier.app.android.base.BindingFragment import dgca.verifier.app.android.databinding.FragmentCountriesSelectorBinding - @AndroidEntryPoint class CountriesSelectorFragment : BindingFragment() { + private val args by navArgs() - override fun onCreateBinding( - inflater: LayoutInflater, - container: ViewGroup? - ): FragmentCountriesSelectorBinding = + override fun onCreateBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentCountriesSelectorBinding = FragmentCountriesSelectorBinding.inflate(inflater, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -57,20 +54,17 @@ class CountriesSelectorFragment : BindingFragment { close() true } else -> super.onOptionsItemSelected(item) } - } private fun close() { setFragmentResult( diff --git a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeSettingsFragment.kt b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeSettingsFragment.kt index f90a2210..26130e91 100644 --- a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeSettingsFragment.kt +++ b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeSettingsFragment.kt @@ -35,19 +35,16 @@ import androidx.navigation.fragment.findNavController import dagger.hilt.android.AndroidEntryPoint import dgca.verifier.app.android.MainActivity import dgca.verifier.app.android.R -import dgca.verifier.app.android.applyStyle import dgca.verifier.app.android.base.BindingFragment import dgca.verifier.app.android.databinding.FragmentDebugModeSettingsBinding - +import dgca.verifier.app.android.utils.applyStyle @AndroidEntryPoint class DebugModeSettingsFragment : BindingFragment() { + private val viewModel by viewModels() - override fun onCreateBinding( - inflater: LayoutInflater, - container: ViewGroup? - ): FragmentDebugModeSettingsBinding = + override fun onCreateBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDebugModeSettingsBinding = FragmentDebugModeSettingsBinding.inflate(inflater, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -63,7 +60,6 @@ class DebugModeSettingsFragment : BindingFragment { } } - } binding.debugModeSwitch.setOnCheckedChangeListener { _, _ -> saveSelectedDebugModeState() } @@ -75,8 +71,16 @@ class DebugModeSettingsFragment : BindingFragment { + findNavController().popBackStack() + true + } + else -> super.onOptionsItemSelected(item) } } @@ -94,46 +98,39 @@ class DebugModeSettingsFragment : BindingFragment { - findNavController().popBackStack() - true - } - else -> super.onOptionsItemSelected(item) + private fun setUpSelectCountry(countriesData: CountriesData) { + if (countriesData.availableCountriesCodes.isEmpty()) { + return } - } - private fun setUpSelectCountry(countriesData: CountriesData) { - if (countriesData.availableCountriesCodes.isNotEmpty()) { - val selectedCountriesText = - if (countriesData.selectedCountriesCodes.isEmpty()) getString(R.string.no_countries_selected) else countriesData.selectedCountriesCodes.sorted() - .joinToString( - separator = ", " - ) - - val context = requireContext() - - val spannable = SpannableStringBuilder() - .append( - getString(R.string.select_country).toSpannable().applyStyle( - context, - R.style.TextAppearance_Dgca_SettingsButtonHeader - ) + val selectedCountriesText = + if (countriesData.selectedCountriesCodes.isEmpty()) { + getString(R.string.no_countries_selected) + } else { + countriesData.selectedCountriesCodes + .sorted() + .joinToString(separator = ", ") + } + + val context = requireContext() + val spannable = SpannableStringBuilder() + .append( + getString(R.string.select_country).toSpannable().applyStyle( + context, + R.style.TextAppearance_Dgca_SettingsButtonHeader ) - .append("\n") - .append( - selectedCountriesText.toSpannable().applyStyle( - context, - R.style.TextAppearance_Dgca_SettingsButtonSubHeader - ) + ) + .append("\n") + .append( + selectedCountriesText.toSpannable().applyStyle( + context, + R.style.TextAppearance_Dgca_SettingsButtonSubHeader ) + ) - binding.selectedCountries.text = spannable - - binding.selectedCountries.setOnClickListener { showCountriesSelector(countriesData) } - binding.selectedCountries.visibility = View.VISIBLE - } + binding.selectedCountries.text = spannable + binding.selectedCountries.setOnClickListener { showCountriesSelector(countriesData) } + binding.selectedCountries.visibility = View.VISIBLE } private fun getSelectedDebugMode(): DebugModeState = when { diff --git a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeSettingsViewModel.kt b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeSettingsViewModel.kt index d721962a..21e04441 100644 --- a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeSettingsViewModel.kt +++ b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeSettingsViewModel.kt @@ -37,10 +37,11 @@ class DebugModeSettingsViewModel @Inject constructor( private val preferences: Preferences, private val countriesRepository: CountriesRepository ) : ViewModel() { + private val _countriesData: MutableLiveData = MutableLiveData() val countriesData: LiveData = _countriesData - private val _debugModeState: MutableLiveData = - MutableLiveData(DebugModeState.OFF) + + private val _debugModeState: MutableLiveData = MutableLiveData(DebugModeState.OFF) val debugModeState: LiveData = _debugModeState init { @@ -52,8 +53,7 @@ class DebugModeSettingsViewModel @Inject constructor( } val countriesData: CountriesData = withContext(Dispatchers.IO) { - val selectedCountriesCodes: Set = - preferences.debugModeSelectedCountriesCodes ?: emptySet() + val selectedCountriesCodes: Set = preferences.debugModeSelectedCountriesCodes ?: emptySet() val availableCountries: Set = try { mutableSetOf().apply { countriesRepository.getCountries().firstOrNull()?.let { @@ -65,6 +65,7 @@ class DebugModeSettingsViewModel @Inject constructor( } return@withContext CountriesData(availableCountries, selectedCountriesCodes) } + _countriesData.value = countriesData } } diff --git a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeState.kt b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeState.kt index 591cfeb0..af1786ff 100644 --- a/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeState.kt +++ b/app/src/main/java/dgca/verifier/app/android/settings/debug/mode/DebugModeState.kt @@ -26,5 +26,8 @@ import androidx.annotation.StringRes import dgca.verifier.app.android.R enum class DebugModeState(@StringRes val stringRes: Int) { - OFF(R.string.off), LEVEL_1(R.string.on_level_1), LEVEL_2(R.string.on_level_2), LEVEL_3(R.string.on_level_3) + OFF(R.string.off), + LEVEL_1(R.string.on_level_1), + LEVEL_2(R.string.on_level_2), + LEVEL_3(R.string.on_level_3) } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/BackportUtils.java b/app/src/main/java/dgca/verifier/app/android/utils/BackportUtils.java similarity index 90% rename from app/src/main/java/dgca/verifier/app/android/BackportUtils.java rename to app/src/main/java/dgca/verifier/app/android/utils/BackportUtils.java index ce4947bf..0aca63b3 100644 --- a/app/src/main/java/dgca/verifier/app/android/BackportUtils.java +++ b/app/src/main/java/dgca/verifier/app/android/utils/BackportUtils.java @@ -17,10 +17,10 @@ * limitations under the License. * ---license-end * - * Created by Admin on 7/26/21, 3:18 AM + * Created by mykhailo.nester on 10/10/2021, 09:13 */ -package dgca.verifier.app.android; +package dgca.verifier.app.android.utils; public class BackportUtils { public static int byteToUnsignedInt(byte x) { diff --git a/app/src/main/java/dgca/verifier/app/android/DimensionExt.kt b/app/src/main/java/dgca/verifier/app/android/utils/DimensionExt.kt similarity index 96% rename from app/src/main/java/dgca/verifier/app/android/DimensionExt.kt rename to app/src/main/java/dgca/verifier/app/android/utils/DimensionExt.kt index a461dcb7..dae879cf 100644 --- a/app/src/main/java/dgca/verifier/app/android/DimensionExt.kt +++ b/app/src/main/java/dgca/verifier/app/android/utils/DimensionExt.kt @@ -20,7 +20,7 @@ * Created by mykhailo.nester on 5/5/21 8:18 PM */ -package dgca.verifier.app.android +package dgca.verifier.app.android.utils import android.content.res.Resources diff --git a/app/src/main/java/dgca/verifier/app/android/utils/Extenssions.kt b/app/src/main/java/dgca/verifier/app/android/utils/Extenssions.kt index 060f20d1..82b9a573 100644 --- a/app/src/main/java/dgca/verifier/app/android/utils/Extenssions.kt +++ b/app/src/main/java/dgca/verifier/app/android/utils/Extenssions.kt @@ -22,7 +22,6 @@ package dgca.verifier.app.android.utils -import dgca.verifier.app.android.BackportUtils import timber.log.Timber import java.security.MessageDigest import java.security.NoSuchAlgorithmException diff --git a/app/src/main/java/dgca/verifier/app/android/TextUtils.kt b/app/src/main/java/dgca/verifier/app/android/utils/TextUtils.kt similarity index 92% rename from app/src/main/java/dgca/verifier/app/android/TextUtils.kt rename to app/src/main/java/dgca/verifier/app/android/utils/TextUtils.kt index eaaeb425..fbf77d02 100644 --- a/app/src/main/java/dgca/verifier/app/android/TextUtils.kt +++ b/app/src/main/java/dgca/verifier/app/android/utils/TextUtils.kt @@ -17,10 +17,10 @@ * limitations under the License. * ---license-end * - * Created by osarapulov on 9/4/21 7:43 PM + * Created by mykhailo.nester on 10/10/2021, 09:10 */ -package dgca.verifier.app.android +package dgca.verifier.app.android.utils import android.content.Context import android.text.Spannable diff --git a/app/src/main/java/dgca/verifier/app/android/TimeExt.kt b/app/src/main/java/dgca/verifier/app/android/utils/TimeExt.kt similarity index 66% rename from app/src/main/java/dgca/verifier/app/android/TimeExt.kt rename to app/src/main/java/dgca/verifier/app/android/utils/TimeExt.kt index 95d2ef69..2864b206 100644 --- a/app/src/main/java/dgca/verifier/app/android/TimeExt.kt +++ b/app/src/main/java/dgca/verifier/app/android/utils/TimeExt.kt @@ -17,10 +17,10 @@ * limitations under the License. * ---license-end * - * Created by mykhailo.nester on 5/5/21 11:57 PM + * Created by mykhailo.nester on 10/10/2021, 09:10 */ -package dgca.verifier.app.android +package dgca.verifier.app.android.utils import java.text.SimpleDateFormat import java.time.Instant @@ -33,35 +33,36 @@ import java.util.* const val YEAR_MONTH_DAY = "yyyy-MM-dd" const val FORMATTED_YEAR_MONTH_DAY = "MMM d, yyyy" private const val FORMATTED_DATE_TIME = "MMM d, yyyy, HH:mm" +private val DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(FORMATTED_DATE_TIME) -private fun String.toZonedDateTime(): ZonedDateTime? = try { - ZonedDateTime.parse(this) -} catch (error: Throwable) { - null -} +private fun String.toZonedDateTime(): ZonedDateTime? = + try { + ZonedDateTime.parse(this) + } catch (error: Throwable) { + null + } -private fun String.toLocalDateTime(): LocalDateTime? = try { - LocalDateTime.parse(this) -} catch (error: Throwable) { - null -} +private fun String.toLocalDateTime(): LocalDateTime? = + try { + LocalDateTime.parse(this) + } catch (error: Throwable) { + null + } -private val DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(FORMATTED_DATE_TIME) fun String.toFormattedDateTime(): String? = - this.toZonedDateTime()?.let { "${DATE_TIME_FORMATTER.format(it)} (UTC)" } - ?: this.toLocalDateTime()?.let { "${DATE_TIME_FORMATTER.format(it)} (UTC)" } + toZonedDateTime()?.let { "${DATE_TIME_FORMATTER.format(it)} (UTC)" } + ?: toLocalDateTime()?.let { "${DATE_TIME_FORMATTER.format(it)} (UTC)" } -fun String.parseFromTo(from: String, to: String): String { - return try { +fun String.parseFromTo(from: String, to: String): String = + try { val parser = SimpleDateFormat(from, Locale.US) val formatter = SimpleDateFormat(to, Locale.US) - return formatter.format(parser.parse(this)!!) + + formatter.format(parser.parse(this)!!) } catch (ex: Exception) { "" } -} -fun Long.toLocalDateTime(): LocalDateTime = - LocalDateTime.ofInstant(Instant.ofEpochMilli(this), ZoneId.systemDefault()) +fun Long.toLocalDateTime(): LocalDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(this), ZoneId.systemDefault()) fun LocalDateTime.formatWith(pattern: String): String = DateTimeFormatter.ofPattern(pattern).format(this) \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/ViewHolderUtils.kt b/app/src/main/java/dgca/verifier/app/android/utils/ViewHolderUtils.kt similarity index 97% rename from app/src/main/java/dgca/verifier/app/android/ViewHolderUtils.kt rename to app/src/main/java/dgca/verifier/app/android/utils/ViewHolderUtils.kt index 521699f6..1d148ec3 100644 --- a/app/src/main/java/dgca/verifier/app/android/ViewHolderUtils.kt +++ b/app/src/main/java/dgca/verifier/app/android/utils/ViewHolderUtils.kt @@ -20,7 +20,7 @@ * Created by osarapulov on 7/22/21 8:42 PM */ -package dgca.verifier.app.android +package dgca.verifier.app.android.utils import android.view.View import android.widget.TextView diff --git a/app/src/main/java/dgca/verifier/app/android/verification/BaseVerificationDialogFragment.kt b/app/src/main/java/dgca/verifier/app/android/verification/BaseVerificationDialogFragment.kt index b2b42771..b0da8906 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/BaseVerificationDialogFragment.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/BaseVerificationDialogFragment.kt @@ -29,19 +29,25 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button -import androidx.lifecycle.MutableLiveData import androidx.viewbinding.ViewBinding import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment -import dgca.verifier.app.android.dpToPx +import dgca.verifier.app.android.utils.dpToPx abstract class BaseVerificationDialogFragment : BottomSheetDialogFragment() { - abstract fun contentLayout(): ViewGroup.LayoutParams + private var _binding: T? = null + val binding get() = _binding!! + open fun timerView(): View? = null + open fun actionButton(): Button? = null + abstract fun onCreateBinding(inflater: LayoutInflater, container: ViewGroup?): T + + abstract fun contentLayout(): ViewGroup.LayoutParams + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val displayMetrics = DisplayMetrics() requireActivity().windowManager.defaultDisplay.getMetrics(displayMetrics) @@ -57,21 +63,14 @@ abstract class BaseVerificationDialogFragment : BottomSheetDial actionButton()?.setOnClickListener { dismiss() } } - private var _binding: T? = null - val binding get() = _binding!! - - abstract fun onCreateBinding(inflater: LayoutInflater, container: ViewGroup?): T open fun onDestroyBinding(binding: T) { } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { val innerBinding = onCreateBinding(inflater, container) _binding = innerBinding + return innerBinding.root } diff --git a/app/src/main/java/dgca/verifier/app/android/verification/VerificationFragment.kt b/app/src/main/java/dgca/verifier/app/android/verification/VerificationFragment.kt index af6cb31c..8ca0ea98 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/VerificationFragment.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/VerificationFragment.kt @@ -38,9 +38,11 @@ import androidx.navigation.fragment.navArgs import dagger.hilt.android.AndroidEntryPoint import dgca.verifier.app.android.databinding.FragmentVerificationBinding import dgca.verifier.app.android.model.rules.RuleValidationResultModelsContainer +import dgca.verifier.app.android.verification.model.QrCodeVerificationResult @AndroidEntryPoint class VerificationFragment : DialogFragment() { + private val viewModel by viewModels() private val args by navArgs() diff --git a/app/src/main/java/dgca/verifier/app/android/verification/VerificationResultDialogFragment.kt b/app/src/main/java/dgca/verifier/app/android/verification/VerificationResultDialogFragment.kt index 9103ccd4..9aaa50ba 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/VerificationResultDialogFragment.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/VerificationResultDialogFragment.kt @@ -32,38 +32,34 @@ import android.widget.Button import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.core.view.isVisible -import androidx.fragment.app.viewModels import androidx.lifecycle.MutableLiveData import androidx.navigation.fragment.navArgs import androidx.recyclerview.widget.LinearLayoutManager import dagger.hilt.android.AndroidEntryPoint -import dgca.verifier.app.android.FORMATTED_YEAR_MONTH_DAY import dgca.verifier.app.android.R -import dgca.verifier.app.android.YEAR_MONTH_DAY import dgca.verifier.app.android.databinding.DialogFragmentVerificationResultBinding import dgca.verifier.app.android.model.CertificateModel import dgca.verifier.app.android.model.TestResult -import dgca.verifier.app.android.parseFromTo +import dgca.verifier.app.android.utils.FORMATTED_YEAR_MONTH_DAY +import dgca.verifier.app.android.utils.YEAR_MONTH_DAY +import dgca.verifier.app.android.utils.parseFromTo import dgca.verifier.app.android.verification.certs.RecoveryViewHolder import dgca.verifier.app.android.verification.certs.TestViewHolder import dgca.verifier.app.android.verification.certs.VaccinationViewHolder -import dgca.verifier.app.android.verification.rules.RuleValidationResultCard +import dgca.verifier.app.android.verification.mapper.toRuleValidationResultCard +import dgca.verifier.app.android.verification.model.RuleValidationResultCard +import dgca.verifier.app.android.verification.model.StandardizedVerificationResult +import dgca.verifier.app.android.verification.model.StandardizedVerificationResultCategory import dgca.verifier.app.android.verification.rules.RuleValidationResultsAdapter -import dgca.verifier.app.android.verification.rules.toRuleValidationResultCard @ExperimentalUnsignedTypes @AndroidEntryPoint -class VerificationResultDialogFragment : - BaseVerificationDialogFragment() { - private val hideLiveData: MutableLiveData = MutableLiveData() +class VerificationResultDialogFragment : BaseVerificationDialogFragment() { - private val viewModel by viewModels() + private val hideLiveData: MutableLiveData = MutableLiveData() private val args by navArgs() - override fun onCreateBinding( - inflater: LayoutInflater, - container: ViewGroup? - ): DialogFragmentVerificationResultBinding = + override fun onCreateBinding(inflater: LayoutInflater, container: ViewGroup?): DialogFragmentVerificationResultBinding = DialogFragmentVerificationResultBinding.inflate(inflater, container, false) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -71,25 +67,29 @@ class VerificationResultDialogFragment : binding.rulesList.apply { layoutManager = LinearLayoutManager(requireContext()) } - handleDecodeResult() - - hideLiveData.observe(viewLifecycleOwner, { - dismiss() - }) + handleDecodeResult() + hideLiveData.observe(viewLifecycleOwner, { dismiss() }) startTimer() } override fun contentLayout(): ViewGroup.LayoutParams = binding.content.layoutParams + override fun timerView(): View = binding.timerView + override fun actionButton(): Button = binding.actionButton private fun handleDecodeResult() { - binding.verificationResultHeaderView.setUp(args.standardizedVerificationResult, args.certificateModel, args.ruleValidationResultModelsContainer) + binding.verificationResultHeaderView.setUp( + args.standardizedVerificationResult, + args.certificateModel, + args.ruleValidationResultModelsContainer + ) handleVerificationResult( args.certificateModel, args.standardizedVerificationResult.category ) + if (args.standardizedVerificationResult.category != StandardizedVerificationResultCategory.VALID) { setCertStatusError(args.standardizedVerificationResult) } @@ -101,105 +101,89 @@ class VerificationResultDialogFragment : ) { setCertStatusUI(standardizedVerificationResultCategory) setCertDataVisibility(standardizedVerificationResultCategory) - certificateModel?.let { it -> - toggleButton(it) - - if (standardizedVerificationResultCategory != StandardizedVerificationResultCategory.INVALID) { - showUserData(it) - - if (binding.greenCertificate.parent != null) { - when { - it.vaccinations?.size == 1 -> { - binding.greenCertificate.layoutResource = - R.layout.item_vaccination - binding.greenCertificate.setOnInflateListener { stub, inflated -> - VaccinationViewHolder.create( - inflated as ViewGroup - ).bind(it.vaccinations.first()) - } - binding.greenCertificate.inflate() - } - it.recoveryStatements?.size == 1 -> { - binding.greenCertificate.layoutResource = R.layout.item_recovery - - binding.greenCertificate.setOnInflateListener { stub, inflated -> - RecoveryViewHolder.create( - inflated as ViewGroup - ).bind(it.recoveryStatements.first()) - } - binding.greenCertificate.inflate() - } - it.tests?.size == 1 -> { - binding.greenCertificate.layoutResource = R.layout.item_test - - binding.greenCertificate.setOnInflateListener { stub, inflated -> - TestViewHolder.create( - inflated as ViewGroup - ).bind(it.tests.first()) - } - binding.greenCertificate.inflate() - } + + if (certificateModel == null || standardizedVerificationResultCategory == StandardizedVerificationResultCategory.INVALID) { + return + } + + toggleButton(certificateModel) + showUserData(certificateModel) + + if (binding.greenCertificate.parent != null) { + when { + certificateModel.vaccinations?.size == 1 -> { + binding.greenCertificate.layoutResource = R.layout.item_vaccination + binding.greenCertificate.setOnInflateListener { stub, inflated -> + VaccinationViewHolder.create(inflated as ViewGroup).bind(certificateModel.vaccinations.first()) + } + binding.greenCertificate.inflate() + } + certificateModel.recoveryStatements?.size == 1 -> { + binding.greenCertificate.layoutResource = R.layout.item_recovery + binding.greenCertificate.setOnInflateListener { stub, inflated -> + RecoveryViewHolder.create(inflated as ViewGroup).bind(certificateModel.recoveryStatements.first()) } + binding.greenCertificate.inflate() + } + certificateModel.tests?.size == 1 -> { + binding.greenCertificate.layoutResource = R.layout.item_test + binding.greenCertificate.setOnInflateListener { stub, inflated -> + TestViewHolder.create(inflated as ViewGroup).bind(certificateModel.tests.first()) + } + binding.greenCertificate.inflate() } } } } private fun setCertStatusUI(standardizedVerificationResultCategory: StandardizedVerificationResultCategory) { - val text: String - val imageId: Int val statusColor: ColorStateList val actionBtnText: String when (standardizedVerificationResultCategory) { StandardizedVerificationResultCategory.VALID -> { - text = getString(R.string.cert_valid) - imageId = R.drawable.check - statusColor = - ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.green)) + statusColor = ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.green)) actionBtnText = getString(R.string.done) } StandardizedVerificationResultCategory.LIMITED_VALIDITY -> { - text = getString(R.string.cert_limited_validity) - imageId = R.drawable.check - statusColor = - ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.yellow)) + statusColor = ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.yellow)) actionBtnText = getString(R.string.retry) } StandardizedVerificationResultCategory.INVALID -> { - text = getString(R.string.cert_invalid) - imageId = R.drawable.error - statusColor = - ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.red)) + statusColor = ColorStateList.valueOf(ContextCompat.getColor(requireContext(), R.color.red)) actionBtnText = getString(R.string.retry) } } - actionButton().isVisible = true - actionButton().backgroundTintList = statusColor - actionButton().text = actionBtnText - actionButton().isVisible = true + actionButton().apply { + isVisible = true + backgroundTintList = statusColor + text = actionBtnText + isVisible = true + } } private fun setCertStatusError(standardizedVerificationResult: StandardizedVerificationResult) { binding.reasonForCertificateInvalidityTitle.visibility = View.VISIBLE binding.reasonForCertificateInvalidityName.visibility = View.VISIBLE - binding.reasonForCertificateInvalidityName.text = getString( - when (standardizedVerificationResult) { - StandardizedVerificationResult.GREEN_CERTIFICATE_EXPIRED -> R.string.certificate_is_expired - StandardizedVerificationResult.CERTIFICATE_REVOKED -> R.string.certificate_was_revoked - StandardizedVerificationResult.VERIFICATION_FAILED -> R.string.verification_failed - StandardizedVerificationResult.CERTIFICATE_EXPIRED -> R.string.signing_certificate_is_expired - StandardizedVerificationResult.VACCINATION_DATE_IS_IN_THE_FUTURE -> R.string.the_vaccination_date_is_in_the_future - StandardizedVerificationResult.TEST_DATE_IS_IN_THE_FUTURE -> R.string.the_test_date_is_in_the_future - StandardizedVerificationResult.TEST_RESULT_POSITIVE -> R.string.test_result_positive - StandardizedVerificationResult.RECOVERY_NOT_VALID_SO_FAR -> R.string.recovery_not_valid_yet - StandardizedVerificationResult.RECOVERY_NOT_VALID_ANYMORE -> R.string.recover_not_valid_anymore - StandardizedVerificationResult.RULES_VALIDATION_FAILED -> R.string.rules_validation_failed - StandardizedVerificationResult.CRYPTOGRAPHIC_SIGNATURE_INVALID -> R.string.cryptographic_signature_invalid - else -> throw IllegalArgumentException() - } - ) + + val invalidityReason = when (standardizedVerificationResult) { + StandardizedVerificationResult.GREEN_CERTIFICATE_EXPIRED -> R.string.certificate_is_expired + StandardizedVerificationResult.CERTIFICATE_REVOKED -> R.string.certificate_was_revoked + StandardizedVerificationResult.VERIFICATION_FAILED -> R.string.verification_failed + StandardizedVerificationResult.CERTIFICATE_EXPIRED -> R.string.signing_certificate_is_expired + StandardizedVerificationResult.VACCINATION_DATE_IS_IN_THE_FUTURE -> R.string.the_vaccination_date_is_in_the_future + StandardizedVerificationResult.TEST_DATE_IS_IN_THE_FUTURE -> R.string.the_test_date_is_in_the_future + StandardizedVerificationResult.TEST_RESULT_POSITIVE -> R.string.test_result_positive + StandardizedVerificationResult.RECOVERY_NOT_VALID_SO_FAR -> R.string.recovery_not_valid_yet + StandardizedVerificationResult.RECOVERY_NOT_VALID_ANYMORE -> R.string.recover_not_valid_anymore + StandardizedVerificationResult.RULES_VALIDATION_FAILED -> R.string.rules_validation_failed + StandardizedVerificationResult.CRYPTOGRAPHIC_SIGNATURE_INVALID -> R.string.cryptographic_signature_invalid + else -> throw IllegalArgumentException() + } + + binding.reasonForCertificateInvalidityName.text = getString(invalidityReason) + if (standardizedVerificationResult == StandardizedVerificationResult.TEST_RESULT_POSITIVE) { binding.errorTestResult.visibility = View.VISIBLE binding.reasonTestResultValue.text = TestResult.DETECTED.value @@ -214,11 +198,9 @@ class VerificationResultDialogFragment : it.toRuleValidationResultCard() ) } - binding.rulesList.adapter = - RuleValidationResultsAdapter(layoutInflater, ruleValidationResultCards) + binding.rulesList.adapter = RuleValidationResultsAdapter(layoutInflater, ruleValidationResultCards) binding.reasonForCertificateInvalidityName.setOnClickListener { - binding.rulesList.visibility = - if (binding.rulesList.visibility == View.VISIBLE) View.GONE else View.VISIBLE + binding.rulesList.isVisible = !binding.rulesList.isVisible binding.reasonForCertificateInvalidityName.setCompoundDrawablesRelativeWithIntrinsicBounds( null, null, @@ -230,8 +212,7 @@ class VerificationResultDialogFragment : null ) } - binding.reasonForCertificateInvalidityTitle.text = - getString(R.string.possible_limitation) + binding.reasonForCertificateInvalidityTitle.text = getString(R.string.possible_limitation) val outValue = TypedValue() requireContext().theme.resolveAttribute( android.R.attr.selectableItemBackground, @@ -249,8 +230,8 @@ class VerificationResultDialogFragment : } private fun setCertDataVisibility(standardizedVerificationResultCategory: StandardizedVerificationResultCategory) { - binding.errorDetails.visibility = - if (standardizedVerificationResultCategory == StandardizedVerificationResultCategory.VALID) View.GONE else View.VISIBLE + binding.errorDetails.isVisible = standardizedVerificationResultCategory != StandardizedVerificationResultCategory.VALID + if (standardizedVerificationResultCategory == StandardizedVerificationResultCategory.VALID) { binding.errorTestResult.visibility = View.GONE } @@ -270,11 +251,9 @@ class VerificationResultDialogFragment : binding.personStandardisedGivenName.visibility = this } - binding.dateOfBirthValue.text = - certificate.dateOfBirth.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) + binding.dateOfBirthValue.text = certificate.dateOfBirth.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) - val dateOfBirth = - certificate.dateOfBirth.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) + val dateOfBirth = certificate.dateOfBirth.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) if (dateOfBirth.isBlank()) { View.GONE } else { diff --git a/app/src/main/java/dgca/verifier/app/android/verification/VerificationViewModel.kt b/app/src/main/java/dgca/verifier/app/android/verification/VerificationViewModel.kt index c26604c3..97e345da 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/VerificationViewModel.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/VerificationViewModel.kt @@ -29,12 +29,11 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import dgca.verifier.app.android.data.VerifierRepository import dgca.verifier.app.android.data.local.Preferences -import dgca.verifier.app.android.model.CertificateModel -import dgca.verifier.app.android.model.rules.RuleValidationResultModel import dgca.verifier.app.android.model.rules.toRuleValidationResultModels import dgca.verifier.app.android.model.toCertificateModel import dgca.verifier.app.android.settings.debug.mode.DebugModeState import dgca.verifier.app.android.verification.* +import dgca.verifier.app.android.verification.model.* import dgca.verifier.app.decoder.base45.Base45Service import dgca.verifier.app.decoder.cbor.CborService import dgca.verifier.app.decoder.cbor.GreenCertificateData @@ -64,19 +63,6 @@ import java.time.ZonedDateTime import java.util.* import javax.inject.Inject -sealed class QrCodeVerificationResult { - class Applicable( - val standardizedVerificationResult: StandardizedVerificationResult, - val certificateModel: CertificateModel?, - val hcert: String?, - val rulesValidationResults: List?, - val isDebugModeEnabled: Boolean, - val debugData: DebugData? - ) : QrCodeVerificationResult() - - object NotApplicable : QrCodeVerificationResult() -} - @HiltViewModel class VerificationViewModel @Inject constructor( private val prefixValidationService: PrefixValidationService, @@ -104,8 +90,7 @@ class VerificationViewModel @Inject constructor( viewModelScope.launch { withContext(Dispatchers.IO) { val verificationResult = VerificationResult() - val innerVerificationResult: InnerVerificationResult = - validateCertificate(code, verificationResult) + val innerVerificationResult: InnerVerificationResult = validateCertificate(code, verificationResult) val validationResults: List? = if (verificationResult.isValid() && innerVerificationResult.base64EncodedKid?.isNotBlank() == true) { @@ -119,8 +104,7 @@ class VerificationViewModel @Inject constructor( } if (innerVerificationResult.isApplicableCode) { - val covidCertificate = - innerVerificationResult.greenCertificateData?.greenCertificate + val covidCertificate = innerVerificationResult.greenCertificateData?.greenCertificate val certificateModel = covidCertificate?.toCertificateModel() val hcert: String? = innerVerificationResult.greenCertificateData?.hcertJson val standardizedVerificationResult: StandardizedVerificationResult = @@ -217,15 +201,20 @@ class VerificationViewModel @Inject constructor( greenCertificateData?.greenCertificate?.getType() ?: dgca.verifier.app.decoder.model.CertificateType.UNKNOWN ) + if (verificationResult.coseVerified) { - val expirationTime: ZonedDateTime? = - if (innerCertificate is X509Certificate) innerCertificate.notAfter.toInstant() - .atZone(UTC_ZONE_ID) else null - val currentTime: ZonedDateTime = - ZonedDateTime.now().withZoneSameInstant(UTC_ZONE_ID) + val expirationTime: ZonedDateTime? = if (innerCertificate is X509Certificate) { + innerCertificate.notAfter.toInstant().atZone(UTC_ZONE_ID) + } else { + null + } + + val currentTime: ZonedDateTime = ZonedDateTime.now().withZoneSameInstant(UTC_ZONE_ID) + if (expirationTime != null && currentTime.isAfter(expirationTime)) { certificateExpired = true } + return@forEach } } diff --git a/app/src/main/java/dgca/verifier/app/android/verification/certs/RecoveryViewHolder.kt b/app/src/main/java/dgca/verifier/app/android/verification/certs/RecoveryViewHolder.kt index 77cecfa0..74f5515d 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/certs/RecoveryViewHolder.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/certs/RecoveryViewHolder.kt @@ -24,27 +24,28 @@ package dgca.verifier.app.android.verification.certs import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import dgca.verifier.app.android.* import dgca.verifier.app.android.databinding.ItemRecoveryBinding import dgca.verifier.app.android.model.RecoveryModel +import dgca.verifier.app.android.utils.* -class RecoveryViewHolder(private val binding: ItemRecoveryBinding) : - RecyclerView.ViewHolder(binding.root) { +class RecoveryViewHolder(private val binding: ItemRecoveryBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(data: RecoveryModel) { data.disease.value.bindText(binding.diseaseTitle, binding.diseaseValue) - val validFrom = - data.certificateValidFrom.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) - val validTo = - data.certificateValidUntil.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) - val validFromTo = - if (validFrom.isNotBlank() && validTo.isNotBlank()) "$validFrom - $validTo" else "" + val validFrom = data.certificateValidFrom.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) + val validTo = data.certificateValidUntil.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) + + val validFromTo = if (validFrom.isNotBlank() && validTo.isNotBlank()) { + "$validFrom - $validTo" + } else { + "" + } + validFromTo.bindText(binding.validFromTitle, binding.validFromValue) data.countryOfVaccination.bindCountryWith(binding.countryTitle, binding.countryValue) } companion object { - fun create(parent: ViewGroup) = - RecoveryViewHolder(ItemRecoveryBinding.bind(parent)) + fun create(parent: ViewGroup) = RecoveryViewHolder(ItemRecoveryBinding.bind(parent)) } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/verification/certs/TestViewHolder.kt b/app/src/main/java/dgca/verifier/app/android/verification/certs/TestViewHolder.kt index 839ae332..1870ea2e 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/certs/TestViewHolder.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/certs/TestViewHolder.kt @@ -24,25 +24,26 @@ package dgca.verifier.app.android.verification.certs import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import dgca.verifier.app.android.bindCountryWith -import dgca.verifier.app.android.bindText import dgca.verifier.app.android.databinding.ItemTestBinding import dgca.verifier.app.android.model.TestModel -import dgca.verifier.app.android.toFormattedDateTime +import dgca.verifier.app.android.utils.bindCountryWith +import dgca.verifier.app.android.utils.bindText +import dgca.verifier.app.android.utils.toFormattedDateTime class TestViewHolder(private val binding: ItemTestBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(data: TestModel) { data.disease.value.bindText(binding.diseaseTitle, binding.diseaseValue) data.resultType.value.bindText(binding.testResultTitle, binding.testResultValue) - (data.dateTimeOfCollection.toFormattedDateTime() - ?: "").bindText(binding.dateOfCollectionTitle, binding.dateOfCollectionValue) + (data.dateTimeOfCollection.toFormattedDateTime() ?: "").bindText( + binding.dateOfCollectionTitle, + binding.dateOfCollectionValue + ) data.typeOfTest.value.bindText(binding.typeOfTestTitle, binding.typeOfTestValue) data.countryOfVaccination.bindCountryWith(binding.countryTitle, binding.countryValue) } companion object { - fun create(parent: ViewGroup) = - TestViewHolder(ItemTestBinding.bind(parent)) + fun create(parent: ViewGroup) = TestViewHolder(ItemTestBinding.bind(parent)) } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/verification/certs/VaccinationViewHolder.kt b/app/src/main/java/dgca/verifier/app/android/verification/certs/VaccinationViewHolder.kt index 737c9e48..bc69ac7e 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/certs/VaccinationViewHolder.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/certs/VaccinationViewHolder.kt @@ -24,25 +24,22 @@ package dgca.verifier.app.android.verification.certs import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import dgca.verifier.app.android.FORMATTED_YEAR_MONTH_DAY -import dgca.verifier.app.android.YEAR_MONTH_DAY -import dgca.verifier.app.android.bindCountryWith import dgca.verifier.app.android.databinding.ItemVaccinationBinding import dgca.verifier.app.android.model.VaccinationModel -import dgca.verifier.app.android.parseFromTo +import dgca.verifier.app.android.utils.FORMATTED_YEAR_MONTH_DAY +import dgca.verifier.app.android.utils.YEAR_MONTH_DAY +import dgca.verifier.app.android.utils.bindCountryWith +import dgca.verifier.app.android.utils.parseFromTo -class VaccinationViewHolder(private val binding: ItemVaccinationBinding) : - RecyclerView.ViewHolder(binding.root) { +class VaccinationViewHolder(private val binding: ItemVaccinationBinding) : RecyclerView.ViewHolder(binding.root) { fun bind(data: VaccinationModel) { - binding.dateValue.text = - data.dateOfVaccination.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) + binding.dateValue.text = data.dateOfVaccination.parseFromTo(YEAR_MONTH_DAY, FORMATTED_YEAR_MONTH_DAY) binding.diseaseValue.text = data.disease.value data.countryOfVaccination.bindCountryWith(binding.countryTitle, binding.countryValue) } companion object { - fun create(parent: ViewGroup) = - VaccinationViewHolder(ItemVaccinationBinding.bind(parent)) + fun create(parent: ViewGroup) = VaccinationViewHolder(ItemVaccinationBinding.bind(parent)) } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/verification/detailed/CertificateContentAdapter.kt b/app/src/main/java/dgca/verifier/app/android/verification/detailed/CertificateContentAdapter.kt index 6e95687e..4b42de6e 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/detailed/CertificateContentAdapter.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/detailed/CertificateContentAdapter.kt @@ -28,7 +28,6 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import dgca.verifier.app.android.databinding.ItemCertificateContentBinding - class CertificateContentAdapter(private val inflater: LayoutInflater) : RecyclerView.Adapter() { diff --git a/app/src/main/java/dgca/verifier/app/android/verification/detailed/CertificateContentView.kt b/app/src/main/java/dgca/verifier/app/android/verification/detailed/CertificateContentView.kt index 0d25200e..e0b7db33 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/detailed/CertificateContentView.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/detailed/CertificateContentView.kt @@ -35,8 +35,7 @@ import dgca.verifier.app.android.R import dgca.verifier.app.android.databinding.ViewCertificateContentViewBinding import dgca.verifier.app.android.model.CertificateModel -class CertificateContentView(context: Context, attrs: AttributeSet?) : - MaterialCardView(context, attrs) { +class CertificateContentView(context: Context, attrs: AttributeSet?) : MaterialCardView(context, attrs) { private val binding: ViewCertificateContentViewBinding = ViewCertificateContentViewBinding.inflate(LayoutInflater.from(context), this) diff --git a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedBaseVerificationResultViewModel.kt b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedBaseVerificationResultViewModel.kt index bd908bc2..82039d96 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedBaseVerificationResultViewModel.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedBaseVerificationResultViewModel.kt @@ -36,7 +36,7 @@ import dgca.verifier.app.android.data.local.Preferences import dgca.verifier.app.android.model.CertificateModel import dgca.verifier.app.android.settings.debug.mode.DebugModeState import dgca.verifier.app.android.utils.sha256 -import dgca.verifier.app.android.verification.DebugData +import dgca.verifier.app.android.verification.model.DebugData import dgca.verifier.app.android.verification.detailed.qr.QrCodeConverter import dgca.verifier.app.decoder.cbor.CborService import dgca.verifier.app.decoder.cose.CoseService diff --git a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedCertificateRawView.kt b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedCertificateRawView.kt index 176d3430..db9d9bff 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedCertificateRawView.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedCertificateRawView.kt @@ -33,8 +33,8 @@ import com.google.android.material.card.MaterialCardView import dgca.verifier.app.android.R import dgca.verifier.app.android.databinding.ViewDetailedCertificateRawViewBinding -class DetailedCertificateRawView(context: Context, attrs: AttributeSet?) : - MaterialCardView(context, attrs) { +class DetailedCertificateRawView(context: Context, attrs: AttributeSet?) : MaterialCardView(context, attrs) { + private val binding: ViewDetailedCertificateRawViewBinding = ViewDetailedCertificateRawViewBinding.inflate(LayoutInflater.from(context), this) diff --git a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedCertificateView.kt b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedCertificateView.kt index 6e5c3257..e657f25d 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedCertificateView.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedCertificateView.kt @@ -33,24 +33,24 @@ import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.card.MaterialCardView -import dgca.verifier.app.android.FORMATTED_YEAR_MONTH_DAY import dgca.verifier.app.android.R -import dgca.verifier.app.android.YEAR_MONTH_DAY import dgca.verifier.app.android.databinding.ViewDetailedCertificateViewBinding import dgca.verifier.app.android.model.* import dgca.verifier.app.android.model.rules.RuleValidationResultModelsContainer -import dgca.verifier.app.android.parseFromTo -import dgca.verifier.app.android.verification.StandardizedVerificationResult -import dgca.verifier.app.android.verification.StandardizedVerificationResultCategory +import dgca.verifier.app.android.utils.FORMATTED_YEAR_MONTH_DAY +import dgca.verifier.app.android.utils.YEAR_MONTH_DAY +import dgca.verifier.app.android.utils.parseFromTo import dgca.verifier.app.android.verification.certs.RecoveryViewHolder import dgca.verifier.app.android.verification.certs.TestViewHolder import dgca.verifier.app.android.verification.certs.VaccinationViewHolder -import dgca.verifier.app.android.verification.rules.RuleValidationResultCard +import dgca.verifier.app.android.verification.mapper.toRuleValidationResultCard +import dgca.verifier.app.android.verification.model.RuleValidationResultCard +import dgca.verifier.app.android.verification.model.StandardizedVerificationResult +import dgca.verifier.app.android.verification.model.StandardizedVerificationResultCategory import dgca.verifier.app.android.verification.rules.RuleValidationResultsAdapter -import dgca.verifier.app.android.verification.rules.toRuleValidationResultCard -class DetailedCertificateView(context: Context, attrs: AttributeSet?) : - MaterialCardView(context, attrs) { +class DetailedCertificateView(context: Context, attrs: AttributeSet?) : MaterialCardView(context, attrs) { + private val binding: ViewDetailedCertificateViewBinding = ViewDetailedCertificateViewBinding.inflate(LayoutInflater.from(context), this) private var isExpanded = false @@ -110,20 +110,16 @@ class DetailedCertificateView(context: Context, attrs: AttributeSet?) : } private fun setUpGreenCertificateData(certificateModel: CertificateModel) { - if (binding.greenCertificate.parent != null) { - when { - certificateModel.vaccinations?.size == 1 -> { - setUpVaccination(certificateModel.vaccinations) - } - certificateModel.recoveryStatements?.size == 1 -> { - setUpRecovery(certificateModel.recoveryStatements) - } - certificateModel.tests?.size == 1 -> { - setUpTest(certificateModel.tests) - } - } - binding.greenCertificate.inflate() + if (binding.greenCertificate.parent == null) { + return + } + + when { + certificateModel.vaccinations?.size == 1 -> setUpVaccination(certificateModel.vaccinations) + certificateModel.recoveryStatements?.size == 1 -> setUpRecovery(certificateModel.recoveryStatements) + certificateModel.tests?.size == 1 -> setUpTest(certificateModel.tests) } + binding.greenCertificate.inflate() } private fun setUpErrorType(standardizedVerificationResult: StandardizedVerificationResult) { diff --git a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultDialogFragment.kt b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultDialogFragment.kt index 9289cae7..ba77cb46 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultDialogFragment.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultDialogFragment.kt @@ -41,12 +41,11 @@ import dgca.verifier.app.android.databinding.DialogFragmentDetailedVerificationR import dgca.verifier.app.android.model.CertificateModel import dgca.verifier.app.android.model.rules.RuleValidationResultModelsContainer import dgca.verifier.app.android.verification.BaseVerificationDialogFragment -import dgca.verifier.app.android.verification.StandardizedVerificationResult -import dgca.verifier.app.android.verification.StandardizedVerificationResultCategory +import dgca.verifier.app.android.verification.model.StandardizedVerificationResult +import dgca.verifier.app.android.verification.model.StandardizedVerificationResultCategory import timber.log.Timber import java.io.File - @AndroidEntryPoint class DetailedVerificationResultDialogFragment : BaseVerificationDialogFragment() { diff --git a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultHeaderView.kt b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultHeaderView.kt index 4ca72840..65fbe9f3 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultHeaderView.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultHeaderView.kt @@ -33,8 +33,8 @@ import dgca.verifier.app.android.R import dgca.verifier.app.android.databinding.ViewDetailedVerificationResultHeaderBinding import dgca.verifier.app.android.model.CertificateModel import dgca.verifier.app.android.model.rules.RuleValidationResultModelsContainer -import dgca.verifier.app.android.verification.StandardizedVerificationResult -import dgca.verifier.app.android.verification.StandardizedVerificationResultCategory +import dgca.verifier.app.android.verification.model.StandardizedVerificationResult +import dgca.verifier.app.android.verification.model.StandardizedVerificationResultCategory class DetailedVerificationResultHeaderView(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) { diff --git a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultView.kt b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultView.kt index 2eb66566..992ed1cf 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultView.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/detailed/DetailedVerificationResultView.kt @@ -30,15 +30,15 @@ import androidx.cardview.widget.CardView import dgca.verifier.app.android.R import dgca.verifier.app.android.databinding.ViewDetailedVerificationResultBinding import dgca.verifier.app.android.model.rules.RuleValidationResultModelsContainer -import dgca.verifier.app.android.verification.StandardizedVerificationResult -import dgca.verifier.app.android.verification.StandardizedVerificationResultCategory +import dgca.verifier.app.android.verification.model.StandardizedVerificationResult +import dgca.verifier.app.android.verification.model.StandardizedVerificationResultCategory import dgca.verifier.app.engine.Result import dgca.verifier.app.engine.data.RuleCertificateType import dgca.verifier.app.engine.data.Type -class DetailedVerificationResultView(context: Context, attrs: AttributeSet?) : - CardView(context, attrs) { +class DetailedVerificationResultView(context: Context, attrs: AttributeSet?) : CardView(context, attrs) { + private val binding: ViewDetailedVerificationResultBinding = ViewDetailedVerificationResultBinding.inflate(LayoutInflater.from(context), this) @@ -62,6 +62,7 @@ class DetailedVerificationResultView(context: Context, attrs: AttributeSet?) : } else { R.drawable.ic_traffic_fail } + binding.techVerificationImage.setImageResource(techVerificationAsset) val (invalidationAsset, nonGeneralAcceptanceAsset, generalAcceptanceAsset) = ruleValidationResultModelsContainer?.getAssets() ?: Triple( @@ -110,6 +111,7 @@ class DetailedVerificationResultView(context: Context, attrs: AttributeSet?) : } } + return Triple( invalidationAsset, nonGeneralAcceptanceAsset, diff --git a/app/src/main/java/dgca/verifier/app/android/verification/detailed/qr/DefaultQrCodeConverter.kt b/app/src/main/java/dgca/verifier/app/android/verification/detailed/qr/DefaultQrCodeConverter.kt index 0f124b85..89bb0051 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/detailed/qr/DefaultQrCodeConverter.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/detailed/qr/DefaultQrCodeConverter.kt @@ -34,6 +34,7 @@ class DefaultQrCodeConverter( override fun convertStringIntoQrCode(text: String, size: Int): Bitmap { val bitMatrix = multiFormatWriter.encode(text, BarcodeFormat.QR_CODE, size, size) + return barcodeEncoder.createBitmap(bitMatrix) } } \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultMapper.kt b/app/src/main/java/dgca/verifier/app/android/verification/mapper/RuleValidationResultMapper.kt similarity index 53% rename from app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultMapper.kt rename to app/src/main/java/dgca/verifier/app/android/verification/mapper/RuleValidationResultMapper.kt index bc70cb48..7ce730dd 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultMapper.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/mapper/RuleValidationResultMapper.kt @@ -17,37 +17,15 @@ * limitations under the License. * ---license-end * - * Created by osarapulov on 6/18/21 9:12 AM + * Created by mykhailo.nester on 10/10/2021, 09:19 */ -package dgca.verifier.app.android.verification.rules +package dgca.verifier.app.android.verification.mapper -import android.content.Context import dgca.verifier.app.android.model.rules.RuleValidationResultModel -import dgca.verifier.app.engine.ValidationResult +import dgca.verifier.app.android.verification.model.RuleValidationResultCard import java.util.* -/*- - * ---license-start - * eu-digital-green-certificates / dgc-certlogic-android - * --- - * Copyright (C) 2021 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - * - * Created by osarapulov on 18.06.21 9:12 - */ fun RuleValidationResultModel.toRuleValidationResultCard(): RuleValidationResultCard { return RuleValidationResultCard( this.rule.getDescriptionFor(Locale.getDefault().language), diff --git a/app/src/main/java/dgca/verifier/app/android/verification/InnerVerificationResult.kt b/app/src/main/java/dgca/verifier/app/android/verification/model/InnerVerificationResult.kt similarity index 96% rename from app/src/main/java/dgca/verifier/app/android/verification/InnerVerificationResult.kt rename to app/src/main/java/dgca/verifier/app/android/verification/model/InnerVerificationResult.kt index 86cc5970..d9624ef4 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/InnerVerificationResult.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/model/InnerVerificationResult.kt @@ -20,7 +20,7 @@ * Created by osarapulov on 7/22/21 11:44 AM */ -package dgca.verifier.app.android.verification +package dgca.verifier.app.android.verification.model import android.os.Parcelable import dgca.verifier.app.decoder.cbor.GreenCertificateData diff --git a/app/src/main/java/dgca/verifier/app/android/verification/model/QrCodeVerificationResult.kt b/app/src/main/java/dgca/verifier/app/android/verification/model/QrCodeVerificationResult.kt new file mode 100644 index 00000000..09f274e1 --- /dev/null +++ b/app/src/main/java/dgca/verifier/app/android/verification/model/QrCodeVerificationResult.kt @@ -0,0 +1,39 @@ +/* + * ---license-start + * eu-digital-green-certificates / dgca-verifier-app-android + * --- + * Copyright (C) 2021 T-Systems International GmbH and all other contributors + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + * + * Created by mykhailo.nester on 10/10/2021, 10:05 + */ + +package dgca.verifier.app.android.verification.model + +import dgca.verifier.app.android.model.CertificateModel +import dgca.verifier.app.android.model.rules.RuleValidationResultModel + +sealed class QrCodeVerificationResult { + class Applicable( + val standardizedVerificationResult: StandardizedVerificationResult, + val certificateModel: CertificateModel?, + val hcert: String?, + val rulesValidationResults: List?, + val isDebugModeEnabled: Boolean, + val debugData: DebugData? + ) : QrCodeVerificationResult() + + object NotApplicable : QrCodeVerificationResult() +} \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/verification/VerificationResultResultViewModel.kt b/app/src/main/java/dgca/verifier/app/android/verification/model/RuleValidationResultCard.kt similarity index 72% rename from app/src/main/java/dgca/verifier/app/android/verification/VerificationResultResultViewModel.kt rename to app/src/main/java/dgca/verifier/app/android/verification/model/RuleValidationResultCard.kt index b0c05a92..58b80d30 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/VerificationResultResultViewModel.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/model/RuleValidationResultCard.kt @@ -17,14 +17,16 @@ * limitations under the License. * ---license-end * - * Created by osarapulov on 8/31/21 5:45 PM + * Created by mykhailo.nester on 10/10/2021, 09:20 */ -package dgca.verifier.app.android.verification +package dgca.verifier.app.android.verification.model -import androidx.lifecycle.ViewModel -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject +import dgca.verifier.app.engine.Result -@HiltViewModel -class VerificationResultResultViewModel @Inject constructor() : ViewModel() \ No newline at end of file +data class RuleValidationResultCard( + val description: String, + val result: Result, + val current: String, + val countryIsoCode: String +) \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/verification/StandardizedVerificationResult.kt b/app/src/main/java/dgca/verifier/app/android/verification/model/StandardizedVerificationResult.kt similarity index 97% rename from app/src/main/java/dgca/verifier/app/android/verification/StandardizedVerificationResult.kt rename to app/src/main/java/dgca/verifier/app/android/verification/model/StandardizedVerificationResult.kt index 929af550..1cd712e2 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/StandardizedVerificationResult.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/model/StandardizedVerificationResult.kt @@ -17,10 +17,10 @@ * limitations under the License. * ---license-end * - * Created by osarapulov on 9/2/21 6:37 PM + * Created by mykhailo.nester on 10/10/2021, 09:19 */ -package dgca.verifier.app.android.verification +package dgca.verifier.app.android.verification.model import dgca.verifier.app.decoder.model.VerificationResult diff --git a/app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultCard.kt b/app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultCard.kt deleted file mode 100644 index 5a9c83e4..00000000 --- a/app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultCard.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * ---license-start - * eu-digital-green-certificates / dgca-verifier-app-android - * --- - * Copyright (C) 2021 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - * - * Created by osarapulov on 6/18/21 8:59 AM - */ - -package dgca.verifier.app.android.verification.rules - -import dgca.verifier.app.engine.Result - -/*- - * ---license-start - * eu-digital-green-certificates / dgc-certlogic-android - * --- - * Copyright (C) 2021 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - * - * Created by osarapulov on 18.06.21 8:59 - */ -data class RuleValidationResultCard( - val description: String, - val result: Result, - val current: String, - val countryIsoCode: String -) \ No newline at end of file diff --git a/app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultsAdapter.kt b/app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultsAdapter.kt index 7c2fb47d..6dbcc10a 100644 --- a/app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultsAdapter.kt +++ b/app/src/main/java/dgca/verifier/app/android/verification/rules/RuleValidationResultsAdapter.kt @@ -30,41 +30,27 @@ import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.RecyclerView import dgca.verifier.app.android.R import dgca.verifier.app.android.databinding.ItemRuleValidationResultBinding +import dgca.verifier.app.android.verification.model.RuleValidationResultCard import dgca.verifier.app.engine.Result import java.util.* -/*- - * ---license-start - * eu-digital-green-certificates / dgc-certlogic-android - * --- - * Copyright (C) 2021 T-Systems International GmbH and all other contributors - * --- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ---license-end - * - * Created by osarapulov on 18.06.21 8:57 - */ class RuleValidationResultsAdapter( private val inflater: LayoutInflater, ruleValidationResultCards: Collection -) : - RecyclerView.Adapter() { +) : RecyclerView.Adapter() { + + private val ruleValidationResultCards: MutableList = ruleValidationResultCards.toMutableList() + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder = + CardViewHolder.create(inflater, parent) + + override fun onBindViewHolder(holder: CardViewHolder, position: Int) { + holder.bind(ruleValidationResultCards[position]) + } - private val ruleValidationResultCards: MutableList = - ruleValidationResultCards.toMutableList() + override fun getItemCount(): Int = ruleValidationResultCards.size - class CardViewHolder(private val binding: ItemRuleValidationResultBinding) : - RecyclerView.ViewHolder(binding.root) { + class CardViewHolder(private val binding: ItemRuleValidationResultBinding) : RecyclerView.ViewHolder(binding.root) { private fun Result.getLocalizedText(context: Context): String = context.getString( when (this) { Result.PASSED -> R.string.passed @@ -115,13 +101,4 @@ class RuleValidationResultsAdapter( CardViewHolder(ItemRuleValidationResultBinding.inflate(inflater, parent, false)) } } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder = - CardViewHolder.create(inflater, parent) - - override fun onBindViewHolder(holder: CardViewHolder, position: Int) { - holder.bind(ruleValidationResultCards[position]) - } - - override fun getItemCount(): Int = ruleValidationResultCards.size } diff --git a/app/src/main/res/color/btn_toggle_selector.xml b/app/src/main/res/color/btn_toggle_selector.xml deleted file mode 100644 index 6c444da0..00000000 --- a/app/src/main/res/color/btn_toggle_selector.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/icon_check.png b/app/src/main/res/drawable-hdpi/icon_check.png deleted file mode 100644 index 6189a45fb020af6b01419062a0461e399b771808..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1234 zcmV;@1TFiCP)p00004b3#c}2nYxW zdMn3VfvP_E-aJPc1$UU*bW zdGTaQC`pk^Aq^RFzoa}6Dat%}5G5qH@cIA0)*j#GT=v;}o$otmR-Mk7Z}whm{nlD% z?|t?z4CqHvEEdNA=QOU(g+k#?99ki+L0%|`%UMETz@;H$t5?&M)|3Ap-C)C;+*J7jTyPgoyI~E&*V>3dt=zz(;}Pehj#Q z{fUP*R6ut*eJ7W_rK__;5IQD=qNM!V7p09GtG0@h)V1N4dVtm3_UytuqgYI?%WWk$a_> zi5gX~GYmgo!_};4rzYb@cWmYb{17_4!!;8D=v8#APnCdQ#SgO;^&f+-ZSa{3n;MCP zheKP@<7ip0w|JhT9e|X;xrF6XHV{0r>;?P?8dV2~0bm92?k%u0R7zbl;{@LVAOA)< z7?^oDv5`DRshF> z!~#1*(23vI+TiQq(;pj$Dl#wNr_gbbO=q-uEftU`00MpieHU5Uv1xV@jaJ)&S7aUz zt-ufG6M!3s7=UIN{b1u^ir{PD12-(JrIdL%#0*@*HQ2gmWy6>Fvn4J7utWW{qnYt5 z(6>A(cq#J&&JyH1=pzikEI9EoNQr=-!~a-eT0-!Zu=&eHA>o;cWiFiq`f!h&hXpkO zfE~V4ZAx~irWe=V$I>*Nhuq%{$M} zNA8VHRSLip=;0Lh6&Gg@PM=yr@TCC%;j6H3s*|lEZU;~HRVw`-ihH;yn z9M1n-2XH-5FR557q-8V~o`z8YEx2)S&36fG!$I(QVasG21-5Oh;3WWDO7a`P_2b9J zr^xRE8wE+)Si?&IR^iT%lemqJBtDq7R$qoLio^OOf|mfa<9-}h;=U1%C)yLx3V;&; z#(?c`;INVtPP;)Gww>Um0`}m(&(n!s^mpC|^tA0)x~PByaA23C69o6(0d}-q>gJqz zV-x{k`SUeMA`J)Ef@c6Z0CFI-5!FKv8-rnOyfZKFKc_xUft(7XB$eYX*8r%%O8~g| z;UXw(UoF*xPL}|v!Ak(R{N*y3%i(e%I0rXQYnc&McnLuDhA0m+c&L#naQdnaF99$c wqD`yDj>CV)TB9JM&~4|l_GE|$>+E&u=k07*qoM6N<$g8oh{?f?J) diff --git a/app/src/main/res/drawable-hdpi/icon_error.png b/app/src/main/res/drawable-hdpi/icon_error.png deleted file mode 100644 index fee6212e0a8583e2f3cb2cdeaf7a674c68817310..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 801 zcmV++1K#|JP)j{00004b3#c}2nYxW zdBh(2T!8(CDfx3ZCVBJ6`uufn*fgM37 zh<7!~OHAOngCl|Ty}af%f$~2Gfk1H(;8T|68D#Sg$5DXns4O;c!+B8@-_(uN^@6&A zx*i$4E=~{uUhpG<2NNKM9~nG|01^B|z`X^q;U@;}C4dD#QE;&UXZVSOiv&2qCj!nE zK*A>m&JtjSPZZo)fDt}%a3=wS@R@*<0($V7fm;Q1-~k+GWnYnIXVjc2^!46ksDZD* zaaxMg(_B9t0ekqFfcKg}F*ES40D%9@Jk(81c!M=x=Gwq1E=~9!`12JU3ph@xf(%@L zgWq;=Tno}VCDDRM@CCeN+*EzanknD~(k`pc7{8yLXqY!?z&GG^S(pME@K$;i0UGd6 zP-{2;E5T7f54<`RG(hPIeE&IP9i_d6xlxXV&)`Ai!= zbfgB&58=`7VbEOD$ZU)77*-gba}uz{Cr764a5fLr~LV|%pE(~;Gi}E8)QB*`-n1ug_|4|z^ z1-2>zvr?;tfePXmco#1G08x>YHrMB;b7j1pb7s7r+rZ2DnD>33-@J2X=9mZnq2+S9 zUNBSGxH0D3MVeCcfp^0Aj8$Sku>nM!=D8&mVBw#DRXGD);l3LY$9h*X0l=S=f3^Ug z*RjS;4|d4Ln61cVNTSztOk-!(an&b+m?!uw z2EY&TX$QXT=De8#5{=UF9xJmBM_gYK5G%sMHRq2!LIv+4*LtDfl>iHW$8C9mgG6*h z1rk$F-;V%zY!0yui3YjOU==Z=_(wf4br!B`Qu9_(0zQyo#FOa2mT<$uzwzAQiP3(q zvM(q3Nq`QCFW3uDLM@*O>@BA9C$$qgdx8J<_+6g`h|rcfhduKJ1oUeK>9Fy_mCIcP z+B#L*mH;}4lH^JQqZlD|35gb7$ zsQD54C>=OS^#+W@f&y)=QA@1F>5Lti<;v$G7 zKt*vDVg}Gaya+J?XegeA7y(ugPeND#65rD6lPj5u|HtYuPW+vmUsM#3xUvuc_$KRf z$&3az9RLP}qi|2?e-TiMgt2q07d zleS7i9%2-CaEOBR>`(!~e++?$;2TzqYSM^fiW*=B;lsQ@d@%qf9%$81f%wusvM2(R zJr5w_#1!P9ehcD++xq>_R0jv4ia;*gbJf9#t8?IfAyE z{h@jU;1K6V>CnQ;FD1&(#^wN4Chgq{->m6hPPyLwu`s00000NkvXXu0mjf2eaBS diff --git a/app/src/main/res/drawable-mdpi/icon_check.png b/app/src/main/res/drawable-mdpi/icon_check.png deleted file mode 100644 index 788542744bfa572fc061fd193dc317eb8855d9be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 762 zcmVv$B3wu-cP(;JsTqh1H))h%AR2`(%#DKE ziqak0l+MhB>!jZdXgAsy54|%PC%K1mbOw>P$2uD zn@27hDEG1LE*mJ2JtSO81?hP|$^r^x7l0p;OXf-fDL%P_D&z{es?tJ6f)c!*n~TUZ zwuXO(1Sd?1(@DqIQXxY@6>^=M4ahcf7g*7zrjW9=TsAl!VEcf4#o-RN6GQJn`gT&$ zdlp#YwBz#)sWw7BCeN2JpJUJn$RMm#b|)?|aaytYl_liy(8oafY+G8{NLYpZiQSdB z2MXMm;f}1NZ|5b148k^3*u)zEz~gN|3-lHRLH!od$Q%vM?-L zOdMxPkfERo+lH3?(DKg`1zR#?B&fo6puZ!QQ;!RKL`QF$Iq3#E^O(nO@DK-?_?B~| zpFao$_PON>!!0MRr6!Xjwlhn0A6x spjz2U^hh}%Qw_bd8_2m-4l=p7|NdR_68oeo2mk;807*qoM6N<$f+L<$o&W#< diff --git a/app/src/main/res/drawable-mdpi/icon_error.png b/app/src/main/res/drawable-mdpi/icon_error.png deleted file mode 100644 index 6438b00fc646fd35d1ab1349d7ae6683a6aff315..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 589 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 + android:layout_height="match_parent"> + android:weightSum="2" + tools:ignore="RtlSymmetry"> - - \ No newline at end of file + tools:text="Germany" /> \ No newline at end of file diff --git a/app/src/main/res/layout/view_certificate_content_view.xml b/app/src/main/res/layout/view_certificate_content_view.xml index 500972e0..1cb88ae0 100644 --- a/app/src/main/res/layout/view_certificate_content_view.xml +++ b/app/src/main/res/layout/view_certificate_content_view.xml @@ -48,7 +48,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - - - - - - - @@ -79,7 +79,7 @@ + app:argType="dgca.verifier.app.android.verification.model.StandardizedVerificationResult" /> + app:argType="dgca.verifier.app.android.verification.model.StandardizedVerificationResult" /> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index be2bcf46..cc3a6989 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -34,7 +34,6 @@ #707070 #9F9F9F #3CD1D0D0 - #00000000 #F2F2F2 #fff8e8 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 5229ce59..cb33fb59 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -57,17 +57,6 @@ 16sp - - - -