Updated on 2026-08-14

This commit is contained in:
Tangem 2020-10-28 10:52:41 +03:00
parent 20f7a7ab0c
commit 195a3d6d7f
11 changed files with 73 additions and 15 deletions

View file

@ -94,6 +94,7 @@ dependencies {
// Firebase
implementation 'com.google.firebase:firebase-crashlytics:17.2.2'
implementation 'com.google.firebase:firebase-analytics:17.6.0'
testImplementation 'junit:junit:4.13'
testImplementation "com.google.truth:truth:1.0.1"

View file

@ -14,6 +14,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

View file

@ -1,6 +1,8 @@
package com.tangem.tap
import android.app.Application
import com.tangem.tap.common.analytics.AnalyticsHandler
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
import com.tangem.tap.common.images.PicassoHelper
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.appReducer
@ -16,6 +18,7 @@ val store = Store(
state = AppState()
)
lateinit var preferencesStorage: PreferencesStorage
lateinit var analytics: AnalyticsHandler
class TapApplication : Application() {
override fun onCreate() {
@ -26,5 +29,6 @@ class TapApplication : Application() {
NetworkConnectivity.createInstance(store, this)
preferencesStorage = PreferencesStorage(this)
PicassoHelper.initPicassoWithCaching(this)
analytics = FirebaseAnalyticsHandler(this)
}
}

View file

@ -0,0 +1,7 @@
package com.tangem.tap.common.analytics
enum class AnalyticsEvent(val event: String) {
CARD_IS_SCANNED("card_is_scanned"),
TRANSACTION_IS_SENT("transaction_is_sent"),
READY_TO_SCAN("ready_to_scan"),
}

View file

@ -0,0 +1,7 @@
package com.tangem.tap.common.analytics
import com.tangem.commands.Card
interface AnalyticsHandler {
fun triggerEvent(event: AnalyticsEvent, card: Card?)
}

View file

@ -0,0 +1,29 @@
package com.tangem.tap.common.analytics
import android.content.Context
import android.os.Bundle
import androidx.core.os.bundleOf
import com.google.firebase.analytics.FirebaseAnalytics
import com.tangem.commands.Card
class FirebaseAnalyticsHandler(private val context: Context): AnalyticsHandler {
override fun triggerEvent(event: AnalyticsEvent, card: Card?) {
FirebaseAnalytics.getInstance(context)
.logEvent(AnalyticsEvent.CARD_IS_SCANNED.event, setCardData(card))
}
private fun setCardData(card: Card?): Bundle {
if (card == null) return bundleOf()
return bundleOf(
AnalyticsParam.BLOCKCHAIN.param to card.cardData?.blockchainName,
AnalyticsParam.BATCH_ID.param to card.cardData?.batchId,
AnalyticsParam.FIRMWARE.param to card.firmwareVersion
)
}
private enum class AnalyticsParam(val param: String) {
BLOCKCHAIN("blockchain"),
BATCH_ID("batch_id"),
FIRMWARE("firmware"),
}
}

View file

@ -7,6 +7,8 @@ import com.tangem.common.CompletionResult
import com.tangem.common.extensions.CardType
import com.tangem.common.extensions.calculateSha256
import com.tangem.tangem_sdk_new.extensions.init
import com.tangem.tap.common.analytics.AnalyticsEvent
import com.tangem.tap.common.analytics.AnalyticsHandler
import com.tangem.tap.domain.tasks.CreateWalletAndRescanTask
import com.tangem.tap.domain.tasks.ScanNoteResponse
import com.tangem.tap.domain.tasks.ScanNoteTask
@ -22,7 +24,8 @@ class TangemSdkManager(val activity: ComponentActivity) {
activity, Config(cardFilter = CardFilter(EnumSet.allOf(CardType::class.java)))
)
suspend fun scanNote(): CompletionResult<ScanNoteResponse> {
suspend fun scanNote(analyticsHandler: AnalyticsHandler): CompletionResult<ScanNoteResponse> {
analyticsHandler.triggerEvent(AnalyticsEvent.READY_TO_SCAN, null)
return runTaskAsyncReturnOnMain(ScanNoteTask(),
initialMessage = Message(activity.getString(R.string.initial_message_scan_header)))
}

View file

@ -6,6 +6,8 @@ import com.tangem.commands.CardStatus
import com.tangem.commands.common.network.Result
import com.tangem.common.extensions.toHexString
import com.tangem.tap.TapConfig
import com.tangem.tap.analytics
import com.tangem.tap.common.analytics.AnalyticsEvent
import com.tangem.tap.common.redux.global.CryptoCurrencyName
import com.tangem.tap.common.redux.global.FiatCurrencyName
import com.tangem.tap.common.redux.global.GlobalAction
@ -77,7 +79,10 @@ class TapWalletManager {
handleFiatRatesResult(results)
}
suspend fun onCardScanned(data: ScanNoteResponse) {
suspend fun onCardScanned(data: ScanNoteResponse, addAnalyticsEvent: Boolean = false) {
if (addAnalyticsEvent) {
analytics.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card)
}
tapWorkarounds = TapWorkarounds(data.card)
withContext(Dispatchers.Main) {
store.dispatch(WalletAction.ResetState)

View file

@ -4,14 +4,11 @@ import android.content.Intent
import android.net.Uri
import androidx.core.content.ContextCompat.startActivity
import com.tangem.common.CompletionResult
import com.tangem.tap.*
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.redux.navigation.AppScreen
import com.tangem.tap.common.redux.navigation.NavigationAction
import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -29,7 +26,7 @@ class HomeMiddleware {
}
is HomeAction.ReadCard -> {
scope.launch {
val result = tangemSdkManager.scanNote()
val result = tangemSdkManager.scanNote(analytics)
withContext(Dispatchers.Main) {
when (result) {
is CompletionResult.Success -> {

View file

@ -4,6 +4,9 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tangem.blockchain.common.*
import com.tangem.blockchain.extensions.Result
import com.tangem.blockchain.extensions.Signer
import com.tangem.commands.Card
import com.tangem.tap.analytics
import com.tangem.tap.common.analytics.AnalyticsEvent
import com.tangem.tap.common.extensions.stripZeroPlainString
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
@ -47,6 +50,7 @@ private fun verifyAndSendTransaction(
) {
val sendState = appState?.sendState ?: return
val walletManager = appState.globalState.scanNoteResponse?.walletManager ?: return
val card = appState.globalState.scanNoteResponse.card
val recipientAddress = sendState.addressPayIdState.recipientWalletAddress ?: return
val typedAmount = sendState.amountState.amountToExtract ?: return
val feeAmount = sendState.feeState.currentFee ?: return
@ -62,14 +66,14 @@ private fun verifyAndSendTransaction(
dispatch(AmountAction.SetAmount(typedAmount.value!!.minus(reduceAmount), false))
dispatch(AmountActionUi.CheckAmountToSend)
}, sendAllCallback = {
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, dispatch)
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, card, dispatch)
}, reduceAmount))
}
transactionErrors.isNotEmpty() -> {
dispatch(SendAction.SendError(createValidateTransactionError(transactionErrors, walletManager)))
}
else -> {
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, dispatch)
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, card, dispatch)
}
}
}
@ -80,6 +84,7 @@ private fun sendTransaction(
amountToSend: Amount,
feeAmount: Amount,
recipientAddress: String,
card: Card,
dispatch: (Action) -> Unit
) {
dispatch(SendAction.ChangeSendButtonState(SendButtonState.PROGRESS))
@ -91,6 +96,7 @@ private fun sendTransaction(
withContext(Dispatchers.Main) {
when (result) {
is Result.Success -> {
analytics.triggerEvent(AnalyticsEvent.TRANSACTION_IS_SENT, card)
dispatch(SendAction.SendSuccess)
dispatch(GlobalAction.UpdateWalletSignedHashes(result.data.walletSignedHashes))
dispatch(WalletAction.UpdateWallet)

View file

@ -11,6 +11,7 @@ import com.tangem.common.CompletionResult
import com.tangem.common.extensions.CardType
import com.tangem.common.extensions.getType
import com.tangem.common.extensions.toHexString
import com.tangem.tap.*
import com.tangem.tap.common.extensions.copyToClipboard
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.navigation.AppScreen
@ -22,10 +23,6 @@ import com.tangem.tap.features.send.redux.PrepareSendScreen
import com.tangem.tap.features.wallet.models.toPendingTransactions
import com.tangem.tap.network.NetworkConnectivity
import com.tangem.tap.network.NetworkStateChanged
import com.tangem.tap.preferencesStorage
import com.tangem.tap.scope
import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -100,10 +97,11 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
}
is WalletAction.Scan -> {
scope.launch {
val result = tangemSdkManager.scanNote()
val result = tangemSdkManager.scanNote(analytics)
when (result) {
is CompletionResult.Success -> {
store.state.globalState.tapWalletManager.onCardScanned(result.data)
store.state.globalState.tapWalletManager
.onCardScanned(result.data, true)
}
}
}