Initial support for stacked links
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user