Updated on 2026-08-14

This commit is contained in:
Tangem 2020-04-06 20:38:17 +03:00
commit 34013da0d4
16 changed files with 55 additions and 25 deletions

View file

@ -58,11 +58,17 @@ abstract class BaseFragment : Fragment() {
Log.d("LIFECYCLE", "onDestroy: ${this::class.java.simpleName}")
}
protected fun navigateUp(@IdRes destination: Int = DESTINATION_NOT_SET): Boolean {
return if (destination == DESTINATION_NOT_SET) {
findNavController(this).popBackStack()
} else {
findNavController(this).popBackStack(destination, false)
protected fun navigateUp(@IdRes destination: Int = DESTINATION_NOT_SET) {
try {
if (destination == DESTINATION_NOT_SET) {
findNavController(this).popBackStack()
} else {
findNavController(this).popBackStack(destination, false)
}
} catch (e: IllegalArgumentException) {
Log.w(this::class.java.simpleName, e.message)
} catch (e: IllegalStateException) {
Log.w(this::class.java.simpleName, e.message)
}
}
@ -84,7 +90,7 @@ abstract class BaseFragment : Fragment() {
}
protected fun navigateBackWithResult(resultCode: Int, data: Bundle? = null,
@IdRes destination: Int = DESTINATION_NOT_SET): Boolean {
@IdRes destination: Int = DESTINATION_NOT_SET) {
(requireActivity() as MainActivity).viewModel.navigationResult =
NavigationResult(requestCode, resultCode, data)
return navigateUp(destination)

View file

@ -9,7 +9,6 @@ import android.nfc.Tag
import android.nfc.tech.IsoDep
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.App
@ -89,11 +88,6 @@ class ValidateIdFragment : BaseFragment(), NavigationResultListener,
super.onPause()
}
override fun onStop() {
signTransactionTask?.cancel(true)
super.onStop()
}
override fun onNavigationResult(requestCode: String, resultCode: Int, data: Bundle?) {
if (requestCode == Constant.REQUEST_CODE_SEND_TRANSACTION_) {
navigateBackWithResult(resultCode, data)
@ -262,7 +256,10 @@ class ValidateIdFragment : BaseFragment(), NavigationResultListener,
NoExtendedLengthSupportDialog().show(requireFragmentManager(), NoExtendedLengthSupportDialog.TAG)
}
} else {
Toast.makeText(context, R.string.general_notification_scan_again, Toast.LENGTH_LONG).show()
(activity as MainActivity).toastHelper.showSingleToast(
context,
getString(R.string.general_notification_scan_again)
)
}
progressBar?.progress = 100
progressBar?.progressTintList = ColorStateList.valueOf(Color.RED)

View file

@ -9,7 +9,6 @@ import android.nfc.Tag
import android.nfc.tech.IsoDep
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.App
@ -49,7 +48,6 @@ class WriteIdFragment : BaseFragment(), NavigationResultListener,
private lateinit var ctx: TangemContext
private lateinit var tx: ByteArray
private lateinit var mpFinishSignSound: MediaPlayer
private var toast: Toast? = null
private var idWasWritten = false
@ -94,7 +92,6 @@ class WriteIdFragment : BaseFragment(), NavigationResultListener,
override fun onStop() {
writeIDCardTask?.cancel(true)
toast?.cancel()
super.onStop()
}
@ -174,7 +171,6 @@ class WriteIdFragment : BaseFragment(), NavigationResultListener,
if (success) {
navigateUp(R.id.main)
} else {
toast?.cancel()
navigateUp(R.id.issueNewIdFragment)
}
}
@ -231,8 +227,10 @@ class WriteIdFragment : BaseFragment(), NavigationResultListener,
}
} else {
if (!idWasWritten) {
toast = Toast.makeText(context, R.string.general_notification_scan_again, Toast.LENGTH_SHORT)
toast?.show()
(activity as MainActivity).toastHelper.showSingleToast(
context,
getString(R.string.general_notification_scan_again)
)
}
}
progressBar?.progress = 100

View file

