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 6189a45f..00000000 Binary files a/app/src/main/res/drawable-hdpi/icon_check.png and /dev/null differ 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 fee6212e..00000000 Binary files a/app/src/main/res/drawable-hdpi/icon_error.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/icon_check.png b/app/src/main/res/drawable-ldpi/icon_check.png deleted file mode 100644 index 2ca7eeda..00000000 Binary files a/app/src/main/res/drawable-ldpi/icon_check.png and /dev/null differ diff --git a/app/src/main/res/drawable-ldpi/icon_error.png b/app/src/main/res/drawable-ldpi/icon_error.png deleted file mode 100644 index 82925909..00000000 Binary files a/app/src/main/res/drawable-ldpi/icon_error.png and /dev/null differ 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 78854274..00000000 Binary files a/app/src/main/res/drawable-mdpi/icon_check.png and /dev/null differ 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 6438b00f..00000000 Binary files a/app/src/main/res/drawable-mdpi/icon_error.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/icon_check.png b/app/src/main/res/drawable-xhdpi/icon_check.png deleted file mode 100644 index 921353d8..00000000 Binary files a/app/src/main/res/drawable-xhdpi/icon_check.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/icon_error.png b/app/src/main/res/drawable-xhdpi/icon_error.png deleted file mode 100644 index 84b5b528..00000000 Binary files a/app/src/main/res/drawable-xhdpi/icon_error.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_check.png b/app/src/main/res/drawable-xxhdpi/icon_check.png deleted file mode 100644 index eca59dc2..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/icon_check.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/icon_error.png b/app/src/main/res/drawable-xxhdpi/icon_error.png deleted file mode 100644 index de28d832..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/icon_error.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_check.png b/app/src/main/res/drawable-xxxhdpi/icon_check.png deleted file mode 100644 index 87aa5535..00000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_check.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/icon_error.png b/app/src/main/res/drawable-xxxhdpi/icon_error.png deleted file mode 100644 index bc4d26d9..00000000 Binary files a/app/src/main/res/drawable-xxxhdpi/icon_error.png and /dev/null differ diff --git a/app/src/main/res/layout/fragment_countries_selector.xml b/app/src/main/res/layout/fragment_countries_selector.xml index 31a5dab5..0ef7468f 100644 --- a/app/src/main/res/layout/fragment_countries_selector.xml +++ b/app/src/main/res/layout/fragment_countries_selector.xml @@ -24,8 +24,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/white"> + 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 - - - -