Fix concurrent modifications to routings

This commit is contained in:
Mygod
2018-04-04 17:54:23 -07:00
parent 65d7a7487a
commit 206e339019
2 changed files with 29 additions and 20 deletions

View File

@@ -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),

View File

@@ -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() {