Updated on 2026-08-14
This commit is contained in:
parent
40af5f555b
commit
8fbfee735b
5 changed files with 73 additions and 19 deletions
|
|
@ -7,16 +7,16 @@ import android.os.Bundle
|
|||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import java.util.*
|
||||
import java.util.WeakHashMap
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class ForegroundActivityObserver : ActivityResultCaller {
|
||||
override var activityResultLauncher: ActivityResultLauncher<Intent>? = null
|
||||
private set
|
||||
|
||||
private val activities = WeakHashMap<KClass<out Activity>, Activity>()
|
||||
private val activities = WeakHashMap<KClass<out Activity>, AppCompatActivity>()
|
||||
|
||||
val foregroundActivity: Activity?
|
||||
val foregroundActivity: AppCompatActivity?
|
||||
get() = activities.entries
|
||||
.filterNot { it.value.isDestroyed }
|
||||
.firstOrNull()
|
||||
|
|
@ -35,7 +35,7 @@ class ForegroundActivityObserver : ActivityResultCaller {
|
|||
}
|
||||
|
||||
override fun onActivityResumed(activity: Activity) {
|
||||
activities[activity::class] = activity
|
||||
activities[activity::class] = activity as? AppCompatActivity
|
||||
}
|
||||
|
||||
override fun onActivityDestroyed(activity: Activity) {
|
||||
|
|
@ -59,6 +59,6 @@ class ForegroundActivityObserver : ActivityResultCaller {
|
|||
}
|
||||
}
|
||||
|
||||
fun ForegroundActivityObserver.withForegroundActivity(block: (Activity) -> Unit) {
|
||||
fun ForegroundActivityObserver.withForegroundActivity(block: (AppCompatActivity) -> Unit) {
|
||||
foregroundActivity?.let { block(it) }
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
package com.tangem.data.card.sdk
|
||||
package com.tangem.tap.data
|
||||
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.tangem.Log
|
||||
import com.tangem.TangemSdk
|
||||
|
|
@ -11,11 +10,15 @@ import com.tangem.common.authentication.AuthenticationManager
|
|||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.common.core.Config
|
||||
import com.tangem.common.services.secure.SecureStorage
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.crypto.bip39.Wordlist
|
||||
import com.tangem.data.card.sdk.CardSdkOwner
|
||||
import com.tangem.data.card.sdk.CardSdkProvider
|
||||
import com.tangem.sdk.DefaultSessionViewDelegate
|
||||
import com.tangem.sdk.extensions.*
|
||||
import com.tangem.sdk.nfc.NfcManager
|
||||
import com.tangem.sdk.storage.create
|
||||
import com.tangem.tap.foregroundActivityObserver
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
|
|
@ -25,19 +28,24 @@ import javax.inject.Singleton
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Singleton
|
||||
internal class DefaultCardSdkProvider @Inject constructor() : CardSdkProvider, CardSdkOwner {
|
||||
internal class DefaultCardSdkProvider @Inject constructor(
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
) : CardSdkProvider, CardSdkOwner {
|
||||
|
||||
override val sdk: TangemSdk
|
||||
get() = requireNotNull(value = holder?.sdk) {
|
||||
"Impossible to get the TangemSdk when activity is destroyed"
|
||||
}
|
||||
|
||||
private val observer: LifecycleObserver = Observer()
|
||||
private val observer = Observer()
|
||||
|
||||
private var holder: Holder? = null
|
||||
|
||||
override val sdk: TangemSdk
|
||||
get() = holder?.sdk ?: tryToRegisterWithForegroundActivity()
|
||||
|
||||
override fun register(activity: FragmentActivity) {
|
||||
Log.info { "Tangem SDK owner registered" }
|
||||
if (activity.isDestroyed || activity.isFinishing || activity.isChangingConfigurations) {
|
||||
val message = "Tangem SDK owner registration skipped: activity is destroyed or finishing"
|
||||
analyticsEventHandler.send(TangemSdkWarningEvent(message))
|
||||
Log.info { message }
|
||||
return
|
||||
}
|
||||
|
||||
if (holder != null) {
|
||||
unsubscribeAndCleanup()
|
||||
|
|
@ -46,6 +54,36 @@ internal class DefaultCardSdkProvider @Inject constructor() : CardSdkProvider, C
|
|||
initialize(activity)
|
||||
|
||||
activity.lifecycle.addObserver(observer)
|
||||
|
||||
Log.info { "Tangem SDK owner registered" }
|
||||
}
|
||||
|
||||
private fun tryToRegisterWithForegroundActivity(): TangemSdk {
|
||||
val warning = "Tangem SDK holder is null, trying to recreate it with foreground activity"
|
||||
analyticsEventHandler.send(TangemSdkWarningEvent(warning))
|
||||
Log.warning { warning }
|
||||
|
||||
val activity = foregroundActivityObserver.foregroundActivity
|
||||
|
||||
if (activity == null) {
|
||||
val error = "Tangem SDK holder is null and foreground activity is null"
|
||||
analyticsEventHandler.send(TangemSdkWarningEvent(error))
|
||||
Log.error { error }
|
||||
error(error)
|
||||
}
|
||||
|
||||
register(activity)
|
||||
|
||||
val sdk = holder?.sdk
|
||||
|
||||
if (sdk == null) {
|
||||
val error = "Tangem SDK is null after re-registering with foreground activity"
|
||||
analyticsEventHandler.send(TangemSdkWarningEvent(error))
|
||||
Log.error { error }
|
||||
error(error)
|
||||
}
|
||||
|
||||
return sdk
|
||||
}
|
||||
|
||||
private fun initialize(activity: FragmentActivity) {
|
||||
|
|
@ -78,7 +116,14 @@ internal class DefaultCardSdkProvider @Inject constructor() : CardSdkProvider, C
|
|||
}
|
||||
|
||||
private fun unsubscribeAndCleanup() {
|
||||
with(receiver = holder ?: return) {
|
||||
val currentHolder = holder
|
||||
|
||||
if (currentHolder == null) {
|
||||
Log.info { "Tangem SDK already unsubscribed and cleaned up" }
|
||||
return
|
||||
}
|
||||
|
||||
with(currentHolder) {
|
||||
nfcManager.unsubscribe(activity)
|
||||
authenticationManager.unsubscribe(activity)
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.tap.data
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
internal class TangemSdkWarningEvent(message: String) : AnalyticsEvent(
|
||||
category = "Tangem SDK",
|
||||
event = "Warning",
|
||||
error = IllegalStateException(message),
|
||||
)
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.data.card.di
|
||||
package com.tangem.tap.di.data
|
||||
|
||||
import com.tangem.data.card.sdk.CardSdkOwner
|
||||
import com.tangem.data.card.sdk.CardSdkProvider
|
||||
import com.tangem.data.card.sdk.DefaultCardSdkProvider
|
||||
import com.tangem.tap.data.DefaultCardSdkProvider
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -7,7 +7,7 @@ import com.tangem.TangemSdk
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal interface CardSdkProvider {
|
||||
interface CardSdkProvider {
|
||||
|
||||
/** CardSDK instance */
|
||||
val sdk: TangemSdk
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue