Updated on 2026-08-14

This commit is contained in:
Tangem 2026-03-20 21:54:46 +04:00
parent 8b75e37e30
commit a9bca131c3
386 changed files with 1369 additions and 1347 deletions

View file

@ -369,9 +369,7 @@ dependencies {
implementation(deps.googlePlay.services)
implementation(deps.googlePlay.advertising)
coreLibraryDesugaring(deps.desugar)
implementation(deps.timber)
implementation(deps.kermit)
implementation(deps.reKotlin)
implementation(deps.zxing.qrCore)
implementation(deps.coil)
implementation(deps.coil.gif)
@ -390,6 +388,7 @@ dependencies {
implementation(deps.viewBindingDelegate)
implementation(deps.armadillo)
implementation(deps.kotlin.serialization)
implementation(deps.reKotlin)
implementation(deps.reownCore)
implementation(deps.reownWeb3)
implementation(deps.prettyLogger)

View file

@ -8,7 +8,7 @@ import dagger.hilt.android.testing.OnComponentReadyRunner
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
import java.lang.reflect.Field
class ApplicationInjectionExecutionRule(
@ -46,7 +46,7 @@ class ApplicationInjectionExecutionRule(
try {
originalVersionValues = FeatureToggles.entries.associateWith { it.version }
} catch (e: Exception) {
Timber.e("Failed to save original toggles values: ${e.message}")
TangemLogger.e("Failed to save original toggles values: ${e.message}")
}
}
@ -60,9 +60,10 @@ class ApplicationInjectionExecutionRule(
versionField.set(toggle, newVersion)
}
Timber.i("FeatureToggles.values updated: $toggleStates")
TangemLogger.i("FeatureToggles.values updated: $toggleStates")
} catch (e: Exception) {
Timber.e("FeatureToggles.values didn't change with error: ${e.message}")
TangemLogger.e("FeatureToggles.values didn't change with error: ${e.message}")
}
}
@ -75,9 +76,9 @@ class ApplicationInjectionExecutionRule(
versionField.set(toggle, originalVersion)
}
Timber.i("FeatureToggles.values restored")
TangemLogger.i("FeatureToggles.values restored")
} catch (e: Exception) {
Timber.e("FeatureToggles.values didn't restored with error: ${e.message}")
TangemLogger.e("FeatureToggles.values didn't restored with error: ${e.message}")
}
}

View file

