Fix ConcurrentModificationException
You must be very lucky to reproduce this error.
This commit is contained in:
@@ -30,37 +30,45 @@ object VpnMonitor : ConnectivityManager.NetworkCallback() {
|
|||||||
val available = HashMap<Network, String>()
|
val available = HashMap<Network, String>()
|
||||||
override fun onAvailable(network: Network) {
|
override fun onAvailable(network: Network) {
|
||||||
val ifname = manager.getLinkProperties(network)?.interfaceName ?: return
|
val ifname = manager.getLinkProperties(network)?.interfaceName ?: return
|
||||||
if (available.put(network, ifname) != null) return
|
synchronized(this) {
|
||||||
debugLog(TAG, "onAvailable: $ifname")
|
if (available.put(network, ifname) != null) return
|
||||||
callbacks.forEach { it.onAvailable(ifname) }
|
debugLog(TAG, "onAvailable: $ifname")
|
||||||
|
callbacks.forEach { it.onAvailable(ifname) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLost(network: Network) {
|
override fun onLost(network: Network) = synchronized(this) {
|
||||||
val ifname = available.remove(network) ?: return
|
val ifname = available.remove(network) ?: return
|
||||||
debugLog(TAG, "onLost: $ifname")
|
debugLog(TAG, "onLost: $ifname")
|
||||||
callbacks.forEach { it.onLost(ifname) }
|
callbacks.forEach { it.onLost(ifname) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerCallback(callback: Callback, failfast: (() -> Unit)? = null) {
|
fun registerCallback(callback: Callback, failfast: (() -> Unit)? = null) {
|
||||||
if (!callbacks.add(callback)) return
|
if (synchronized(this) {
|
||||||
if (registered) {
|
if (!callbacks.add(callback)) return
|
||||||
if (failfast != null && available.isEmpty()) {
|
if (registered) {
|
||||||
|
if (failfast != null && available.isEmpty()) {
|
||||||
|
callbacks.remove(callback)
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
available.forEach { callback.onAvailable(it.value) }
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else if (failfast != null && manager.allNetworks.all {
|
||||||
|
val cap = manager.getNetworkCapabilities(it)
|
||||||
|
!cap.hasTransport(NetworkCapabilities.TRANSPORT_VPN) ||
|
||||||
|
cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
|
||||||
|
}) {
|
||||||
callbacks.remove(callback)
|
callbacks.remove(callback)
|
||||||
failfast()
|
true
|
||||||
} else available.forEach { callback.onAvailable(it.value) }
|
} else {
|
||||||
} else if (failfast != null && manager.allNetworks.all {
|
manager.registerNetworkCallback(request, this)
|
||||||
val cap = manager.getNetworkCapabilities(it)
|
registered = true
|
||||||
!cap.hasTransport(NetworkCapabilities.TRANSPORT_VPN) ||
|
false
|
||||||
cap.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
|
}
|
||||||
}) {
|
}) failfast!!()
|
||||||
callbacks.remove(callback)
|
|
||||||
failfast()
|
|
||||||
} else {
|
|
||||||
manager.registerNetworkCallback(request, this)
|
|
||||||
registered = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fun unregisterCallback(callback: Callback) {
|
fun unregisterCallback(callback: Callback) = synchronized(this) {
|
||||||
if (!callbacks.remove(callback) || callbacks.isNotEmpty() || !registered) return
|
if (!callbacks.remove(callback) || callbacks.isNotEmpty() || !registered) return
|
||||||
manager.unregisterNetworkCallback(this)
|
manager.unregisterNetworkCallback(this)
|
||||||
registered = false
|
registered = false
|
||||||
|
|||||||
Reference in New Issue
Block a user