Fix everything wrong with TetheringService
I must be very sleepy when writing this.
This commit is contained in:
@@ -13,8 +13,8 @@ class TetheringService : Service(), VpnListener.Callback {
|
|||||||
const val EXTRA_REMOVE_INTERFACE = "interface.remove"
|
const val EXTRA_REMOVE_INTERFACE = "interface.remove"
|
||||||
private const val KEY_ACTIVE = "persist.service.tether.active"
|
private const val KEY_ACTIVE = "persist.service.tether.active"
|
||||||
|
|
||||||
var active: Set<String>?
|
var active: Set<String>
|
||||||
get() = app.pref.getStringSet(KEY_ACTIVE, null)
|
get() = app.pref.getStringSet(KEY_ACTIVE, null) ?: emptySet()
|
||||||
private set(value) {
|
private set(value) {
|
||||||
app.pref.edit().putStringSet(KEY_ACTIVE, value).apply()
|
app.pref.edit().putStringSet(KEY_ACTIVE, value).apply()
|
||||||
LocalBroadcastManager.getInstance(app).sendBroadcast(Intent(ACTION_ACTIVE_INTERFACES_CHANGED))
|
LocalBroadcastManager.getInstance(app).sendBroadcast(Intent(ACTION_ACTIVE_INTERFACES_CHANGED))
|
||||||
@@ -25,46 +25,58 @@ class TetheringService : Service(), VpnListener.Callback {
|
|||||||
private var upstream: String? = null
|
private var upstream: String? = null
|
||||||
private var receiverRegistered = false
|
private var receiverRegistered = false
|
||||||
private val receiver = broadcastReceiver { _, intent ->
|
private val receiver = broadcastReceiver { _, intent ->
|
||||||
val remove = routings - intent.extras.getStringArrayList(NetUtils.EXTRA_ACTIVE_TETHER).toSet()
|
val remove = routings.keys - intent.extras.getStringArrayList(NetUtils.EXTRA_ACTIVE_TETHER).toSet()
|
||||||
if (remove.isEmpty()) return@broadcastReceiver
|
if (remove.isEmpty()) return@broadcastReceiver
|
||||||
for ((iface, routing) in remove) {
|
for (iface in remove) routings.remove(iface)?.stop()
|
||||||
routing?.stop()
|
updateRoutings()
|
||||||
routings.remove(iface)
|
}
|
||||||
}
|
|
||||||
val upstream = upstream
|
private fun updateRoutings() {
|
||||||
if (upstream == null) onLost("") else onAvailable(upstream)
|
|
||||||
active = routings.keys
|
active = routings.keys
|
||||||
if (routings.isEmpty()) terminate()
|
if (routings.isEmpty()) {
|
||||||
|
if (receiverRegistered) {
|
||||||
|
unregisterReceiver(receiver)
|
||||||
|
VpnListener.unregisterCallback(this)
|
||||||
|
upstream = null
|
||||||
|
receiverRegistered = false
|
||||||
|
}
|
||||||
|
stopSelf()
|
||||||
|
} else {
|
||||||
|
val upstream = upstream
|
||||||
|
if (upstream != null) {
|
||||||
|
for ((downstream, value) in routings) if (value == null) {
|
||||||
|
val routing = Routing(upstream, downstream).rule().forward().dnsRedirect(app.dns)
|
||||||
|
if (routing.start()) routings[downstream] = routing else routing.stop()
|
||||||
|
}
|
||||||
|
} else if (!receiverRegistered) {
|
||||||
|
registerReceiver(receiver, intentFilter(NetUtils.ACTION_TETHER_STATE_CHANGED))
|
||||||
|
VpnListener.registerCallback(this)
|
||||||
|
receiverRegistered = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent?) = null
|
override fun onBind(intent: Intent?) = null
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
if (intent != null) { // otw service is recreated after being killed
|
if (intent != null) { // otw service is recreated after being killed
|
||||||
var iface = intent.getStringExtra(EXTRA_ADD_INTERFACE)
|
val iface = intent.getStringExtra(EXTRA_ADD_INTERFACE)
|
||||||
if (iface != null && VpnListener.connectivityManager.tetheredIfaces.contains(iface))
|
if (iface != null && VpnListener.connectivityManager.tetheredIfaces.contains(iface))
|
||||||
routings.put(iface, null)
|
routings.put(iface, null)
|
||||||
iface = intent.getStringExtra(EXTRA_REMOVE_INTERFACE)
|
routings.remove(intent.getStringExtra(EXTRA_REMOVE_INTERFACE))?.stop()
|
||||||
if (iface != null) routings.remove(iface)?.stop()
|
} else {
|
||||||
active = routings.keys
|
val active = active
|
||||||
} else active?.forEach { routings.put(it, null) }
|
if (active.isNotEmpty()) active.intersect(VpnListener.connectivityManager.tetheredIfaces.asIterable())
|
||||||
if (routings.isEmpty()) terminate() else {
|
.forEach { routings.put(it, null) }
|
||||||
if (!receiverRegistered) {
|
|
||||||
registerReceiver(receiver, intentFilter(NetUtils.ACTION_TETHER_STATE_CHANGED))
|
|
||||||
VpnListener.registerCallback(this)
|
|
||||||
receiverRegistered = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
updateRoutings()
|
||||||
return START_STICKY
|
return START_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAvailable(ifname: String) {
|
override fun onAvailable(ifname: String) {
|
||||||
check(upstream == null || upstream == ifname)
|
check(upstream == null || upstream == ifname)
|
||||||
upstream = ifname
|
upstream = ifname
|
||||||
for ((downstream, value) in routings) if (value == null) {
|
updateRoutings()
|
||||||
val routing = Routing(ifname, downstream).rule().forward().dnsRedirect(app.dns)
|
|
||||||
if (routing.start()) routings[downstream] = routing else routing.stop()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLost(ifname: String) {
|
override fun onLost(ifname: String) {
|
||||||
@@ -75,13 +87,4 @@ class TetheringService : Service(), VpnListener.Callback {
|
|||||||
routings[iface] = null
|
routings[iface] = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun terminate() {
|
|
||||||
if (receiverRegistered) {
|
|
||||||
unregisterReceiver(receiver)
|
|
||||||
VpnListener.unregisterCallback(this)
|
|
||||||
receiverRegistered = false
|
|
||||||
}
|
|
||||||
stopSelf()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user