Updated on 2026-08-14

This commit is contained in:
Tangem 2020-03-24 19:29:44 +03:00
parent 8a6f9f3ff6
commit 875e220c61
16 changed files with 626 additions and 137 deletions

View file

@ -51,5 +51,5 @@ dependencies {
implementation "androidx.viewpager2:viewpager2:1.0.0"
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.github.gbIxaHue:eu4d:0.3.6'
implementation 'com.github.gbIxaHue:eu4d:0.3.7'
}

View file

@ -0,0 +1,116 @@
package com.tangem.tangemtest._arch.structure.base
/**
[REDACTED_AUTHOR]
*/
interface Id
enum class BlockId : Id {
CARD_NUMBER,
COMMON,
SIGNING_METHOD,
SIGN_HASH_EX_PROP,
DENOMINATION,
TOKEN,
PROD_MASK,
SETTINGS_MASK,
SETTINGS_MASK_PROTOCOL_ENC,
SETTINGS_MASK_NDEF,
PINS,
}
enum class CardNumber : Id {
SERIES,
NUMBER,
}
enum class Common : Id {
CURVE,
BLOCKCHAIN,
BLOCKCHAIN_CUSTOM,
MAX_SIGNATURES,
CREATE_WALLET,
}
enum class SigningMethod : Id {
SIGN_TX,
SIGN_TX_RAW,
SIGN_VALIDATED_TX,
SIGN_VALIDATED_TX_RAW,
SIGN_VALIDATED_TX_ISSUER,
SIGN_VALIDATED_TX_RAW_ISSUER,
SIGN_EXTERNAL,
}
enum class SignHashExProp : Id {
PIN_LESS_FLOOR_LIMIT,
CRYPTO_EXTRACT_KEY,
REQUIRE_TERMINAL_CERT_SIG,
REQUIRE_TERMINAL_TX_SIG,
CHECK_PIN3,
}
enum class Denomination : Id {
WRITE_ON_PERSONALIZE,
DENOMINATION,
}
enum class Token : Id {
ITS_TOKEN,
SYMBOL,
CONTRACT_ADDRESS,
DECIMAL
}
enum class ProductMask : Id {
NOTE,
TAG,
ID_CARD
}
enum class SettingsMask : Id {
IS_REUSABLE,
NEED_ACTIVATION,
FORBID_PURGE,
ALLOW_SELECT_BLOCKCHAIN,
USE_BLOCK,
ONE_APDU,
USE_CVC,
ALLOW_SWAP_PIN,
ALLOW_SWAP_PIN2,
FORBID_DEFAULT_PIN,
SMART_SECURITY_DELAY,
PROTECT_ISSUER_DATA_AGAINST_REPLAY,
SKIP_SECURITY_DELAY_IF_VALIDATED,
SKIP_PIN2_CVC_IF_VALIDATED,
SKIP_SECURITY_DELAY_ON_LINKED_TERMINAL,
RESTRICT_OVERWRITE_EXTRA_ISSUER_DATA,
}
enum class SettingsMaskProtocolEnc : Id {
ALLOW_UNENCRYPTED,
ALLOW_FAST_ENCRYPTION
}
enum class SettingsMaskNdef : Id {
USE_NDEF,
DYNAMIC_NDEF,
DISABLE_PRECOMPUTED_NDEF,
AAR,
CUSTOM_AAR
}
enum class Pins : Id {
PIN,
PIN2,
PIN3,
CVC,
PAUSE_BEFORE_PIN2
}
enum class Additional : Id {
UNDEFINED,
JSON_INCOMING,
JSON_OUTGOING,
JSON_TAILS,
}

View file

