diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/LoginConstant.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/LoginConstant.kt new file mode 100644 index 000000000000..af8f89ce9824 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/LoginConstant.kt @@ -0,0 +1,3 @@ +package net.mullvad.mullvadvpn.constant + +const val LOGIN_TIMEOUT_MILLIS = 10000L // 10 seconds diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt index e782f6f43937..a754b5a6c29e 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/FlowUtils.kt @@ -2,12 +2,14 @@ package net.mullvad.mullvadvpn.util import android.view.animation.Animation import kotlin.coroutines.EmptyCoroutineContext +import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.take +import kotlinx.coroutines.withTimeoutOrNull import net.mullvad.mullvadvpn.lib.common.util.safeOffer import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState import net.mullvad.talpid.util.EventNotifier @@ -124,3 +126,6 @@ inline fun combine( ) } } + +suspend inline fun Deferred.awaitWithTimeoutOrNull(timeout: Long) = + withTimeoutOrNull(timeout) { await() } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt index b31478ce1a95..87174f2063bc 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/LoginViewModel.kt @@ -19,12 +19,14 @@ import net.mullvad.mullvadvpn.compose.state.LoginError import net.mullvad.mullvadvpn.compose.state.LoginState import net.mullvad.mullvadvpn.compose.state.LoginState.* import net.mullvad.mullvadvpn.compose.state.LoginUiState +import net.mullvad.mullvadvpn.constant.LOGIN_TIMEOUT_MILLIS import net.mullvad.mullvadvpn.model.AccountCreationResult import net.mullvad.mullvadvpn.model.AccountToken import net.mullvad.mullvadvpn.model.LoginResult import net.mullvad.mullvadvpn.repository.AccountRepository import net.mullvad.mullvadvpn.repository.DeviceRepository import net.mullvad.mullvadvpn.usecase.NewDeviceNotificationUseCase +import net.mullvad.mullvadvpn.util.awaitWithTimeoutOrNull private const val MINIMUM_LOADING_SPINNER_TIME_MILLIS = 500L @@ -81,7 +83,8 @@ class LoginViewModel( delay(MINIMUM_LOADING_SPINNER_TIME_MILLIS) val uiState = - when (val result = loginDeferred.await()) { + // If timed out will go to the else branch + when (val result = loginDeferred.awaitWithTimeoutOrNull(LOGIN_TIMEOUT_MILLIS)) { LoginResult.Ok -> { launch { delay(1000)