diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index e09a17503a..d1c975f5b6 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -94,7 +94,7 @@ class LoggedInFlowNode @AssistedInject constructor( private val notificationDrawerManager: NotificationDrawerManager, private val ftueState: FtueState, private val pinEntryPoint: PinEntryPoint, - private val pinStateService PinStateService, + private val pinStateService: PinStateService, private val matrixClient: MatrixClient, snackbarDispatcher: SnackbarDispatcher, ) : BackstackNode( @@ -134,9 +134,18 @@ class LoggedInFlowNode @AssistedInject constructor( backstack.push(NavTarget.Ftue) } }, + onResume = { + coroutineScope.launch { + pinStateService.entersForeground() + } + }, + onPause = { + coroutineScope.launch { + pinStateService.entersBackground() + } + }, onStop = { coroutineScope.launch { - pinStateDataSource.lock() //Counterpart startSync is done in observeSyncStateAndNetworkStatus method. syncService.stopSync() } @@ -336,7 +345,7 @@ class LoggedInFlowNode @AssistedInject constructor( @Composable override fun View(modifier: Modifier) { Box(modifier = modifier) { - val pinState by pinStateDataSource.pinState.collectAsState() + val pinState by pinStateService.pinState.collectAsState() when (pinState) { PinState.Unlocked -> { Children( diff --git a/features/pin/api/src/main/kotlin/io/element/android/features/pin/api/PinStateService.kt b/features/pin/api/src/main/kotlin/io/element/android/features/pin/api/PinStateService.kt index 92ec8715ab..4ecb473c18 100644 --- a/features/pin/api/src/main/kotlin/io/element/android/features/pin/api/PinStateService.kt +++ b/features/pin/api/src/main/kotlin/io/element/android/features/pin/api/PinStateService.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.flow.StateFlow interface PinStateService { val pinState: StateFlow - suspend fun lock() + suspend fun entersForeground() + suspend fun entersBackground() suspend fun unlock() } diff --git a/features/pin/impl/src/main/kotlin/io/element/android/features/pin/impl/auth/PinAuthenticationPresenter.kt b/features/pin/impl/src/main/kotlin/io/element/android/features/pin/impl/auth/PinAuthenticationPresenter.kt index 754ca3a4fa..5e7e274ba7 100644 --- a/features/pin/impl/src/main/kotlin/io/element/android/features/pin/impl/auth/PinAuthenticationPresenter.kt +++ b/features/pin/impl/src/main/kotlin/io/element/android/features/pin/impl/auth/PinAuthenticationPresenter.kt @@ -24,7 +24,7 @@ import kotlinx.coroutines.launch import javax.inject.Inject class PinAuthenticationPresenter @Inject constructor( - private val pinStateService PinStateService, + private val pinStateService: PinStateService, private val coroutineScope: CoroutineScope, ) : Presenter { @@ -33,7 +33,7 @@ class PinAuthenticationPresenter @Inject constructor( fun handleEvents(event: PinAuthenticationEvents) { when (event) { - PinAuthenticationEvents.Unlock -> coroutineScope.launch { pinStateDataSource.unlock() } + PinAuthenticationEvents.Unlock -> coroutineScope.launch { pinStateService.unlock() } } } return PinAuthenticationState( diff --git a/features/pin/impl/src/main/kotlin/io/element/android/features/pin/impl/state/DefaultPinStateService.kt b/features/pin/impl/src/main/kotlin/io/element/android/features/pin/impl/state/DefaultPinStateService.kt index e08a96f458..69371c40ee 100644 --- a/features/pin/impl/src/main/kotlin/io/element/android/features/pin/impl/state/DefaultPinStateService.kt +++ b/features/pin/impl/src/main/kotlin/io/element/android/features/pin/impl/state/DefaultPinStateService.kt @@ -23,10 +23,16 @@ import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.SingleIn import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags +import kotlinx.coroutines.Job +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch import javax.inject.Inject +private const val GRACE_PERIOD_IN_MILLIS = 90 * 1000L + @SingleIn(AppScope::class) @ContributesBinding(AppScope::class) class DefaultPinStateService @Inject constructor( @@ -36,15 +42,24 @@ class DefaultPinStateService @Inject constructor( private val _pinState = MutableStateFlow(PinState.Unlocked) override val pinState: StateFlow = _pinState + private var lockJob: Job? = null + override suspend fun unlock() { if (featureFlagService.isFeatureEnabled(FeatureFlags.PinUnlock)) { _pinState.value = PinState.Unlocked } } - override suspend fun lock() { - if (featureFlagService.isFeatureEnabled(FeatureFlags.PinUnlock)) { - _pinState.value = PinState.Locked + override suspend fun entersForeground() { + lockJob?.cancel() + } + + override suspend fun entersBackground(): Unit = coroutineScope { + lockJob = launch { + if (featureFlagService.isFeatureEnabled(FeatureFlags.PinUnlock)) { + delay(GRACE_PERIOD_IN_MILLIS) + _pinState.value = PinState.Locked + } } } }