@ -4,6 +4,7 @@ package com.tangem.tangemtest._arch.structure.base
[REDACTED_AUTHOR]
*/
interface Unit : Payload {
val id: Id
var parent: Unit?
}
@ -12,6 +13,6 @@ abstract class BaseUnit : Unit {
override val payload: MutableMap<String, Any?> = mutableMapOf()
}
open class DataUnit<D>(
abstract class DataUnit<D>(
override var viewModel: UnitViewModel<D>?
) : BaseUnit(), DataHolder<UnitViewModel<D>>

View file

@ -17,10 +17,12 @@ abstract class BaseBlock : Block {
override var blockModified: BlockModified? = null
}
open class ListUnitBlock : BaseBlock(), ItemListHolder<Unit> {
open class ListUnitBlock(
override val id: Id
) : BaseBlock(), ItemListHolder<Unit> {
override fun setItems(list: MutableList<Unit>) {
ULog.d(this, "setUnits: ${list.size}")
ULog.d(this, "setUnits: $id, ${list.size}")
unitList.clear()
unitList.addAll(list)
unitList.forEach { it.parent = this }
@ -28,12 +30,12 @@ open class ListUnitBlock : BaseBlock(), ItemListHolder<Unit> {
}
override fun getItems(): MutableList<Unit> {
ULog.d(this, "getUnits: ${unitList.size}")
ULog.d(this, "getUnits: $id, ${unitList.size}")
return unitList
}
override fun addItem(item: Unit) {
ULog.d(this, "addUnit: ${unitList.size}")
ULog.d(this, "addUnit: $id, ${unitList.size}")
item.parent = this
unitList.add(item)
blockModified?.invoke()

View file

@ -1,8 +1,9 @@
package com.tangem.tangemtest._arch.structure.impl
import com.tangem.tangemtest._arch.structure.base.Id
import com.tangem.tangemtest._arch.structure.base.ListUnitBlock
/**
[REDACTED_AUTHOR]
*/
class LinearBlock : ListUnitBlock()
class LinearBlock(id: Id) : ListUnitBlock(id)

View file

@ -1,14 +1,15 @@
package com.tangem.tangemtest._arch.structure.impl
import com.tangem.tangemtest._arch.structure.base.DataUnit
import com.tangem.tangemtest._arch.structure.base.Id
class TextUnit(value: String? = null) : DataUnit<String>(StringViewModel(value))
class EditTextUnit(value: String? = null) : DataUnit<String>(StringViewModel(value))
class NumberUnit(value: Number? = null) : DataUnit<Number>(NumberViewModel(value))
class BoolUnit(value: Boolean? = null) : DataUnit<Boolean>(BoolViewModel(value))
class TextUnit(override val id: Id, value: String? = null) : DataUnit<String>(StringViewModel(value))
class EditTextUnit(override val id: Id, value: String? = null) : DataUnit<String>(StringViewModel(value))
class NumberUnit(override val id: Id, value: Number? = null) : DataUnit<Number>(NumberViewModel(value))
class BoolUnit(override val id: Id, value: Boolean? = null) : DataUnit<Boolean>(BoolViewModel(value))
class ListUnit(value: List<KeyValue>, selectedValue: Any)
class ListUnit(override val id: Id, value: List<KeyValue>, selectedValue: Any)
: DataUnit<ModelHelper>(ListViewModel(ModelHelper(selectedValue, value))
)

View file

@ -5,7 +5,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
@ -24,7 +24,7 @@ import java.nio.charset.Charset
class PersonalizeFragment : Fragment() {
protected val blockContainer: ViewGroup by lazy {
mainView.findViewById<FrameLayout>(R.id.ll_container)
mainView.findViewById<LinearLayout>(R.id.ll_container)
}
protected val viewModel: PersonalizeViewModel by viewModels { PersonalizeViewModelFactory(getPersonalizeJson()) }
protected lateinit var mainView: View
@ -38,8 +38,9 @@ class PersonalizeFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.ldBlockList.observe(viewLifecycleOwner, Observer {
WidgetBuilder().build(it, blockContainer)
viewModel.ldBlockList.observe(viewLifecycleOwner, Observer { blocList ->
blocList.forEach { WidgetBuilder().build(it, blockContainer) }
})
}

View file

@ -0,0 +1,339 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.base.*
/**
[REDACTED_AUTHOR]
*/
data class UnitInfo(
val resName: Int,
val resDescription: Int? = null
)
object InfoHolder {
private val map = mutableMapOf<Id, UnitInfo>()
init {
InfoInitializer().init(map)
}
fun getInfo(id: Id): UnitInfo = map[id] ?: UnitInfo(R.string.unknown, R.string.unknown)
}
internal class InfoInitializer() {
fun init(map: MutableMap<Id, UnitInfo>) {
initBlock(map)
initCardNumber(map)
initCommon(map)
initSigningMethod(map)
initSignHashExProp(map)
initDenomination(map)
initToken(map)
initProductMask(map)
initSettingsMask(map)
initSettingsMaskProtocolEnc(map)
initSettingsMaskNde(map)
initPins(map)
}
private fun initBlock(map: MutableMap<Id, UnitInfo>) {
map[BlockId.CARD_NUMBER] = UnitInfo(
R.string.pers_block_card_number,
R.string.info_
)
map[BlockId.COMMON] = UnitInfo(
R.string.pers_block_common,
R.string.info_
)
map[BlockId.SIGNING_METHOD] = UnitInfo(
R.string.pers_block_signing_method,
R.string.info_
)
map[BlockId.SIGN_HASH_EX_PROP] = UnitInfo(
R.string.pers_block_sign_hash_ex_prop,
R.string.info_
)
map[BlockId.DENOMINATION] = UnitInfo(
R.string.pers_block_denomination,
R.string.info_
)
map[BlockId.TOKEN] = UnitInfo(
R.string.pers_block_token,
R.string.info_
)
map[BlockId.PROD_MASK] = UnitInfo(
R.string.pers_block_product_mask,
R.string.info_
)
map[BlockId.SETTINGS_MASK] = UnitInfo(
R.string.pers_block_settings_mask,
R.string.info_
)
map[BlockId.SETTINGS_MASK_PROTOCOL_ENC] = UnitInfo(
R.string.pers_block_settings_mask_protocol_enc,
R.string.info_
)
map[BlockId.SETTINGS_MASK_NDEF] = UnitInfo(
R.string.pers_block_settings_mask_ndef,
R.string.info_
)
map[BlockId.PINS] = UnitInfo(
R.string.pers_block_pins,
R.string.info_
)
}
private fun initCardNumber(map: MutableMap<Id, UnitInfo>) {
map[CardNumber.SERIES] = UnitInfo(
R.string.pers_item_series,
R.string.info_
)
map[CardNumber.NUMBER] = UnitInfo(
R.string.pers_item_number,
R.string.info_
)
}
private fun initCommon(map: MutableMap<Id, UnitInfo>) {
map[Common.CURVE] = UnitInfo(
R.string.pers_item_curve,
R.string.info_
)
map[Common.BLOCKCHAIN] = UnitInfo(
R.string.pers_item_blockchain,
R.string.info_
)
map[Common.BLOCKCHAIN_CUSTOM] = UnitInfo(
R.string.pers_item_custom_blockchain,
R.string.info_
)
map[Common.MAX_SIGNATURES] = UnitInfo(
R.string.pers_item_max_signatures,
R.string.info_
)
map[Common.CREATE_WALLET] = UnitInfo(
R.string.pers_item_create_wallet,
R.string.info_
)
}
private fun initSigningMethod(map: MutableMap<Id, UnitInfo>) {
map[SigningMethod.SIGN_TX] = UnitInfo(
R.string.pers_item_sign_tx_hashes,
R.string.info_
)
map[SigningMethod.SIGN_TX_RAW] = UnitInfo(
R.string.pers_item_sign_raw_tx,
R.string.info_
)
map[SigningMethod.SIGN_VALIDATED_TX] = UnitInfo(
R.string.pers_item_sign_validated_tx_hashes,
R.string.info_
)
map[SigningMethod.SIGN_VALIDATED_TX_RAW] = UnitInfo(
R.string.pers_item_sign_validated_raw_tx,
R.string.info_
)
map[SigningMethod.SIGN_VALIDATED_TX_ISSUER] = UnitInfo(
R.string.pers_item_sign_validated_tx_hashes_with_iss_data,
R.string.info_
)
map[SigningMethod.SIGN_VALIDATED_TX_RAW_ISSUER] = UnitInfo(
R.string.pers_item_sign_validated_raw_tx_with_iss_data,
R.string.info_
)
map[SigningMethod.SIGN_EXTERNAL] = UnitInfo(
R.string.pers_item_sign_hash_ex,
R.string.info_
)
}
private fun initSignHashExProp(map: MutableMap<Id, UnitInfo>) {
map[SignHashExProp.PIN_LESS_FLOOR_LIMIT] = UnitInfo(
R.string.pers_item_pin_less_floor_limit,
R.string.info_
)
map[SignHashExProp.CRYPTO_EXTRACT_KEY] = UnitInfo(
R.string.pers_item_cr_ex_key,
R.string.info_
)
map[SignHashExProp.REQUIRE_TERMINAL_CERT_SIG] = UnitInfo(
R.string.pers_item_require_terminal_cert_sig,
R.string.info_
)
map[SignHashExProp.REQUIRE_TERMINAL_TX_SIG] = UnitInfo(
R.string.pers_item_require_terminal_tx_sig,
R.string.info_
)
map[SignHashExProp.CHECK_PIN3] = UnitInfo(
R.string.pers_item_pin3,
R.string.info_
)
}
private fun initDenomination(map: MutableMap<Id, UnitInfo>) {
map[Denomination.WRITE_ON_PERSONALIZE] = UnitInfo(
R.string.pers_item_write_on_personalize,
R.string.info_
)
map[Denomination.DENOMINATION] = UnitInfo(
R.string.pers_item_denomination,
R.string.info_
)
}
private fun initToken(map: MutableMap<Id, UnitInfo>) {
map[Token.ITS_TOKEN] = UnitInfo(
R.string.pers_item_its_token,
R.string.info_
)
map[Token.SYMBOL] = UnitInfo(
R.string.pers_item_symbol,
R.string.info_
)
map[Token.CONTRACT_ADDRESS] = UnitInfo(
R.string.pers_item_contract_address,
R.string.info_
)
map[Token.DECIMAL] = UnitInfo(
R.string.pers_item_decimal,
R.string.info_
)
}
private fun initProductMask(map: MutableMap<Id, UnitInfo>) {
map[ProductMask.NOTE] = UnitInfo(
R.string.pers_item_note,
R.string.info_
)
map[ProductMask.TAG] = UnitInfo(
R.string.pers_item_tag,
R.string.info_
)
map[ProductMask.ID_CARD] = UnitInfo(
R.string.pers_item_id_card,
R.string.info_
)
}
private fun initSettingsMask(map: MutableMap<Id, UnitInfo>) {
map[SettingsMask.IS_REUSABLE] = UnitInfo(
R.string.pers_item_is_reusable,
R.string.info_
)
map[SettingsMask.NEED_ACTIVATION] = UnitInfo(
R.string.pers_item_need_activation,
R.string.info_
)
map[SettingsMask.FORBID_PURGE] = UnitInfo(
R.string.pers_item_forbid_purge,
R.string.info_
)
map[SettingsMask.ALLOW_SELECT_BLOCKCHAIN] = UnitInfo(
R.string.pers_item_allow_select_blockchain,
R.string.info_
)
map[SettingsMask.USE_BLOCK] = UnitInfo(
R.string.pers_item_use_block,
R.string.info_
)
map[SettingsMask.ONE_APDU] = UnitInfo(
R.string.pers_item_one_apdu_at_once,
R.string.info_
)
map[SettingsMask.USE_CVC] = UnitInfo(
R.string.pers_item_use_cvc,
R.string.info_
)
map[SettingsMask.ALLOW_SWAP_PIN] = UnitInfo(
R.string.pers_item_allow_swap_pin,
R.string.info_
)
map[SettingsMask.ALLOW_SWAP_PIN2] = UnitInfo(
R.string.pers_item_allow_swap_pin2,
R.string.info_
)
map[SettingsMask.FORBID_DEFAULT_PIN] = UnitInfo(
R.string.pers_item_forbid_default_pin,
R.string.info_
)
map[SettingsMask.SMART_SECURITY_DELAY] = UnitInfo(
R.string.pers_item_smart_security_delay,
R.string.info_
)
map[SettingsMask.PROTECT_ISSUER_DATA_AGAINST_REPLAY] = UnitInfo(
R.string.pers_item_protect_issuer_data_against_replay,
R.string.info_
)
map[SettingsMask.SKIP_SECURITY_DELAY_IF_VALIDATED] = UnitInfo(
R.string.pers_item_skip_security_delay_if_validated,
R.string.info_
)
map[SettingsMask.SKIP_PIN2_CVC_IF_VALIDATED] = UnitInfo(
R.string.pers_item_skip_pin2_and_cvc_if_validated,
R.string.info_
)
map[SettingsMask.SKIP_SECURITY_DELAY_ON_LINKED_TERMINAL] = UnitInfo(
R.string.pers_item_skip_security_delay_on_linked_terminal,
R.string.info_
)
map[SettingsMask.RESTRICT_OVERWRITE_EXTRA_ISSUER_DATA] = UnitInfo(
R.string.pers_item_restrict_overwrite_ex_issuer_data,
R.string.info_
)
}
private fun initSettingsMaskProtocolEnc(map: MutableMap<Id, UnitInfo>) {
map[SettingsMaskProtocolEnc.ALLOW_UNENCRYPTED] = UnitInfo(
R.string.pers_item_allow_unencrypted,
R.string.info_
)
map[SettingsMaskProtocolEnc.ALLOW_FAST_ENCRYPTION] = UnitInfo(
R.string.pers_item_allow_fast_encryption,
R.string.info_
)
}
private fun initSettingsMaskNde(map: MutableMap<Id, UnitInfo>) {
map[SettingsMaskNdef.USE_NDEF] = UnitInfo(
R.string.pers_item_use_ndef,
R.string.info_
)
map[SettingsMaskNdef.DYNAMIC_NDEF] = UnitInfo(
R.string.pers_item_dynamic_ndef,
R.string.info_
)
map[SettingsMaskNdef.DISABLE_PRECOMPUTED_NDEF] = UnitInfo(
R.string.pers_item_disable_precomputed_ndef,
R.string.info_
)
map[SettingsMaskNdef.AAR] = UnitInfo(
R.string.pers_item_aar,
R.string.info_
)
}
private fun initPins(map: MutableMap<Id, UnitInfo>) {
map[Pins.PIN] = UnitInfo(
R.string.pers_item_pin,
R.string.info_
)
map[Pins.PIN2] = UnitInfo(
R.string.pers_item_pin2,
R.string.info_
)
map[Pins.PIN3] = UnitInfo(
R.string.pers_item_pin3,
R.string.info_
)
map[Pins.CVC] = UnitInfo(
R.string.pers_item_cvc,
R.string.info_
)
map[Pins.PAUSE_BEFORE_PIN2] = UnitInfo(
R.string.pers_item_pause_before_pin2,
R.string.info_
)
}
}

View file

@ -13,9 +13,9 @@ interface EncodeDecode<A, B> {
class JsonBlockEnDe(
private val jsonToBlock: JsonToBlockConverter,
private val blockToJson: BlockToJsonConverter
) : EncodeDecode<TestJsonDto, Block> {
) : EncodeDecode<TestJsonDto, List<Block>> {
override fun encode(from: Block): TestJsonDto = blockToJson.convert(from)
override fun encode(from: List<Block>): TestJsonDto = blockToJson.convert(from)
override fun decode(from: TestJsonDto): Block = jsonToBlock.convert(from)
override fun decode(from: TestJsonDto): List<Block> = jsonToBlock.convert(from)
}

View file

@ -1,161 +1,171 @@
package com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converter.json_test
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.base.Block
import com.tangem.tangemtest._arch.structure.base.*
import com.tangem.tangemtest._arch.structure.impl.*
import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter
class JsonToBlockConverter : Converter<TestJsonDto, Block> {
class JsonToBlockConverter : Converter<TestJsonDto, List<Block>> {
override fun convert(from: TestJsonDto): Block {
val initialBlock = LinearBlock()
initialBlock.addItem(cardNumber(from))
initialBlock.addItem(common(from))
initialBlock.addItem(signingMethod(from))
initialBlock.addItem(signHashExProperties(from))
initialBlock.addItem(denomination(from))
initialBlock.addItem(token(from))
initialBlock.addItem(productMask(from))
initialBlock.addItem(settingsMask(from))
initialBlock.addItem(settingsMaskProtocolEnc(from))
initialBlock.addItem(cardNumber(from))
initialBlock.addItem(settingsMaskNdef(from))
initialBlock.addItem(pins(from))
addPayload(initialBlock, from)
return initialBlock
override fun convert(from: TestJsonDto): List<Block> {
val blocList = mutableListOf<Block>()
blocList.add(cardNumber(from))
blocList.add(common(from))
blocList.add(signingMethod(from))
blocList.add(signHashExProperties(from))
blocList.add(denomination(from))
blocList.add(token(from))
blocList.add(productMask(from))
blocList.add(settingsMask(from))
blocList.add(settingsMaskProtocolEnc(from))
blocList.add(settingsMaskNdef(from))
blocList.add(pins(from))
val payloadBlock = LinearBlock(Additional.JSON_TAILS)
addPayload(payloadBlock, from)
blocList.add(payloadBlock)
return blocList
}
private fun cardNumber(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_card_number))
block.addItem(EditTextUnit(from.series).resName(R.string.pers_item_series))
block.addItem(NumberUnit(from.startNumber).resName(R.string.pers_item_number))
val block = LinearBlock(BlockId.CARD_NUMBER)
block.addItem(TextUnit(BlockId.CARD_NUMBER))
block.addItem(EditTextUnit(CardNumber.SERIES, from.series))
block.addItem(NumberUnit(CardNumber.NUMBER, from.startNumber))
return block
}
private fun common(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_common))
block.addItem(ListUnit(Helper.listOfCurves(), from.curveID).resName(R.string.pers_item_curve))
block.addItem(ListUnit(Helper.listOfBlockchain(), from.blockchain.name).resName(R.string.pers_item_blockchain))
block.addItem(EditTextUnit(from.blockchain.customName).resName(R.string.pers_item_custom_blockchain))
block.addItem(NumberUnit(from.MaxSignatures).resName(R.string.pers_item_max_signatures))
block.addItem(BoolUnit(from.createWalletB).resName(R.string.action_wallet_create))
val block = LinearBlock(BlockId.COMMON)
block.addItem(TextUnit(BlockId.COMMON))
block.addItem(ListUnit(Common.CURVE, Helper.listOfCurves(), from.curveID))
block.addItem(ListUnit(Common.BLOCKCHAIN, Helper.listOfBlockchain(), from.blockchain.name))
block.addItem(EditTextUnit(Common.BLOCKCHAIN_CUSTOM, from.blockchain.customName))
block.addItem(NumberUnit(Common.MAX_SIGNATURES, from.MaxSignatures))
block.addItem(BoolUnit(Common.CREATE_WALLET, from.createWalletB))
return block
}
private fun signingMethod(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_signing_method))
block.addItem(BoolUnit(from.SigningMethod0).resName(R.string.pers_item_sign_tx_hashes))
block.addItem(BoolUnit(from.SigningMethod1).resName(R.string.pers_item_sign_raw_tx))
block.addItem(BoolUnit(from.SigningMethod2).resName(R.string.pers_item_sign_validated_tx_hashes))
block.addItem(BoolUnit(from.SigningMethod3).resName(R.string.pers_item_sign_validated_raw_tx))
block.addItem(BoolUnit(from.SigningMethod4).resName(R.string.pers_item_sign_validated_tx_hashes_with_iss_data))
block.addItem(BoolUnit(from.SigningMethod5).resName(R.string.pers_item_sign_validated_raw_tx_with_iss_data))
block.addItem(BoolUnit(from.SigningMethod6).resName(R.string.pers_item_sign_hash_ex))
val block = LinearBlock(BlockId.SIGNING_METHOD)
block.addItem(TextUnit(BlockId.SIGNING_METHOD))
block.addItem(BoolUnit(SigningMethod.SIGN_TX, from.SigningMethod0))
block.addItem(BoolUnit(SigningMethod.SIGN_TX_RAW, from.SigningMethod1))
block.addItem(BoolUnit(SigningMethod.SIGN_VALIDATED_TX, from.SigningMethod2))
block.addItem(BoolUnit(SigningMethod.SIGN_VALIDATED_TX_RAW, from.SigningMethod3))
block.addItem(BoolUnit(SigningMethod.SIGN_VALIDATED_TX_ISSUER, from.SigningMethod4))
block.addItem(BoolUnit(SigningMethod.SIGN_VALIDATED_TX_RAW_ISSUER, from.SigningMethod5))
block.addItem(BoolUnit(SigningMethod.SIGN_EXTERNAL, from.SigningMethod6))
return block
}
private fun signHashExProperties(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_sign_hash_ex_prop))
block.addItem(NumberUnit(from.pinLessFloorLimit).resName(R.string.pers_item_pin_less_floor_limit))
block.addItem(EditTextUnit(from.hexCrExKey).resName(R.string.pers_item_cr_ex_key))
block.addItem(BoolUnit(from.requireTerminalCertSignature).resName(R.string.pers_item_require_terminal_cert_sig))
block.addItem(BoolUnit(from.requireTerminalTxSignature).resName(R.string.pers_item_require_terminal_tx_sig))
block.addItem(BoolUnit(from.checkPIN3onCard).resName(R.string.pers_item_check_pin3_on_card))
val block = LinearBlock(BlockId.SIGN_HASH_EX_PROP)
block.addItem(TextUnit(BlockId.SIGN_HASH_EX_PROP))
block.addItem(NumberUnit(SignHashExProp.PIN_LESS_FLOOR_LIMIT, from.pinLessFloorLimit))
block.addItem(EditTextUnit(SignHashExProp.CRYPTO_EXTRACT_KEY, from.hexCrExKey))
block.addItem(BoolUnit(SignHashExProp.REQUIRE_TERMINAL_CERT_SIG, from.requireTerminalCertSignature))
block.addItem(BoolUnit(SignHashExProp.REQUIRE_TERMINAL_TX_SIG, from.requireTerminalTxSignature))
block.addItem(BoolUnit(SignHashExProp.CHECK_PIN3, from.checkPIN3onCard))
return block
}
private fun denomination(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_denomination))
block.addItem(BoolUnit(from.writeOnPersonalization).resName(R.string.pers_item_write_on_personalize))
block.addItem(NumberUnit(from.denomination).resName(R.string.pers_item_denomination))
val block = LinearBlock(BlockId.DENOMINATION)
block.addItem(TextUnit(BlockId.DENOMINATION))
block.addItem(BoolUnit(Denomination.WRITE_ON_PERSONALIZE, from.writeOnPersonalization))
block.addItem(NumberUnit(Denomination.DENOMINATION, from.denomination))
return block
}
private fun token(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_token))
block.addItem(BoolUnit(from.itsToken).resName(R.string.pers_item_its_token))
block.addItem(EditTextUnit(from.symbol).resName(R.string.pers_item_symbol))
block.addItem(EditTextUnit(from.contractAddress).resName(R.string.pers_item_contract_address))
block.addItem(NumberUnit(from.decimal).resName(R.string.pers_item_decimal))
val block = LinearBlock(BlockId.TOKEN)
block.addItem(TextUnit(BlockId.TOKEN))
block.addItem(BoolUnit(Token.ITS_TOKEN, from.itsToken))
block.addItem(EditTextUnit(Token.SYMBOL, from.symbol))
block.addItem(EditTextUnit(Token.CONTRACT_ADDRESS, from.contractAddress))
block.addItem(NumberUnit(Token.DECIMAL, from.decimal))
return block
}
private fun productMask(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_product_mask))
block.addItem(BoolUnit(from.cardData.product_note).resName(R.string.pers_item_note))
block.addItem(BoolUnit(from.cardData.product_tag).resName(R.string.pers_item_tag))
block.addItem(BoolUnit(from.cardData.product_id_card).resName(R.string.pers_item_id_card))
val block = LinearBlock(BlockId.PROD_MASK)
block.addItem(TextUnit(BlockId.PROD_MASK))
block.addItem(BoolUnit(ProductMask.NOTE, from.cardData.product_note))
block.addItem(BoolUnit(ProductMask.TAG, from.cardData.product_tag))
block.addItem(BoolUnit(ProductMask.ID_CARD, from.cardData.product_id_card))
return block
}
private fun settingsMask(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_settings_mask))
block.addItem(BoolUnit(from.isReusable).resName(R.string.pers_item_is_reusable))
block.addItem(BoolUnit(from.useActivation).resName(R.string.pers_item_need_activation))
block.addItem(BoolUnit(from.forbidPurgeWallet).resName(R.string.pers_item_forbid_purge))
block.addItem(BoolUnit(from.allowSelectBlockchain).resName(R.string.pers_item_allow_select_blockchain))
block.addItem(BoolUnit(from.useBlock).resName(R.string.pers_item_use_block))
block.addItem(BoolUnit(from.useOneCommandAtTime).resName(R.string.pers_item_one_apdu_at_once))
block.addItem(BoolUnit(from.useCVC).resName(R.string.pers_item_use_cvc))
block.addItem(BoolUnit(from.allowSwapPIN).resName(R.string.pers_item_allow_swap_pin))
block.addItem(BoolUnit(from.allowSwapPIN2).resName(R.string.pers_item_allow_swap_pin2))
block.addItem(BoolUnit(from.forbidDefaultPIN).resName(R.string.pers_item_forbid_default_pin))
block.addItem(BoolUnit(from.smartSecurityDelay).resName(R.string.pers_item_smart_security_delay))
block.addItem(BoolUnit(from.protectIssuerDataAgainstReplay).resName(R.string.pers_item_protect_issuer_data_against_replay))
block.addItem(BoolUnit(from.skipSecurityDelayIfValidatedByIssuer).resName(R.string.pers_item_skip_security_delay_if_validated))
block.addItem(BoolUnit(from.skipCheckPIN2andCVCIfValidatedByIssuer).resName(R.string.pers_item_skip_pin2_and_cvc_if_validated))
block.addItem(BoolUnit(from.skipSecurityDelayIfValidatedByLinkedTerminal).resName(R.string.pers_item_skip_security_delay_on_linked_terminal))
block.addItem(BoolUnit(from.restrictOverwriteIssuerDataEx).resName(R.string.pers_item_restrict_overwrite_ex_issuer_data))
val block = LinearBlock(BlockId.SETTINGS_MASK)
block.addItem(TextUnit(BlockId.SETTINGS_MASK))
block.addItem(BoolUnit(SettingsMask.IS_REUSABLE, from.isReusable))
block.addItem(BoolUnit(SettingsMask.NEED_ACTIVATION, from.useActivation))
block.addItem(BoolUnit(SettingsMask.FORBID_PURGE, from.forbidPurgeWallet))
block.addItem(BoolUnit(SettingsMask.ALLOW_SELECT_BLOCKCHAIN, from.allowSelectBlockchain))
block.addItem(BoolUnit(SettingsMask.USE_BLOCK, from.useBlock))
block.addItem(BoolUnit(SettingsMask.ONE_APDU, from.useOneCommandAtTime))
block.addItem(BoolUnit(SettingsMask.USE_CVC, from.useCVC))
block.addItem(BoolUnit(SettingsMask.ALLOW_SWAP_PIN, from.allowSwapPIN))
block.addItem(BoolUnit(SettingsMask.ALLOW_SWAP_PIN2, from.allowSwapPIN2))
block.addItem(BoolUnit(SettingsMask.FORBID_DEFAULT_PIN, from.forbidDefaultPIN))
block.addItem(BoolUnit(SettingsMask.SMART_SECURITY_DELAY, from.smartSecurityDelay))
block.addItem(BoolUnit(SettingsMask.PROTECT_ISSUER_DATA_AGAINST_REPLAY, from.protectIssuerDataAgainstReplay))
block.addItem(BoolUnit(SettingsMask.SKIP_SECURITY_DELAY_IF_VALIDATED, from.skipSecurityDelayIfValidatedByIssuer))
block.addItem(BoolUnit(SettingsMask.SKIP_PIN2_CVC_IF_VALIDATED, from.skipCheckPIN2andCVCIfValidatedByIssuer))
block.addItem(BoolUnit(SettingsMask.SKIP_SECURITY_DELAY_ON_LINKED_TERMINAL, from.skipSecurityDelayIfValidatedByLinkedTerminal))
block.addItem(BoolUnit(SettingsMask.RESTRICT_OVERWRITE_EXTRA_ISSUER_DATA, from.restrictOverwriteIssuerDataEx))
return block
}
private fun settingsMaskProtocolEnc(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_settings_mask_protocol_enc))
block.addItem(BoolUnit(from.protocolAllowUnencrypted).resName(R.string.pers_item_allow_unencrypted))
block.addItem(BoolUnit(false).resName(R.string.pers_item_allow_fast_encryption))
val block = LinearBlock(BlockId.SETTINGS_MASK_PROTOCOL_ENC)
block.addItem(TextUnit(BlockId.SETTINGS_MASK_PROTOCOL_ENC))
block.addItem(BoolUnit(SettingsMaskProtocolEnc.ALLOW_UNENCRYPTED, from.protocolAllowUnencrypted))
block.addItem(BoolUnit(SettingsMaskProtocolEnc.ALLOW_FAST_ENCRYPTION, false))
return block
}
private fun settingsMaskNdef(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_settings_mask_ndef))
block.addItem(BoolUnit(from.useNDEF).resName(R.string.pers_item_use_ndef))
block.addItem(BoolUnit(from.useDynamicNDEF).resName(R.string.pers_item_dynamic_ndef))
block.addItem(BoolUnit(from.disablePrecomputedNDEF).resName(R.string.pers_item_disable_precomputed_ndef))
block.addItem(ListUnit(Helper.aarList(), from.NDEF[0].type).resName(R.string.pers_item_aar))
// block.addItem(TextItem(R.string.pers_item_custom_aar_package_name, from.ndef[0].value))
val block = LinearBlock(BlockId.SETTINGS_MASK_NDEF)
block.addItem(TextUnit(BlockId.SETTINGS_MASK_NDEF))
block.addItem(BoolUnit(SettingsMaskNdef.USE_NDEF, from.useNDEF))
block.addItem(BoolUnit(SettingsMaskNdef.DYNAMIC_NDEF, from.useDynamicNDEF))
block.addItem(BoolUnit(SettingsMaskNdef.DISABLE_PRECOMPUTED_NDEF, from.disablePrecomputedNDEF))
block.addItem(ListUnit(SettingsMaskNdef.AAR, Helper.aarList(), from.NDEF[0].type))
return block
}
private fun pins(from: TestJsonDto): Block {
val block = LinearBlock()
block.addItem(TextUnit().resName(R.string.pers_block_pins))
block.addItem(EditTextUnit(from.PIN).resName(R.string.pers_item_pin))
block.addItem(EditTextUnit(from.PIN2).resName(R.string.pers_item_pin2))
block.addItem(EditTextUnit(from.PIN3).resName(R.string.pers_item_pin3))
block.addItem(EditTextUnit(from.CVC).resName(R.string.pers_item_cvc))
block.addItem(ListUnit(Helper.pauseBeforePin(), from.pauseBeforePIN2).resName(R.string.pers_item_pause_before_pin2))
val block = LinearBlock(BlockId.PINS)
block.addItem(TextUnit(BlockId.PINS))
block.addItem(EditTextUnit(Pins.PIN, from.PIN))
block.addItem(EditTextUnit(Pins.PIN2, from.PIN2))
block.addItem(EditTextUnit(Pins.PIN3, from.PIN3))
block.addItem(EditTextUnit(Pins.CVC, from.CVC))
block.addItem(ListUnit(Pins.PAUSE_BEFORE_PIN2, Helper.pauseBeforePin(), from.pauseBeforePIN2))
return block
}
private fun addPayload(block: Block, from: TestJsonDto) {
block.payload["count"] = from.count
block.payload["numberFormat"] = from.numberFormat
block.payload["issuerData"] = from.issuerData
block.payload["releaseVersion"] = from.releaseVersion
block.payload["issuerName"] = from.issuerName
block.payload[Additional.JSON_INCOMING.name] = from
block.payload[Additional.JSON_TAILS.name] = JsonTails(
from.count,
from.numberFormat,
from.issuerData,
from.releaseVersion,
from.issuerName
)
}
}
class JsonTails(
val count: Int,
val numberFormat: String,
val issuerData: Any?,
val releaseVersion: Boolean,
val issuerName: String
)
internal class Helper {
companion object {
fun listOfCurves(): List<KeyValue> {

View file

@ -3,6 +3,6 @@ package com.tangem.tangemtest.card_use_cases.ui.personalize.personalize_converte
import com.tangem.tangemtest._arch.structure.base.Block
import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter
class BlockToJsonConverter : Converter<Block, TestJsonDto> {
override fun convert(from: Block): TestJsonDto = TestJsonDto()
class BlockToJsonConverter : Converter<List<Block>, TestJsonDto> {
override fun convert(from: List<Block>): TestJsonDto = TestJsonDto()
}

View file

@ -19,9 +19,9 @@ class PersonalizeViewModelFactory(private val jsonPersonalizeString: String) : V
class PersonalizeViewModel(private val jsonPersonalizeString: String) : ViewModel() {
val ldBlockList: MutableLiveData<Block> by lazy { MutableLiveData(readJson()) }
val ldBlockList: MutableLiveData<List<Block>> by lazy { MutableLiveData(readJson()) }
private fun readJson(): Block {
private fun readJson(): List<Block> {
val enDe = JsonBlockEnDe(JsonToBlockConverter(), BlockToJsonConverter())
val jsonDto = Gson().fromJson(jsonPersonalizeString, TestJsonDto::class.java)
return enDe.decode(jsonDto)

View file

@ -8,8 +8,8 @@ import androidx.transition.AutoTransition
import androidx.transition.TransitionManager
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.base.DataUnit
import com.tangem.tangemtest.card_use_cases.ui.personalize.InfoHolder
import ru.dev.gbixahue.eu4d.lib.kotlin.common.LayoutHolder
import ru.dev.gbixahue.eu4d.lib.kotlin.stringOf
/**
[REDACTED_AUTHOR]
@ -48,17 +48,12 @@ abstract class BaseParamWidget<D>(
override fun toggleDescriptionVisibility() {
val tvDescription = view.findViewById<TextView>(R.id.tv_description) ?: return
tvDescription.text = getDescription()
getResDescription()?.let { tvDescription.setText(it) }
TransitionManager.beginDelayedTransition(tvDescription.parent as ViewGroup, AutoTransition())
tvDescription.visibility = unit.viewModel?.viewState?.descriptionVisibility ?: View.GONE
}
}
fun UnitWidget<*>.getResNameId(): Int {
val id = unit.payload["resName"] ?: R.string.unknown
return id as Int
}
fun UnitWidget<*>.getResNameId(): Int = InfoHolder.getInfo(unit.id).resName
fun UnitWidget<*>.getDescription(): String {
return stringOf(unit.payload["description"], isNull = "not found")
}
fun UnitWidget<*>.getResDescription(): Int? = InfoHolder.getInfo(unit.id).resDescription

View file

@ -20,6 +20,10 @@ class TextWidget(parent: ViewGroup, private val textUnit: TextUnit) : BaseParamW
private val tvName = view.findViewById<TextView>(R.id.tv_name)
init {
bindData()
}
private fun bindData() {
tvName.setText(getResNameId())
}
@ -32,6 +36,10 @@ class EditTextWidget(parent: ViewGroup, private val editTextUnit: EditTextUnit)
private val etItem = view.findViewById<TextInputEditText>(R.id.et_item)
init {
bindData()
}
private fun bindData() {
tilItem.hint = tilItem.context.getString(getResNameId())
etItem.setText(editTextUnit.viewModel?.data)
etItem.afterTextChanged { editTextUnit.viewModel?.updateData(it) }
@ -46,6 +54,10 @@ class NumberWidget(parent: ViewGroup, private val numberUnit: NumberUnit) : Base
private val etItem = view.findViewById<TextInputEditText>(R.id.et_item)
init {
bindData()
}
private fun bindData() {
tilItem.hint = tilItem.context.getString(getResNameId())
etItem.setText(stringOf(numberUnit.viewModel?.data))
etItem.afterTextChanged { numberUnit.viewModel?.updateData(getIntValue(it)) }
@ -63,6 +75,10 @@ class SwitchWidget(parent: ViewGroup, private val boolUnit: BoolUnit) : BasePara
private val switchItem = view.findViewById<Switch>(R.id.sw_item)
init {
bindData()
}
private fun bindData() {
switchItem.setText(getResNameId())
switchItem.isChecked = boolUnit.viewModel?.data ?: false
switchItem.setOnCheckedChangeListener { view, isChecked -> boolUnit.viewModel?.updateData(isChecked) }
@ -78,6 +94,10 @@ class SpinnerWidget(parent: ViewGroup, private val listUnit: ListUnit) : BasePar
private val spAdapter = SpItemAdapter(listUnit.viewModel?.data?.itemList)
init {
bindData()
}
private fun bindData() {
val name = view.findViewById<TextView>(R.id.tv_name)
name.setText(getResNameId())
spItem.adapter = spAdapter

View file

@ -3,11 +3,12 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
<LinearLayout
android:id="@+id/ll_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="vertical">
</FrameLayout>
</LinearLayout>
</ScrollView>

View file

@ -84,4 +84,6 @@
<string name="pers_item_pin3">PIN3</string>
<string name="pers_item_cvc">CVC</string>
<string name="pers_item_pause_before_pin2">Pause before PIN2</string>
<string name="info_">Some very useful description</string>
</resources>