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