diff --git a/src/main/java/com/infomaniak/lib/core/utils/NetworkExtensions.kt b/src/main/java/com/infomaniak/lib/core/networking/NetworkAvailability.kt
similarity index 57%
rename from src/main/java/com/infomaniak/lib/core/utils/NetworkExtensions.kt
rename to src/main/java/com/infomaniak/lib/core/networking/NetworkAvailability.kt
index 14200ef9..98b41a4e 100644
--- a/src/main/java/com/infomaniak/lib/core/utils/NetworkExtensions.kt
+++ b/src/main/java/com/infomaniak/lib/core/networking/NetworkAvailability.kt
@@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.infomaniak.lib.core.utils
+package com.infomaniak.lib.core.networking
import android.content.Context
import android.net.ConnectivityManager
@@ -23,16 +23,59 @@ import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.channels.ProducerScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.launch
-fun Context.networkStatusFlow(): Flow {
- val networks = mutableSetOf()
- val rootServerUrl = "a.root-servers.net"
+class NetworkAvailability(private val context: Context) {
- fun networkRequestBuilder(): NetworkRequest {
+ val isNetworkAvailable: Flow = callbackFlow {
+ val networks = mutableSetOf()
+ val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+
+ val callback = object : ConnectivityManager.NetworkCallback() {
+
+ override fun onAvailable(network: Network) {
+ networks.add(network)
+ sendNetworkAvailability(networks)
+ }
+
+ override fun onLost(network: Network) {
+ networks.remove(network)
+ sendNetworkAvailability(networks)
+ }
+ }
+
+ launch(Dispatchers.IO) {
+ send(getInitialNetworkAvailability(connectivityManager))
+ }
+
+ connectivityManager.registerNetworkCallback(networkRequestBuilder(), callback)
+
+ awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
+ }
+
+ @Suppress("DEPRECATION")
+ private fun getInitialNetworkAvailability(connectivityManager: ConnectivityManager): Boolean {
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ connectivityManager.activeNetwork?.let {
+ hasInternetConnectivity(it)
+ } ?: false
+ } else {
+ connectivityManager.activeNetworkInfo?.isConnected ?: false
+ }
+ }
+
+ private fun ProducerScope.sendNetworkAvailability(networks: MutableSet) {
+ launch(Dispatchers.IO) {
+ send(hasAvailableNetwork(networks))
+ }
+ }
+
+ private fun networkRequestBuilder(): NetworkRequest {
return NetworkRequest.Builder().apply {
addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH)
addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
@@ -45,31 +88,13 @@ fun Context.networkStatusFlow(): Flow {
}.build()
}
- fun hasInternetConnectivity(network: Network): Boolean = runCatching {
- network.getByName(rootServerUrl) != null
+ private fun hasInternetConnectivity(network: Network) = runCatching {
+ network.getByName(ROOT_SERVER_URL) != null
}.getOrDefault(false)
- fun hasAvailableNetwork() = networks.any(::hasInternetConnectivity)
+ private fun hasAvailableNetwork(networks: MutableSet) = networks.any { hasInternetConnectivity(it) }
- return callbackFlow {
- val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
-
- val callback = object : ConnectivityManager.NetworkCallback() {
- override fun onAvailable(network: Network) {
- networks.add(network)
- launch { send(hasAvailableNetwork()) }
- }
-
- override fun onLost(network: Network) {
- networks.remove(network)
- launch { send(hasAvailableNetwork()) }
- }
- }
-
- connectivityManager.registerNetworkCallback(networkRequestBuilder(), callback)
-
- awaitClose {
- connectivityManager.unregisterNetworkCallback(callback)
- }
+ companion object {
+ private const val ROOT_SERVER_URL = "a.root-servers.net"
}
}