diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/NetworkConnectionManager.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/NetworkConnectionManager.kt index 50c48eacb..013be604d 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/NetworkConnectionManager.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/NetworkConnectionManager.kt @@ -1,5 +1,7 @@ package com.x8bit.bitwarden.data.platform.manager +import kotlinx.coroutines.flow.StateFlow + /** * Manager to detect and handle changes to network connectivity. */ @@ -9,4 +11,6 @@ interface NetworkConnectionManager { * available. */ val isNetworkConnected: Boolean + + val isNetworkConnectedFlow: StateFlow } diff --git a/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/NetworkConnectionManagerImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/NetworkConnectionManagerImpl.kt index d2ced16a0..70c6bdae1 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/NetworkConnectionManagerImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/platform/manager/NetworkConnectionManagerImpl.kt @@ -2,13 +2,21 @@ package com.x8bit.bitwarden.data.platform.manager import android.content.Context import android.net.ConnectivityManager +import android.net.Network import android.net.NetworkCapabilities +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.stateIn /** * Primary implementation of [NetworkConnectionManager]. */ class NetworkConnectionManagerImpl( context: Context, + private val externalScope: CoroutineScope ) : NetworkConnectionManager { private val connectivityManager: ConnectivityManager = context .applicationContext @@ -19,4 +27,31 @@ class NetworkConnectionManagerImpl( .getNetworkCapabilities(connectivityManager.activeNetwork) ?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ?: false + + override val isNetworkConnectedFlow: StateFlow + get() = _connectedFlow + .stateIn( + scope = externalScope, + started = SharingStarted.WhileSubscribed(5000), + initialValue = isNetworkConnected + ) + + private val _connectedFlow = callbackFlow { + val networkCallback = object : ConnectivityManager.NetworkCallback() { + override fun onLost(network : Network) { + trySend(false) + } + + override fun onCapabilitiesChanged(network : Network, networkCapabilities : NetworkCapabilities) { + if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) { + trySend(true) + } + } + } + connectivityManager.registerDefaultNetworkCallback(networkCallback) + awaitClose { + connectivityManager.unregisterNetworkCallback(networkCallback) + } + } }