@ -11,7 +11,7 @@ import kotlinx.coroutines.runBlocking
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
/**
* A JUnit rule that sets up the API environment for tests based on annotations or instrumentation arguments.
@ -82,11 +82,11 @@ class ApiEnvironmentRule : TestRule {
val environment = ApiEnvironment.valueOf(parts[1])
apiConfigId to environment
} catch (e: IllegalArgumentException) {
Timber.w("Invalid config or environment: $configPair")
TangemLogger.w("Invalid config or environment: $configPair")
null
}
} else {
Timber.w("Invalid config format: $configPair. Expected format: 'ConfigId=Environment'")
TangemLogger.w("Invalid config format: $configPair. Expected format: 'ConfigId=Environment'")
null
}
}
@ -94,7 +94,7 @@ class ApiEnvironmentRule : TestRule {
DEFAULT_API_CONFIGS.associateWith { ApiEnvironment.MOCK } + parsedConfigs
} catch (e: Exception) {
Timber.w("Failed to parse environment configs: $envConfigArg")
TangemLogger.w("Failed to parse environment configs: $envConfigArg")
DEFAULT_API_CONFIGS.associateWith { ApiEnvironment.MOCK }
}
}
@ -115,7 +115,7 @@ class ApiEnvironmentRule : TestRule {
runBlocking {
targetEnvironments.forEach { (apiConfigId, environment) ->
changeEnvironment(apiConfigId.name, environment)
Timber.i("$apiConfigId environment set to: ${environment.name}")
TangemLogger.i("$apiConfigId environment set to: ${environment.name}")
}
}
}

View file

@ -3,7 +3,7 @@ package com.tangem.common.utils
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
import java.util.concurrent.TimeUnit
/**
@ -13,7 +13,7 @@ fun getWcUri(
network: String = "ethereum",
baseUrl: String = "[REDACTED_ENV_URL]"
): String? {
Timber.i("Getting WC URI for network: $network")
TangemLogger.i("Getting WC URI for network: $network")
val client = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // Таймаут подключения
@ -29,31 +29,31 @@ fun getWcUri(
return try {
client.newCall(request).execute().use { response ->
Timber.i("Response code: ${response.code}")
TangemLogger.i("Response code: ${response.code}")
if (response.isSuccessful) {
val body = response.body?.string() ?: ""
Timber.i("Response body: $body")
TangemLogger.i("Response body: $body")
val jsonObject = JSONObject(body)
if (jsonObject.getBoolean("success")) {
val wcUri = jsonObject.getString("wcUri")
Timber.i("Got WC URI successfully: $wcUri")
TangemLogger.i("Got WC URI successfully: $wcUri")
wcUri
} else {
Timber.e("API returned error: ${jsonObject.optString("error", "Unknown")}")
TangemLogger.e("API returned error: ${jsonObject.optString("error", "Unknown")}")
null
}
} else {
val errorBody = response.body?.string() ?: "No error body"
Timber.e("Request failed: ${response.code}, body: $errorBody")
TangemLogger.e("Request failed: ${response.code}, body: $errorBody")
null
}
}
} catch (e: Exception) {
Timber.e(e, "Error getting WC URI")
TangemLogger.e("Error getting WC URI", e)
null
}
}
@ -61,7 +61,7 @@ fun getWcUri(
fun checkServiceHealth(
baseUrl: String = "[REDACTED_ENV_URL]"
): String? {
Timber.i("Checking service health")
TangemLogger.i("Checking service health")
val client = OkHttpClient()
val request = Request.Builder()
@ -71,14 +71,14 @@ fun checkServiceHealth(
return try {
client.newCall(request).execute().use { response ->
Timber.i("Response code: ${response.code}")
TangemLogger.i("Response code: ${response.code}")
if (response.isSuccessful) {
val body = response.body?.string() ?: ""
Timber.i("Response body: $body")
TangemLogger.i("Response body: $body")
if (body.isEmpty()) {
Timber.e("Response body is empty")
TangemLogger.e("Response body is empty")
return null
}
@ -86,20 +86,20 @@ fun checkServiceHealth(
val status = jsonObject.optString("status", "")
if (status.isNotEmpty()) {
Timber.i("Got status successfully: $status")
TangemLogger.i("Got status successfully: $status")
status
} else {
Timber.e("Status field is missing or empty")
TangemLogger.e("Status field is missing or empty")
null
}
} else {
val errorBody = response.body?.string() ?: "No error body"
Timber.e("Request failed: ${response.code}, body: $errorBody")
TangemLogger.e("Request failed: ${response.code}, body: $errorBody")
null
}
}
} catch (e: Exception) {
Timber.e(e, "Error checking health")
TangemLogger.e("Error checking health", e)
null
}
}

View file

@ -4,7 +4,7 @@ import com.tangem.datasource.utils.WireMockRedirectInterceptor
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
import java.io.IOException
private const val DEFAULT_WIREMOCK_URL = "[REDACTED_ENV_URL]"
@ -27,8 +27,8 @@ fun setWireMockScenarioState(
state: String,
baseUrl: String = getWireMockBaseUrl()
): Boolean {
Timber.i("=== WireMock Scenario Set ===")
Timber.i("Setting scenario '$scenarioName' to state: $state")
TangemLogger.i("=== WireMock Scenario Set ===")
TangemLogger.i("Setting scenario '$scenarioName' to state: $state")
val client = OkHttpClient()
val json = """{"state": "$state"}"""
val mediaType = "application/json".toMediaType()
@ -41,14 +41,14 @@ fun setWireMockScenarioState(
return try {
client.newCall(request).execute().use { response ->
val body = response.body?.string() ?: ""
Timber.d("WireMock scenario request URL: ${request.url}")
Timber.d("WireMock scenario request body: $json")
Timber.d("WireMock scenario response: ${response.code} - ${response.message}")
Timber.d("WireMock scenario response body: $body")
TangemLogger.d("WireMock scenario request URL: ${request.url}")
TangemLogger.d("WireMock scenario request body: $json")
TangemLogger.d("WireMock scenario response: ${response.code} - ${response.message}")
TangemLogger.d("WireMock scenario response body: $body")
response.isSuccessful
}
} catch (e: IOException) {
Timber.e(e, "WireMock scenario error")
TangemLogger.e("WireMock scenario error", e)
false
}
}
@ -67,12 +67,12 @@ fun checkWireMockStatus(baseUrl: String = getWireMockBaseUrl()): Boolean {
return try {
client.newCall(request).execute().use { response ->
val body = response.body?.string() ?: ""
Timber.d("WireMock status check: ${response.code}")
Timber.d("Available scenarios: $body")
TangemLogger.d("WireMock status check: ${response.code}")
TangemLogger.d("Available scenarios: $body")
response.isSuccessful
}
} catch (e: IOException) {
Timber.e(e, "WireMock not accessible")
TangemLogger.e("WireMock not accessible", e)
false
}
}
@ -82,12 +82,12 @@ fun checkWireMockStatus(baseUrl: String = getWireMockBaseUrl()): Boolean {
* @param baseUrl WireMock base URL (defaults to local override if set, otherwise remote)
*/
fun resetWireMockScenarios(baseUrl: String = getWireMockBaseUrl()): Boolean {
Timber.i("=== WireMock Scenarios Reset ===")
Timber.i("Base URL: $baseUrl")
TangemLogger.i("=== WireMock Scenarios Reset ===")
TangemLogger.i("Base URL: $baseUrl")
val client = OkHttpClient()
val url = "$baseUrl/__admin/scenarios/reset"
Timber.i("Request URL: $url")
TangemLogger.i("Request URL: $url")
val request = Request.Builder()
.url(url)
@ -95,19 +95,19 @@ fun resetWireMockScenarios(baseUrl: String = getWireMockBaseUrl()): Boolean {
.build()
return try {
Timber.d("Sending reset request...")
TangemLogger.d("Sending reset request...")
client.newCall(request).execute().use { response ->
Timber.d("Response code: ${response.code}")
Timber.d("Response message: ${response.message}")
TangemLogger.d("Response code: ${response.code}")
TangemLogger.d("Response message: ${response.message}")
val responseBody = response.body?.string() ?: ""
Timber.d("Response body: $responseBody")
TangemLogger.d("Response body: $responseBody")
val isSuccessful = response.isSuccessful
Timber.d("Is successful: $isSuccessful")
TangemLogger.d("Is successful: $isSuccessful")
isSuccessful
}
} catch (e: IOException) {
Timber.e(e, "Exception during reset")
TangemLogger.e("Exception during reset", e)
false
}
}
@ -124,7 +124,7 @@ fun resetWireMockScenarioState(
initialState: String = "Started",
baseUrl: String = getWireMockBaseUrl()
): Boolean {
Timber.i("=== WireMock Scenario Reset ===")
Timber.i("Resetting scenario '$scenarioName' to initial state: $initialState")
TangemLogger.i("=== WireMock Scenario Reset ===")
TangemLogger.i("Resetting scenario '$scenarioName' to initial state: $initialState")
return setWireMockScenarioState(scenarioName, initialState, baseUrl)
}

View file

@ -1,9 +1,9 @@
package com.tangem.tap
import com.google.firebase.messaging.FirebaseMessaging
import com.tangem.utils.logging.TangemLogger
import com.tangem.utils.notifications.PushNotificationsTokenProvider
import kotlinx.coroutines.tasks.await
import timber.log.Timber
import javax.inject.Inject
internal class FirebasePushNotificationsTokenProvider @Inject constructor() : PushNotificationsTokenProvider {
@ -11,7 +11,7 @@ internal class FirebasePushNotificationsTokenProvider @Inject constructor() : Pu
return try {
FirebaseMessaging.getInstance().token.await()
} catch (ex: Exception) {
Timber.e(ex)
TangemLogger.e("Error", ex)
""
}
}

View file

@ -5,7 +5,7 @@ import com.google.android.gms.tasks.Task
import com.google.android.play.core.review.ReviewInfo
import com.google.android.play.core.review.ReviewManagerFactory
import com.tangem.core.navigation.review.ReviewManager
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
import com.google.android.play.core.review.ReviewManager as GReviewManager
/**
@ -26,7 +26,7 @@ internal class GoogleReviewManager : ReviewManager {
onDismissClick = onDismissClick,
)
}
.addOnFailureListener(Timber::e)
.addOnFailureListener { TangemLogger.e("Error", it) }
}
}
@ -42,9 +42,9 @@ internal class GoogleReviewManager : ReviewManager {
.addOnCompleteListener { resultReviewTask ->
if (!resultReviewTask.isSuccessful) onDismissClick()
}
.addOnFailureListener(Timber::e)
.addOnFailureListener { TangemLogger.e("Error", it) }
} else {
Timber.e(task.exception)
TangemLogger.e("Error", task.exception)
}
}
}

View file

@ -11,7 +11,7 @@ import com.tangem.utils.notifications.PushNotificationsTokenProvider
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
import javax.inject.Inject
internal class HuaweiPushNotificationsTokenProvider @Inject constructor(
@ -25,7 +25,7 @@ internal class HuaweiPushNotificationsTokenProvider @Inject constructor(
try {
FirebaseMessaging.getInstance().token.await()
} catch (ex: Exception) {
Timber.e(ex)
TangemLogger.e("Error", ex)
""
}
} else {
@ -33,10 +33,10 @@ internal class HuaweiPushNotificationsTokenProvider @Inject constructor(
try {
val appId = AGConnectOptionsBuilder().build(context).getString(APP_ID_KEY)
val token = HmsInstanceId.getInstance(context).getToken(appId, TOKEN_REQUEST_MODE)
Timber.i("Requested token from HuaweiService: $token")
TangemLogger.i("Requested token from HuaweiService: $token")
token
} catch (e: ApiException) {
Timber.i("Fetching token from HuaweiService failed cause: ${e.message}")
TangemLogger.i("Fetching token from HuaweiService failed cause: ${e.message}")
""
}
}

View file

@ -5,7 +5,7 @@ import com.huawei.hms.push.HmsMessageService
import com.huawei.hms.push.RemoteMessage
import com.tangem.google.GoogleServicesHelper
import com.tangem.tap.common.pushes.PushNotificationDelegate
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
class HuaweiPushService : HmsMessageService() {
@ -15,12 +15,12 @@ class HuaweiPushService : HmsMessageService() {
override fun onNewToken(token: String?, bundle: Bundle?) {
super.onNewToken(token, bundle)
Timber.i("HuaweiPushService: On new token from HuaweiService: $token")
TangemLogger.i("HuaweiPushService: On new token from HuaweiService: $token")
}
override fun onTokenError(e: Exception?, bundle: Bundle?) {
super.onTokenError(e, bundle)
Timber.i("HuaweiPushService: Fetching token from HuaweiService failed cause: ${e?.message}")
TangemLogger.i("HuaweiPushService: Fetching token from HuaweiService failed cause: ${e?.message}")
}
override fun onMessageReceived(message: RemoteMessage?) {

View file

@ -4,7 +4,7 @@ import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
import kotlin.reflect.KClass
object ForegroundActivityObserver {
@ -14,7 +14,7 @@ object ForegroundActivityObserver {
val foregroundActivity: AppCompatActivity?
get() = activities.entries
.firstOrNull { entry ->
Timber.i("foregroundActivity: ${entry.key} | ${entry.value.isDestroyed}")
TangemLogger.i("foregroundActivity: ${entry.key} | ${entry.value.isDestroyed}")
entry.value.isDestroyed == false
}
?.value
@ -27,15 +27,15 @@ object ForegroundActivityObserver {
}
override fun onActivityResumed(activity: Activity) {
Timber.i("onActivityResumed ${activity::class}")
TangemLogger.i("onActivityResumed ${activity::class}")
if (activity is AppCompatActivity) {
Timber.i("onActivityResumed store activity")
TangemLogger.i("onActivityResumed store activity")
activities[activity::class] = activity
}
}
override fun onActivityDestroyed(activity: Activity) {
Timber.i("onActivityDestroyed")
TangemLogger.i("onActivityDestroyed")
activities.remove(activity::class)
}

View file

@ -6,9 +6,9 @@ import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.utils.logging.TangemLogger
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import timber.log.Timber
@HiltWorker
class LockTimerWorker @AssistedInject constructor(
@ -19,11 +19,11 @@ class LockTimerWorker @AssistedInject constructor(
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
Timber.i("onStart job")
TangemLogger.i("onStart job")
userWalletsListRepository.lockAllWallets().onRight {
settingsRepository.setShouldOpenWelcomeScreenOnResume(value = true)
}
Timber.i("onStart job complete")
TangemLogger.i("onStart job complete")
return Result.success()
}

View file

@ -12,11 +12,11 @@ import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.domain.wallets.usecase.ClearAllHotWalletContextualUnlockUseCase
import com.tangem.tap.LockTimerWorker.Companion.TAG
import com.tangem.tap.common.extensions.dispatchNavigationAction
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import timber.log.Timber
import java.util.concurrent.TimeUnit
import kotlin.time.Duration
@ -45,7 +45,7 @@ internal class LockUserWalletsTimer(
WorkManager.getInstance(context).cancelAllWorkByTag(TAG)
coroutineScope.launch {
val shouldOpenWelcomeScreenOnResume = settingsRepository.shouldOpenWelcomeScreenOnResume()
Timber.i(
TangemLogger.i(
"""
Owner resumed
|- Need to open welcome screen: $shouldOpenWelcomeScreenOnResume
@ -65,7 +65,7 @@ internal class LockUserWalletsTimer(
}
override fun onStop(owner: LifecycleOwner) {
Timber.i("Owner stopped")
TangemLogger.i("Owner stopped")
delayJob = null
startTimerWorker()
@ -73,7 +73,7 @@ internal class LockUserWalletsTimer(
fun restart() {
if (delayJob == null) return
Timber.i(
TangemLogger.i(
"""
Timer restart
|- Duration millis: ${duration.inWholeMilliseconds}
@ -93,7 +93,7 @@ internal class LockUserWalletsTimer(
private fun start(log: Boolean = true) {
if (log) {
Timber.i(
TangemLogger.i(
"""
Timer start
|- Duration millis: ${duration.inWholeMilliseconds}

View file

@ -63,11 +63,11 @@ import com.tangem.tap.routing.utils.DeepLinkFactory
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.FeatureCoroutineExceptionHandler
import com.tangem.utils.extensions.uriValidate
import com.tangem.utils.logging.TangemLogger
import com.tangem.wallet.BuildConfig
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import timber.log.Timber
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
import kotlin.time.Duration.Companion.seconds
@ -169,7 +169,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
private val onActivityResultCallbacks = mutableListOf<OnActivityResultCallback>()
override fun onCreate(savedInstanceState: Bundle?) {
Timber.i("onCreate")
TangemLogger.i("onCreate")
// We need to call it before onCreate to prevent unnecessary activity recreation
installAppTheme()
@ -306,18 +306,18 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
override fun onStart() {
super.onStart()
Timber.i("onStart")
TangemLogger.i("onStart")
dialogManager.onStart(this)
}
override fun onStop() {
dialogManager.onStop()
super.onStop()
Timber.i("onStop")
TangemLogger.i("onStop")
}
override fun onDestroy() {
Timber.i("onDestroy")
TangemLogger.i("onDestroy")
// workaround: kill process when activity destroy to avoid state when lock() wallets
// and navigation to unlock screen was skipped because system kills activity but not process
if (BuildConfig.BUILD_TYPE != MOCKED_BUILD_TYPE) {
@ -416,8 +416,8 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
private fun sendStakingUnsubmittedHashes() {
lifecycleScope.launch {
sendUnsubmittedHashesUseCase.invoke()
.onLeft { Timber.e(it.toString()) }
.onRight { Timber.d("Submitting hashes succeeded") }
.onLeft { TangemLogger.e(it.toString()) }
.onRight { TangemLogger.d("Submitting hashes succeeded") }
}
}

View file

@ -75,13 +75,13 @@ import com.tangem.tap.common.redux.appReducer
import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles
import com.tangem.tap.proxy.AppStateHolder
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.utils.logging.TangemLogger
import com.tangem.wallet.BuildConfig
import dagger.hilt.EntryPoints
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import org.rekotlin.Store
import timber.log.Timber
lateinit var store: Store<AppState>
@ -299,10 +299,10 @@ open class TangemApplication : Application(), ImageLoaderFactory, Configuration.
store = createReduxStore()
Timber.i("APP STARTED")
TangemLogger.i("APP STARTED")
if (BuildConfig.TESTER_MENU_ENABLED) {
Timber.i(featureTogglesManager.toString())
Timber.i(excludedBlockchainsManager.toString())
TangemLogger.i(featureTogglesManager.toString())
TangemLogger.i(excludedBlockchainsManager.toString())
}
initWithConfigDependency(environmentConfig = environmentConfig)

View file

@ -7,7 +7,7 @@ import androidx.lifecycle.LifecycleOwner
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.event.TechAnalyticsEvent
import com.tangem.core.analytics.models.event.TechAnalyticsEvent.WindowObscured.ObscuredState
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
internal object WindowObscurationObserver : DefaultLifecycleObserver {
@ -36,7 +36,7 @@ internal object WindowObscurationObserver : DefaultLifecycleObserver {
}
if (isPartiallyObscured) {
Timber.d("Window is partially obscured")
TangemLogger.d("Window is partially obscured")
if (!isWindowPartiallyObscuredAlreadySent) {
analyticsEventHandler.send(
@ -50,7 +50,7 @@ internal object WindowObscurationObserver : DefaultLifecycleObserver {
val isFullyObscured = event.flags and MotionEvent.FLAG_WINDOW_IS_OBSCURED != 0
if (isFullyObscured) {
Timber.d("Window is partially or fully obscured")
TangemLogger.d("Window is partially or fully obscured")
if (!isWindowFullyObscuredAlreadySent) {
analyticsEventHandler.send(

View file

@ -1,9 +1,9 @@
package com.tangem.tap.common.analytics
import com.tangem.common.json.MoshiJsonConverter
import com.tangem.core.analytics.api.ExceptionLogger
import com.tangem.core.analytics.api.EventLogger
import timber.log.Timber
import com.tangem.core.analytics.api.ExceptionLogger
import com.tangem.utils.logging.TangemLogger
class AnalyticsEventsLogger(
private val name: String,
@ -11,11 +11,11 @@ class AnalyticsEventsLogger(
) : EventLogger, ExceptionLogger {
override fun logEvent(event: String, params: Map<String, String>) {
Timber.d(jsonConverter.prettyPrint(PrintEventModel(name, event, params)))
TangemLogger.d(jsonConverter.prettyPrint(PrintEventModel(name, event, params)))
}
override fun logException(error: Throwable, params: Map<String, String>) {
Timber.e(error, jsonConverter.prettyPrint(PrintEventModel(name, "error", params)))
TangemLogger.e(jsonConverter.prettyPrint(PrintEventModel(name, "error", params)), error)
}
}

View file

@ -2,7 +2,7 @@ package com.tangem.tap.common.analytics.appsflyer
import com.appsflyer.deeplink.DeepLinkListener
import com.appsflyer.deeplink.DeepLinkResult
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
import javax.inject.Inject
import javax.inject.Singleton
@ -17,10 +17,10 @@ class AppsFlyerDeepLinkListener @Inject constructor(
referralParamsHandler.handle(deepLink = p0.deepLink)
}
DeepLinkResult.Status.NOT_FOUND -> {
Timber.i("No deep link found")
TangemLogger.i("No deep link found")
}
DeepLinkResult.Status.ERROR -> {
Timber.e("Deep link error: ${p0.error}")
TangemLogger.e("Deep link error: ${p0.error}")
}
}
}

View file

@ -2,13 +2,13 @@ package com.tangem.tap.common.analytics.appsflyer
import com.appsflyer.deeplink.DeepLink
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.domain.wallets.models.AppsFlyerConversionData
import com.tangem.feature.referral.domain.SetShouldShowMobileWalletPromoUseCase
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.contracts.ExperimentalContracts
@ -41,15 +41,15 @@ class AppsFlyerReferralParamsHandler @Inject constructor(
private fun handle(deepLinkValue: String?, deepLinkSub1: String?, deepLinkSub2: String?) {
if (deepLinkValue != REFERRAL_DEEP_LINK_VALUE) {
Timber.i("Ignoring deep link with value: ${deepLinkValue ?: "null"}")
TangemLogger.i("Ignoring deep link with value: ${deepLinkValue ?: "null"}")
return
}
@Suppress("NullableToStringCall")
Timber.i("refcode=$deepLinkSub1\ncampaign=$deepLinkSub2")
TangemLogger.i("refcode=$deepLinkSub1\ncampaign=$deepLinkSub2")
if (!isValidParam(deepLinkSub1)) {
Timber.e("Deeplink conversion data is invalid")
TangemLogger.e("Deeplink conversion data is invalid")
return
}
@ -69,7 +69,7 @@ class AppsFlyerReferralParamsHandler @Inject constructor(
coroutineScope.launch {
mutex.withLock {
setShouldShowMobileWalletPromoUseCase(true)
.onLeft { Timber.e(it) }
.onLeft { TangemLogger.e("Error", it) }
appsFlyerStore.storeIfAbsent(
value = AppsFlyerConversionData(refcode = refcode, campaign = campaign),
)

View file

@ -1,7 +1,7 @@
package com.tangem.tap.common.analytics.appsflyer
import com.appsflyer.AppsFlyerConversionListener
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
import javax.inject.Inject
import javax.inject.Singleton
@ -11,7 +11,7 @@ class TangemAFConversionListener @Inject constructor(
) : AppsFlyerConversionListener {
override fun onConversionDataSuccess(p0: Map<String?, Any?>?) {
Timber.i("AppsFlyer conversion data success: ${p0.orEmpty()}")
TangemLogger.i("AppsFlyer conversion data success: ${p0.orEmpty()}")
if (p0 == null) return
@ -19,14 +19,14 @@ class TangemAFConversionListener @Inject constructor(
}
override fun onConversionDataFail(p0: String?) {
Timber.e("AppsFlyer conversion data failure: ${p0.orEmpty()}")
TangemLogger.e("AppsFlyer conversion data failure: ${p0.orEmpty()}")
}
override fun onAppOpenAttribution(p0: Map<String?, String?>?) {
Timber.i("AppsFlyer app open attribution: ${p0.orEmpty()}")
TangemLogger.i("AppsFlyer app open attribution: ${p0.orEmpty()}")
}
override fun onAttributionFailure(p0: String?) {
Timber.e("AppsFlyer attribution failure: ${p0.orEmpty()}")
TangemLogger.e("AppsFlyer attribution failure: ${p0.orEmpty()}")
}
}

View file

@ -6,16 +6,16 @@ import com.appsflyer.attribution.AppsFlyerRequestListener
import com.tangem.core.analytics.api.EventLogger
import com.tangem.core.analytics.api.UserIdHolder
import com.tangem.datasource.local.appsflyer.AppsFlyerStore
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.tap.common.analytics.appsflyer.AppsFlyerDeepLinkListener
import com.tangem.tap.common.analytics.appsflyer.TangemAFConversionListener
import com.tangem.tap.common.analytics.handlers.firebase.UnderscoreAnalyticsEventConverter
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.utils.logging.TangemLogger
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.launch
import timber.log.Timber
interface AppsFlyerAnalyticsClient : EventLogger, UserIdHolder
@ -40,9 +40,9 @@ class AppsFlyerClient @AssistedInject constructor(
init(apiKey, tangemAFConversionListener, context)
Timber.i("Starting AppsFlyer SDK")
TangemLogger.i("Starting AppsFlyer SDK")
start(context, apiKey, InitializationListener)
Timber.i("AppsFlyer SDK started")
TangemLogger.i("AppsFlyer SDK started")
saveUID()
}
@ -57,7 +57,7 @@ class AppsFlyerClient @AssistedInject constructor(
}
override fun logEvent(event: String, params: Map<String, String>) {
Timber.tag("AppsFlyer").i("Logging event: $event with params: $params")
TangemLogger.withTag("AppsFlyer").i("Logging event: $event with params: $params")
appsFlyerLib.logEvent(
context,
event,
@ -78,21 +78,21 @@ class AppsFlyerClient @AssistedInject constructor(
private object InitializationListener : AppsFlyerRequestListener {
override fun onSuccess() {
Timber.d("AppsFlyer initialized successfully")
TangemLogger.d("AppsFlyer initialized successfully")
}
override fun onError(p0: Int, p1: String) {
Timber.e("AppsFlyer initialization error: $p0, $p1")
TangemLogger.e("AppsFlyer initialization error: $p0, $p1")
}
}
private object LogEventListener : AppsFlyerRequestListener {
override fun onSuccess() {
Timber.tag("AppsFlyerClient").i("AppsFlyerRequestListener send")
TangemLogger.withTag("AppsFlyerClient").i("AppsFlyerRequestListener send")
}
override fun onError(p0: Int, p1: String) {
Timber.tag("AppsFlyerClient").e("AppsFlyerRequestListener onError: $p0, $p1")
TangemLogger.withTag("AppsFlyerClient").e("AppsFlyerRequestListener onError: $p0, $p1")
}
}

View file

@ -6,14 +6,14 @@ import com.tangem.core.analytics.models.AnalyticsEvent
import com.tangem.core.analytics.models.AppsFlyerIncludedEvent
import com.tangem.core.analytics.models.AppsFlyerOnlyEvent
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
class AppsFlyerAnalyticsHandler(
private val client: AppsFlyerAnalyticsClient,
) : AnalyticsHandler, AnalyticsUserIdHandler {
init {
Timber.tag("AppsFlyer").i("AppsFlyer Analytics Handler created")
TangemLogger.withTag("AppsFlyer").i("AppsFlyer Analytics Handler created")
}
override fun id(): String = ID
@ -21,11 +21,15 @@ class AppsFlyerAnalyticsHandler(
override fun send(event: AnalyticsEvent) {
when (event) {
is AppsFlyerOnlyEvent -> {
Timber.tag("AppsFlyer").i("Sending event to AppsFlyer: ${event.id} with params: ${event.params}")
TangemLogger.withTag(
"AppsFlyer",
).i("Sending event to AppsFlyer: ${event.id} with params: ${event.params}")
client.logEvent(event.id, event.params)
}
is AppsFlyerIncludedEvent -> {
Timber.tag("AppsFlyer").i("Sending event to AppsFlyer: ${event.id} with params: ${event.params}")
TangemLogger.withTag(
"AppsFlyer",
).i("Sending event to AppsFlyer: ${event.id} with params: ${event.params}")
val replacedEvent = event.appsFlyerReplacedEvent ?: event.event
client.logEvent(
event = AnalyticsEvent(category = event.category, event = replacedEvent).id,
@ -52,15 +56,15 @@ class AppsFlyerAnalyticsHandler(
) : AnalyticsHandlerBuilder {
init {
Timber.tag("AppsFlyer").i("AppsFlyer Analytics Handler Builder created")
TangemLogger.withTag("AppsFlyer").i("AppsFlyer Analytics Handler Builder created")
}
override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsHandler = AppsFlyerAnalyticsHandler(
client = if (data.logConfig.isAppsflyerLogEnabled) {
Timber.tag("AppsFlyer").i("AppsFlyer log enabled, mock client created")
TangemLogger.withTag("AppsFlyer").i("AppsFlyer log enabled, mock client created")
AppsFlyerLogClient(data.jsonConverter)
} else {
Timber.tag("AppsFlyer").i("AppsFlyer log disabled, real client created")
TangemLogger.withTag("AppsFlyer").i("AppsFlyer log disabled, real client created")
appsFlyerClientFactory.create(apiKey = data.config.appsFlyerApiKey)
},
)

View file

@ -1,11 +1,11 @@
package com.tangem.tap.common.analytics.handlers.customerio
import android.app.Application
import com.tangem.utils.logging.TangemLogger
import io.customer.messagingpush.ModuleMessagingPushFCM
import io.customer.sdk.CustomerIO
import io.customer.sdk.CustomerIOBuilder
import io.customer.sdk.data.model.Region
import timber.log.Timber
/**
* Real Customer.io SDK client.
@ -32,7 +32,7 @@ internal class CustomerIoClient(
.addCustomerIOModule(ModuleMessagingPushFCM())
.build()
Timber.d("CustomerIO SDK initialized")
TangemLogger.d("CustomerIO SDK initialized")
}
override fun setUserId(userId: String) {

View file

@ -1,6 +1,6 @@
package com.tangem.tap.common.analytics.handlers.customerio
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
/**
* Log client for Customer.io (used in debug mode).
@ -13,11 +13,11 @@ internal class CustomerIoLogClient : CustomerIoAnalyticsClient {
override fun setUserId(userId: String) {
this.userId = userId
Timber.tag(CustomerIoAnalyticsHandler.ID).d("identify: userId=$userId")
TangemLogger.withTag(CustomerIoAnalyticsHandler.ID).d("identify: userId=$userId")
}
override fun clearUserId() {
Timber.tag(CustomerIoAnalyticsHandler.ID).d("clearIdentify: previous userId=$userId")
TangemLogger.withTag(CustomerIoAnalyticsHandler.ID).d("clearIdentify: previous userId=$userId")
this.userId = null
}
}

View file

@ -3,8 +3,8 @@ package com.tangem.tap.common.analytics.handlers.firebase
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import com.tangem.core.analytics.AppInstanceIdProvider
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.suspendCancellableCoroutine
import timber.log.Timber
import kotlin.coroutines.resume
internal class FirebaseAppInstanceIdProvider : AppInstanceIdProvider {
@ -13,7 +13,7 @@ internal class FirebaseAppInstanceIdProvider : AppInstanceIdProvider {
Firebase.analytics.appInstanceId
.addOnSuccessListener { continuation.resume(it) }
.addOnFailureListener {
Timber.w("Fail to get appInstanceId")
TangemLogger.w("Fail to get appInstanceId")
continuation.resume(null)
}
}
@ -22,7 +22,7 @@ internal class FirebaseAppInstanceIdProvider : AppInstanceIdProvider {
return try {
Firebase.analytics.appInstanceId.result
} catch (e: IllegalStateException) {
Timber.e(e, "getAppInstanceIdSync")
TangemLogger.e("getAppInstanceIdSync", e)
null
}
}

View file

@ -6,7 +6,7 @@ import android.content.ClipDescription.MIMETYPE_TEXT_PLAIN
import android.os.Build
import android.os.PersistableBundle
import com.tangem.core.ui.clipboard.ClipboardManager
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
import android.content.ClipboardManager as AndroidClipboardManager
internal class DefaultClipboardManager(private val clipboardManager: AndroidClipboardManager) : ClipboardManager {
@ -24,13 +24,13 @@ internal class DefaultClipboardManager(private val clipboardManager: AndroidClip
val clip = clipboardManager.primaryClip
if (clip == null || clip.itemCount == 0) {
Timber.d("Clipboard is empty")
TangemLogger.d("Clipboard is empty")
return default
}
val clipDescription = clipboardManager.primaryClipDescription
if (clipDescription?.hasMimeType(MIMETYPE_TEXT_PLAIN) == false) {
Timber.d("Clipboard doesn't contain text")
TangemLogger.d("Clipboard doesn't contain text")
return default
}

View file

@ -1,12 +1,12 @@
package com.tangem.tap.common.clipboard
import com.tangem.core.ui.clipboard.ClipboardManager
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
internal object MockClipboardManager : ClipboardManager {
override fun setText(text: String, isSensitive: Boolean, label: String) {
Timber.w("Clipboard Manager not available")
TangemLogger.w("Clipboard Manager not available")
}
override fun getText(default: String?): String? = null

View file

@ -3,11 +3,11 @@ package com.tangem.tap.common.deeplink
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.core.net.toUri
import com.tangem.common.routing.DeepLinkScheme
import com.tangem.core.navigation.deeplink.DeeplinkLauncher
import com.tangem.core.navigation.url.UrlOpener
import androidx.core.net.toUri
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
/**
* [DeeplinkLauncher] implementation that launches deep links as intents to the current Activity
@ -26,7 +26,7 @@ internal class DefaultDeeplinkLauncher(
-> launchDeepLink(deeplinkUri)
DeepLinkScheme.Https.scheme -> launchDeeplinkOrOpenBrowser(deeplinkUri, link)
else -> {
Timber.i(
TangemLogger.i(
"""
No match found for deep link
|- Received URI: $deeplinkUri

View file

@ -10,8 +10,8 @@ import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.getFirstToken
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.store
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.delay
import timber.log.Timber
/**
[REDACTED_AUTHOR]
@ -31,7 +31,7 @@ suspend fun WalletManager.safeUpdate(isDemoCard: Boolean): Result<Wallet> = try
Result.Success(wallet)
}
} catch (exception: Exception) {
Timber.e(exception)
TangemLogger.e("Error", exception)
val networkConnectionManager = store.inject(DaggerGraphState::networkConnectionManager)
if (!networkConnectionManager.isOnline) {

View file

@ -9,10 +9,10 @@ import coil.decode.ImageDecoderDecoder
import coil.decode.SvgDecoder
import coil.memory.MemoryCache
import coil.request.CachePolicy
import coil.util.Logger
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
import com.tangem.utils.logging.TangemLogger
import okhttp3.OkHttpClient
import timber.log.Timber
import coil.util.Logger as CoilLogger
private const val COIL_LOG_TAG = "COIL"
private const val COIL_MEMORY_CACHE_SIZE = 0.25
@ -22,7 +22,7 @@ fun createCoilImageLoader(context: Context, logEnabled: Boolean = false): ImageL
.apply {
if (!logEnabled) return@apply
logger(CoilTimberLogger())
logger(CoilKermitLogger())
okHttpClient {
OkHttpClient.Builder()
.addNetworkInterceptor(createNetworkLoggingInterceptor())
@ -48,14 +48,16 @@ fun createCoilImageLoader(context: Context, logEnabled: Boolean = false): ImageL
.build()
}
private class CoilTimberLogger : Logger {
private class CoilKermitLogger : CoilLogger {
override var level: Int = Log.DEBUG
private val logger = TangemLogger.withTag(COIL_LOG_TAG)
override fun log(tag: String, priority: Int, message: String?, throwable: Throwable?) {
with(Timber.tag(COIL_LOG_TAG)) {
if (throwable != null) e(throwable, message)
if (message != null) d(message)
if (throwable != null) {
logger.e(message ?: "<EMPTY>", throwable)
} else if (message != null) {
logger.d(message)
}
}
}

View file

@ -8,8 +8,8 @@ import co.touchlab.kermit.Logger
import co.touchlab.kermit.Severity
import com.orhanobut.logger.AndroidLogAdapter
import com.tangem.datasource.local.logs.AppLogsStore
import com.tangem.utils.logging.TangemLogger
import com.tangem.wallet.BuildConfig
import timber.log.Timber
import java.util.regex.Pattern
import com.orhanobut.logger.Logger as PrettyLogger
@ -30,18 +30,9 @@ class TangemAppLoggerInitializer(
PrettyLogger.addLogAdapter(AndroidLogAdapter(TimberFormatStrategy()))
}
Timber.plant(tree = createTimberTree())
Logger.setLogWriters(KermitLogWriter(::finalLogOutput))
}
private fun createTimberTree(): Timber.Tree {
return object : Timber.DebugTree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
finalLogOutput(priority = priority, tag = tag, message = message, t = t)
}
}
}
private fun finalLogOutput(priority: Int, tag: String?, message: String, t: Throwable?) {
if (IS_LOG_ENABLED) {
PrettyLogger.log(priority, tag, message, t)
@ -71,6 +62,8 @@ private class KermitLogWriter(
KermitLogWriter::class.java.name,
BaseLogger::class.java.name,
Logger::class.java.name,
TangemLogger::class.java.name,
TangemLogger.TaggedLogger::class.java.name,
)
override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {
@ -87,7 +80,7 @@ private class KermitLogWriter(
tag
} else {
/**
* like in [Timber.DebugTree.tag]
* like in [Logger.debugTree.tag]
*/
@Suppress("UnnecessaryLet", "ThrowingExceptionsWithoutMessageOrCause")
Throwable().stackTrace
@ -99,7 +92,7 @@ private class KermitLogWriter(
}
/**
* copy from [Timber.DebugTree.createStackElementTag]
* copy from [Logger.debugTree.createStackElementTag]
*/
@Suppress("MagicNumber")
private fun createStackElementTag(element: StackTraceElement): String? {
@ -120,7 +113,7 @@ private class KermitLogWriter(
private const val KERMIT_LOGGER_DEFAULT_TAG = ""
/**
* copy from [Timber.DebugTree.Companion]
* copy from [Logger.debugTree.Companion]
*/
private const val MAX_TAG_LENGTH = 23
private val ANONYMOUS_CLASS = Pattern.compile("(\\$\\d+)+$")

View file

@ -4,9 +4,9 @@ import android.annotation.SuppressLint
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.tangem.tap.common.analytics.CustomerIoFeatureToggles
import com.tangem.utils.logging.TangemLogger
import dagger.hilt.android.AndroidEntryPoint
import io.customer.messagingpush.CustomerIOFirebaseMessagingService
import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
@ -22,7 +22,7 @@ internal class TangemPushNotificationService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
Timber.d("New FCM token received: $token")
TangemLogger.d("New FCM token received: $token")
if (customerIoFeatureToggles.isFeatureEnabled) {
CustomerIOFirebaseMessagingService.onNewToken(applicationContext, token)

View file

@ -1,7 +1,7 @@
package com.tangem.tap.common.redux
import com.tangem.utils.logging.TangemLogger
import org.rekotlin.Middleware
import timber.log.Timber
/**
[REDACTED_AUTHOR]
@ -9,7 +9,7 @@ import timber.log.Timber
val logMiddleware: Middleware<AppState> = { _, _ ->
{ nextDispatch ->
{ action ->
Timber.i("Dispatch action: ${action::class.java.simpleName}")
TangemLogger.i("Dispatch action: ${action::class.java.simpleName}")
nextDispatch(action)
}
}

View file

@ -14,8 +14,8 @@ import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder
import com.tangem.tap.common.extensions.getColorCompat
import com.tangem.tap.foregroundActivityObserver
import com.tangem.tap.withForegroundActivity
import com.tangem.utils.logging.TangemLogger
import com.tangem.wallet.R
import timber.log.Timber
internal class CustomTabsUrlOpener : UrlOpener {
@ -55,7 +55,7 @@ internal class CustomTabsUrlOpener : UrlOpener {
customTabsIntent.launchUrl(context, url.toUri())
}
}.onFailure {
Timber.e(it)
TangemLogger.e("Error", it)
}
}

View file

@ -1,10 +1,10 @@
package com.tangem.tap.core
import co.touchlab.kermit.Logger
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
import com.tangem.utils.coroutines.AppCoroutineScope
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.SupervisorJob
@ -28,7 +28,7 @@ internal class DefaultAppCoroutineScope @Inject constructor(
}
private fun logError(throwable: Throwable, coroutineName: String) {
Logger.withTag(tag).e(
TangemLogger.withTag(tag).e(
messageString = "CoroutineName $coroutineName",
throwable = throwable,
)

View file

@ -8,7 +8,7 @@ import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import com.tangem.core.navigation.email.EmailSender
import com.tangem.tap.foregroundActivityObserver
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
/**
* Implementation of email sender for Android
@ -21,7 +21,7 @@ internal class AndroidEmailSender : EmailSender {
val activity = foregroundActivityObserver.foregroundActivity
if (activity == null) {
Timber.e("Foreground activity not found")
TangemLogger.e("Foreground activity not found")
return
}
@ -50,7 +50,7 @@ internal class AndroidEmailSender : EmailSender {
ContextCompat.startActivity(activity, chooserIntent, null)
} catch (ex: Exception) {
Timber.e("Failed to send email: $ex")
TangemLogger.e("Failed to send email: $ex")
}
}

View file

@ -2,7 +2,7 @@ package com.tangem.tap.core.security
import com.dexprotector.rtc.RtcStatus
import com.tangem.security.DeviceSecurityInfoProvider
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
internal class DefaultDeviceSecurityInfoProvider : DeviceSecurityInfoProvider {
override val isRooted: Boolean
@ -16,7 +16,7 @@ internal class DefaultDeviceSecurityInfoProvider : DeviceSecurityInfoProvider {
return try {
RtcStatus.getRtcStatus()
} catch (e: Throwable) {
Timber.e(e)
TangemLogger.e("Error", e)
null
}
}

View file

@ -2,7 +2,7 @@ package com.tangem.tap.data
import com.tangem.blockchain.common.logging.BlockchainSDKLogger
import com.tangem.datasource.local.logs.AppLogsStore
import timber.log.Timber
import com.tangem.utils.logging.TangemLogger
/**
* BlockchainSDK logger implementation
@ -16,7 +16,7 @@ internal class TangemBlockchainSDKLogger(
) : BlockchainSDKLogger {
override fun log(level: BlockchainSDKLogger.Level, message: String) {
Timber.d(message)
TangemLogger.d(message)
appLogsStore.saveLogMessage(tag = "BlockchainSDK_${level.name}", message)
}
}

View file

@ -19,10 +19,10 @@ import com.tangem.datasource.local.visa.VisaOtpData
import com.tangem.datasource.local.visa.hasSavedOTP
import com.tangem.domain.card.common.visa.VisaWalletPublicKeyUtility
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource
import com.tangem.domain.visa.error.VisaActivationError
import com.tangem.domain.visa.model.*
import com.tangem.domain.visa.repository.VisaActivationRepository
import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource
import com.tangem.operations.GenerateOTPCommand
import com.tangem.operations.attestation.AttestCardKeyCommand
import com.tangem.operations.pins.SetUserCodeCommand
@ -31,11 +31,11 @@ import com.tangem.operations.sign.SignHashResponse
import com.tangem.operations.wallet.CreateWalletTask
import com.tangem.sdk.api.visa.VisaCardActivationResponse
import com.tangem.sdk.api.visa.VisaCardActivationTaskMode
import com.tangem.utils.logging.TangemLogger
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.*
import timber.log.Timber
import kotlin.coroutines.resume
import kotlin.time.measureTimedValue
@ -94,7 +94,7 @@ class VisaCardActivationTask @AssistedInject constructor(
}
}
}
Timber.i("VisaCardActivationTask all time: ${timedResult.duration}")
TangemLogger.i("VisaCardActivationTask all time: ${timedResult.duration}")
return timedResult.value
}
@ -109,11 +109,11 @@ class VisaCardActivationTask @AssistedInject constructor(
}
}
}
Timber.i("AttestCardKeyCommand time: ${timedResult.duration}")
TangemLogger.i("AttestCardKeyCommand time: ${timedResult.duration}")
return when (val result = timedResult.value) {
is CompletionResult.Success -> {
Timber.i("AttestCardKeyCommand success")
TangemLogger.i("AttestCardKeyCommand success")
processSignedAuthorizationChallenge(
signedChallenge = challengeToSign.toSignedChallenge(
signedChallenge = result.data.cardSignature.toHexString(),
@ -122,7 +122,7 @@ class VisaCardActivationTask @AssistedInject constructor(
)
}
is CompletionResult.Failure -> {
Timber.e("AttestCardKeyCommand failure ${result.error}")
TangemLogger.e("AttestCardKeyCommand failure ${result.error}")
CompletionResult.Failure(result.error)
}
}
@ -206,15 +206,15 @@ class VisaCardActivationTask @AssistedInject constructor(
}
}
Timber.i("CreateWalletTask time: ${timedResult.duration}")
TangemLogger.i("CreateWalletTask time: ${timedResult.duration}")
when (val result = timedResult.value) {
is CompletionResult.Success -> {
Timber.i("CreateWalletTask success")
TangemLogger.i("CreateWalletTask success")
CompletionResult.Success(Unit)
}
is CompletionResult.Failure -> {
Timber.e("CreateWalletTask failure ${result.error}")
TangemLogger.e("CreateWalletTask failure ${result.error}")
CompletionResult.Failure(result.error)
}
}
@ -237,11 +237,11 @@ class VisaCardActivationTask @AssistedInject constructor(
}
}
Timber.i("GenerateOTPCommand time: ${timedResult.duration}")
TangemLogger.i("GenerateOTPCommand time: ${timedResult.duration}")
return when (val result = timedResult.value) {
is CompletionResult.Success -> {
Timber.i("GenerateOTPCommand success")
TangemLogger.i("GenerateOTPCommand success")
otpStorage.saveOTP(
cardId = cardId,
data = VisaOtpData(result.data.rootOTP, result.data.rootOTPCounter),
@ -249,7 +249,7 @@ class VisaCardActivationTask @AssistedInject constructor(
CompletionResult.Success(Unit)
}
is CompletionResult.Failure -> {
Timber.e("GenerateOTPCommand failure ${result.error}")
TangemLogger.e("GenerateOTPCommand failure ${result.error}")
CompletionResult.Failure(result.error)
}
}
@ -278,11 +278,11 @@ class VisaCardActivationTask @AssistedInject constructor(
}
}
Timber.i("SignHashCommand time: ${timedResult.duration}")
TangemLogger.i("SignHashCommand time: ${timedResult.duration}")
return when (val result = timedResult.value) {
is CompletionResult.Success -> {
Timber.i("SignHashCommand success")
TangemLogger.i("SignHashCommand success")
handleSignedData(
dataToSign = dataToSign,
response = result.data,
@ -290,7 +290,7 @@ class VisaCardActivationTask @AssistedInject constructor(
)
}
is CompletionResult.Failure -> {
Timber.e("SignHashCommand failure ${result.error}")
TangemLogger.e("SignHashCommand failure ${result.error}")
CompletionResult.Failure(result.error)
}
}
@ -336,7 +336,7 @@ class VisaCardActivationTask @AssistedInject constructor(
return CompletionResult.Success(Unit)
}
Timber.i("Setting access code")
TangemLogger.i("Setting access code")
val task = SetUserCodeCommand.changeAccessCode(mode.accessCode)
@ -348,15 +348,15 @@ class VisaCardActivationTask @AssistedInject constructor(
}
}
Timber.i("SetUserCodeCommand time: ${timedResult.duration}")
TangemLogger.i("SetUserCodeCommand time: ${timedResult.duration}")
return when (val result = timedResult.value) {
is CompletionResult.Success -> {
Timber.i("SetUserCodeCommand success")
TangemLogger.i("SetUserCodeCommand success")
CompletionResult.Success(Unit)
}
is CompletionResult.Failure -> {
Timber.i("SetUserCodeCommand failure ${result.error}")
TangemLogger.i("SetUserCodeCommand failure ${result.error}")
CompletionResult.Failure(result.error)
}
}

View file

@ -14,9 +14,9 @@ import com.tangem.tap.domain.userWalletList.model.UserWalletEncryptionKey
import com.tangem.tap.domain.userWalletList.model.UserWalletSensitiveInformation
import com.tangem.tap.domain.userWalletList.repository.UserWalletsSensitiveInformationRepository
import com.tangem.tap.domain.userWalletList.utils.sensitiveInformation
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.crypto.spec.SecretKeySpec
internal class DefaultUserWalletsSensitiveInformationRepository(
@ -123,7 +123,7 @@ internal class DefaultUserWalletsSensitiveInformationRepository(
this@decodeToSensitiveInformation.decodeToString(throwOnInvalidSequence = true),
)
} catch (e: CharacterCodingException) {
Timber.e(e, "Unable to decode sensitive information")
TangemLogger.e("Unable to decode sensitive information", e)
null
}

View file

@ -10,19 +10,18 @@ import com.tangem.common.extensions.toHexString
import com.tangem.core.error.ext.tangemError
import com.tangem.datasource.local.visa.VisaAuthTokenStorage
import com.tangem.domain.card.common.visa.VisaWalletPublicKeyUtility
import com.tangem.domain.visa.model.VisaCardActivationStatus
import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource
import com.tangem.domain.visa.error.VisaActivationError
import com.tangem.domain.visa.error.VisaApiError
import com.tangem.domain.visa.error.VisaCardScanError
import com.tangem.domain.visa.model.*
import com.tangem.domain.visa.repository.VisaActivationRepository
import com.tangem.domain.visa.datasource.VisaAuthRemoteDataSource
import com.tangem.operations.attestation.AttestCardKeyCommand
import com.tangem.operations.attestation.AttestCardKeyResponse
import com.tangem.operations.attestation.AttestWalletKeyResponse
import com.tangem.operations.attestation.AttestWalletKeyTask
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.suspendCancellableCoroutine
import timber.log.Timber
import javax.inject.Inject
import kotlin.coroutines.resume
@ -38,10 +37,10 @@ internal class VisaCardScanHandler @Inject constructor(
)
suspend fun handleVisaCardScan(session: CardSession): CompletionResult<VisaCardActivationStatus> {
Timber.i("Attempting to handle Visa card scan")
TangemLogger.i("Attempting to handle Visa card scan")
val card = session.environment.card ?: run {
Timber.e("Card is null")
TangemLogger.e("Card is null")
return CompletionResult.Failure(TangemSdkError.MissingPreflightRead())
}
@ -68,12 +67,12 @@ internal class VisaCardScanHandler @Inject constructor(
}
private suspend fun SessionContext.handleWalletAuthorization(): CompletionResult<VisaCardActivationStatus> {
Timber.i("Started handling authorization using Visa wallet")
TangemLogger.i("Started handling authorization using Visa wallet")
val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead())
val wallet = card.wallets.firstOrNull { it.curve == EllipticCurve.Secp256k1 } ?: run {
Timber.e("Failed to find extended public key while handling wallet authorization")
TangemLogger.e("Failed to find extended public key while handling wallet authorization")
return CompletionResult.Failure(VisaCardScanError.FailedToFindWallet.tangemError)
}
@ -82,14 +81,14 @@ internal class VisaCardScanHandler @Inject constructor(
return CompletionResult.Failure(it.tangemError)
}
Timber.i("Requesting challenge for wallet authorization")
TangemLogger.i("Requesting challenge for wallet authorization")
val challengeResponse = visaAuthRemoteDataSource.getCardWalletAuthChallenge(
cardId = card.cardId,
// This is the wallet public key, not the address and it's alright, as the API expects it in this format
cardWalletAddress = wallet.publicKey.toHexString(),
).getOrElse { error ->
Timber.i("Failed to get Access token for Wallet public key authorization")
TangemLogger.i("Failed to get Access token for Wallet public key authorization")
return CompletionResult.Failure(error.tangemError)
}
@ -103,7 +102,7 @@ internal class VisaCardScanHandler @Inject constructor(
val signature = signChallengeResult.data.walletSignature
val salt = signChallengeResult.data.salt
Timber.i("Challenge signed with Wallet public key")
TangemLogger.i("Challenge signed with Wallet public key")
handleWalletAuthorizationTokens(
cardWalletAddress = walletAddress.value,
signedChallenge = challengeResponse.toSignedChallenge(
@ -113,7 +112,9 @@ internal class VisaCardScanHandler @Inject constructor(
)
}
is CompletionResult.Failure -> {
Timber.e("Error during Wallet authorization process. Tangem Sdk Error: ${signChallengeResult.error}")
TangemLogger.e(
"Error during Wallet authorization process. Tangem Sdk Error: ${signChallengeResult.error}",
)
CompletionResult.Failure(signChallengeResult.error)
}
}
@ -125,19 +126,19 @@ internal class VisaCardScanHandler @Inject constructor(
): CompletionResult<VisaCardActivationStatus> {
val authorizationTokensResponse = visaAuthRemoteDataSource.getAccessTokens(signedChallenge = signedChallenge)
.getOrElse { error ->
Timber.i("Failed to get Access token for Wallet public key authorization.")
TangemLogger.i("Failed to get Access token for Wallet public key authorization.")
return if (
error is VisaApiError.ProductInstanceIsNotActivated ||
error is VisaApiError.ProductInstanceNotFoundActivationRequired
) {
Timber.i("Proceeding with card authorization.")
TangemLogger.i("Proceeding with card authorization.")
handleCardAuthorization(cardWalletAddress = cardWalletAddress)
} else {
CompletionResult.Failure(error.tangemError)
}
}
Timber.i("Authorized using Wallet public key successfully")
TangemLogger.i("Authorized using Wallet public key successfully")
return CompletionResult.Success(VisaCardActivationStatus.Activated(authorizationTokensResponse))
}
@ -148,27 +149,27 @@ internal class VisaCardScanHandler @Inject constructor(
): CompletionResult<VisaCardActivationStatus> {
val card = session.environment.card ?: return CompletionResult.Failure(TangemSdkError.MissingPreflightRead())
Timber.i("Requesting authorization challenge to sign")
TangemLogger.i("Requesting authorization challenge to sign")
val challengeResponse = visaAuthRemoteDataSource.getCardAuthChallenge(
cardId = card.cardId,
cardPublicKey = card.cardPublicKey.toHexString(),
).getOrElse { error ->
Timber.e("Failed to get challenge for Card authorization. Plain error: ${error.errorCode}")
TangemLogger.e("Failed to get challenge for Card authorization. Plain error: ${error.errorCode}")
return CompletionResult.Failure(error.tangemError)
}
Timber.i("Received challenge to sign: ${challengeResponse.challenge}")
TangemLogger.i("Received challenge to sign: ${challengeResponse.challenge}")
val signChallengeResult = signChallengeWithCard(challenge = challengeResponse.challenge)
val attestCardKeyResponse = when (signChallengeResult) {
is CompletionResult.Success -> {
Timber.i("Challenged signed.")
TangemLogger.i("Challenged signed.")
signChallengeResult.data
}
is CompletionResult.Failure -> {
Timber.e(
TangemLogger.e(
"Failed to sign challenge with Card public key. Tangem Sdk Error: ${signChallengeResult.error}",
)
return CompletionResult.Failure(signChallengeResult.error)
@ -181,7 +182,7 @@ internal class VisaCardScanHandler @Inject constructor(
salt = attestCardKeyResponse.salt.toHexString(),
),
).getOrElse { error ->
Timber.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
TangemLogger.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
return CompletionResult.Failure(error.tangemError)
}
@ -191,7 +192,7 @@ internal class VisaCardScanHandler @Inject constructor(
)
val activationRemoteState = visaActivationRepository.getActivationRemoteState().getOrElse { error ->
Timber.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
TangemLogger.e("Failed to sign challenge with Card public key. Plain error: ${error.errorCode}")
return CompletionResult.Failure(error.tangemError)
}

View file

@ -20,6 +20,7 @@ import com.tangem.tap.store
import com.tangem.tap.tangemSdkManager
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.distinctUntilChanged
@ -29,7 +30,6 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.rekotlin.Action
import org.rekotlin.Middleware
import timber.log.Timber
@Suppress("MemberNameEqualsClassName")
class DetailsMiddleware {
@ -228,7 +228,7 @@ class DetailsMiddleware {
)
}
.doOnFailure { error ->
Timber.e(error, "Unable to delete saved access codes")
TangemLogger.e("Unable to delete saved access codes", error)
}
}
}

View file

@ -36,11 +36,11 @@ import com.tangem.tap.features.details.ui.common.utils.*
import com.tangem.tap.store
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.addIf
import com.tangem.utils.logging.TangemLogger
import com.tangem.wallet.R
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import timber.log.Timber
import javax.inject.Inject
@Suppress("LongParameterList")
@ -244,7 +244,7 @@ internal class CardSettingsModel @Inject constructor(
when (val result = tangemSdkManager.setAccessCode(scanResponse.card.cardId)) {
is CompletionResult.Success -> Analytics.send(Settings.CardSettings.UserCodeChanged())
is CompletionResult.Failure -> {
Timber.e("Failed to change access code: ${result.error}")
TangemLogger.e("Failed to change access code: ${result.error}")
}
}
}

View file

@ -28,6 +28,7 @@ import com.tangem.tap.features.details.ui.resetcard.api.ResetCardComponent
import com.tangem.tap.store
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.DELAY_SDK_DIALOG_CLOSE
import com.tangem.utils.logging.TangemLogger
import com.tangem.wallet.R
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@ -35,7 +36,6 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@Suppress("LongParameterList")
@ -190,7 +190,7 @@ internal class ResetCardModel @Inject constructor(
resetCardUseCase(cardId = primaryCardId, params = currentUserCodeParams).onRight {
deleteSavedAccessCodesUseCase(cardId = primaryCardId)
val hasUserWallets = deleteWalletUseCase(userWalletId = currentUserWalletId).getOrElse { error ->
Timber.e("Unable to delete user wallet: $error")
TangemLogger.e("Unable to delete user wallet: $error")
return@launch
}

View file

@ -43,13 +43,13 @@ import com.tangem.tap.network.exchangeServices.SellService
import com.tangem.tap.proxy.AppStateHolder
import com.tangem.tap.routing.configurator.AppRouterConfig
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.logging.TangemLogger
import com.tangem.wallet.BuildConfig
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeout
import timber.log.Timber
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
@ -155,7 +155,7 @@ internal class MainViewModel @Inject constructor(
private suspend fun fetchUserCountry() {
fetchUserCountryUseCase().onLeft {
Timber.e("Unable to fetch the user country code $it")
TangemLogger.e("Unable to fetch the user country code $it")
}
}
@ -189,8 +189,8 @@ internal class MainViewModel @Inject constructor(
private suspend fun fetchStakingOptions() {
fetchStakingOptionsUseCase()
.onLeft { Timber.e(it.toString(), "Unable to fetch staking options") }
.onRight { Timber.d("Staking options were fetched successfully") }
.onLeft { TangemLogger.e("Unable to fetch staking options: $it") }
.onRight { TangemLogger.d("Staking options were fetched successfully") }
}
private fun initializeOffRamp() {
@ -346,7 +346,9 @@ internal class MainViewModel @Inject constructor(
val keyboardId = keyboardValidator.getKeyboardId()
if (keyboardId != null) {
Timber.d("Keyboard ID: https://play.google.com/store/apps/details?id=${keyboardId.getPackageName()}")
TangemLogger.d(
"Keyboard ID: https://play.google.com/store/apps/details?id=${keyboardId.getPackageName()}",
)
analyticsEventHandler.send(
event = TechAnalyticsEvent.KeyboardIdentifier(
@ -356,7 +358,7 @@ internal class MainViewModel @Inject constructor(
),
)
} else {
Timber.e("Unable to get keyboard identifier")
TangemLogger.e("Unable to get keyboard identifier")
}
}
}
@ -370,7 +372,7 @@ internal class MainViewModel @Inject constructor(
refresh = true,
).fold(
ifLeft = { error ->
Timber.e(error)
TangemLogger.e("Error", error)
analyticsEventHandler.send(
StoriesEvents.Error(
type = StoryContentIds.STORY_FIRST_TIME_SWAP.analyticType,
@ -387,7 +389,7 @@ internal class MainViewModel @Inject constructor(
)
}
} catch (ex: Exception) {
Timber.e(ex)
TangemLogger.e("Error", ex)
analyticsEventHandler.send(
StoriesEvents.Error(
type = StoryContentIds.STORY_FIRST_TIME_SWAP.analyticType,
@ -412,7 +414,7 @@ internal class MainViewModel @Inject constructor(
associateAndUpdateWallets(applicationId = applicationId)
}
}
.onLeft(Timber::e)
.onLeft { TangemLogger.e("Error", it) }
}
private suspend fun associateAndUpdateWallets(applicationId: ApplicationId) {

View file

@ -19,9 +19,9 @@ import com.tangem.tap.domain.model.Currency
import com.tangem.tap.network.exchangeServices.SellService
import com.tangem.tap.network.exchangeServices.SellServiceInitializationStatus
import com.tangem.tap.network.exchangeServices.moonpay.models.MoonPayAvailableCurrency
import com.tangem.utils.logging.TangemLogger
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import timber.log.Timber
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
@ -42,13 +42,13 @@ class MoonPayService(
override suspend fun update() {
withIOContext {
Timber.i("Start updating")
TangemLogger.i("Start updating")
_initializationStatus.value = lceLoading()
performRequest {
val userStatus = when (val result = performRequest { api.getUserStatus(apiKey) }) {
is Result.Failure -> {
Timber.e(result.error, "Failed to load user status")
TangemLogger.e("Failed to load user status", result.error)
_initializationStatus.value = result.error.lceError()
return@performRequest
}
@ -57,7 +57,7 @@ class MoonPayService(
val currencies = when (val result = performRequest { api.getCurrencies(apiKey) }) {
is Result.Failure -> {
Timber.e(result.error, "Failed to load currencies")
TangemLogger.e("Failed to load currencies", result.error)
_initializationStatus.value = result.error.lceError()
return@performRequest
}
@ -77,7 +77,7 @@ class MoonPayService(
)
}
Timber.i("Successfully updated")
TangemLogger.i("Successfully updated")
_initializationStatus.value = lceContent()
status = MoonPayStatus(currenciesToSell, userStatus, currencies)
}

View file

@ -7,10 +7,10 @@ import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
import com.tangem.core.decompose.navigation.Router
import com.tangem.tap.routing.configurator.AppRouterConfig
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.logging.TangemLogger
import com.tangem.wallet.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import timber.log.Timber
import kotlin.reflect.KClass
internal class ProxyAppRouter(
@ -51,7 +51,7 @@ internal class ProxyAppRouter(
runCatching {
innerRouter.replaceAll(*routes, onComplete = onComplete)
}.getOrElse {
Timber.e(it)
TangemLogger.e("Error", it)
}
}
}
@ -76,12 +76,12 @@ internal class ProxyAppRouter(
private fun safeNavigate(onComplete: (isSuccess: Boolean) -> Unit, message: String, block: () -> Unit) {
routerScope.launch(dispatchers.mainImmediate) {
Timber.i(message)
TangemLogger.i(message)
try {
block()
} catch (e: Throwable) {
Timber.e(e)
TangemLogger.e("Error", e)
onComplete(false)
}
}
@ -90,7 +90,7 @@ internal class ProxyAppRouter(
override fun defaultCompletionHandler(isSuccess: Boolean, errorMessage: String) {
if (!isSuccess) {
analyticsExceptionHandler.sendException(ExceptionAnalyticsEvent(RuntimeException(errorMessage)))
Timber.w(errorMessage)
TangemLogger.w(errorMessage)
with(receiver = config.snackbarHandler ?: return) {
showSnackbar(

View file

@ -45,11 +45,11 @@ import com.tangem.tap.routing.configurator.AppRouterConfig
import com.tangem.tap.routing.utils.ChildFactory
import com.tangem.tap.routing.utils.DeepLinkFactory
import com.tangem.tap.store
import com.tangem.utils.logging.TangemLogger
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.launch
import timber.log.Timber
@Suppress("LongParameterList")
internal class DefaultRoutingComponent @AssistedInject constructor(
@ -101,7 +101,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
try {
childFactory.createChild(route, childByContext(childContext))
} catch (e: Exception) {
Timber.e(e, "App Router Failed")
TangemLogger.e("App Router Failed", e)
analyticsExceptionHandler.sendException(
ExceptionAnalyticsEvent(exception = e, params = mapOf("Category" to "App Routing")),
)

View file

@ -23,6 +23,7 @@ import com.tangem.features.walletconnect.components.deeplink.WalletConnectDeepLi
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
import com.tangem.utils.extensions.uriValidate
import com.tangem.utils.logging.TangemLogger
import dagger.hilt.android.scopes.ActivityScoped
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@ -30,7 +31,6 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.transformLatest
import timber.log.Timber
import javax.inject.Inject
@Suppress("LongParameterList")
@ -62,7 +62,7 @@ internal class DeepLinkFactory @Inject constructor(
fun handleDeeplink(deeplinkUri: Uri, coroutineScope: CoroutineScope, isFromOnNewIntent: Boolean) {
lastDeepLink = deeplinkUri
Timber.i(
TangemLogger.i(
"""
Received deep link intent
|- Received URI: $deeplinkUri
@ -108,7 +108,7 @@ internal class DeepLinkFactory @Inject constructor(
DeepLinkScheme.Tangem.scheme -> handleTangemDeepLinks(deeplinkUri, coroutineScope, isFromOnNewIntent)
DeepLinkScheme.WalletConnect.scheme -> walletConnectDeepLink.create(deeplinkUri)
else -> {
Timber.i(
TangemLogger.i(
"""
No match found for deep link
|- Received URI: $deeplinkUri
@ -157,7 +157,7 @@ internal class DeepLinkFactory @Inject constructor(
DeepLinkRoute.Promo.host -> promoDeepLink.create(coroutineScope, queryParams)
DeepLinkRoute.OnboardVisa.host -> onboardVisaDeepLink.create(deeplinkUri)
else -> {
Timber.i(
TangemLogger.i(
"""
No match found for deep link
|- Received URI: $deeplinkUri

View file

@ -29,7 +29,6 @@ import kotlinx.coroutines.test.*
import org.junit.After
import org.junit.Before
import org.junit.Test
import timber.log.Timber
@OptIn(ExperimentalCoroutinesApi::class)
class DeepLinkFactoryTest {
@ -126,7 +125,6 @@ class DeepLinkFactoryTest {
every { mockedUri.port } returns 443 // Default HTTPS port
every { mockedUri.fragment } returns null // No fragment in this URI
Timber.uprootAll() // Disable Timber logging for tests
}
@OptIn(ExperimentalCoroutinesApi::class)