summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
Diffstat (limited to 'android')
-rw-r--r--android/app/src/test/kotlin/net/mullvad/talpid/TalpidVpnServiceFallbackDnsTest.kt3
-rw-r--r--android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt17
-rw-r--r--android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt29
3 files changed, 21 insertions, 28 deletions
diff --git a/android/app/src/test/kotlin/net/mullvad/talpid/TalpidVpnServiceFallbackDnsTest.kt b/android/app/src/test/kotlin/net/mullvad/talpid/TalpidVpnServiceFallbackDnsTest.kt
index 27e7658a11..e3faaf3884 100644
--- a/android/app/src/test/kotlin/net/mullvad/talpid/TalpidVpnServiceFallbackDnsTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/talpid/TalpidVpnServiceFallbackDnsTest.kt
@@ -34,6 +34,9 @@ class TalpidVpnServiceFallbackDnsTest {
every { talpidVpnService.prepareVpnSafe() } returns Prepared.right()
builderMockk = mockk<VpnService.Builder>()
+ every { talpidVpnService getProperty "connectivityListener" } returns
+ mockk<ConnectivityListener>(relaxed = true)
+
mockkConstructor(VpnService.Builder::class)
every { anyConstructed<VpnService.Builder>().setMtu(any()) } returns builderMockk
every { anyConstructed<VpnService.Builder>().setBlocking(any()) } returns builderMockk
diff --git a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt
index 9c82d62251..b702a39a6e 100644
--- a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt
+++ b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/ConnectivityListener.kt
@@ -10,6 +10,7 @@ import kotlin.collections.ArrayList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
@@ -18,7 +19,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.scan
import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.launch
import net.mullvad.talpid.model.NetworkState
import net.mullvad.talpid.util.NetworkEvent
import net.mullvad.talpid.util.RawNetworkState
@@ -31,29 +32,30 @@ class ConnectivityListener(private val connectivityManager: ConnectivityManager)
val isConnected
get() = _isConnected.value
- private lateinit var _currentNetworkState: StateFlow<NetworkState?>
+ private val _mutableNetworkState = MutableStateFlow<NetworkState?>(null)
private val resetNetworkState: Channel<Unit> = Channel()
// Used by JNI
val currentDefaultNetworkState: NetworkState?
- get() = _currentNetworkState.value
+ get() = _mutableNetworkState.value
// Used by JNI
val currentDnsServers: ArrayList<InetAddress>
- get() = _currentNetworkState.value?.dnsServers ?: ArrayList()
+ get() = _mutableNetworkState.value?.dnsServers ?: ArrayList()
fun register(scope: CoroutineScope) {
// Consider implementing retry logic for the flows below, because registering a listener on
// the default network may fail if the network on Android 11
// https://issuetracker.google.com/issues/175055271?pli=1
- _currentNetworkState =
+ scope.launch {
merge(
connectivityManager.defaultRawNetworkStateFlow(),
resetNetworkState.receiveAsFlow().map { null },
)
.map { it?.toNetworkState() }
.onEach { notifyDefaultNetworkChange(it) }
- .stateIn(scope, SharingStarted.Eagerly, null)
+ .collect(_mutableNetworkState)
+ }
_isConnected =
hasInternetCapability()
@@ -70,8 +72,7 @@ class ConnectivityListener(private val connectivityManager: ConnectivityManager)
* know the last known values not to be correct anymore.
*/
fun invalidateNetworkStateCache() {
- // TODO remove runBlocking
- runBlocking { resetNetworkState.send(Unit) }
+ _mutableNetworkState.value = null
}
private fun LinkProperties.dnsServersWithoutFallback(): List<InetAddress> =
diff --git a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
index a143df6132..1457ff35f4 100644
--- a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
+++ b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
@@ -57,34 +57,22 @@ open class TalpidVpnService : LifecycleVpnService() {
// Used by JNI
fun openTun(config: TunConfig): CreateTunResult =
synchronized(this) {
- val tunStatus = activeTunStatus
-
- if (config == currentTunConfig && tunStatus != null && tunStatus.isOpen) {
- tunStatus
- } else {
- openTunImpl(config)
+ createTun(config).merge().also {
+ currentTunConfig = config
+ activeTunStatus = it
}
}
// Used by JNI
- fun openTunForced(config: TunConfig): CreateTunResult =
- synchronized(this) { openTunImpl(config) }
-
- // Used by JNI
- fun closeTun(): Unit = synchronized(this) { activeTunStatus = null }
+ fun closeTun(): Unit =
+ synchronized(this) {
+ connectivityListener.invalidateNetworkStateCache()
+ activeTunStatus = null
+ }
// Used by JNI
fun bypass(socket: Int): Boolean = protect(socket)
- private fun openTunImpl(config: TunConfig): CreateTunResult {
- val newTunStatus = createTun(config).merge()
-
- currentTunConfig = config
- activeTunStatus = newTunStatus
-
- return newTunStatus
- }
-
private fun createTun(
config: TunConfig
): Either<CreateTunResult.Error, CreateTunResult.Success> = either {
@@ -123,6 +111,7 @@ open class TalpidVpnService : LifecycleVpnService() {
builder.addDnsServer(FALLBACK_DUMMY_DNS_SERVER)
}
+ connectivityListener.invalidateNetworkStateCache()
val vpnInterfaceFd =
builder
.establishSafe()