From 30d2fab20896034fc3f7c62726f6628696761c4b Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 15 Sep 2022 09:31:18 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../java/com/tangem/tap/TapApplication.kt | 142 +++++++++--------- .../java/com/tangem/tap/common/AssetReader.kt | 32 ++++ .../analytics/AppsFlyerAnalyticsHandler.kt | 7 +- .../analytics/GlobalAnalyticsHandler.kt | 4 +- .../common/feedback/AdditionalFeedbackInfo.kt | 11 -- .../configurable/config/ConfigLoaders.kt | 41 +---- .../configurable/config/ConfigManager.kt | 13 +- .../tap/domain/twins/TwinCardsManager.kt | 5 +- .../products/twins/redux/TwinCardsAction.kt | 2 +- .../products/twins/ui/TwinsCardsFragment.kt | 12 +- 10 files changed, 120 insertions(+), 149 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/common/AssetReader.kt diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index e0c6267ceb..d8a0b72c7e 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -1,17 +1,17 @@ package com.tangem.tap import android.app.Application +import android.content.Context +import android.content.pm.PackageManager import coil.ImageLoader import coil.ImageLoaderFactory import com.appsflyer.AppsFlyerLib -import com.google.firebase.ktx.Firebase -import com.google.firebase.remoteconfig.ktx.remoteConfig -import com.google.firebase.remoteconfig.ktx.remoteConfigSettings import com.tangem.Log import com.tangem.LogFormat import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder import com.tangem.domain.DomainLayer import com.tangem.network.common.MoshiConverter +import com.tangem.tap.common.AndroidAssetReader import com.tangem.tap.common.analytics.GlobalAnalyticsHandler import com.tangem.tap.common.feedback.AdditionalFeedbackInfo import com.tangem.tap.common.feedback.FeedbackManager @@ -21,9 +21,9 @@ import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.appReducer import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.shop.TangemShopService +import com.tangem.tap.domain.configurable.config.Config import com.tangem.tap.domain.configurable.config.ConfigManager import com.tangem.tap.domain.configurable.config.FeaturesLocalLoader -import com.tangem.tap.domain.configurable.config.FeaturesRemoteLoader import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager import com.tangem.tap.domain.tokens.CurrenciesRepository import com.tangem.tap.domain.walletconnect.WalletConnectRepository @@ -36,7 +36,7 @@ import timber.log.Timber val store = Store( reducer = ::appReducer, middleware = AppState.getMiddleware(), - state = AppState() + state = AppState(), ) val logConfig = LogConfig() @@ -48,98 +48,98 @@ lateinit var walletConnectRepository: WalletConnectRepository lateinit var shopService: TangemShopService class TapApplication : Application(), ImageLoaderFactory { + override fun onCreate() { super.onCreate() - DomainLayer.init() if (BuildConfig.DEBUG) { Timber.plant(Timber.DebugTree()) - Firebase.remoteConfig.setConfigSettingsAsync(remoteConfigSettings { - this.minimumFetchIntervalInSeconds = 60 - }) - } else { - Firebase.remoteConfig.setConfigSettingsAsync(remoteConfigSettings { - this.minimumFetchIntervalInSeconds = 3600 - }) } + foregroundActivityObserver = ForegroundActivityObserver() + registerActivityLifecycleCallbacks(foregroundActivityObserver.callbacks) + + DomainLayer.init() NetworkConnectivity.createInstance(store, this) preferencesStorage = PreferencesStorage(this) currenciesRepository = CurrenciesRepository(this, store.state.domainNetworks.tangemTechService) walletConnectRepository = WalletConnectRepository(this) - foregroundActivityObserver = ForegroundActivityObserver() - registerActivityLifecycleCallbacks(foregroundActivityObserver.callbacks) - initFeedbackManager() - loadConfigs() + val configLoader = FeaturesLocalLoader(AndroidAssetReader(this), MoshiConverter.defaultMoshi()) + initConfigManager(configLoader) { config -> + shopService = TangemShopService(this, config.shopify!!) + initAppsFlyer(this, config) + initFeedbackManager(this, preferencesStorage, config) + } + initWarningMessagesManager() BlockchainSdkRetrofitBuilder.enableNetworkLogging = BuildConfig.DEBUG - - initAppsFlyer() } override fun newImageLoader(): ImageLoader { return createCoilImageLoader(context = this) } - private fun loadConfigs() { - val moshi = MoshiConverter.defaultMoshi() - val localLoader = FeaturesLocalLoader(this, moshi) - val remoteLoader = FeaturesRemoteLoader(moshi) - val configManager = ConfigManager(localLoader, remoteLoader) - configManager.load { config -> + private fun initConfigManager(loader: FeaturesLocalLoader, onComplete: (Config) -> Unit) { + val configManager = ConfigManager() + configManager.load(loader) { config -> store.dispatch(GlobalAction.SetConfigManager(configManager)) - shopService = TangemShopService( - application = this, - shopifyShop = config.shopify!! - ) - store.state.globalState.feedbackManager?.initChat( - context = this, - zendeskConfig = config.zendesk!! - ) + onComplete(config) } - store.dispatch(GlobalAction.SetWarningManager(WarningMessagesManager())) } } - private fun initFeedbackManager() { - val infoHolder = AdditionalFeedbackInfo() - infoHolder.setAppVersion(this) - - val logLevels = listOf( - Log.Level.ApduCommand, - Log.Level.Apdu, - Log.Level.Tlv, - Log.Level.Nfc, - Log.Level.Command, - Log.Level.Session, - Log.Level.View, - Log.Level.Network, - Log.Level.Error, - ) - val logWriter = TangemLogCollector( - levels = logLevels, - messageFormatter = LogFormat.StairsFormatter(), - ) - Log.addLogger(logWriter) - - store.dispatch( - GlobalAction.SetFeedbackManager( - FeedbackManager( - infoHolder = infoHolder, - logCollector = logWriter, - preferencesStorage = preferencesStorage, - ), - ), - ) - } - - private fun initAppsFlyer() { - val devKey = store.state.globalState.configManager?.config?.appsFlyerDevKey ?: return - AppsFlyerLib.getInstance().init(devKey, null, this) - AppsFlyerLib.getInstance().start(this) - val analyticsHandler = GlobalAnalyticsHandler.createDefaultAnalyticHandlers(this) + private fun initAppsFlyer(context: Context, config: Config) { + AppsFlyerLib.getInstance().init(config.appsFlyerDevKey, null, context) + AppsFlyerLib.getInstance().start(context) + val analyticsHandler = GlobalAnalyticsHandler.createDefaultAnalyticHandlers(context) store.dispatch(GlobalAction.SetAnanlyticHandlers(analyticsHandler)) } + + private fun initFeedbackManager(context: Context, preferencesStorage: PreferencesStorage, config: Config) { + fun initAdditionalFeedbackInfo(context: Context): AdditionalFeedbackInfo = AdditionalFeedbackInfo().apply { + appVersion = try { + val pInfo = context.packageManager.getPackageInfo(context.packageName, 0) + pInfo.versionName + } catch (e: PackageManager.NameNotFoundException) { + e.printStackTrace() + "x.y.z" + } + } + + fun initTangemLogCollector(): TangemLogCollector { + val logLevels = listOf( + Log.Level.ApduCommand, + Log.Level.Apdu, + Log.Level.Tlv, + Log.Level.Nfc, + Log.Level.Command, + Log.Level.Session, + Log.Level.View, + Log.Level.Network, + Log.Level.Error, + ) + return TangemLogCollector(logLevels, LogFormat.StairsFormatter()) + } + + val additionalFeedbackInfo = initAdditionalFeedbackInfo(context) + val tangemLogCollector = initTangemLogCollector() + Log.addLogger(tangemLogCollector) + + val feedbackManager = FeedbackManager( + infoHolder = additionalFeedbackInfo, + logCollector = tangemLogCollector, + preferencesStorage = preferencesStorage, + ) + feedbackManager.initChat( + context = context, + zendeskConfig = config.zendesk!!, + ) + store.dispatch(GlobalAction.SetFeedbackManager(feedbackManager)) + } + + private fun initWarningMessagesManager() { + store.dispatch(GlobalAction.SetWarningManager(WarningMessagesManager())) + } } data class LogConfig( diff --git a/app/src/main/java/com/tangem/tap/common/AssetReader.kt b/app/src/main/java/com/tangem/tap/common/AssetReader.kt new file mode 100644 index 0000000000..2beadc1c7b --- /dev/null +++ b/app/src/main/java/com/tangem/tap/common/AssetReader.kt @@ -0,0 +1,32 @@ +package com.tangem.tap.common + +import android.content.Context +import com.tangem.tap.common.extensions.readAssetAsString +import com.tangem.tap.common.extensions.readFile +import com.tangem.tap.common.extensions.rewriteFile + +/** +[REDACTED_AUTHOR] + */ +interface AssetReader { + fun readAssetAsString(name: String): String + fun readFile(fileName: String): String + fun rewriteFile(content: String, fileName: String) +} + +class AndroidAssetReader( + private val context: Context, +) : AssetReader { + + override fun readAssetAsString(name: String): String { + return context.readAssetAsString(name) + } + + override fun readFile(fileName: String): String { + return context.readFile(fileName) + } + + override fun rewriteFile(content: String, fileName: String) { + context.rewriteFile(content, fileName) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/analytics/AppsFlyerAnalyticsHandler.kt b/app/src/main/java/com/tangem/tap/common/analytics/AppsFlyerAnalyticsHandler.kt index 64beb11b4a..16fa1644ab 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/AppsFlyerAnalyticsHandler.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/AppsFlyerAnalyticsHandler.kt @@ -1,6 +1,6 @@ package com.tangem.tap.common.analytics -import android.app.Application +import android.content.Context import com.appsflyer.AFInAppEventParameterName import com.appsflyer.AFInAppEventType import com.appsflyer.AppsFlyerLib @@ -8,7 +8,7 @@ import com.shopify.buy3.Storefront import com.tangem.common.card.Card import com.tangem.common.core.TangemSdkError -class AppsFlyerAnalyticsHandler(val context: Application): AnalyticsHandler() { +class AppsFlyerAnalyticsHandler(val context: Context): AnalyticsHandler() { override fun triggerEvent( event: AnalyticsEvent, @@ -16,8 +16,7 @@ class AppsFlyerAnalyticsHandler(val context: Application): AnalyticsHandler() { blockchain: String?, params: Map ) { - AppsFlyerLib.getInstance().logEvent(context, - event.event, prepareParams(card, blockchain)) + AppsFlyerLib.getInstance().logEvent(context, event.event, prepareParams(card, blockchain)) } override fun logCardSdkError( diff --git a/app/src/main/java/com/tangem/tap/common/analytics/GlobalAnalyticsHandler.kt b/app/src/main/java/com/tangem/tap/common/analytics/GlobalAnalyticsHandler.kt index c500f330b2..197f396621 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/GlobalAnalyticsHandler.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/GlobalAnalyticsHandler.kt @@ -1,6 +1,6 @@ package com.tangem.tap.common.analytics -import android.app.Application +import android.content.Context import com.shopify.buy3.Storefront import com.tangem.common.card.Card import com.tangem.common.core.TangemSdkError @@ -42,7 +42,7 @@ class GlobalAnalyticsHandler(val analyticsHandlers: List) : } companion object { - fun createDefaultAnalyticHandlers(context: Application): GlobalAnalyticsHandler { + fun createDefaultAnalyticHandlers(context: Context): GlobalAnalyticsHandler { return GlobalAnalyticsHandler( listOf( FirebaseAnalyticsHandler, diff --git a/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt b/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt index ddc7a41b23..70912f24a6 100644 --- a/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt +++ b/app/src/main/java/com/tangem/tap/common/feedback/AdditionalFeedbackInfo.kt @@ -1,7 +1,5 @@ package com.tangem.tap.common.feedback -import android.content.Context -import android.content.pm.PackageManager import android.os.Build import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.AmountType @@ -45,15 +43,6 @@ class AdditionalFeedbackInfo { var fee: String = "" var token: String = "" - fun setAppVersion(context: Context) { - try { - val pInfo = context.packageManager.getPackageInfo(context.packageName, 0) - appVersion = pInfo.versionName - } catch (e: PackageManager.NameNotFoundException) { - e.printStackTrace() - } - } - fun setCardInfo(data: ScanResponse) { cardId = data.card.cardId cardBlockchain = data.walletData?.blockchain ?: "" diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigLoaders.kt b/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigLoaders.kt index 4c19bab889..ba33d98210 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigLoaders.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigLoaders.kt @@ -1,12 +1,8 @@ package com.tangem.tap.domain.configurable.config -import android.content.Context -import com.google.firebase.ktx.Firebase -import com.google.firebase.remoteconfig.ktx.remoteConfig import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi -import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler -import com.tangem.tap.common.extensions.readAssetAsString +import com.tangem.tap.common.AssetReader import com.tangem.tap.domain.configurable.Loader import timber.log.Timber @@ -14,8 +10,8 @@ import timber.log.Timber [REDACTED_AUTHOR] */ class FeaturesLocalLoader( - private val context: Context, - private val moshi: Moshi, + private val assetReader: AssetReader, + private val moshi: Moshi, ) : Loader { override fun load(onComplete: (ConfigModel) -> Unit) { @@ -23,8 +19,8 @@ class FeaturesLocalLoader( val featureAdapter: JsonAdapter = moshi.adapter(FeatureModel::class.java) val valuesAdapter: JsonAdapter = moshi.adapter(ConfigValueModel::class.java) - val jsonFeatures = context.readAssetAsString(Loader.featuresName) - val jsonConfigValues = context.readAssetAsString(Loader.configValuesName) + val jsonFeatures = assetReader.readAssetAsString(Loader.featuresName) + val jsonConfigValues = assetReader.readAssetAsString(Loader.configValuesName) ConfigModel(featureAdapter.fromJson(jsonFeatures), valuesAdapter.fromJson(jsonConfigValues)) } catch (ex: Exception) { @@ -33,31 +29,4 @@ class FeaturesLocalLoader( } onComplete(config) } -} - -class FeaturesRemoteLoader( - private val moshi: Moshi, -) : Loader { - - override fun load(onComplete: (ConfigModel) -> Unit) { - val emptyConfig = ConfigModel.empty() - val remoteConfig = Firebase.remoteConfig - remoteConfig.fetchAndActivate().addOnCompleteListener { - if (it.isSuccessful) { - val config = remoteConfig.getValue(Loader.featuresName) - val jsonConfig = config.asString() - if (jsonConfig.isEmpty()) { - onComplete(emptyConfig) - return@addOnCompleteListener - } - val featureAdapter: JsonAdapter = moshi.adapter(FeatureModel::class.java) - onComplete(ConfigModel(featureAdapter.fromJson(jsonConfig), null)) - } else { - onComplete(emptyConfig) - } - }.addOnFailureListener { - FirebaseAnalyticsHandler.logException("remote_config_error.features", it) - onComplete(emptyConfig) - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt b/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt index bb94004636..62f367cb33 100644 --- a/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/configurable/config/ConfigManager.kt @@ -24,26 +24,19 @@ data class Config( val zendesk: ZendeskConfig? = null, ) -class ConfigManager( - private val localLoader: Loader, - private val remoteLoader: Loader -) { +class ConfigManager { var config: Config = Config() private set private var defaultConfig = Config() - fun load(onComplete: ((config: Config) -> Unit)? = null) { - localLoader.load { configModel -> + fun load(configLoader: Loader, onComplete: ((config: Config) -> Unit)? = null) { + configLoader.load { configModel -> setupFeature(configModel.features) setupKey(configModel.configValues) onComplete?.invoke(config) } - // Uncomment to enable remote config -// remoteLoader.load { config -> -// setupFeature(config.features) -// } } fun turnOff(name: String) { diff --git a/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt b/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt index 43c91a54fb..1d02623442 100644 --- a/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/twins/TwinCardsManager.kt @@ -13,6 +13,7 @@ import com.tangem.common.extensions.toHexString import com.tangem.domain.common.ScanResponse import com.tangem.network.common.MoshiConverter import com.tangem.operations.wallet.CreateWalletResponse +import com.tangem.tap.common.AssetReader import com.tangem.tap.common.analytics.Analytics import com.tangem.tap.common.analytics.AnalyticsHandler import com.tangem.tap.tangemSdkManager @@ -119,10 +120,6 @@ class TwinCardsManager( } } -interface AssetReader { - fun readAssetAsString(name: String): String -} - private class Issuer( val id: String, val privateKey: String, diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt index ee4bd5ddab..5c915f9cb0 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsAction.kt @@ -4,9 +4,9 @@ import com.tangem.Message import com.tangem.blockchain.common.WalletManager import com.tangem.common.extensions.VoidCallback import com.tangem.domain.common.ScanResponse +import com.tangem.tap.common.AssetReader import com.tangem.tap.common.redux.StateDialog import com.tangem.tap.domain.TapError -import com.tangem.tap.domain.twins.AssetReader import com.tangem.tap.domain.twins.TwinCardsManager import com.tangem.tap.features.onboarding.OnboardingWalletBalance import org.rekotlin.Action diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt index 7827a4f196..ee7eb79471 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/ui/TwinsCardsFragment.kt @@ -15,10 +15,10 @@ import com.tangem.blockchain.common.Blockchain import com.tangem.common.extensions.VoidCallback import com.tangem.domain.common.TwinCardNumber import com.tangem.tangem_sdk_new.ui.widget.leapfrogWidget.LeapfrogWidget +import com.tangem.tap.common.AndroidAssetReader import com.tangem.tap.common.extensions.beginDelayedTransition import com.tangem.tap.common.extensions.getDrawableCompat import com.tangem.tap.common.extensions.hide -import com.tangem.tap.common.extensions.readAssetAsString import com.tangem.tap.common.extensions.show import com.tangem.tap.common.extensions.stripZeroPlainString import com.tangem.tap.common.redux.navigation.AppScreen @@ -26,7 +26,6 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.common.redux.navigation.ShareElement import com.tangem.tap.common.toggleWidget.RefreshBalanceWidget import com.tangem.tap.common.transitions.InternalNoteLayoutTransition -import com.tangem.tap.domain.twins.AssetReader import com.tangem.tap.domain.twins.TwinsCardWidget import com.tangem.tap.features.addBackPressHandler import com.tangem.tap.features.onboarding.products.BaseOnboardingFragment @@ -46,13 +45,6 @@ class TwinsCardsFragment : BaseOnboardingFragment() { private lateinit var twinsWidget: TwinsCardWidget private lateinit var btnRefreshBalanceWidget: RefreshBalanceWidget - private val assetReader: AssetReader by lazy { - object : AssetReader { - override fun readAssetAsString(name: String): String = - requireContext().readAssetAsString(name) - } - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) postponeEnterTransition() @@ -250,7 +242,7 @@ class TwinsCardsFragment : BaseOnboardingFragment() { store.dispatch( TwinCardsAction.Wallet.LaunchFirstStep( Message(getString(R.string.twins_recreate_title_format, twinIndexNumber)), - assetReader + AndroidAssetReader(requireContext()), ) ) }