fix: ethernet monitoring and auto tunnel override

This commit is contained in:
Zane Schepke 2025-01-01 19:14:56 -05:00
parent f772dc0f8a
commit 53c09267df
7 changed files with 34 additions and 26 deletions

View File

@ -173,19 +173,12 @@ class AutoTunnelService : LifecycleService() {
combineSettings(), combineSettings(),
combineNetworkEventsJob(), combineNetworkEventsJob(),
) { double, networkState -> ) { double, networkState ->
// quick fix for bug where when first setting up auto tunneling we probably want to query for ssid right away var wifiName: String? = null
var netState: NetworkState? = null
if (networkState.wifiName == Constants.UNREADABLE_SSID && double.first.isTunnelOnWifiEnabled) { if (networkState.wifiName == Constants.UNREADABLE_SSID && double.first.isTunnelOnWifiEnabled) {
if (double.first.isWifiNameByShellEnabled) { wifiName = getWifiName(double.first)
netState = networkState.copy(wifiName = rootShell.get().getCurrentWifiName())
} else if (networkState.capabilities != null) {
netState = networkState.copy(
wifiName =
WifiService.getNetworkName(networkState.capabilities, this@AutoTunnelService),
)
}
} }
AutoTunnelState(tunnelService.get().vpnState.value, netState ?: networkState, double.first, double.second) val netState = wifiName?.let { networkState.copy(wifiName = it) } ?: networkState
AutoTunnelState(tunnelService.get().vpnState.value, netState, double.first, double.second)
}.collect { state -> }.collect { state ->
Timber.d("Network state: ${state.networkState}") Timber.d("Network state: ${state.networkState}")
autoTunnelStateFlow.update { autoTunnelStateFlow.update {
@ -194,18 +187,28 @@ class AutoTunnelService : LifecycleService() {
} }
} }
private fun getWifiName(setting: Settings): String? {
return if (setting.isWifiNameByShellEnabled) {
rootShell.get().getCurrentWifiName()
} else if (wifiService.capabilities != null) {
WifiService.getNetworkName(wifiService.capabilities!!, this@AutoTunnelService)
} else {
null
}
}
@OptIn(FlowPreview::class) @OptIn(FlowPreview::class)
private fun combineNetworkEventsJob(): Flow<NetworkState> { private fun combineNetworkEventsJob(): Flow<NetworkState> {
return combine( return combine(
wifiService.status, wifiService.status,
mobileDataService.status, mobileDataService.status,
) { wifi, mobileData -> ethernetService.status,
) { wifi, mobileData, ethernet ->
NetworkState( NetworkState(
wifi.available, wifi.available,
mobileData.available, mobileData.available,
false, ethernet.available,
wifi.name, wifi.name,
wifi.capabilities,
) )
}.distinctUntilChanged() }.distinctUntilChanged()
} }

View File

@ -1,11 +1,8 @@
package com.zaneschepke.wireguardautotunnel.service.foreground.autotunnel.model package com.zaneschepke.wireguardautotunnel.service.foreground.autotunnel.model
import android.net.NetworkCapabilities
data class NetworkState( data class NetworkState(
val isWifiConnected: Boolean = false, val isWifiConnected: Boolean = false,
val isMobileDataConnected: Boolean = false, val isMobileDataConnected: Boolean = false,
val isEthernetConnected: Boolean = false, val isEthernetConnected: Boolean = false,
val wifiName: String? = null, val wifiName: String? = null,
val capabilities: NetworkCapabilities? = null,
) )

View File

@ -20,6 +20,8 @@ constructor(
@ApplicationContext context: Context, @ApplicationContext context: Context,
) : NetworkService { ) : NetworkService {
override var capabilities: NetworkCapabilities? = null
private val connectivityManager = private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@ -32,6 +34,7 @@ constructor(
trySend(NetworkStatus.Unavailable()) trySend(NetworkStatus.Unavailable())
} }
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
capabilities = networkCapabilities
trySend( trySend(
NetworkStatus.CapabilitiesChanged( NetworkStatus.CapabilitiesChanged(
network, network,
@ -57,8 +60,8 @@ constructor(
emit(NetworkStatus.Unavailable()) emit(NetworkStatus.Unavailable())
}.map { }.map {
when (it) { when (it) {
is NetworkStatus.Available, is NetworkStatus.CapabilitiesChanged -> Status(true, null, null) is NetworkStatus.Available, is NetworkStatus.CapabilitiesChanged -> Status(true, null)
is NetworkStatus.Unavailable -> Status(false, null, null) is NetworkStatus.Unavailable -> Status(false, null)
} }
} }
} }

View File

@ -19,6 +19,9 @@ class MobileDataService
constructor( constructor(
@ApplicationContext context: Context, @ApplicationContext context: Context,
) : NetworkService { ) : NetworkService {
override var capabilities: NetworkCapabilities? = null
private val connectivityManager = private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
@ -31,6 +34,7 @@ constructor(
trySend(NetworkStatus.Unavailable()) trySend(NetworkStatus.Unavailable())
} }
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
capabilities = networkCapabilities
trySend( trySend(
NetworkStatus.CapabilitiesChanged( NetworkStatus.CapabilitiesChanged(
network, network,
@ -56,8 +60,8 @@ constructor(
emit(NetworkStatus.Unavailable()) emit(NetworkStatus.Unavailable())
}.map { }.map {
when (it) { when (it) {
is NetworkStatus.Available, is NetworkStatus.CapabilitiesChanged -> Status(true, null, null) is NetworkStatus.Available, is NetworkStatus.CapabilitiesChanged -> Status(true, null)
is NetworkStatus.Unavailable -> Status(false, null, null) is NetworkStatus.Unavailable -> Status(false, null)
} }
} }
} }

View File

@ -7,6 +7,7 @@ import kotlinx.coroutines.flow.map
interface NetworkService { interface NetworkService {
val status: Flow<Status> val status: Flow<Status>
var capabilities: NetworkCapabilities?
} }
inline fun <Result> Flow<NetworkStatus>.map( inline fun <Result> Flow<NetworkStatus>.map(

View File

@ -1,9 +1,6 @@
package com.zaneschepke.wireguardautotunnel.service.network package com.zaneschepke.wireguardautotunnel.service.network
import android.net.NetworkCapabilities
data class Status( data class Status(
val available: Boolean, val available: Boolean,
val name: String?, val name: String?,
val capabilities: NetworkCapabilities?,
) )

View File

@ -34,6 +34,8 @@ constructor(
@AppShell private val rootShell: Provider<RootShell>, @AppShell private val rootShell: Provider<RootShell>,
) : NetworkService { ) : NetworkService {
override var capabilities: NetworkCapabilities? = null
val mutex = Mutex() val mutex = Mutex()
private var ssid: String? = null private var ssid: String? = null
@ -80,6 +82,7 @@ constructor(
} }
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
capabilities = networkCapabilities
trySend( trySend(
NetworkStatus.CapabilitiesChanged( NetworkStatus.CapabilitiesChanged(
network, network,
@ -120,9 +123,9 @@ constructor(
getNetworkName(it.networkCapabilities, context) getNetworkName(it.networkCapabilities, context)
} }
} }
emit(Status(true, ssid, it.networkCapabilities)) emit(Status(true, ssid))
} }
is NetworkStatus.Unavailable -> emit(Status(false, null, null)) is NetworkStatus.Unavailable -> emit(Status(false, null))
} }
} }