Fix concurrent modifications to routings
This commit is contained in:
@@ -31,7 +31,7 @@ class TetheringFragment : Fragment(), ServiceConnection {
|
|||||||
|
|
||||||
inner class Data(val iface: TetheredInterface) : BaseObservable() {
|
inner class Data(val iface: TetheredInterface) : BaseObservable() {
|
||||||
val icon: Int get() = TetherType.ofInterface(iface.name).icon
|
val icon: Int get() = TetherType.ofInterface(iface.name).icon
|
||||||
val active = binder?.active?.contains(iface.name) == true
|
val active = binder?.isActive(iface.name) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
private class InterfaceViewHolder(val binding: ListitemInterfaceBinding) : RecyclerView.ViewHolder(binding.root),
|
private class InterfaceViewHolder(val binding: ListitemInterfaceBinding) : RecyclerView.ViewHolder(binding.root),
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ class TetheringService : Service(), VpnMonitor.Callback, IpNeighbourMonitor.Call
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class TetheringBinder : Binder() {
|
inner class TetheringBinder : Binder() {
|
||||||
val active get() = routings.keys
|
|
||||||
var fragment: TetheringFragment? = null
|
var fragment: TetheringFragment? = null
|
||||||
|
|
||||||
|
fun isActive(iface: String): Boolean = synchronized(routings) { routings.keys.contains(iface) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val binder = TetheringBinder()
|
private val binder = TetheringBinder()
|
||||||
@@ -28,6 +29,7 @@ class TetheringService : Service(), VpnMonitor.Callback, IpNeighbourMonitor.Call
|
|||||||
private var dns: List<InetAddress> = emptyList()
|
private var dns: List<InetAddress> = emptyList()
|
||||||
private var receiverRegistered = false
|
private var receiverRegistered = false
|
||||||
private val receiver = broadcastReceiver { _, intent ->
|
private val receiver = broadcastReceiver { _, intent ->
|
||||||
|
synchronized(routings) {
|
||||||
when (intent.action) {
|
when (intent.action) {
|
||||||
ConnectivityManagerHelper.ACTION_TETHER_STATE_CHANGED -> {
|
ConnectivityManagerHelper.ACTION_TETHER_STATE_CHANGED -> {
|
||||||
val remove = routings.keys - ConnectivityManagerHelper.getTetheredIfaces(intent.extras)
|
val remove = routings.keys - ConnectivityManagerHelper.getTetheredIfaces(intent.extras)
|
||||||
@@ -37,10 +39,11 @@ class TetheringService : Service(), VpnMonitor.Callback, IpNeighbourMonitor.Call
|
|||||||
}
|
}
|
||||||
App.ACTION_CLEAN_ROUTINGS -> for (iface in routings.keys) routings[iface] = null
|
App.ACTION_CLEAN_ROUTINGS -> for (iface in routings.keys) routings[iface] = null
|
||||||
}
|
}
|
||||||
updateRoutings()
|
updateRoutingsLocked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateRoutings() {
|
private fun updateRoutingsLocked() {
|
||||||
if (routings.isEmpty()) {
|
if (routings.isEmpty()) {
|
||||||
unregisterReceiver()
|
unregisterReceiver()
|
||||||
ServiceNotification.stopForeground(this)
|
ServiceNotification.stopForeground(this)
|
||||||
@@ -80,10 +83,12 @@ class TetheringService : Service(), VpnMonitor.Callback, IpNeighbourMonitor.Call
|
|||||||
|
|
||||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||||
val iface = intent.getStringExtra(EXTRA_ADD_INTERFACE)
|
val iface = intent.getStringExtra(EXTRA_ADD_INTERFACE)
|
||||||
|
synchronized(routings) {
|
||||||
if (iface != null) routings[iface] = null
|
if (iface != null) routings[iface] = null
|
||||||
if (routings.remove(intent.getStringExtra(EXTRA_REMOVE_INTERFACE))?.stop() == false)
|
if (routings.remove(intent.getStringExtra(EXTRA_REMOVE_INTERFACE))?.stop() == false)
|
||||||
Toast.makeText(this, getText(R.string.noisy_su_failure), Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getText(R.string.noisy_su_failure), Toast.LENGTH_SHORT).show()
|
||||||
updateRoutings()
|
updateRoutingsLocked()
|
||||||
|
}
|
||||||
return START_NOT_STICKY
|
return START_NOT_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +96,7 @@ class TetheringService : Service(), VpnMonitor.Callback, IpNeighbourMonitor.Call
|
|||||||
check(upstream == null || upstream == ifname)
|
check(upstream == null || upstream == ifname)
|
||||||
upstream = ifname
|
upstream = ifname
|
||||||
this.dns = dns
|
this.dns = dns
|
||||||
updateRoutings()
|
synchronized(routings) { updateRoutingsLocked() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLost(ifname: String) {
|
override fun onLost(ifname: String) {
|
||||||
@@ -99,10 +104,12 @@ class TetheringService : Service(), VpnMonitor.Callback, IpNeighbourMonitor.Call
|
|||||||
upstream = null
|
upstream = null
|
||||||
this.dns = emptyList()
|
this.dns = emptyList()
|
||||||
var failed = false
|
var failed = false
|
||||||
|
synchronized(routings) {
|
||||||
for ((iface, routing) in routings) {
|
for ((iface, routing) in routings) {
|
||||||
if (routing?.stop() == false) failed = true
|
if (routing?.stop() == false) failed = true
|
||||||
routings[iface] = null
|
routings[iface] = null
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (failed) Toast.makeText(this, getText(R.string.noisy_su_failure), Toast.LENGTH_SHORT).show()
|
if (failed) Toast.makeText(this, getText(R.string.noisy_su_failure), Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +123,9 @@ class TetheringService : Service(), VpnMonitor.Callback, IpNeighbourMonitor.Call
|
|||||||
.distinctBy { it.lladdr }
|
.distinctBy { it.lladdr }
|
||||||
.size
|
.size
|
||||||
}
|
}
|
||||||
ServiceNotification.startForeground(this, routings.keys.associate { Pair(it, sizeLookup[it] ?: 0) })
|
ServiceNotification.startForeground(this, synchronized(routings) {
|
||||||
|
routings.keys.associate { Pair(it, sizeLookup[it] ?: 0) }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
|||||||
Reference in New Issue
Block a user