Add a global state management for internet connectivity (#907)
parent
e5e00c4548
commit
75ccd3dd2b
@ -0,0 +1,80 @@
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.Context.CONNECTIVITY_SERVICE
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.ConnectivityManager.NetworkCallback
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.NetworkRequest
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.shareIn
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Provides a flow that emits `true` when the device has internet connectivity and `false` otherwise.
|
||||
*/
|
||||
@Singleton
|
||||
class InternetConnectivity @Inject constructor(application: Application) {
|
||||
val networkAvailable = callbackFlow {
|
||||
val connectivityManager = application.getSystemService(ConnectivityManager::class.java)
|
||||
|
||||
val callback = object : NetworkCallback() {
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
trySend(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET))
|
||||
}
|
||||
|
||||
override fun onAvailable(network: Network) {
|
||||
trySend(true)
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
trySend(false)
|
||||
}
|
||||
}
|
||||
|
||||
connectivityManager.registerNetworkCallback(
|
||||
NetworkRequest.Builder()
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
.build(),
|
||||
callback
|
||||
)
|
||||
|
||||
awaitClose {
|
||||
connectivityManager.unregisterNetworkCallback(callback)
|
||||
}
|
||||
}.stateIn(
|
||||
scope = GlobalScope,
|
||||
started = SharingStarted.WhileSubscribed(),
|
||||
initialValue = haveValidNetworkConnection(application)
|
||||
)
|
||||
|
||||
|
||||
companion object {
|
||||
// Method to determine if we have a valid Internet connection or not
|
||||
private fun haveValidNetworkConnection(context: Context): Boolean {
|
||||
val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
|
||||
// Early exit if we have no active network..
|
||||
val activeNetwork = cm.activeNetwork ?: return false
|
||||
|
||||
// ..otherwise determine what capabilities are available to the active network.
|
||||
val networkCapabilities = cm.getNetworkCapabilities(activeNetwork)
|
||||
val internetConnectionValid = networkCapabilities != null &&
|
||||
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
|
||||
return internetConnectionValid
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Context.CONNECTIVITY_SERVICE
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
|
||||
class NetworkUtils {
|
||||
|
||||
companion object {
|
||||
|
||||
// Method to determine if we have a valid Internet connection or not
|
||||
fun haveValidNetworkConnection(context: Context) : Boolean {
|
||||
val cm = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
|
||||
// Early exit if we have no active network..
|
||||
if (cm.activeNetwork == null) return false
|
||||
|
||||
// ..otherwise determine what capabilities are available to the active network.
|
||||
val networkCapabilities = cm.getNetworkCapabilities(cm.activeNetwork)
|
||||
val internetConnectionValid = cm.activeNetwork != null &&
|
||||
networkCapabilities != null &&
|
||||
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
|
||||
return internetConnectionValid
|
||||
}
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
package org.thoughtcrime.securesms.webrtc
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.util.NetworkUtils
|
||||
|
||||
class NetworkChangeReceiver(private val onNetworkChangedCallback: (Boolean)->Unit) {
|
||||
|
||||
private val networkList: MutableSet<Network> = mutableSetOf()
|
||||
|
||||
private val broadcastDelegate = object: BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
receiveBroadcast(context, intent)
|
||||
}
|
||||
}
|
||||
|
||||
val defaultObserver = object: ConnectivityManager.NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
Log.i("Loki", "onAvailable: $network")
|
||||
networkList += network
|
||||
onNetworkChangedCallback(networkList.isNotEmpty())
|
||||
}
|
||||
|
||||
override fun onLosing(network: Network, maxMsToLive: Int) {
|
||||
Log.i("Loki", "onLosing: $network, maxMsToLive: $maxMsToLive")
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
Log.i("Loki", "onLost: $network")
|
||||
networkList -= network
|
||||
onNetworkChangedCallback(networkList.isNotEmpty())
|
||||
}
|
||||
|
||||
override fun onUnavailable() {
|
||||
Log.i("Loki", "onUnavailable")
|
||||
}
|
||||
}
|
||||
|
||||
fun receiveBroadcast(context: Context, intent: Intent) {
|
||||
val connected = NetworkUtils.haveValidNetworkConnection(context)
|
||||
Log.i("Loki", "received broadcast, network connected: $connected")
|
||||
onNetworkChangedCallback(connected)
|
||||
}
|
||||
|
||||
fun register(context: Context) {
|
||||
val intentFilter = IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")
|
||||
context.registerReceiver(broadcastDelegate, intentFilter)
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
// val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
// cm.registerDefaultNetworkCallback(defaultObserver)
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
fun unregister(context: Context) {
|
||||
context.unregisterReceiver(broadcastDelegate)
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
// val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
// cm.unregisterNetworkCallback(defaultObserver)
|
||||
// } else {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue