diff --git a/android/app/src/main/java/com/naviapp/app/initializers/AppLifecycleManagerInitializer.kt b/android/app/src/main/java/com/naviapp/app/initializers/AppLifecycleManagerInitializer.kt index 8ec652828a..0c72a74d66 100644 --- a/android/app/src/main/java/com/naviapp/app/initializers/AppLifecycleManagerInitializer.kt +++ b/android/app/src/main/java/com/naviapp/app/initializers/AppLifecycleManagerInitializer.kt @@ -8,14 +8,11 @@ package com.naviapp.app.initializers import android.app.Activity -import android.os.Build import android.os.Bundle import android.view.WindowManager import com.navi.analytics.utils.NaviTrackEvent -import com.navi.base.sharedpref.PreferenceManager import com.navi.base.utils.AppLaunchUtils import com.navi.base.utils.coroutine.CoroutineManager -import com.navi.base.utils.isNull import com.navi.chat.base.ChatBaseActivity import com.navi.common.NaviActivityLifecycleCallbacks import com.navi.common.checkmate.core.CheckMateManager @@ -28,8 +25,6 @@ import com.navi.common.resourcemanager.manager.ResourceManager import com.navi.common.ui.activity.BaseActivity import com.navi.common.utils.BiometricPromptUtils import com.navi.common.utils.CommonUtils.isQaRelease -import com.navi.common.utils.Constants.ScreenLockConstants.ENABLED -import com.navi.common.utils.Constants.ScreenLockConstants.IS_SCREEN_LOCK_ENABLED import com.navi.insurance.health.activity.BaseActivity as InsuranceBaseActivity import com.navi.pay.common.setup.NaviPayManager import com.naviapp.analytics.utils.NaviAnalytics.Companion.EXTERNAL @@ -66,16 +61,6 @@ constructor( if (activity is HomePageActivity) { AppLaunchUtils.resetAppOpenOnLaunch() } - CoroutineScope(Dispatchers.IO).launch { - if ( - Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && - PreferenceManager.getStringPreference(IS_SCREEN_LOCK_ENABLED) - .isNull() && - BiometricPromptUtils().isDeviceSecure(application) - ) { - PreferenceManager.setStringPreference(IS_SCREEN_LOCK_ENABLED, ENABLED) - } - } } override fun onActivityStarted(activity: Activity) { @@ -163,7 +148,6 @@ constructor( application.decrementAppInForeground() if (application.getAppInForegroundCounter() == 0) { - BiometricPromptUtils.appInBackgroundTimeStamp = System.currentTimeMillis() startSessionDetails?.let { initSessionDetails -> CoroutineScope(Dispatchers.IO).launch { val endSessionDetails = getCurrentSessionMetrics(application) @@ -200,6 +184,7 @@ constructor( eventName = NAVIAPP_BACKGROUND_PUSH, mapOf("screenName" to screenName), ) + BiometricPromptUtils.appInBackgroundTimeStamp = System.currentTimeMillis() } } } diff --git a/android/app/src/main/java/com/naviapp/home/compose/activity/HomePageActivity.kt b/android/app/src/main/java/com/naviapp/home/compose/activity/HomePageActivity.kt index fdbda71d55..2ee85f3d60 100644 --- a/android/app/src/main/java/com/naviapp/home/compose/activity/HomePageActivity.kt +++ b/android/app/src/main/java/com/naviapp/home/compose/activity/HomePageActivity.kt @@ -64,6 +64,7 @@ import com.navi.common.model.common.NetworkConnectivityNudgeData import com.navi.common.network.models.GenericErrorResponse import com.navi.common.resourcemanager.manager.ResourceManager import com.navi.common.utils.ApiPollScheduler +import com.navi.common.utils.BiometricPromptUtils import com.navi.common.utils.BiometricPromptUtils.Companion.getScreenLockEventName import com.navi.common.utils.CommonNaviAnalytics import com.navi.common.utils.Constants.IN_APP_UPDATE_REQUEST_CODE @@ -71,7 +72,6 @@ import com.navi.common.utils.Constants.NAVI_PAY_SECTION_GLANCE_WIDGET_SCREEN import com.navi.common.utils.Constants.SUB_REDIRECT import com.navi.common.utils.Constants.ScreenLockConstants.DISABLED import com.navi.common.utils.Constants.ScreenLockConstants.ENABLED -import com.navi.common.utils.Constants.ScreenLockConstants.HPC_SCREEN_LOCK_EXPERIMENT import com.navi.common.utils.Constants.ScreenLockConstants.IS_SCREEN_LOCK_ENABLED import com.navi.common.utils.TemporaryStorageHelper import com.navi.common.utils.getDeviceSignature @@ -535,9 +535,10 @@ class HomePageActivity : observeGIPaymentFailed() observeNetworkConnectivity() observeLoansTabPaymentData() - observeScreenLockEnabledData() + observeScreenLockToggleData() observeCollectRequestFromPn() observeScreenOverlayEffect() + observeScreenLockEnableStatus() } private fun observeScreenOverlayEffect() { @@ -588,6 +589,28 @@ class HomePageActivity : } } + private fun observeScreenLockEnableStatus() { + lifecycleScope.launch(Dispatchers.IO) { + homeVM.handle.getStateFlow(IS_SCREEN_LOCK_ENABLED, null).collect { state -> + when (state) { + ENABLED -> { + if ( + PreferenceManager.getStringPreference(IS_SCREEN_LOCK_ENABLED) == null && + biometricPromptUtils.isDeviceSecure(this@HomePageActivity) + ) { + BiometricPromptUtils().reset() + PreferenceManager.setStringPreference(IS_SCREEN_LOCK_ENABLED, ENABLED) + } + } + DISABLED -> { + BiometricPromptUtils().reset() + PreferenceManager.setStringPreference(IS_SCREEN_LOCK_ENABLED, DISABLED) + } + } + } + } + } + private fun observeCollectRequestFromPn() { lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { @@ -603,17 +626,20 @@ class HomePageActivity : } } - private fun observeScreenLockEnabledData() { + private fun observeScreenLockToggleData() { lifecycleScope.launch(Dispatchers.IO) { repeatOnLifecycle(state = Lifecycle.State.STARTED) { - profileVM.isScreenLockToggled.collect { isScreenLockToggled -> + profileVM.handle.getStateFlow(IS_SCREEN_LOCK_ENABLED, null).collect { + isScreenLockToggled -> NaviTrackEvent.trackEventOnClickStream( eventName = - getScreenLockEventName(eventType = ::observeScreenLockEnabledData.name) + getScreenLockEventName(eventType = ::observeScreenLockToggleData.name) ) isScreenLockToggled?.let { profileVM.canCachedDataBeUsed = false - PreferenceManager.setStringPreference(IS_SCREEN_LOCK_ENABLED, it) + if (PreferenceManager.getStringPreference(IS_SCREEN_LOCK_ENABLED) != it) + PreferenceManager.setStringPreference(IS_SCREEN_LOCK_ENABLED, it) + else return@collect biometricPromptUtils.reset() } if ( @@ -907,13 +933,11 @@ class HomePageActivity : if (fetchDataDisabled.not()) { profileVM.fetchProfileItems( isScreenLockEnabled = - FirebaseRemoteConfigHelper.getBoolean(IS_SCREEN_LOCK_ENABLED) && - PreferenceManager.getStringPreference(HPC_SCREEN_LOCK_EXPERIMENT) == - ENABLED, + FirebaseRemoteConfigHelper.getBoolean(IS_SCREEN_LOCK_ENABLED), isMobileScreenLockSet = biometricPromptUtils.isDeviceSecure(this@HomePageActivity) && - PreferenceManager.getStringPreference(IS_SCREEN_LOCK_ENABLED) != - DISABLED, + PreferenceManager.getStringPreference(IS_SCREEN_LOCK_ENABLED) == + ENABLED, naeScreenName = screenName, isProfileDrawerOpen = isProfileDrawerOpen, ) diff --git a/android/app/src/main/java/com/naviapp/home/viewmodel/ProfileVM.kt b/android/app/src/main/java/com/naviapp/home/viewmodel/ProfileVM.kt index e1bda8afe5..8895246164 100644 --- a/android/app/src/main/java/com/naviapp/home/viewmodel/ProfileVM.kt +++ b/android/app/src/main/java/com/naviapp/home/viewmodel/ProfileVM.kt @@ -21,7 +21,6 @@ import com.navi.common.network.models.RepoResult import com.navi.common.utils.BiometricPromptUtils import com.navi.common.utils.Constants.ScreenLockConstants.DISABLED import com.navi.common.utils.Constants.ScreenLockConstants.ENABLED -import com.navi.common.utils.Constants.ScreenLockConstants.HPC_SCREEN_LOCK_EXPERIMENT import com.navi.common.utils.Constants.ScreenLockConstants.IS_SCREEN_LOCK_ENABLED import com.navi.common.utils.Constants.ScreenLockConstants.TOGGLE_SWITCH_CHECKED_STATE import com.navi.common.utils.Constants.ScreenLockConstants.TOGGLE_SWITCH_LAYOUT_ID @@ -44,9 +43,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.update @@ -67,9 +64,6 @@ constructor( MutableStateFlow(ProfileScreenState.Loading) val profileScreenDataState = _profileScreenDataState.asStateFlow() - private val _isScreenLockToggled = MutableSharedFlow() - val isScreenLockToggled = _isScreenLockToggled.asSharedFlow() - private lateinit var cacheResponse: ScreenDefinition var canCachedDataBeUsed: Boolean = true @@ -93,13 +87,11 @@ constructor( } else { getProfileResponseFromApi( isScreenLockEnabled = - FirebaseRemoteConfigHelper.getBoolean(IS_SCREEN_LOCK_ENABLED) && - PreferenceManager.getStringPreference(HPC_SCREEN_LOCK_EXPERIMENT) == - ENABLED, + FirebaseRemoteConfigHelper.getBoolean(IS_SCREEN_LOCK_ENABLED), isMobileScreenLockSet = biometricPromptUtils.isDeviceSecure(context) && - PreferenceManager.getStringPreference(IS_SCREEN_LOCK_ENABLED) != - DISABLED, + PreferenceManager.getStringPreference(IS_SCREEN_LOCK_ENABLED) == + ENABLED, naeScreenName = NaviAnalytics.NEW_HOME_ACTIVITY, isNaeRequired = false, ) @@ -108,7 +100,6 @@ constructor( } private fun initListeners() { - observeScreenToggleDataFromHandle() observeBiometricAuthenticationEnabledStatus() observeEmailSuccess() } @@ -128,14 +119,6 @@ constructor( } } - private fun observeScreenToggleDataFromHandle() { - viewModelScope.launch(Dispatchers.IO) { - handle.getStateFlow(IS_SCREEN_LOCK_ENABLED, null).collect { state -> - _isScreenLockToggled.emit(state) - } - } - } - private fun observeBiometricAuthenticationEnabledStatus() { viewModelScope.launch(Dispatchers.IO) { BiometricPromptUtils.isBiometricAuthenticationEnabled.collect { state -> @@ -162,6 +145,7 @@ constructor( } fun enabledToggle() { + PreferenceManager.setStringPreference(IS_SCREEN_LOCK_ENABLED, ENABLED) handle[IS_SCREEN_LOCK_ENABLED] = ENABLED handleActions( UiTronActionData( diff --git a/android/app/src/main/java/com/naviapp/launcher/ui/BaseLauncherActivity.kt b/android/app/src/main/java/com/naviapp/launcher/ui/BaseLauncherActivity.kt index 4caf9d2448..7c8602d193 100644 --- a/android/app/src/main/java/com/naviapp/launcher/ui/BaseLauncherActivity.kt +++ b/android/app/src/main/java/com/naviapp/launcher/ui/BaseLauncherActivity.kt @@ -12,15 +12,12 @@ import android.os.Bundle import androidx.lifecycle.ViewModelProvider import com.navi.analytics.utils.NaviTrackEvent import com.navi.analytics.utils.NaviTrackEvent.trackEventOnClickStream -import com.navi.base.sharedpref.PreferenceManager import com.navi.base.utils.BaseUtils -import com.navi.base.utils.isNull import com.navi.base.utils.orTrue import com.navi.common.constants.APP_UPGRADE_DATA import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper import com.navi.common.model.AppUpgradeResponse import com.navi.common.ui.activity.BaseActivity -import com.navi.common.utils.Constants.ScreenLockConstants.HPC_SCREEN_LOCK_EXPERIMENT import com.navi.common.utils.observeNonNull import com.navi.common.utils.observeNullable import com.navi.insurance.util.Constants.CLICKED @@ -72,7 +69,6 @@ abstract class BaseLauncherActivity : BaseActivity() { uploadAnalyticsData() updateFcmToken() updateMarketingDataToSaphyra() - fetchScreenLockExperiment() } fun initJuspaySDK() { @@ -103,15 +99,6 @@ abstract class BaseLauncherActivity : BaseActivity() { launcherVM.fetchLoginSettings(naeScreenName = screenName) } - private fun fetchScreenLockExperiment() { - if ( - BaseUtils.isUserLoggedIn() && - PreferenceManager.getStringPreference(HPC_SCREEN_LOCK_EXPERIMENT).isNull() - ) { - launcherVM.fetchABExperiment(HPC_SCREEN_LOCK_EXPERIMENT) - } - } - private fun setFirebaseAppInstanceId() { launcherVM.setFirebaseAppInstanceId() } diff --git a/android/app/src/main/java/com/naviapp/launcher/vm/LauncherVM.kt b/android/app/src/main/java/com/naviapp/launcher/vm/LauncherVM.kt index f3b311682a..6feb9043b3 100644 --- a/android/app/src/main/java/com/naviapp/launcher/vm/LauncherVM.kt +++ b/android/app/src/main/java/com/naviapp/launcher/vm/LauncherVM.kt @@ -24,15 +24,11 @@ import com.navi.base.sharedpref.CommonPrefConstants.PREVIOUS_APPSFLYER_ID import com.navi.base.sharedpref.CommonPrefConstants.PREVIOUS_GOOGLE_ADVERTISEMENT_ID import com.navi.base.sharedpref.PreferenceManager import com.navi.base.utils.BaseUtils -import com.navi.base.utils.isNotNull import com.navi.base.utils.orFalse import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper import com.navi.common.managers.NaviLocationManager import com.navi.common.model.CommunicationAppLaunchData import com.navi.common.utils.Constants.SAPHYRA_APP_LOGIN_EVENT -import com.navi.common.utils.Constants.ScreenLockConstants.DISABLED -import com.navi.common.utils.Constants.ScreenLockConstants.ENABLED -import com.navi.common.utils.Constants.ScreenLockConstants.HPC_SCREEN_LOCK_EXPERIMENT import com.navi.common.utils.deviceId import com.navi.common.utils.getAppsflyerUid import com.navi.common.utils.isValidResponse @@ -250,23 +246,4 @@ constructor( } } } - - fun fetchABExperiment(experimentName: String) { - viewModelScope.launch(Dispatchers.IO) { - val response = configRepository.fetchABExperiment(experimentName) - - if (response.isSuccessful && response.body()?.result.isNotNull()) { - val experimentResult = - response.body()?.result?.let { - when (it) { - true -> ENABLED - false -> DISABLED - } - } - experimentResult?.let { result -> - PreferenceManager.setStringPreference(HPC_SCREEN_LOCK_EXPERIMENT, result) - } - } - } - } } diff --git a/android/navi-common/src/main/java/com/navi/common/ui/dialog/NaviLockScreenDialog.kt b/android/navi-common/src/main/java/com/navi/common/ui/dialog/NaviLockScreenDialog.kt index 4763ad834f..d1bd001001 100644 --- a/android/navi-common/src/main/java/com/navi/common/ui/dialog/NaviLockScreenDialog.kt +++ b/android/navi-common/src/main/java/com/navi/common/ui/dialog/NaviLockScreenDialog.kt @@ -9,6 +9,7 @@ package com.navi.common.ui.dialog import android.os.Bundle import android.view.ViewStub +import android.view.WindowManager import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -16,12 +17,14 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -36,6 +39,8 @@ import androidx.databinding.DataBindingUtil import com.navi.common.R import com.navi.common.databinding.NaviLockScreenDialogBinding import com.navi.common.ui.fragment.BaseBottomSheet +import com.navi.common.utils.BiometricAuthenticationStatus +import com.navi.common.utils.BiometricPromptUtils import com.navi.design.font.FontWeightEnum import com.navi.design.font.getFontWeight import com.navi.design.font.naviFontFamily @@ -60,12 +65,6 @@ class NaviLockScreenDialog : BaseBottomSheet() { } override fun setContainerView(viewStub: ViewStub) { - setBackgroundTint( - ContextCompat.getColor( - requireContext(), - com.navi.design.R.color.translucent_blue_midnight, - ) - ) viewStub.layoutResource = R.layout.navi_lock_screen_dialog binding = DataBindingUtil.getBinding(viewStub.inflate())!! initUI() @@ -77,62 +76,89 @@ class NaviLockScreenDialog : BaseBottomSheet() { @Composable fun LockScreen() { - Box(modifier = Modifier.fillMaxWidth().wrapContentSize()) { - Column( - modifier = - Modifier.fillMaxWidth() - .align(Alignment.BottomCenter) - .background( - color = Color.White, - shape = RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp), - ) - .padding(all = 16.dp) - ) { - Image( - painter = painterResource(id = R.drawable.ic_purple_lock), - contentDescription = null, + val showDialog = + remember(BiometricPromptUtils.biometricAuthenticationStatus.value) { + mutableStateOf( + BiometricPromptUtils.biometricAuthenticationStatus.value == + BiometricAuthenticationStatus.FAILED ) - Text( - modifier = Modifier.padding(top = 8.dp), - text = resources.getString(R.string.navi_app_is_locked), - style = TextStyle(fontFamily = naviFontFamily), - fontWeight = getFontWeight(FontWeightEnum.NAVI_BODY_DEMI_BOLD), - fontSize = 16.sp, - color = FF191919, - textAlign = TextAlign.Start, + } + if (showDialog.value) { + requireActivity().window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) + setBackgroundTint( + ContextCompat.getColor( + requireContext(), + com.navi.design.R.color.translucent_blue_midnight, ) - Text( - modifier = Modifier.padding(top = 8.dp), - text = resources.getString(R.string.your_sensitive_data_is_protected), - style = TextStyle(fontFamily = naviFontFamily), - fontWeight = getFontWeight(FontWeightEnum.NAVI_BODY_REGULAR), - fontSize = 14.sp, - color = FF6B6B6B, - textAlign = TextAlign.Start, - ) - Row( + ) + + Box(modifier = Modifier.fillMaxSize()) { + Column( modifier = Modifier.fillMaxWidth() - .padding(top = 32.dp, bottom = 16.dp) + .align(Alignment.BottomCenter) .background( - color = Color(0xFF1F002A), - shape = RoundedCornerShape(size = 4.dp), + color = Color.White, + shape = RoundedCornerShape(topStart = 8.dp, topEnd = 8.dp), ) .padding(all = 16.dp) - .clickable { unlock?.invoke() }, - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, ) { + Image( + painter = painterResource(id = R.drawable.ic_purple_lock), + contentDescription = null, + ) Text( - text = resources.getString(R.string.log_in_securely), + modifier = Modifier.padding(top = 8.dp), + text = resources.getString(R.string.navi_app_is_locked), style = TextStyle(fontFamily = naviFontFamily), fontWeight = getFontWeight(FontWeightEnum.NAVI_BODY_DEMI_BOLD), - fontSize = 14.sp, - color = Color.White, - textAlign = TextAlign.Center, + fontSize = 16.sp, + color = FF191919, + textAlign = TextAlign.Start, ) + Text( + modifier = Modifier.padding(top = 8.dp), + text = resources.getString(R.string.your_sensitive_data_is_protected), + style = TextStyle(fontFamily = naviFontFamily), + fontWeight = getFontWeight(FontWeightEnum.NAVI_BODY_REGULAR), + fontSize = 14.sp, + color = FF6B6B6B, + textAlign = TextAlign.Start, + ) + Row( + modifier = + Modifier.fillMaxWidth() + .padding(top = 32.dp, bottom = 16.dp) + .background( + color = Color(0xFF1F002A), + shape = RoundedCornerShape(size = 4.dp), + ) + .padding(all = 16.dp) + .clickable { unlock?.invoke() }, + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = resources.getString(R.string.log_in_securely), + style = TextStyle(fontFamily = naviFontFamily), + fontWeight = getFontWeight(FontWeightEnum.NAVI_BODY_DEMI_BOLD), + fontSize = 14.sp, + color = Color.White, + textAlign = TextAlign.Center, + ) + } } } + } else { + setBackgroundTint( + ContextCompat.getColor(requireContext(), com.navi.design.R.color.black_opacity_0) + ) + Box( + modifier = + Modifier.fillMaxSize().background(color = Color.Transparent).clickable( + enabled = false + ) {} + ) } } diff --git a/android/navi-common/src/main/java/com/navi/common/utils/BiometricPromptUtils.kt b/android/navi-common/src/main/java/com/navi/common/utils/BiometricPromptUtils.kt index 31bbb2038f..e5a9afd322 100644 --- a/android/navi-common/src/main/java/com/navi/common/utils/BiometricPromptUtils.kt +++ b/android/navi-common/src/main/java/com/navi/common/utils/BiometricPromptUtils.kt @@ -11,12 +11,15 @@ import android.content.Context import android.content.Intent import android.os.Build import android.provider.Settings +import android.view.WindowManager import androidx.activity.result.ActivityResultLauncher import androidx.appcompat.app.AppCompatActivity import androidx.biometric.BiometricManager import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL import androidx.biometric.BiometricPrompt +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import com.navi.analytics.utils.NaviTrackEvent @@ -28,7 +31,6 @@ import com.navi.common.firebaseremoteconfig.FirebaseRemoteConfigHelper import com.navi.common.utils.Constants.ScreenLockConstants.AUTHENTICATION_SESSION_TIME_OUT_THRESHOLD import com.navi.common.utils.Constants.ScreenLockConstants.DISABLED import com.navi.common.utils.Constants.ScreenLockConstants.ENABLED -import com.navi.common.utils.Constants.ScreenLockConstants.HPC_SCREEN_LOCK_EXPERIMENT import com.navi.common.utils.Constants.ScreenLockConstants.IS_SCREEN_LOCK_ENABLED import com.navi.common.utils.Constants.ScreenLockConstants.LOGIN_SESSION_ID import kotlinx.coroutines.Dispatchers @@ -55,7 +57,6 @@ class BiometricPromptUtils { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && FirebaseRemoteConfigHelper.getBoolean(IS_SCREEN_LOCK_ENABLED) && BaseUtils.isUserLoggedIn() && - PreferenceManager.getStringPreference(HPC_SCREEN_LOCK_EXPERIMENT) == ENABLED && isScreenLockToggled == ENABLED } @@ -78,7 +79,7 @@ class BiometricPromptUtils { NaviTrackEvent.trackEventOnClickStream( eventName = getScreenLockEventName(eventType = ::onAuthenticationError.name) ) - biometricAuthenticationStatus = BiometricAuthenticationStatus.FAILED + biometricAuthenticationStatus.value = BiometricAuthenticationStatus.FAILED onFailed() } @@ -88,7 +89,7 @@ class BiometricPromptUtils { eventName = getScreenLockEventName(eventType = ::onAuthenticationFailed.name) ) - biometricAuthenticationStatus = BiometricAuthenticationStatus.FAILED + biometricAuthenticationStatus.value = BiometricAuthenticationStatus.FAILED onFailed() } @@ -101,8 +102,9 @@ class BiometricPromptUtils { getScreenLockEventName(eventType = ::onAuthenticationSucceeded.name) ) reset() - biometricAuthenticationStatus = BiometricAuthenticationStatus.SUCCESS + biometricAuthenticationStatus.value = BiometricAuthenticationStatus.SUCCESS onSuccess() + activity.window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) } } return BiometricPrompt(activity, executor, callback) @@ -164,11 +166,10 @@ class BiometricPromptUtils { ) && PreferenceManager.getStringPreference(LOGIN_SESSION_ID) != getSessionId() ) { if (isDeviceSecure(activity)) { - if ( - isAuthenticationSessionExpired() || - biometricAuthenticationStatus == BiometricAuthenticationStatus.FAILED - ) { + if (isAuthenticationSessionExpired() || hasBiometricAuthenticationFailed()) { withContext(Dispatchers.Main) { + activity.window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) + showLockScreenDialog() showBiometricPrompt( activity = activity, onSuccess = hideLockScreenDialog, @@ -193,10 +194,15 @@ class BiometricPromptUtils { return result } + private fun hasBiometricAuthenticationFailed(): Boolean { + return biometricAuthenticationStatus.value != BiometricAuthenticationStatus.SUCCESS && + biometricAuthenticationStatus.value != BiometricAuthenticationStatus.RESET + } + fun reset() { appInForegroundTimeStamp = null appInBackgroundTimeStamp = null - biometricAuthenticationStatus = null + biometricAuthenticationStatus.value = BiometricAuthenticationStatus.RESET } companion object { @@ -204,16 +210,19 @@ class BiometricPromptUtils { var appInBackgroundTimeStamp: Long? = null - private var biometricAuthenticationStatus: BiometricAuthenticationStatus? = null + var biometricAuthenticationStatus: MutableState = + mutableStateOf(null) + private set private val _isBiometricAuthenticationEnabled = MutableSharedFlow() val isBiometricAuthenticationEnabled = _isBiometricAuthenticationEnabled.asSharedFlow() - fun getScreenLockEventName(eventType: String) = "screen_lock_${eventType}" + fun getScreenLockEventName(eventType: String) = "naviapp_screen_lock_${eventType}" } } enum class BiometricAuthenticationStatus { SUCCESS, FAILED, + RESET, } diff --git a/android/navi-common/src/main/java/com/navi/common/utils/Constants.kt b/android/navi-common/src/main/java/com/navi/common/utils/Constants.kt index 7a5c97a375..c553a2deb7 100644 --- a/android/navi-common/src/main/java/com/navi/common/utils/Constants.kt +++ b/android/navi-common/src/main/java/com/navi/common/utils/Constants.kt @@ -375,7 +375,6 @@ object Constants { const val ENABLED = "ENABLED" const val DISABLED = "DISABLED" const val IS_SCREEN_LOCK_ENABLED = "IS_SCREEN_LOCK_ENABLED" - const val HPC_SCREEN_LOCK_EXPERIMENT = "hpc-screen-lock-experiment" const val TOGGLE_SWITCH_LAYOUT_ID = "lock_screen_toggle_switch" const val TOGGLE_SWITCH_UNCHECKED_STATE = "unchecked" const val TOGGLE_SWITCH_CHECKED_STATE = "checked" diff --git a/android/navi-common/src/main/res/values/styles.xml b/android/navi-common/src/main/res/values/styles.xml index c084d6f16b..dca019be3a 100644 --- a/android/navi-common/src/main/res/values/styles.xml +++ b/android/navi-common/src/main/res/values/styles.xml @@ -113,7 +113,12 @@