Initial support for stacked links

This commit is contained in:
Mygod
2020-09-11 15:14:46 -04:00
parent bd176bc6f0
commit b675bdda09
9 changed files with 165 additions and 227 deletions

View File

@@ -14,39 +14,40 @@ import be.mygod.vpnhotspot.R
import be.mygod.vpnhotspot.net.monitor.FallbackUpstreamMonitor
import be.mygod.vpnhotspot.net.monitor.UpstreamMonitor
import be.mygod.vpnhotspot.util.SpanFormatter
import be.mygod.vpnhotspot.util.allRoutes
import be.mygod.vpnhotspot.util.allStackedLinks
import be.mygod.vpnhotspot.util.parseNumericAddress
import timber.log.Timber
class UpstreamsPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs),
DefaultLifecycleObserver {
companion object {
private val internetAddress = parseNumericAddress("8.8.8.8")
private val internetV4Address = parseNumericAddress("8.8.8.8")
private val internetV6Address = parseNumericAddress("2001:4860:4860::8888")
}
private data class Interface(val ifname: String, val internet: Boolean = true)
private open inner class Monitor : UpstreamMonitor.Callback {
protected var currentInterface: Interface? = null
val charSequence get() = currentInterface?.run {
protected var currentInterfaces = emptyList<Interface>()
val charSequence get() = currentInterfaces.map { (ifname, internet) ->
if (internet) SpannableStringBuilder(ifname).apply {
setSpan(StyleSpan(Typeface.BOLD), 0, length, 0)
} else ifname
} ?: ""
}.joinToString().let { if (it.isEmpty()) "" else it }
override fun onAvailable(ifname: String, properties: LinkProperties) {
currentInterface = Interface(ifname, properties.allRoutes.any {
try {
it.matches(internetAddress)
} catch (e: RuntimeException) {
Timber.w(e)
false
override fun onAvailable(properties: LinkProperties?) {
currentInterfaces = properties?.allStackedLinks?.mapNotNull { prop ->
prop.interfaceName?.let { ifname ->
Interface(ifname, prop.routes.any {
try {
it.matches(internetV4Address) || it.matches(internetV6Address)
} catch (e: RuntimeException) {
Timber.w(e)
false
}
})
}
})
onUpdate()
}
override fun onLost() {
currentInterface = null
}?.toList() ?: emptyList()
onUpdate()
}
}
@@ -54,7 +55,7 @@ class UpstreamsPreference(context: Context, attrs: AttributeSet) : Preference(co
private val primary = Monitor()
private val fallback: Monitor = object : Monitor() {
override fun onFallback() {
currentInterface = Interface("<default>")
currentInterfaces = listOf(Interface("<default>"))
onUpdate()
}
}