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 2e449c2cf9..dbf7ab6c6a 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -77,17 +77,20 @@ import io.element.android.libraries.matrix.api.verification.SessionVerificationS import io.element.android.libraries.matrix.api.verification.VerificationRequest import io.element.android.services.appnavstate.api.AppNavigationStateService import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.delay import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import kotlinx.coroutines.withTimeout import kotlinx.parcelize.Parcelize import timber.log.Timber +import java.time.Duration +import java.time.Instant import java.util.Optional import java.util.UUID -import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds +import kotlin.time.toKotlinDuration @ContributesNode(SessionScope::class) class LoggedInFlowNode @AssistedInject constructor( @@ -134,12 +137,29 @@ class LoggedInFlowNode @AssistedInject constructor( override fun onIncomingSessionRequest(verificationRequest: VerificationRequest.Incoming) { // Without this launch the rendering and actual state of this Appyx node's children gets out of sync, resulting in a crash. // This might be because this method is called back from Rust in a background thread. - MainScope().launch { + lifecycleScope.launch { + val receivedAt = Instant.now() + // Wait until the app is in foreground to display the incoming verification request appNavigationStateService.appNavigationState.first { it.isInForeground } - // Wait for the UI to be ready - delay(500.milliseconds) + // TODO there should also be a timeout for > 10 minutes elapsed since the request was created, but the SDK doesn't expose that info yet + val now = Instant.now() + val elapsedTimeSinceReceived = Duration.between(receivedAt, now).toKotlinDuration() + + // Discard the incoming verification request if it has timed out + if (elapsedTimeSinceReceived > 2.minutes) { + Timber.w("Incoming verification request ${verificationRequest.details.flowId} discarded due to timeout.") + return@launch + } + + // Wait for the RoomList UI to be ready so the incoming verification screen can be displayed on top of it + // Otherwise, the RoomList UI may be incorrectly displayed on top + withTimeout(5.seconds) { + backstack.elements.first { elements -> + elements.any { it.key.navTarget == NavTarget.RoomList } + } + } backstack.singleTop(NavTarget.IncomingVerificationRequest(verificationRequest)) }