From 6124121f3137ca0df5ebcd28886d0a0a554e4d69 Mon Sep 17 00:00:00 2001 From: shankar yadav Date: Fri, 6 Dec 2024 16:45:18 +0530 Subject: [PATCH] NTP-7163 | Temporary changes for screen render time (#14019) --- .../InitInvestmentsScreenComponents.kt.kt | 1 - .../investmentTab/InitLifeCycleListener.kt | 2 + .../investmentTab/InvestmentsScreen.kt | 10 +++ .../dashboard/viewmodels/InvestmentsVm.kt | 5 ++ .../kyc/fragment/EmploymentDetailsFragment.kt | 4 ++ .../navi/amc/kyc/fragment/KycStartFragment.kt | 5 +- .../com/navi/amc/kyc/fragment/PanFragment.kt | 8 ++- .../kyc/fragment/PersonalDetailsFragment.kt | 4 ++ .../BillHistoryDetailsViewModel.kt | 7 +- .../ui/BillTransactionsListView.kt | 6 +- .../ui/MyBillHistoryDetailsScreen.kt | 14 +++- .../bbps/feature/mybills/MyBillsViewModel.kt | 3 +- .../bbps/feature/mybills/ui/MyBillsScreen.kt | 11 +++- .../checkmate/core/CheckMateLatencyMapper.kt | 66 +++++++++++++++---- .../common/checkmate/core/CheckMateManager.kt | 23 +++++-- .../sendmoney/viewmodel/SendMoneyViewModel.kt | 11 +++- .../nativepayment/viewmodel/MPSViewModel.kt | 7 +- .../viewmodel/NaviPaymentBaseVM.kt | 3 +- 18 files changed, 157 insertions(+), 33 deletions(-) diff --git a/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InitInvestmentsScreenComponents.kt.kt b/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InitInvestmentsScreenComponents.kt.kt index a433fcf7cc..4ce7b2913a 100644 --- a/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InitInvestmentsScreenComponents.kt.kt +++ b/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InitInvestmentsScreenComponents.kt.kt @@ -27,7 +27,6 @@ fun InitInvestmentsScreenComponents( investmentsScreenHelper = investmentsScreenHelper, bottomNavBarVM = bottomNavBarVM ) - LaunchedEffect(Unit) { investmentsTabVM.fireEvent( eventName = InvestmentTabEvents.INVESTMENT_TAB_INIT_LANDING_PAGE.eventName, diff --git a/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InitLifeCycleListener.kt b/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InitLifeCycleListener.kt index aeba6b43a8..00662ae8de 100644 --- a/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InitLifeCycleListener.kt +++ b/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InitLifeCycleListener.kt @@ -14,6 +14,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import com.naviapp.common.viewmodel.BottomNavBarVM import com.naviapp.home.dashboard.viewmodels.InvestmentsVm +import com.naviapp.utils.Constants.INVESTMENT_TAB_SCREEN_V3 @Composable fun InitLifeCycleListener( @@ -26,6 +27,7 @@ fun InitLifeCycleListener( val observer = LifecycleEventObserver { _, event -> when (event) { Lifecycle.Event.ON_RESUME -> { + investmentsTabVM.recordApiStartTime(INVESTMENT_TAB_SCREEN_V3) investmentsScreenHelper.refreshInvestmentTabScreen(investmentsTabVM) } Lifecycle.Event.ON_STOP -> { diff --git a/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InvestmentsScreen.kt b/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InvestmentsScreen.kt index ed4aa6c3b7..34fcf85b34 100644 --- a/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InvestmentsScreen.kt +++ b/android/app/src/main/java/com/naviapp/home/dashboard/ui/compose/investmentTab/InvestmentsScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.navi.common.model.ModuleNameV2 import com.navi.common.ui.errorview.FullScreenErrorComposeView import com.navi.common.utils.setStatusBarColorInt import com.navi.design.utils.parseColorSafe @@ -24,6 +25,7 @@ import com.naviapp.home.dashboard.ui.compose.investmentTab.InvestmentsTabShimmer import com.naviapp.home.dashboard.viewmodels.InvestmentsVm import com.naviapp.home.utils.InvestmentTabEvents import com.naviapp.home.viewmodel.SharedVM +import com.naviapp.utils.Constants.INVESTMENT_TAB_SCREEN_V3 @Composable fun InvestmentsScreen( @@ -70,6 +72,10 @@ fun InvestmentsScreen( investmentsScreenHelper = investmentsScreenHelper, bottomNavBarVM = bottomNavBarVM ) + investmentsTabVm.recordScreenRenderTime( + INVESTMENT_TAB_SCREEN_V3, + ModuleNameV2.AMC.name + ) } } is InvestmentsVm.InvestmentsTabScreenState.Error -> { @@ -77,6 +83,10 @@ fun InvestmentsScreen( error = investmentsScreenData.error, onRetryClick = { investmentsTabVm.fetchInvestmentTabScreen() } ) + investmentsTabVm.recordScreenRenderTime( + INVESTMENT_TAB_SCREEN_V3, + ModuleNameV2.AMC.name + ) } } } diff --git a/android/app/src/main/java/com/naviapp/home/dashboard/viewmodels/InvestmentsVm.kt b/android/app/src/main/java/com/naviapp/home/dashboard/viewmodels/InvestmentsVm.kt index b27e8523ca..32c485bd36 100644 --- a/android/app/src/main/java/com/naviapp/home/dashboard/viewmodels/InvestmentsVm.kt +++ b/android/app/src/main/java/com/naviapp/home/dashboard/viewmodels/InvestmentsVm.kt @@ -115,6 +115,10 @@ constructor( val bottomStickyNudgeData: StateFlow get() = _bottomStickyNudgeData + init { + recordScreenLandTime(INVESTMENT_TAB_SCREEN_V3) + } + fun setTimerChangeData(data: String?) { _cutOffTimerDataChange.value = data } @@ -212,6 +216,7 @@ constructor( val response = investmentsTabRepository.fetchInvestmentTabScreenResponse(screenName, metricInfo) if (response.isValidResponse()) { + recordApiEndTime(INVESTMENT_TAB_SCREEN_V3) response.data?.let { data -> _statusBarColor.emit(data.metaData?.get(STATUS_BAR_COLOR) ?: YELLOW_COLOR) data.bottomStickyNudgeData?.let { diff --git a/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/EmploymentDetailsFragment.kt b/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/EmploymentDetailsFragment.kt index 76e370ead6..2fd2a60ca7 100644 --- a/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/EmploymentDetailsFragment.kt +++ b/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/EmploymentDetailsFragment.kt @@ -32,6 +32,7 @@ import com.navi.base.utils.orTrue import com.navi.base.utils.orZero import com.navi.common.listeners.FragmentInterchangeListener import com.navi.common.listeners.HeaderInteractionListener +import com.navi.common.model.ModuleNameV2 import com.navi.common.model.UploadDataAsyncResponse import com.navi.common.ui.fragment.SingleSelectionBottomSheet import com.navi.common.utils.ApiPollScheduler @@ -74,12 +75,14 @@ class EmploymentDetailsFragment : AmcBaseFragment(), WidgetCallback, FooterInter private fun fetchData() { showLoader() + recordApiStartTime(screenName) viewModel.fetchData() viewModel.fetchTracker() } private fun initObservers() { viewModel.dataItems.observe(viewLifecycleOwner) { response -> + recordApiEndTime(screenName) hideLoader() setHeaderProperties(response?.header) hideDivider() @@ -90,6 +93,7 @@ class EmploymentDetailsFragment : AmcBaseFragment(), WidgetCallback, FooterInter adapter = FormAdapter(response?.content?.widgets.orEmpty(), this) binding.recycleView.layoutManager = LinearLayoutManager(requireContext()) binding.recycleView.adapter = adapter + recordScreenRenderTime(screenName, ModuleNameV2.AMC.name) } viewModel.postDataResponse.observe(viewLifecycleOwner) { response -> response?.requestId?.let { apiPollInit(response) } diff --git a/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/KycStartFragment.kt b/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/KycStartFragment.kt index a49f7adb61..1701b2b1f3 100644 --- a/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/KycStartFragment.kt +++ b/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/KycStartFragment.kt @@ -59,6 +59,7 @@ import com.navi.base.utils.orFalse import com.navi.common.CommonLibManager import com.navi.common.listeners.FragmentInterchangeListener import com.navi.common.listeners.HeaderInteractionListener +import com.navi.common.model.ModuleNameV2 import com.navi.common.model.UploadDataAsyncResponse import com.navi.common.network.models.GenericErrorResponse import com.navi.common.utils.ApiPollScheduler @@ -101,11 +102,13 @@ class KycStartFragment : AmcBaseFragment(), OKYCListener { private fun fetchData() { showLoader() + recordApiStartTime(screenName) viewModel.fetchData() } private fun initObservers() { viewModel.dataItems.observe(viewLifecycleOwner) { response -> + recordApiEndTime(screenName) hideLoader() response?.content?.optionsPageContent?.let { optionsContent -> val bundle = @@ -148,7 +151,7 @@ class KycStartFragment : AmcBaseFragment(), OKYCListener { arguments?.getParcelable(CheckerActivity.ERROR_DATA)?.let { viewModel.setErrorData(listOf(it)) } - + recordScreenRenderTime(screenName, ModuleNameV2.AMC.name) sendInitEvent() } viewModel.kycDigioConfig.observe(viewLifecycleOwner) { response -> diff --git a/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/PanFragment.kt b/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/PanFragment.kt index 9d9bab7e14..12a253b5e3 100644 --- a/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/PanFragment.kt +++ b/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/PanFragment.kt @@ -37,6 +37,7 @@ import com.navi.base.utils.isNotNullAndNotEmpty import com.navi.base.utils.orTrue import com.navi.common.listeners.FragmentInterchangeListener import com.navi.common.listeners.HeaderInteractionListener +import com.navi.common.model.ModuleNameV2 import com.navi.common.network.models.GenericErrorResponse import com.navi.design.utils.* import com.navi.naviwidgets.adapters.FormAdapter @@ -85,6 +86,7 @@ class PanFragment : AmcBaseFragment(), WidgetCallback, FooterInteractionListener private fun fetchData() { showLoader() + recordApiStartTime(screenName) when (pageType) { SubPageStatusType.PAN -> viewModel.fetchData() SubPageStatusType.NAME, @@ -95,7 +97,11 @@ class PanFragment : AmcBaseFragment(), WidgetCallback, FooterInteractionListener } private fun initObservers() { - viewModel.panItems.observe(viewLifecycleOwner) { response -> renderUI(response) } + viewModel.panItems.observe(viewLifecycleOwner) { response -> + recordApiEndTime(screenName) + renderUI(response) + recordScreenRenderTime(screenName, ModuleNameV2.AMC.name) + } viewModel.postData.observe(viewLifecycleOwner) { hideLoader() fragmentInterchangeListener?.navigateToNextScreen( diff --git a/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/PersonalDetailsFragment.kt b/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/PersonalDetailsFragment.kt index 3a027db9b5..46fb3cea92 100644 --- a/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/PersonalDetailsFragment.kt +++ b/android/navi-amc/src/main/java/com/navi/amc/kyc/fragment/PersonalDetailsFragment.kt @@ -46,6 +46,7 @@ import com.navi.base.utils.orFalse import com.navi.base.utils.orTrue import com.navi.common.listeners.FragmentInterchangeListener import com.navi.common.listeners.HeaderInteractionListener +import com.navi.common.model.ModuleNameV2 import com.navi.common.model.UploadDataAsyncResponse import com.navi.common.pushnotification.NotificationConstants import com.navi.common.utils.ApiPollScheduler @@ -89,11 +90,13 @@ class PersonalDetailsFragment : private fun fetchData() { showLoader() + recordApiStartTime(screenName) viewModel.fetchData() } private fun initObservers() { viewModel.dataItems.observe(viewLifecycleOwner) { response -> + recordApiEndTime(screenName) hideLoader() setHeaderProperties(response?.header) hideDivider() @@ -115,6 +118,7 @@ class PersonalDetailsFragment : view?.let { (it as LabeledTextInputWidgetV2).setListener { populateEmail() } } } } + recordScreenRenderTime(screenName, ModuleNameV2.AMC.name) } viewModel.postDataResponse.observe(viewLifecycleOwner) { response -> response?.requestId?.let { apiPollInit(response) } diff --git a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/BillHistoryDetailsViewModel.kt b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/BillHistoryDetailsViewModel.kt index d47acbf643..9cce31cbb9 100644 --- a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/BillHistoryDetailsViewModel.kt +++ b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/BillHistoryDetailsViewModel.kt @@ -150,8 +150,12 @@ constructor( stringResouceProvider.getString(R.string.bbps_new_contact) init { + recordScreenLandTime(screen = naviBbpsVmData.screen.screenName) viewModelScope.launch(dispatcherProvider.io) { - launch { fetchBillHistoryList() } + launch { + recordApiStartTime(screen = naviBbpsVmData.screen.screenName) + fetchBillHistoryList() + } launch { naviBbpsDefaultConfig = naviBbpsConfigUseCase.getDefaultConfig(naviBbpsVmData.screen.screenName) @@ -204,7 +208,6 @@ constructor( savedBillId = myBillEntity.billId, metricInfo = getBbpsMetricInfo(screenName = naviBbpsVmData.screen.screenName) ) - if (billTransactionsResponse.isSuccessWithData()) { val transactions = billTransactionsResponse.data!!.transactions.orEmpty() _billHistoryDetailsState.update { diff --git a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/ui/BillTransactionsListView.kt b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/ui/BillTransactionsListView.kt index b1db59c8ef..3b2cd8d371 100644 --- a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/ui/BillTransactionsListView.kt +++ b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/ui/BillTransactionsListView.kt @@ -40,11 +40,14 @@ import com.navi.naviwidgets.extensions.NaviText @Composable fun BillTransactionsListView( billHistoryDetailsState: BillTransactionsState, - onItemClicked: (BillTransactionItemEntity) -> Unit + onItemClicked: (BillTransactionItemEntity) -> Unit, + recordScreenRenderTime: () -> Unit, + recordApiEndTime: () -> Unit ) { when (billHistoryDetailsState) { is BillTransactionsState.Loading -> MyBillsTransactionsShimmer() is BillTransactionsState.Loaded -> { + recordApiEndTime() NaviText( modifier = Modifier.padding(horizontal = NaviBbpsDimens.horizontalMargin), text = stringResource(id = R.string.bbps_bill_payment_history), @@ -66,6 +69,7 @@ fun BillTransactionsListView( } } } + recordScreenRenderTime() } is BillTransactionsState.Empty -> {} is BillTransactionsState.Error -> {} diff --git a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/ui/MyBillHistoryDetailsScreen.kt b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/ui/MyBillHistoryDetailsScreen.kt index ee66641f32..c9fcdeff97 100644 --- a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/ui/MyBillHistoryDetailsScreen.kt +++ b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/billhistorydetail/ui/MyBillHistoryDetailsScreen.kt @@ -56,6 +56,7 @@ import com.navi.bbps.feature.billhistorydetail.model.view.BillTransactionItemEnt import com.navi.bbps.feature.mybills.model.view.MyBillEntity import com.navi.common.R as CommonR import com.navi.common.customview.LoaderRoundedButton +import com.navi.common.model.ModuleNameV2 import com.navi.design.font.FontWeightEnum import com.navi.design.font.getFontWeight import com.navi.design.font.naviFontFamily @@ -243,7 +244,18 @@ fun MyBillHistoryDetailsScreen( ) BillTransactionsListView( billHistoryDetailsState = billHistoryDetailsState, - onItemClicked = onTransactionItemClicked + onItemClicked = onTransactionItemClicked, + recordScreenRenderTime = { + billHistoryDetailsViewModel.recordScreenRenderTime( + billHistoryDetailsViewModel.naviBbpsVmData.screen.screenName, + ModuleNameV2.BBPS.name + ) + }, + recordApiEndTime = { + billHistoryDetailsViewModel.recordApiEndTime( + billHistoryDetailsViewModel.naviBbpsVmData.screen.screenName, + ) + } ) } }, diff --git a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/mybills/MyBillsViewModel.kt b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/mybills/MyBillsViewModel.kt index de19d2255b..d91c992c7e 100644 --- a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/mybills/MyBillsViewModel.kt +++ b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/mybills/MyBillsViewModel.kt @@ -104,6 +104,7 @@ constructor( private var naviBbpsDefaultConfig = NaviBbpsDefaultConfig() init { + recordScreenLandTime(screen = naviBbpsVmData.screen.screenName) initConfig() fetchMySavedBills() } @@ -136,7 +137,7 @@ constructor( val isBillReminderEnabled = isBillReminderEnabled() naviBbpsAnalytics.onVmInit(isBillReminderEnabled = isBillReminderEnabled) - + recordApiStartTime(screen = naviBbpsVmData.screen.screenName) myBillsRepository.fetchMySavedBills().collect { myBillEntities -> val myUnpaidBills = if (isBillReminderEnabled) myBillEntities.filter { it.isBillPaid.not() } diff --git a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/mybills/ui/MyBillsScreen.kt b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/mybills/ui/MyBillsScreen.kt index 6b1f5923e6..924a21fc54 100644 --- a/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/mybills/ui/MyBillsScreen.kt +++ b/android/navi-bbps/src/main/kotlin/com/navi/bbps/feature/mybills/ui/MyBillsScreen.kt @@ -38,6 +38,7 @@ import com.navi.bbps.feature.destinations.MyBillHistoryDetailsScreenDestination import com.navi.bbps.feature.mybills.MyBillsViewModel import com.navi.bbps.feature.mybills.model.view.MyBillEntity import com.navi.bbps.feature.mybills.model.view.MyBillsState +import com.navi.common.model.ModuleNameV2 import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.result.NavResult @@ -174,7 +175,10 @@ fun MyBillsScreen( ) { when (myBillsState) { MyBillsState.Loading -> MyBillsShimmer() - is MyBillsState.Loaded -> + is MyBillsState.Loaded -> { + myBillsViewModel.recordApiEndTime( + myBillsViewModel.naviBbpsVmData.screen.screenName + ) RenderMyBillsScreen( isBillReminderEnabled = (myBillsState as MyBillsState.Loaded).isBillReminderEnabled, @@ -197,6 +201,11 @@ fun MyBillsScreen( }, onBillMarkAsPaidClicked = onBillMarkAsPaidClicked, ) + myBillsViewModel.recordScreenRenderTime( + myBillsViewModel.naviBbpsVmData.screen.screenName, + ModuleNameV2.BBPS.name + ) + } is MyBillsState.Empty -> { RenderEmptyMyBillsScreen( naviBbpsAnalytics = naviBbpsAnalytics, diff --git a/android/navi-common/src/main/java/com/navi/common/checkmate/core/CheckMateLatencyMapper.kt b/android/navi-common/src/main/java/com/navi/common/checkmate/core/CheckMateLatencyMapper.kt index b82e488047..f805598898 100644 --- a/android/navi-common/src/main/java/com/navi/common/checkmate/core/CheckMateLatencyMapper.kt +++ b/android/navi-common/src/main/java/com/navi/common/checkmate/core/CheckMateLatencyMapper.kt @@ -7,29 +7,71 @@ package com.navi.common.checkmate.core -import com.navi.common.checkmate.model.MetricInfo +import com.navi.base.utils.orZero interface CheckMateMapper { fun recordScreenLandTime(screen: String) - fun recordScreenRenderLatency(metricInfo: MetricInfo) + fun recordApiStartTime(screen: String) + + fun recordApiEndTime(screen: String, source: DataSource = DataSource.Backend) + + fun recordScreenRenderTime(screen: String, vertical: String) } object CheckMateLatencyMapper : CheckMateMapper { - private val latencyMap: MutableMap = mutableMapOf() + private val screenLandTimeMap: MutableMap = mutableMapOf() + private val apiStartTimeMap: MutableMap = mutableMapOf() + private val apiEndTimeMap: MutableMap = mutableMapOf() + private val dataSource: MutableMap = mutableMapOf() override fun recordScreenLandTime(screen: String) { - latencyMap[screen] = System.currentTimeMillis() + screenLandTimeMap[screen] = System.currentTimeMillis() } - override fun recordScreenRenderLatency(metricInfo: MetricInfo) { - val screenStartTime = latencyMap[metricInfo.screen] - if (screenStartTime != null) { - latencyMap.remove(metricInfo.screen) - CheckMateManager.logScreenLatencyEvent( - metricInfo = metricInfo, - latency = System.currentTimeMillis() - screenStartTime - ) + override fun recordApiStartTime(screen: String) { + if (screenLandTimeMap[screen] != null && apiStartTimeMap[screen] == null) { + apiStartTimeMap[screen] = System.currentTimeMillis() } } + + override fun recordApiEndTime(screen: String, source: DataSource) { + if (apiStartTimeMap[screen] != null && apiEndTimeMap[screen] == null) { + apiEndTimeMap[screen] = System.currentTimeMillis() + dataSource[screen] = source.name + } + } + + override fun recordScreenRenderTime(screen: String, vertical: String) { + if ( + screenLandTimeMap[screen] == null || + apiStartTimeMap[screen] == null || + apiEndTimeMap[screen] == null + ) + return + + val screenLandTime = screenLandTimeMap[screen].orZero() + val apiStartTime = apiStartTimeMap[screen].orZero() + val apiEndTime = apiEndTimeMap[screen].orZero() + val source = dataSource[screen].orEmpty() + screenLandTimeMap.remove(screen) + apiStartTimeMap.remove(screen) + apiEndTimeMap.remove(screen) + + CheckMateManager.logScreenLatencyEvent( + screen = screen, + vertical = vertical, + source = source, + apiStartDelayTime = apiStartTime - screenLandTime, + apiE2ELatency = apiEndTime - apiStartTime, + uIRenderLatency = System.currentTimeMillis() - apiEndTime, + screenE2ELatency = System.currentTimeMillis() - screenLandTime + ) + } +} + +enum class DataSource { + Backend, + DB, + Memory } diff --git a/android/navi-common/src/main/java/com/navi/common/checkmate/core/CheckMateManager.kt b/android/navi-common/src/main/java/com/navi/common/checkmate/core/CheckMateManager.kt index 68a77f2fba..2466a595fd 100644 --- a/android/navi-common/src/main/java/com/navi/common/checkmate/core/CheckMateManager.kt +++ b/android/navi-common/src/main/java/com/navi/common/checkmate/core/CheckMateManager.kt @@ -131,15 +131,26 @@ object CheckMateManager { ) } - fun logScreenLatencyEvent(metricInfo: MetricInfo, latency: Long) { + fun logScreenLatencyEvent( + screen: String, + vertical: String, + source: String, + apiStartDelayTime: Long, + apiE2ELatency: Long, + uIRenderLatency: Long, + screenE2ELatency: Long + ) { NaviTrackEvent.trackEventOnClickStream( - eventName = - getEventNameWithVerticalPrefix("screen_latency_metric", metricInfo.vertical), + eventName = getEventNameWithVerticalPrefix("screen_latency_metric", vertical), eventValues = mapOf( - "vertical" to metricInfo.vertical, - "screen" to metricInfo.screen, - "latency" to latency.toString(), + "vertical" to vertical, + "screen" to screen, + "source" to source, + "apiStartDelayTime" to apiStartDelayTime.toString(), + "apiE2ELatency" to apiE2ELatency.toString(), + "uIRenderLatency" to uIRenderLatency.toString(), + "screenE2ELatency" to screenE2ELatency.toString(), "alfredSessionId" to AlfredManager.getAlfredSessionId() ) ) diff --git a/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/sendmoney/viewmodel/SendMoneyViewModel.kt b/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/sendmoney/viewmodel/SendMoneyViewModel.kt index 459c1f06c1..6a64a74d76 100644 --- a/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/sendmoney/viewmodel/SendMoneyViewModel.kt +++ b/android/navi-pay/src/main/kotlin/com/navi/pay/management/common/sendmoney/viewmodel/SendMoneyViewModel.kt @@ -24,12 +24,14 @@ import com.navi.base.utils.isNotNull import com.navi.base.utils.isNotNullAndNotEmpty import com.navi.base.utils.orFalse import com.navi.common.R as CommonR +import com.navi.common.checkmate.core.DataSource import com.navi.common.di.CoroutineDispatcherProvider import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_PAY_REMOVE_APP_ON_INTENT_PAYMENT_SUCCESS import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_PAY_REMOVE_TASK_ON_INTENT_PAYMENT_SUCCESS import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_PAY_SCRATCH_CARD_OPTIMISATION_V2_ENABLED import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper.NAVI_PAY_UPI_LITE_LOW_BALANCE_NOTIFICATION_PN_DISABLED +import com.navi.common.model.ModuleNameV2 import com.navi.common.network.models.RepoResult import com.navi.common.network.models.isSuccess import com.navi.common.network.models.isSuccessWithData @@ -522,6 +524,7 @@ constructor( private val isLiteAutoTopUpExperimentEnabled = MutableStateFlow(false) init { + recordScreenLandTime(screenName) setLitmusExperimentValues() updateNaviPayDefaultConfig() updateUPILiteConfig() @@ -1867,8 +1870,9 @@ constructor( isPayeeVerified = payeeEntity.value.isVerifiedVpa, naviPaySessionAttributes = getNaviPaySessionAttributes() ) - + recordApiStartTime(screenName) if (payeeEntity.value.isVerifiedVpa) { + recordApiEndTime(screenName, DataSource.Memory) onVpaValidationSuccess() return true } @@ -1895,7 +1899,7 @@ constructor( transactionType = transactionType, naviPaySessionAttributes = getNaviPaySessionAttributes() ) - + recordApiEndTime(screenName) if (validateVpaAPIResponse.isSuccessWithData()) { updatePayeeEntity( payeeEntity = @@ -1915,6 +1919,7 @@ constructor( isNpciData = validateVpaAPIResponse.data!!.isNpciData ) ) + recordScreenRenderTime(screenName, ModuleNameV2.NAVIPAY.name) onVpaValidationSuccess() return true } else { @@ -1947,7 +1952,7 @@ constructor( } else { notifyError(response = validateVpaAPIResponse, cancelable = false, tag = errorTag) } - + recordScreenRenderTime(screenName, ModuleNameV2.NAVIPAY.name) triggerKeyboardVisibility(visibility = false) return false } diff --git a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/MPSViewModel.kt b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/MPSViewModel.kt index 12295fc310..cc893c95ae 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/MPSViewModel.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/MPSViewModel.kt @@ -22,6 +22,7 @@ import com.navi.base.utils.orTrue import com.navi.base.utils.orZero import com.navi.common.checkmate.core.CheckMateManager import com.navi.common.checkmate.model.MetricInfo +import com.navi.common.model.ModuleNameV2 import com.navi.common.network.models.isSuccessWithData import com.navi.common.upi.UpiDataType import com.navi.common.utils.toJsonObject @@ -190,6 +191,7 @@ constructor( init { recordScreenLandTime(screenName) + recordApiStartTime(screenName) initSdkInitParams() getPaymentMethodData() viewModelScope.launch(Dispatchers.IO) { getNaviUpiConnectedAccounts() } @@ -217,6 +219,7 @@ constructor( paymentDataProvider.getAndRemove(PaymentDataProvider.ERROR_RESPONSE) as PaymentErrorData? errorData?.let { + recordApiEndTime(screenName) updateBottomSheetUIState( showBottomSheet = true, bottomSheetUIState = @@ -229,7 +232,7 @@ constructor( ), bottomSheetStateChange = true ) - + recordScreenRenderTime(screenName, ModuleNameV2.PG.name) delay(500) isDismissAllowed = true } @@ -242,7 +245,9 @@ constructor( paymentDataProvider.get(PaymentDataProvider.ACTION_TYPE) == PaymentMethodType.S2S_INTEGRATION.name ) { + recordApiEndTime(screenName) refreshUI(data) + recordScreenRenderTime(screenName, ModuleNameV2.PG.name) } else { _npsRedirection.update { true } } diff --git a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/NaviPaymentBaseVM.kt b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/NaviPaymentBaseVM.kt index 6b4f56a2ed..ad4e6cee8c 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/NaviPaymentBaseVM.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/nativepayment/viewmodel/NaviPaymentBaseVM.kt @@ -8,7 +8,6 @@ package com.navi.payment.nativepayment.viewmodel import androidx.lifecycle.viewModelScope -import com.navi.common.checkmate.model.MetricInfo import com.navi.common.model.ModuleNameV2 import com.navi.common.network.models.ErrorMessage import com.navi.common.network.models.GenericErrorResponse @@ -115,7 +114,7 @@ abstract class NaviPaymentBaseVM(open val screenName: String) : BaseVM() { } fun recordScreenLatency(screenName: String) { - recordScreenRenderLatency(metricInfo = MetricInfo.PMSMetric(screen = screenName)) + recordScreenRenderTime(screenName, ModuleNameV2.PG.name) } companion object {