diff --git a/android/navi-common/src/main/java/com/navi/common/firebaseremoteconfig/FirebaseRemoteConfigHelper.kt b/android/navi-common/src/main/java/com/navi/common/firebaseremoteconfig/FirebaseRemoteConfigHelper.kt
index d294fc46d9..15c422dc91 100644
--- a/android/navi-common/src/main/java/com/navi/common/firebaseremoteconfig/FirebaseRemoteConfigHelper.kt
+++ b/android/navi-common/src/main/java/com/navi/common/firebaseremoteconfig/FirebaseRemoteConfigHelper.kt
@@ -111,6 +111,8 @@ object FirebaseRemoteConfigHelper {
const val NAVI_PAY_REWARDS_NUDGE_ENABLED = "NAVI_PAY_REWARDS_NUDGE_ENABLED"
const val NAVI_PAY_REWARDS_GRATIFICATION_ENABLED = "NAVI_PAY_REWARDS_GRATIFICATION_ENABLED"
const val NAVI_PAY_CL_INIT_RETRY_COUNT = "NAVI_PAY_CL_INIT_RETRY_COUNT"
+ const val NAVI_PAY_LITMUS_EXPERIMENTS_CACHE_DURATION_IN_MILLIS =
+ "NAVI_PAY_LITMUS_EXPERIMENTS_CACHE_DURATION_IN_MILLIS"
// BBPS
const val NAVI_BBPS_CATEGORIES_CACHE_MILLIS = "NAVI_BBPS_CATEGORIES_CACHE_MILLIS"
diff --git a/android/navi-common/src/main/res/xml/default_remote_config.xml b/android/navi-common/src/main/res/xml/default_remote_config.xml
index bb9aa01e7c..bc65fe7916 100644
--- a/android/navi-common/src/main/res/xml/default_remote_config.xml
+++ b/android/navi-common/src/main/res/xml/default_remote_config.xml
@@ -477,4 +477,8 @@
FRONT_LAYER_UPPER_CONTENT_LENGTH
7
+
+ NAVI_PAY_LITMUS_EXPERIMENTS_CACHE_DURATION_IN_MILLIS
+ 86400000
+
\ No newline at end of file
diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/model/network/LitmusExperimentsResponse.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/model/network/LitmusExperimentsResponse.kt
new file mode 100644
index 0000000000..b97d163aab
--- /dev/null
+++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/model/network/LitmusExperimentsResponse.kt
@@ -0,0 +1,20 @@
+/*
+ *
+ * * Copyright © 2024 by Navi Technologies Limited
+ * * All rights reserved. Strictly confidential
+ *
+ */
+
+package com.navi.pay.common.model.network
+
+import com.google.gson.annotations.SerializedName
+
+data class LitmusExperimentsResponse(
+ @SerializedName("experiments") val experiments: List?
+)
+
+data class LitmusExperimentItemResponse(
+ @SerializedName("name") val name: String,
+ @SerializedName("isEnabled") val isEnabled: Boolean? = false,
+ @SerializedName("metaData") val metaData: Map? = emptyMap()
+)
diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/repository/CommonRepository.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/repository/CommonRepository.kt
index 632cf75657..8dfaed3a9d 100644
--- a/android/navi-pay/src/main/kotlin/com/navi/pay/common/repository/CommonRepository.kt
+++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/repository/CommonRepository.kt
@@ -88,4 +88,7 @@ constructor(private val naviPayRetrofitService: NaviPayRetrofitService) : Respon
suspend fun liteDeregistration(sendMoneyRequest: SendMoneyRequest) =
apiResponseCallback(naviPayRetrofitService.sendMoney(sendMoneyRequest = sendMoneyRequest))
+
+ suspend fun fetchABTestingExperiments() =
+ apiResponseCallback(response = naviPayRetrofitService.fetchABTestingExperiments())
}
diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/SyncLitmusExperimentsUseCase.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/SyncLitmusExperimentsUseCase.kt
new file mode 100644
index 0000000000..782fbd69fd
--- /dev/null
+++ b/android/navi-pay/src/main/kotlin/com/navi/pay/common/usecase/SyncLitmusExperimentsUseCase.kt
@@ -0,0 +1,114 @@
+/*
+ *
+ * * Copyright © 2024 by Navi Technologies Limited
+ * * All rights reserved. Strictly confidential
+ *
+ */
+
+package com.navi.pay.common.usecase
+
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import com.navi.base.cache.model.NaviCacheAltSourceEntity
+import com.navi.base.cache.model.NaviCacheEntity
+import com.navi.base.cache.repository.NaviCacheRepository
+import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper
+import com.navi.common.network.models.isSuccessWithData
+import com.navi.pay.common.model.network.LitmusExperimentItemResponse
+import com.navi.pay.common.repository.CommonRepository
+import com.navi.pay.common.sync.model.view.SyncEntity
+import com.navi.pay.common.sync.repository.SyncRepository
+import com.navi.pay.network.di.NaviPayGsonBuilder
+import com.navi.pay.utils.NAVI_PAY_LITMUS_EXPERIMENTS_CACHE_KEY
+import com.navi.pay.utils.NAVI_PAY_LITMUS_EXPERIMENTS_LAST_REFRESHED_TIMESTAMP
+import javax.inject.Inject
+
+class SyncLitmusExperimentsUseCase
+@Inject
+constructor(
+ private val commonRepository: CommonRepository,
+ private val naviCacheRepository: NaviCacheRepository,
+ private val syncRepository: SyncRepository,
+ @NaviPayGsonBuilder private val gson: Gson
+) {
+
+ suspend fun execute(skipLastSyncedTimestampCheck: Boolean = true) {
+
+ val firebaseCacheDurationInMillis =
+ FirebaseRemoteConfigHelper.getLong(
+ FirebaseRemoteConfigHelper.NAVI_PAY_LITMUS_EXPERIMENTS_CACHE_DURATION_IN_MILLIS
+ )
+
+ val lastRefreshTimeStampForABTesting =
+ syncRepository
+ .get(key = NAVI_PAY_LITMUS_EXPERIMENTS_LAST_REFRESHED_TIMESTAMP)
+ ?.lastSyncedTimestamp
+ ?.toLongOrNull() ?: 0L
+
+ if (!skipLastSyncedTimestampCheck) {
+ // Refresh is not needed
+ if (
+ System.currentTimeMillis() - lastRefreshTimeStampForABTesting <
+ firebaseCacheDurationInMillis
+ ) {
+ return
+ }
+ }
+
+ val abTestingResponse = commonRepository.fetchABTestingExperiments()
+ if (!abTestingResponse.isSuccessWithData()) {
+ return
+ }
+
+ naviCacheRepository.save(
+ NaviCacheEntity(
+ value = gson.toJson(abTestingResponse.data?.experiments),
+ ttl = firebaseCacheDurationInMillis,
+ version = 1,
+ key = NAVI_PAY_LITMUS_EXPERIMENTS_CACHE_KEY
+ )
+ )
+
+ syncRepository.insert(
+ syncEntity =
+ SyncEntity(
+ key = NAVI_PAY_LITMUS_EXPERIMENTS_LAST_REFRESHED_TIMESTAMP,
+ lastSyncedTimestamp = System.currentTimeMillis().toString()
+ )
+ )
+ }
+
+ private suspend fun getABExperiments(): List {
+ val experimentsJson =
+ naviCacheRepository.getDataOrFetchFromAltSource(
+ key = NAVI_PAY_LITMUS_EXPERIMENTS_CACHE_KEY,
+ version = 1,
+ getDataFromAltSource = {
+ NaviCacheAltSourceEntity(
+ value = gson.toJson(emptyList()),
+ version = 1,
+ isSuccess = false
+ )
+ }
+ )
+
+ val type = object : TypeToken>() {}.type
+ val experiments =
+ try {
+ gson
+ .fromJson>(
+ experimentsJson?.value.orEmpty(),
+ type
+ )
+ .let { it.ifEmpty { emptyList() } }
+ } catch (e: Exception) {
+ emptyList()
+ }
+
+ return experiments
+ }
+
+ private suspend fun getExperimentValues(experimentName: String): LitmusExperimentItemResponse? {
+ return getABExperiments().firstOrNull { it.name == experimentName }
+ }
+}
diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt
index 8bff167208..4478bde3c1 100644
--- a/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt
+++ b/android/navi-pay/src/main/kotlin/com/navi/pay/entry/NaviPayViewModel.kt
@@ -33,6 +33,7 @@ import com.navi.pay.common.usecase.RefreshBankListUseCase
import com.navi.pay.common.usecase.RefreshConfigUseCase
import com.navi.pay.common.usecase.RefreshLinkedAccountsUseCase
import com.navi.pay.common.usecase.RefreshUiTronScreenResponseUseCase
+import com.navi.pay.common.usecase.SyncLitmusExperimentsUseCase
import com.navi.pay.common.viewmodel.NaviPayBaseVM
import com.navi.pay.management.common.model.view.NudgeDetailEntity
import com.navi.pay.network.di.NaviPayGsonBuilder
@@ -76,6 +77,7 @@ constructor(
private val bankUptimeRepository: BankUptimeRepository,
private val scratchCardNudgeHelper: ScratchCardNudgeHelper,
private val naviCacheRepository: NaviCacheRepository,
+ private val syncLitmusExperimentsUseCase: SyncLitmusExperimentsUseCase,
@NaviPayGsonBuilder private val gson: Gson
) : NaviPayBaseVM(naviPayVmData = NaviPayVmData(screenName = NaviPayAnalytics.NAVI_PAY_ACTIVITY)) {
@@ -106,6 +108,10 @@ constructor(
taskList.add(async { refreshConfigUseCase.execute() })
+ taskList.add(
+ async { syncLitmusExperimentsUseCase.execute(skipLastSyncedTimestampCheck = false) }
+ )
+
taskList.add(
async {
if (isUserOnboarded()) {
diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/network/retrofit/NaviPayRetrofitService.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/network/retrofit/NaviPayRetrofitService.kt
index 995a7d299b..957a55245e 100644
--- a/android/navi-pay/src/main/kotlin/com/navi/pay/network/retrofit/NaviPayRetrofitService.kt
+++ b/android/navi-pay/src/main/kotlin/com/navi/pay/network/retrofit/NaviPayRetrofitService.kt
@@ -8,6 +8,7 @@
package com.navi.pay.network.retrofit
import com.navi.common.network.models.GenericResponse
+import com.navi.pay.common.model.network.LitmusExperimentsResponse
import com.navi.pay.common.model.network.RequestIdResponse
import com.navi.pay.common.model.network.ValidateVpaRequest
import com.navi.pay.common.model.network.ValidateVpaResponse
@@ -396,4 +397,7 @@ interface NaviPayRetrofitService {
suspend fun sendMoneyAdditionalInfo(
@Body sendMoneyAdditionalInfoRequest: SendMoneyAdditionalInfoRequest
): Response>
+
+ @GET("/gateway-service/$NAVI_PAY_API_VERSION/navipay/user-experiments")
+ suspend fun fetchABTestingExperiments(): Response>
}
diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/utils/NaviPayConstants.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/utils/NaviPayConstants.kt
index d913805570..3b2724f175 100644
--- a/android/navi-pay/src/main/kotlin/com/navi/pay/utils/NaviPayConstants.kt
+++ b/android/navi-pay/src/main/kotlin/com/navi/pay/utils/NaviPayConstants.kt
@@ -153,6 +153,7 @@ const val DEFAULT_INITIATION_MODE_DYNAMIC_ATM_QR = "18"
// Navi Pay cache keys
const val NPCI_KEY = "npciKey"
+const val NAVI_PAY_LITMUS_EXPERIMENTS_CACHE_KEY = "NAVI_PAY_LITMUS_EXPERIMENTS_CACHE_KEY"
// Navi Common DB cache keys
const val NAVI_PAY_HOME_PAGE_CACHE_KEY = "naviPayHomePage"
@@ -163,6 +164,8 @@ const val NAVI_PAY_SYNC_TABLE_TRANSACTION_HISTORY_KEY = "transactionHistoryKey"
const val NAVI_PAY_SYNC_TABLE_LINKED_ACCOUNTS_KEY = "linkedAccountsKey"
const val NAVI_PAY_SYNC_TABLE_SAVED_BENEFICIARY_KEY = "savedBeneficiaryKey"
const val NAVI_PAY_SYNC_TABLE_FREQUENT_TRANSACTIONS_KEY = "frequentTransactionsKey"
+const val NAVI_PAY_LITMUS_EXPERIMENTS_LAST_REFRESHED_TIMESTAMP =
+ "litmusExperimentsLastRefreshedTimestamp"
// Generic
const val NAVIPAY_NETWORK_INFO_TIMEOUT = 65L