NTP-4629 | Changed implementation to use mutex with suspend coroutine (#12792)
This commit is contained in:
@@ -8,15 +8,13 @@
|
||||
package com.navi.pay.npcicl
|
||||
|
||||
import android.content.Context
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
|
||||
import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_UPI_NOT_RESET_CL_SERVICE_ON_DISCONNECT
|
||||
import com.navi.pay.common.utils.NaviPayCommonUtils
|
||||
import com.navi.pay.utils.NAVI_PAY_CL_INIT_RETRY_COUNT
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import org.npci.upi.security.services.CLServices
|
||||
import org.npci.upi.security.services.ServiceConnectionStatusNotifier
|
||||
|
||||
@@ -26,72 +24,31 @@ class NpciClService @Inject constructor(@ApplicationContext private val context:
|
||||
const val TAG = "NpciClService"
|
||||
}
|
||||
|
||||
private var clService: CLServices? =
|
||||
null // This is the limitation from NPCI side to make it static.
|
||||
private val isServiceInitRunning = AtomicBoolean(false)
|
||||
private val mutex = Mutex()
|
||||
private var clService: CLServices? = null
|
||||
|
||||
init {
|
||||
initService()
|
||||
}
|
||||
|
||||
private fun initService() {
|
||||
val naviPayAccessEligibility = NaviPayCommonUtils.getNaviPayAccessEligibility(context)
|
||||
if (!naviPayAccessEligibility.isNaviPayAccessible) {
|
||||
// User device doesn't meet the requirements to use UPI
|
||||
return
|
||||
}
|
||||
if (isServiceInitRunning.get()) {
|
||||
return
|
||||
}
|
||||
isServiceInitRunning.set(true)
|
||||
|
||||
if (clService != null) {
|
||||
return
|
||||
}
|
||||
CLServices.initService(
|
||||
context,
|
||||
object : ServiceConnectionStatusNotifier {
|
||||
override fun serviceConnected(clServices: CLServices) {
|
||||
clService = clServices
|
||||
isServiceInitRunning.set(false)
|
||||
suspend fun instance(): CLServices {
|
||||
mutex.withLock {
|
||||
return suspendCoroutine { continuation ->
|
||||
clService?.let {
|
||||
continuation.resume(it)
|
||||
return@suspendCoroutine
|
||||
}
|
||||
|
||||
override fun serviceDisconnected() {
|
||||
isServiceInitRunning.set(false)
|
||||
if (
|
||||
!FirebaseRemoteConfigHelper.getBoolean(
|
||||
NAVI_UPI_NOT_RESET_CL_SERVICE_ON_DISCONNECT
|
||||
)
|
||||
) {
|
||||
clService = null
|
||||
CLServices.initService(
|
||||
context,
|
||||
object : ServiceConnectionStatusNotifier {
|
||||
override fun serviceConnected(clServices: CLServices) {
|
||||
clService = clServices
|
||||
continuation.resume(clServices)
|
||||
}
|
||||
|
||||
override fun serviceDisconnected() {
|
||||
clService = null
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun instance(retries: Int = 0): CLServices {
|
||||
// Ensure initService() is called if clService is null
|
||||
if (clService == null && !isServiceInitRunning.get()) {
|
||||
initService()
|
||||
}
|
||||
|
||||
// Check if CL service is already initialized
|
||||
if (clService != null) {
|
||||
return clService!!
|
||||
}
|
||||
|
||||
// If maximum retries exceeded, throw an exception
|
||||
if (retries >= NAVI_PAY_CL_INIT_RETRY_COUNT) {
|
||||
throw NullPointerException(
|
||||
"CL service is not initialized. Call initService() or check status of isServiceInitRunning before using it."
|
||||
)
|
||||
}
|
||||
|
||||
// If initialization is in progress, wait for it to complete
|
||||
delay(timeMillis = 100)
|
||||
|
||||
// Retry with incremented count
|
||||
return instance(retries = retries + 1)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user