Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45736566 authored by Moez Bhatti's avatar Moez Bhatti
Browse files

Fix crash in billingmanager when service is disconnected

parent f766745e
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -11,7 +11,7 @@ buildscript {
    ext.autodispose_version = '1.3.0'
    ext.autodispose_version = '1.3.0'
    ext.billing_version = '3.0.2'
    ext.billing_version = '3.0.2'
    ext.conductor_version = '2.1.5'
    ext.conductor_version = '2.1.5'
    ext.coroutines_version = '1.2.2'
    ext.coroutines_version = '1.4.3'
    ext.dagger_version = "2.16"
    ext.dagger_version = "2.16"
    ext.espresso_version = '3.1.0-alpha3'
    ext.espresso_version = '3.1.0-alpha3'
    ext.exoplayer_version = "2.8.1"
    ext.exoplayer_version = "2.8.1"
+25 −23
Original line number Original line Diff line number Diff line
@@ -40,19 +40,20 @@ import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.Subject
import io.reactivex.subjects.Subject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withContext
import timber.log.Timber
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Inject
import javax.inject.Singleton
import javax.inject.Singleton
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine


@Singleton
@Singleton
class BillingManagerImpl @Inject constructor(
class BillingManagerImpl @Inject constructor(
    context: Context,
    context: Context,
    private val analyticsManager: AnalyticsManager
    private val analyticsManager: AnalyticsManager
) : BillingManager, PurchasesUpdatedListener {
) : BillingManager, BillingClientStateListener, PurchasesUpdatedListener {


    private val productsSubject: Subject<List<SkuDetails>> = BehaviorSubject.create()
    private val productsSubject: Subject<List<SkuDetails>> = BehaviorSubject.create()
    override val products: Observable<List<BillingManager.Product>> = productsSubject
    override val products: Observable<List<BillingManager.Product>> = productsSubject
@@ -78,7 +79,14 @@ class BillingManagerImpl @Inject constructor(
            .enablePendingPurchases()
            .enablePendingPurchases()
            .build()
            .build()


    private var isServiceConnected = false
    private val billingClientState = MutableSharedFlow<Int>(
            replay = 1,
            onBufferOverflow = BufferOverflow.DROP_OLDEST
    )

    init {
        billingClientState.tryEmit(BillingClient.BillingResponseCode.SERVICE_DISCONNECTED)
    }


    override suspend fun checkForPurchases() = executeServiceRequest {
    override suspend fun checkForPurchases() = executeServiceRequest {
        // Load the cached data
        // Load the cached data
@@ -146,29 +154,23 @@ class BillingManagerImpl @Inject constructor(
    }
    }


    private suspend fun executeServiceRequest(runnable: suspend () -> Unit) {
    private suspend fun executeServiceRequest(runnable: suspend () -> Unit) {
        when (billingClient.isReady) {
        if (billingClientState.first() != BillingClient.BillingResponseCode.OK) {
            true -> runnable()
            Timber.i("Starting billing service")
            false -> startServiceConnection(runnable)
            billingClient.startConnection(this)
        }
        }
        }


    private suspend fun startServiceConnection(onSuccess: suspend () -> Unit) = withContext(Dispatchers.IO) {
        billingClientState.first { state -> state == BillingClient.BillingResponseCode.OK }
        val result = suspendCoroutine<BillingResult> { cont ->
        runnable()
            val listener = object : BillingClientStateListener {
                override fun onBillingSetupFinished(result: BillingResult) = cont.resume(result)
                override fun onBillingServiceDisconnected() = Timber.i("Billing service disconnected")
    }
    }


            Timber.i("Starting billing service")
    override fun onBillingSetupFinished(result: BillingResult) {
            billingClient.startConnection(listener)
        Timber.i("Billing response: ${result.responseCode}")
        billingClientState.tryEmit(result.responseCode)
    }
    }


        if (result.responseCode == BillingClient.BillingResponseCode.OK) {
    override fun onBillingServiceDisconnected() {
            Timber.i("Billing service connected")
        Timber.i("Billing service disconnected")
            onSuccess()
        billingClientState.tryEmit(BillingClient.BillingResponseCode.SERVICE_DISCONNECTED)
        } else {
            Timber.w("Billing response: ${result.responseCode}")
        }
    }
    }


}
}