447 lines
No EOL
18 KiB
Kotlin
447 lines
No EOL
18 KiB
Kotlin
package com.tangem.tap
|
|
|
|
import android.app.Application
|
|
import android.os.StrictMode
|
|
import android.os.StrictMode.ThreadPolicy
|
|
import android.os.StrictMode.VmPolicy
|
|
import androidx.hilt.work.HiltWorkerFactory
|
|
import androidx.work.Configuration
|
|
import coil.ImageLoader
|
|
import coil.ImageLoaderFactory
|
|
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
|
import com.tangem.Log
|
|
import com.tangem.TangemSdkLogger
|
|
import com.tangem.blockchain.common.ExceptionHandler
|
|
import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
|
|
import com.tangem.blockchainsdk.BlockchainSDKFactory
|
|
import com.tangem.blockchainsdk.utils.ExcludedBlockchains
|
|
import com.tangem.common.routing.AppRouter
|
|
import com.tangem.core.abtests.manager.ABTestsManager
|
|
import com.tangem.core.analytics.Analytics
|
|
import com.tangem.core.analytics.api.ParamsInterceptor
|
|
import com.tangem.core.analytics.filter.AppsFlyerEventFilter
|
|
import com.tangem.core.analytics.filter.OneTimeEventFilter
|
|
import com.tangem.core.analytics.models.AnalyticsEvent
|
|
import com.tangem.core.analytics.models.AnalyticsParam
|
|
import com.tangem.core.analytics.models.Basic
|
|
import com.tangem.core.analytics.models.Basic.TransactionSent.WalletForm
|
|
import com.tangem.core.configtoggle.blockchain.ExcludedBlockchainsManager
|
|
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
|
import com.tangem.core.decompose.ui.UiMessageSender
|
|
import com.tangem.core.navigation.settings.SettingsManager
|
|
import com.tangem.core.ui.clipboard.ClipboardManager
|
|
import com.tangem.data.card.TransactionSignerFactory
|
|
import com.tangem.datasource.api.common.MoshiConverter
|
|
import com.tangem.datasource.api.common.config.managers.ApiConfigsManager
|
|
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
|
|
import com.tangem.datasource.connection.NetworkConnectionManager
|
|
import com.tangem.datasource.local.config.environment.EnvironmentConfig
|
|
import com.tangem.datasource.local.config.issuers.IssuersConfigStorage
|
|
import com.tangem.datasource.local.logs.AppLogsStore
|
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
|
import com.tangem.datasource.local.token.UserTokensResponseStore
|
|
import com.tangem.datasource.utils.NetworkLogsSaveInterceptor
|
|
import com.tangem.datasource.utils.WireMockRedirectInterceptor
|
|
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
|
|
import com.tangem.domain.apptheme.GetAppThemeModeUseCase
|
|
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
|
|
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
|
|
import com.tangem.domain.card.ScanCardProcessor
|
|
import com.tangem.domain.card.repository.CardRepository
|
|
import com.tangem.domain.common.LogConfig
|
|
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
|
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
|
import com.tangem.domain.onboarding.SaveTwinsOnboardingShownUseCase
|
|
import com.tangem.domain.onboarding.WasTwinsOnboardingShownUseCase
|
|
import com.tangem.domain.onboarding.repository.OnboardingRepository
|
|
import com.tangem.domain.settings.repositories.SettingsRepository
|
|
import com.tangem.domain.walletmanager.WalletManagersFacade
|
|
import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
|
|
import com.tangem.domain.wallets.repository.WalletsRepository
|
|
import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles
|
|
import com.tangem.operations.attestation.api.TangemApiServiceSettings
|
|
import com.tangem.tap.common.analytics.AnalyticsFactory
|
|
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
|
import com.tangem.tap.common.analytics.handlers.BlockchainExceptionHandler
|
|
import com.tangem.tap.common.analytics.handlers.amplitude.AmplitudeAnalyticsHandler
|
|
import com.tangem.tap.common.analytics.handlers.appsflyer.AppsFlyerAnalyticsHandler
|
|
import com.tangem.tap.common.analytics.handlers.appsflyer.AppsFlyerClient
|
|
import com.tangem.tap.common.analytics.handlers.customerio.CustomerIoAnalyticsHandler
|
|
import com.tangem.tap.common.analytics.handlers.firebase.FirebaseAnalyticsHandler
|
|
import com.tangem.tap.common.images.createCoilImageLoader
|
|
import com.tangem.tap.common.log.TangemAppLoggerInitializer
|
|
import com.tangem.tap.common.redux.AppState
|
|
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.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>
|
|
|
|
val foregroundActivityObserver = ForegroundActivityObserver
|
|
|
|
open class TangemApplication : Application(), ImageLoaderFactory, Configuration.Provider {
|
|
|
|
// region DI
|
|
private val entryPoint: ApplicationEntryPoint
|
|
get() = EntryPoints.get(this, ApplicationEntryPoint::class.java)
|
|
|
|
private val appStateHolder: AppStateHolder
|
|
get() = entryPoint.getAppStateHolder()
|
|
|
|
private val issuersConfigStorage: IssuersConfigStorage
|
|
get() = entryPoint.getIssuersConfigStorage()
|
|
|
|
private val environmentConfig: EnvironmentConfig
|
|
get() = entryPoint.getEnvironmentConfig()
|
|
|
|
private val featureTogglesManager: FeatureTogglesManager
|
|
get() = entryPoint.getFeatureTogglesManager()
|
|
|
|
private val excludedBlockchainsManager: ExcludedBlockchainsManager
|
|
get() = entryPoint.getExcludedBlockchainsManager()
|
|
|
|
private val networkConnectionManager: NetworkConnectionManager
|
|
get() = entryPoint.getNetworkConnectionManager()
|
|
|
|
private val cardScanningFeatureToggles: CardScanningFeatureToggles
|
|
get() = entryPoint.getCardScanningFeatureToggles()
|
|
|
|
private val scanCardProcessor: ScanCardProcessor
|
|
get() = entryPoint.getScanCardProcessor()
|
|
|
|
private val appCurrencyRepository: AppCurrencyRepository
|
|
get() = entryPoint.getAppCurrencyRepository()
|
|
|
|
private val walletManagersFacade: WalletManagersFacade
|
|
get() = entryPoint.getWalletManagersFacade()
|
|
|
|
private val appThemeModeRepository: AppThemeModeRepository
|
|
get() = entryPoint.getAppThemeModeRepository()
|
|
|
|
private val balanceHidingRepository: BalanceHidingRepository
|
|
get() = entryPoint.getBalanceHidingRepository()
|
|
|
|
private val appPreferencesStore: AppPreferencesStore
|
|
get() = entryPoint.getAppPreferencesStore()
|
|
|
|
val getAppThemeModeUseCase: GetAppThemeModeUseCase
|
|
get() = entryPoint.getGetAppThemeModeUseCase()
|
|
|
|
private val walletsRepository: WalletsRepository
|
|
get() = entryPoint.getWalletsRepository()
|
|
|
|
private val oneTimeEventFilter: OneTimeEventFilter
|
|
get() = entryPoint.getOneTimeEventFilter()
|
|
|
|
private val wasTwinsOnboardingShownUseCase: WasTwinsOnboardingShownUseCase
|
|
get() = entryPoint.getWasTwinsOnboardingShownUseCase()
|
|
|
|
private val saveTwinsOnboardingShownUseCase: SaveTwinsOnboardingShownUseCase
|
|
get() = entryPoint.getSaveTwinsOnboardingShownUseCase()
|
|
|
|
private val cardRepository: CardRepository
|
|
get() = entryPoint.getCardRepository()
|
|
|
|
private val tangemSdkLogger: TangemSdkLogger
|
|
get() = entryPoint.getTangemSdkLogger()
|
|
|
|
private val settingsRepository: SettingsRepository
|
|
get() = entryPoint.getSettingsRepository()
|
|
|
|
private val blockchainSDKFactory: BlockchainSDKFactory
|
|
get() = entryPoint.getBlockchainSDKFactory()
|
|
|
|
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase
|
|
get() = entryPoint.getSendFeedbackEmailUseCase()
|
|
|
|
private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase
|
|
get() = entryPoint.getWalletMetaInfoUseCase()
|
|
|
|
private val urlOpener
|
|
get() = entryPoint.getUrlOpener()
|
|
|
|
private val shareManager
|
|
get() = entryPoint.getShareManager()
|
|
|
|
private val appRouter: AppRouter
|
|
get() = entryPoint.getAppRouter()
|
|
|
|
private val tangemAppLoggerInitializer: TangemAppLoggerInitializer
|
|
get() = entryPoint.getTangemAppLogger()
|
|
|
|
private val transactionSignerFactory: TransactionSignerFactory
|
|
get() = entryPoint.getTransactionSignerFactory()
|
|
|
|
private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles
|
|
get() = entryPoint.getOnboardingV2FeatureToggles()
|
|
|
|
private val onboardingRepository: OnboardingRepository
|
|
get() = entryPoint.getOnboardingRepository()
|
|
|
|
private val excludedBlockchains: ExcludedBlockchains
|
|
get() = entryPoint.getExcludedBlockchains()
|
|
|
|
private val appLogsStore: AppLogsStore
|
|
get() = entryPoint.getAppLogsStore()
|
|
|
|
private val clipboardManager: ClipboardManager
|
|
get() = entryPoint.getClipboardManager()
|
|
|
|
private val settingsManager: SettingsManager
|
|
get() = entryPoint.getSettingsManager()
|
|
|
|
private val uiMessageSender: UiMessageSender
|
|
get() = entryPoint.getUiMessageSender()
|
|
|
|
private val blockchainExceptionHandler: BlockchainExceptionHandler
|
|
get() = entryPoint.getBlockchainExceptionHandler()
|
|
|
|
private val workerFactory: HiltWorkerFactory
|
|
get() = entryPoint.getWorkerFactory()
|
|
|
|
override val workManagerConfiguration: Configuration
|
|
get() = Configuration.Builder()
|
|
.setWorkerFactory(workerFactory)
|
|
.build()
|
|
|
|
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory
|
|
get() = entryPoint.getColdUserWalletBuilderFactory()
|
|
|
|
private val apiConfigsManager: ApiConfigsManager
|
|
get() = entryPoint.getApiConfigsManager()
|
|
|
|
private val userTokensResponseStore: UserTokensResponseStore
|
|
get() = entryPoint.getUserTokensResponseStore()
|
|
|
|
private val userWalletsListRepository
|
|
get() = entryPoint.getUserWalletsListRepository()
|
|
|
|
private val tangemHotSdk
|
|
get() = entryPoint.getTangemHotSdk()
|
|
|
|
private val wcInitializeUseCase
|
|
get() = entryPoint.getWcInitializeUseCase()
|
|
|
|
private val trackingContextProxy
|
|
get() = entryPoint.getTrackingContextProxy()
|
|
|
|
private val abTestsManager: ABTestsManager
|
|
get() = entryPoint.getABTestsManager()
|
|
|
|
private val appsFlyerClientFactory: AppsFlyerClient.Factory
|
|
get() = entryPoint.getAppsFlyerClientFactory()
|
|
|
|
// endregion
|
|
|
|
private val appScope = MainScope()
|
|
|
|
override fun onCreate() {
|
|
enableStrictModeInDebug()
|
|
preInit()
|
|
super.onCreate()
|
|
init()
|
|
}
|
|
|
|
private fun enableStrictModeInDebug() {
|
|
if (BuildConfig.DEBUG) {
|
|
StrictMode.setThreadPolicy(
|
|
ThreadPolicy.Builder()
|
|
.detectDiskReads()
|
|
.detectDiskWrites()
|
|
.detectAll()
|
|
.penaltyLog()
|
|
.build(),
|
|
)
|
|
StrictMode.setVmPolicy(
|
|
VmPolicy.Builder()
|
|
.detectLeakedSqlLiteObjects()
|
|
.detectLeakedClosableObjects()
|
|
.penaltyLog()
|
|
.build(),
|
|
)
|
|
}
|
|
}
|
|
|
|
private fun updateLogFiles() {
|
|
appLogsStore.deleteOldLogsFile()
|
|
|
|
if (!BuildConfig.TESTER_MENU_ENABLED) {
|
|
appLogsStore.deleteLastLogFile()
|
|
}
|
|
|
|
// Temporally logs are not saved
|
|
// scope.launch {
|
|
// if (!appPreferencesStore.getSyncOrDefault(WAS_LOG_FILE_CLEARED, false)) {
|
|
// appLogsStore.deleteLastLogFile()
|
|
// appPreferencesStore.store(WAS_LOG_FILE_CLEARED, true)
|
|
// }
|
|
// }
|
|
}
|
|
|
|
/**
|
|
* Initialize components that need to be initialized before [super.onCreate] is called
|
|
*/
|
|
fun preInit() {
|
|
tangemAppLoggerInitializer.initialize()
|
|
registerActivityLifecycleCallbacks(foregroundActivityObserver.callbacks)
|
|
}
|
|
|
|
fun init() {
|
|
apiConfigsManager.initialize()
|
|
|
|
store = createReduxStore()
|
|
|
|
Timber.i("APP STARTED")
|
|
if (BuildConfig.TESTER_MENU_ENABLED) {
|
|
Timber.i(featureTogglesManager.toString())
|
|
Timber.i(excludedBlockchainsManager.toString())
|
|
}
|
|
|
|
initWithConfigDependency(environmentConfig = environmentConfig)
|
|
|
|
abTestsManager.init()
|
|
|
|
appScope.launch {
|
|
launch(Dispatchers.IO) {
|
|
loadNativeLibraries()
|
|
updateLogFiles()
|
|
}
|
|
}
|
|
|
|
ExceptionHandler.append(blockchainExceptionHandler)
|
|
|
|
if (LogConfig.network.isBlockchainSdkNetworkLogEnabled) {
|
|
BlockchainSdkRetrofitBuilder.interceptors = buildList {
|
|
if (BuildConfig.MOCK_DATA_SOURCE) {
|
|
add(WireMockRedirectInterceptor())
|
|
}
|
|
add(createNetworkLoggingInterceptor())
|
|
add(ChuckerInterceptor(this@TangemApplication))
|
|
}
|
|
|
|
TangemApiServiceSettings.addInterceptors(
|
|
*buildList {
|
|
if (BuildConfig.MOCK_DATA_SOURCE) {
|
|
add(WireMockRedirectInterceptor())
|
|
}
|
|
add(createNetworkLoggingInterceptor())
|
|
add(ChuckerInterceptor(this@TangemApplication))
|
|
add(NetworkLogsSaveInterceptor(appLogsStore))
|
|
}.toTypedArray(),
|
|
)
|
|
}
|
|
|
|
appStateHolder.mainStore = store
|
|
|
|
wcInitializeUseCase.init(
|
|
projectId = environmentConfig.walletConnectProjectId,
|
|
)
|
|
}
|
|
|
|
private fun createReduxStore(): Store<AppState> {
|
|
return Store(
|
|
reducer = { action, state -> appReducer(action, requireNotNull(state)) },
|
|
middleware = AppState.getMiddleware(),
|
|
state = AppState(
|
|
daggerGraphState = DaggerGraphState(
|
|
networkConnectionManager = networkConnectionManager,
|
|
cardScanningFeatureToggles = cardScanningFeatureToggles,
|
|
scanCardProcessor = scanCardProcessor,
|
|
appCurrencyRepository = appCurrencyRepository,
|
|
walletManagersFacade = walletManagersFacade,
|
|
appStateHolder = appStateHolder,
|
|
appThemeModeRepository = appThemeModeRepository,
|
|
balanceHidingRepository = balanceHidingRepository,
|
|
walletsRepository = walletsRepository,
|
|
wasTwinsOnboardingShownUseCase = wasTwinsOnboardingShownUseCase,
|
|
saveTwinsOnboardingShownUseCase = saveTwinsOnboardingShownUseCase,
|
|
cardRepository = cardRepository,
|
|
settingsRepository = settingsRepository,
|
|
blockchainSDKFactory = blockchainSDKFactory,
|
|
sendFeedbackEmailUseCase = sendFeedbackEmailUseCase,
|
|
getWalletMetaInfoUseCase = getWalletMetaInfoUseCase,
|
|
issuersConfigStorage = issuersConfigStorage,
|
|
urlOpener = urlOpener,
|
|
shareManager = shareManager,
|
|
appRouter = appRouter,
|
|
transactionSignerFactory = transactionSignerFactory,
|
|
onboardingV2FeatureToggles = onboardingV2FeatureToggles,
|
|
onboardingRepository = onboardingRepository,
|
|
excludedBlockchains = excludedBlockchains,
|
|
appPreferencesStore = appPreferencesStore,
|
|
clipboardManager = clipboardManager,
|
|
settingsManager = settingsManager,
|
|
uiMessageSender = uiMessageSender,
|
|
coldUserWalletBuilderFactory = coldUserWalletBuilderFactory,
|
|
userTokensResponseStore = userTokensResponseStore,
|
|
userWalletsListRepository = userWalletsListRepository,
|
|
tangemHotSdk = tangemHotSdk,
|
|
trackingContextProxy = trackingContextProxy,
|
|
),
|
|
),
|
|
)
|
|
}
|
|
|
|
override fun newImageLoader(): ImageLoader {
|
|
return createCoilImageLoader(
|
|
context = this,
|
|
logEnabled = LogConfig.imageLoader,
|
|
)
|
|
}
|
|
|
|
private fun loadNativeLibraries() {
|
|
System.loadLibrary("TrustWalletCore")
|
|
}
|
|
|
|
private fun initWithConfigDependency(environmentConfig: EnvironmentConfig) {
|
|
initAnalytics(this, environmentConfig)
|
|
Log.addLogger(logger = tangemSdkLogger)
|
|
}
|
|
|
|
private fun initAnalytics(application: Application, environmentConfig: EnvironmentConfig) {
|
|
val factory = AnalyticsFactory()
|
|
factory.addHandlerBuilder(AmplitudeAnalyticsHandler.Builder())
|
|
factory.addHandlerBuilder(FirebaseAnalyticsHandler.Builder())
|
|
factory.addHandlerBuilder(AppsFlyerAnalyticsHandler.Builder(appsFlyerClientFactory))
|
|
factory.addHandlerBuilder(CustomerIoAnalyticsHandler.Builder())
|
|
|
|
factory.addFilter(oneTimeEventFilter)
|
|
factory.addFilter(AppsFlyerEventFilter())
|
|
|
|
val buildData = AnalyticsHandlerBuilder.Data(
|
|
application = application,
|
|
config = environmentConfig,
|
|
isDebug = BuildConfig.DEBUG,
|
|
logConfig = LogConfig.analyticsHandlers,
|
|
jsonConverter = MoshiConverter.sdkMoshiConverter,
|
|
)
|
|
|
|
Analytics.addParamsInterceptor(
|
|
interceptor = object : ParamsInterceptor {
|
|
override fun id(): String = "SendTransactionSignerInfoInterceptor"
|
|
|
|
override fun canBeAppliedTo(event: AnalyticsEvent): Boolean = event is Basic.TransactionSent
|
|
|
|
override fun intercept(params: MutableMap<String, String>) {
|
|
val isLastSignWithRing = store.state.globalState.isLastSignWithRing
|
|
|
|
params[AnalyticsParam.WALLET_FORM] = if (isLastSignWithRing) {
|
|
WalletForm.Ring.name
|
|
} else {
|
|
WalletForm.Card.name
|
|
}
|
|
}
|
|
},
|
|
)
|
|
|
|
factory.build(Analytics, buildData)
|
|
}
|
|
} |