@ -228,6 +228,12 @@ class LocalStorage
fun getCardArtworkBitmap(card: TangemCard): Bitmap {
// special cases (first series of cards, hardcode CID->artwork), on new series batch<->artwork
if (card.isIDIssuer) {
val artworkId = context.resources.getResourceEntryName(R.drawable.card_id_issuer)
return getArtworkBitmap(artworkId) ?: return getDefaultArtworkBitmap(card)
}
val hexCID = Util.bytesToHex(card.cid)
val artworkResourceId: Int? = when {
hexCID in "AA01000000000000".."AA01000000004999" -> R.drawable.card_ru006

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

View file

@ -634,6 +634,15 @@ public class TangemCard {
}
}
public boolean isIDIssuer() {
try {
return (productMask & ProductMask.IdIssuer) != 0;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public TLVList tlvIDCardData = null;
public void setTlvIdCardData(TLVList tlvIDCardData) {

View file

@ -8,6 +8,7 @@ public class ProductMask {
public static final int Note = 0x0001;
public static final int Tag = 0x0002;
public static final int IdCard = 0x0004;
public static final int IdIssuer = 0x0008;
public static String getDescription(int iValue) {
StringBuilder sb = new StringBuilder();
@ -17,6 +18,8 @@ public class ProductMask {
sb.append("Tag, ");
if ((iValue & ProductMask.IdCard) != 0)
sb.append("IdCard, ");
if ((iValue & ProductMask.IdIssuer) != 0)
sb.append("IdIssuer, ");
if (sb.length() > 1) sb.delete(sb.length() - 2, sb.length());
sb.append("]");

View file

@ -119,6 +119,7 @@ data class ProductMask(val rawValue: Int) {
const val note = 0x01
const val tag = 0x02
const val idCard = 0x04
const val idIssuer = 0x08
}
}

View file

@ -87,7 +87,8 @@ class PersonalizeResources() {
private fun initProductMask(holder: TypedHolder<Id, Resources>) {
holder.register(ProductMask.Note, Resources(R.string.pers_item_note, R.string.info_pers_item_note))
holder.register(ProductMask.Tag, Resources(R.string.pers_item_tag, R.string.info_pers_item_tag))
holder.register(ProductMask.CardId, Resources(R.string.pers_item_id_card, R.string.info_pers_item_id_card))
holder.register(ProductMask.IdCard, Resources(R.string.pers_item_id_card, R.string.info_pers_item_id_card))
holder.register(ProductMask.IdIssuerCard, Resources(R.string.pers_item_id_issuer_card, R.string.info_pers_item_id_issuer_card))
}
private fun initSettingsMask(holder: TypedHolder<Id, Resources>) {

View file

@ -71,7 +71,8 @@ enum class Token : BlockItem {
enum class ProductMask : BlockItem {
Note,
Tag,
CardId
IdCard,
IdIssuerCard
}
enum class SettingsMask : BlockItem {

View file

@ -42,7 +42,8 @@ class PersonalizeConfigValuesHolder : BaseTypedHolder<Id, Value>() {
register(Token.Decimal, Value(default.decimal))
register(ProductMask.Note, Value(default.cardData.product_note))
register(ProductMask.Tag, Value(default.cardData.product_tag))
register(ProductMask.CardId, Value(default.cardData.product_id_card))
register(ProductMask.IdCard, Value(default.cardData.product_id_card))
register(ProductMask.IdIssuerCard, Value(default.cardData.product_id_issuer))
register(SettingsMask.IsReusable, Value(default.isReusable))
register(SettingsMask.NeedActivation, Value(default.useActivation))
register(SettingsMask.ForbidPurge, Value(default.forbidPurgeWallet))

View file

@ -17,7 +17,7 @@ class ItemTypes {
SigningMethod.SignValidatedTxRaw, SigningMethod.SignValidatedTxIssuer,
SigningMethod.SignValidatedTxRawIssuer, SigningMethod.SignExternal, SignHashExProp.RequireTerminalCertSig,
SignHashExProp.RequireTerminalTxSig, SignHashExProp.CheckPin3, Denomination.WriteOnPersonalize, Token.ItsToken,
ProductMask.Note, ProductMask.Tag, ProductMask.CardId, SettingsMask.IsReusable, SettingsMask.NeedActivation,
ProductMask.Note, ProductMask.Tag, ProductMask.IdCard, ProductMask.IdIssuerCard,SettingsMask.IsReusable, SettingsMask.NeedActivation,
SettingsMask.ForbidPurge, SettingsMask.AllowSelectBlockchain, SettingsMask.UseBlock, SettingsMask.OneApdu,
SettingsMask.UseCvc, SettingsMask.AllowSwapPin, SettingsMask.AllowSwapPin2, SettingsMask.ForbidDefaultPin,
SettingsMask.SmartSecurityDelay, SettingsMask.ProtectIssuerDataAgainstReplay,

View file

@ -67,7 +67,8 @@ class ItemsToPersonalizeConfig : ItemsToModel<PersonalizeConfig> {
export.decimal = getTyped(Token.Decimal)
export.cardData = export.cardData.apply { this.product_note = getTyped(ProductMask.Note) }
export.cardData = export.cardData.apply { this.product_tag = getTyped(ProductMask.Tag) }
export.cardData = export.cardData.apply { this.product_id_card = getTyped(ProductMask.CardId) }
export.cardData = export.cardData.apply { this.product_id_card = getTyped(ProductMask.IdCard) }
export.cardData = export.cardData.apply { this.product_id_issuer = getTyped(ProductMask.IdIssuerCard) }
export.isReusable = getTyped(SettingsMask.IsReusable)
export.useActivation = getTyped(SettingsMask.NeedActivation)
export.forbidPurgeWallet = getTyped(SettingsMask.ForbidPurge)

View file

@ -121,7 +121,8 @@ class PersonalizeConfigToItem : ModelToItems<PersonalizeConfig> {
mutableListOf(
ProductMask.Note,
ProductMask.Tag,
ProductMask.CardId
ProductMask.IdCard,
ProductMask.IdIssuerCard
).forEach { createItem(block, it) }
return block
}
@ -215,11 +216,13 @@ class PersonalizeConfigToCardConfig : Converter<PersonalizeConfig, CardConfig> {
val isNote = from.cardData.product_note
val isTag = from.cardData.product_tag
val isIdCard = from.cardData.product_id_card
val isIdIssuer = from.cardData.product_id_issuer
val productMaskBuilder = ProductMaskBuilder()
if (isNote) productMaskBuilder.add(com.tangem.commands.ProductMask.note)
if (isTag) productMaskBuilder.add(com.tangem.commands.ProductMask.tag)
if (isIdCard) productMaskBuilder.add(com.tangem.commands.ProductMask.idCard)
if (isIdIssuer) productMaskBuilder.add(com.tangem.commands.ProductMask.idIssuer)
val productMask = productMaskBuilder.build()
var tokenSymbol: String? = null

View file

@ -105,4 +105,5 @@ class CardData {
var product_note = true
var product_tag = false
var product_id_card = false
var product_id_issuer = false
}

View file

@ -44,6 +44,7 @@
<string name="pers_item_note">Note</string>
<string name="pers_item_tag">Tag</string>
<string name="pers_item_id_card">ID card</string>
<string name="pers_item_id_issuer_card">ID Issuer</string>
<string name="pers_item_is_reusable">Is reusable</string>
<string name="pers_item_need_activation">Need activation</string>
<string name="pers_item_forbid_purge">Forbid purge</string>
@ -115,6 +116,7 @@
<string name="info_pers_item_note">Self-custodial wallet or note</string>
<string name="info_pers_item_tag">Anti-counterfeit tag</string>
<string name="info_pers_item_id_card">Personal ID card</string>
<string name="info_pers_item_id_issuer_card"></string>
<string name="info_pers_item_is_reusable">Defines what happens when user calls PURGE_WALLET command:
\nOff - Card will switch to Purged state
\nOn - Card will switch to Empty state and let create a new wallet again