summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson@mullvad.net>2025-03-07 11:33:11 +0100
committerDavid Göransson <david.goransson@mullvad.net>2025-03-07 11:33:11 +0100
commita6543aa58a0fefaa52a78e87d5ddbd3112c7e0c1 (patch)
treea14c4a13d4e5d7ecac41a3d0f9f2e2110370c70d /android
parentcae71a342274fbe39a39283d6a833e8671b017c8 (diff)
parentc17b6fa0d465dd39c9cefa7fe69af23031b67189 (diff)
downloadmullvadvpn-a6543aa58a0fefaa52a78e87d5ddbd3112c7e0c1.tar.xz
mullvadvpn-a6543aa58a0fefaa52a78e87d5ddbd3112c7e0c1.zip
Merge branch 'implement-device-ip-setting'
Diffstat (limited to 'android')
-rw-r--r--android/CHANGELOG.md1
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt3
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt30
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/WireguardConstraintsRepository.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt25
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt4
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/SelectedLocationUseCaseTest.kt1
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/MultihopViewModelTest.kt1
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SettingsViewModelTest.kt1
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt43
-rw-r--r--android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt18
-rw-r--r--android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/FromDomain.kt13
-rw-r--r--android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/ToDomain.kt14
-rw-r--r--android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/IpVersion.kt6
-rw-r--r--android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/WireguardConstraints.kt1
-rw-r--r--android/lib/resource/src/main/res/values-da/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-de/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-es/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-fi/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-fr/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-it/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-ja/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-ko/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-my/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-nb/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-nl/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-pl/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-pt/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-ru/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-sv/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-th/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-tr/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-zh-rCN/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-zh-rTW/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values/strings.xml3
36 files changed, 199 insertions, 49 deletions
diff --git a/android/CHANGELOG.md b/android/CHANGELOG.md
index 76be993cd6..8e84283b32 100644
--- a/android/CHANGELOG.md
+++ b/android/CHANGELOG.md
@@ -25,6 +25,7 @@ Line wrap the file at 100 chars. Th
### Added
- Prompt password manager to store new account number on account creation.
+- Add the ability to force the ip version used to connect to a relay.
### Changed
- Disable Wireguard port setting when a obfuscation is selected since it is not used when an
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt
index 13ef28dd23..073c81b6f8 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt
@@ -23,6 +23,7 @@ import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_WIREGUARD_CUSTOM_PORT_TEXT_
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_WIREGUARD_OBFUSCATION_TITLE_TEST_TAG
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_WIREGUARD_PORT_ITEM_X_TEST_TAG
import net.mullvad.mullvadvpn.lib.model.Constraint
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.Mtu
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
import net.mullvad.mullvadvpn.lib.model.Port
@@ -72,6 +73,7 @@ class VpnSettingsScreenTest {
navigateToShadowSocksSettings: () -> Unit = {},
navigateToUdp2TcpSettings: () -> Unit = {},
onToggleAutoStartAndConnectOnBoot: (Boolean) -> Unit = {},
+ onSelectDeviceIpVersion: (Constraint<IpVersion>) -> Unit = {},
) {
setContentWithTheme {
VpnSettingsScreen(
@@ -103,6 +105,7 @@ class VpnSettingsScreenTest {
navigateToShadowSocksSettings = navigateToShadowSocksSettings,
navigateToUdp2TcpSettings = navigateToUdp2TcpSettings,
onToggleAutoStartAndConnectOnBoot = onToggleAutoStartAndConnectOnBoot,
+ onSelectDeviceIpVersion = onSelectDeviceIpVersion,
)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
index 779b4792b4..2989dba047 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
@@ -93,6 +93,7 @@ import net.mullvad.mullvadvpn.compose.util.OnNavResultValue
import net.mullvad.mullvadvpn.compose.util.showSnackbarImmediately
import net.mullvad.mullvadvpn.constant.WIREGUARD_PRESET_PORTS
import net.mullvad.mullvadvpn.lib.model.Constraint
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.Mtu
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
import net.mullvad.mullvadvpn.lib.model.Port
@@ -140,6 +141,7 @@ private fun PreviewVpnSettings(
navigateToLocalNetworkSharingInfo = {},
navigateToWireguardPortDialog = {},
navigateToServerIpOverrides = {},
+ onSelectDeviceIpVersion = {},
)
}
}
@@ -268,6 +270,7 @@ fun VpnSettings(
navigateToUdp2TcpSettings =
dropUnlessResumed { navigator.navigate(Udp2TcpSettingsDestination) },
onToggleAutoStartAndConnectOnBoot = vm::onToggleAutoStartAndConnectOnBoot,
+ onSelectDeviceIpVersion = vm::onDeviceIpVersionSelected,
)
}
@@ -304,6 +307,7 @@ fun VpnSettingsScreen(
navigateToShadowSocksSettings: () -> Unit,
navigateToUdp2TcpSettings: () -> Unit,
onToggleAutoStartAndConnectOnBoot: (Boolean) -> Unit,
+ onSelectDeviceIpVersion: (ipVersion: Constraint<IpVersion>) -> Unit,
) {
var expandContentBlockersState by rememberSaveable { mutableStateOf(false) }
val biggerPadding = 54.dp
@@ -651,6 +655,32 @@ fun VpnSettingsScreen(
Spacer(modifier = Modifier.height(Dimens.cellVerticalSpacing))
}
+ itemWithDivider {
+ InformationComposeCell(title = stringResource(R.string.device_ip_version_title))
+ }
+ itemWithDivider {
+ SelectableCell(
+ title = stringResource(id = R.string.automatic),
+ isSelected = state.deviceIpVersion == Constraint.Any,
+ onCellClicked = { onSelectDeviceIpVersion(Constraint.Any) },
+ )
+ }
+ itemWithDivider {
+ SelectableCell(
+ title = stringResource(id = R.string.device_ip_version_ipv4),
+ isSelected = state.deviceIpVersion.getOrNull() == IpVersion.IPV4,
+ onCellClicked = { onSelectDeviceIpVersion(Constraint.Only(IpVersion.IPV4)) },
+ )
+ }
+ item {
+ SelectableCell(
+ title = stringResource(id = R.string.device_ip_version_ipv6),
+ isSelected = state.deviceIpVersion.getOrNull() == IpVersion.IPV6,
+ onCellClicked = { onSelectDeviceIpVersion(Constraint.Only(IpVersion.IPV6)) },
+ )
+ Spacer(modifier = Modifier.height(Dimens.cellVerticalSpacing))
+ }
+
item {
MtuComposeCell(mtuValue = state.mtu, onEditMtu = { navigateToMtuDialog(state.mtu) })
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt
index c9fd0257c0..ec069001cc 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt
@@ -2,6 +2,7 @@ package net.mullvad.mullvadvpn.compose.state
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.DefaultDnsOptions
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.Mtu
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
import net.mullvad.mullvadvpn.lib.model.Port
@@ -24,6 +25,7 @@ data class VpnSettingsUiState(
val availablePortRanges: List<PortRange>,
val systemVpnSettingsAvailable: Boolean,
val autoStartAndConnectOnBoot: Boolean,
+ val deviceIpVersion: Constraint<IpVersion>,
) {
val isCustomWireguardPort =
selectedWireguardPort is Constraint.Only &&
@@ -48,6 +50,7 @@ data class VpnSettingsUiState(
availablePortRanges: List<PortRange> = emptyList(),
systemVpnSettingsAvailable: Boolean = false,
autoStartAndConnectOnBoot: Boolean = false,
+ deviceIpVersion: Constraint<IpVersion> = Constraint.Any,
) =
VpnSettingsUiState(
mtu,
@@ -64,6 +67,7 @@ data class VpnSettingsUiState(
availablePortRanges,
systemVpnSettingsAvailable,
autoStartAndConnectOnBoot,
+ deviceIpVersion,
)
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/WireguardConstraintsRepository.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/WireguardConstraintsRepository.kt
index 093b87cafc..f92367bcf6 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/WireguardConstraintsRepository.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/WireguardConstraintsRepository.kt
@@ -8,6 +8,7 @@ import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.stateIn
import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService
import net.mullvad.mullvadvpn.lib.model.Constraint
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.Port
import net.mullvad.mullvadvpn.lib.model.RelayItemId
@@ -26,4 +27,7 @@ class WireguardConstraintsRepository(
suspend fun setEntryLocation(relayItemId: RelayItemId) =
managementService.setEntryLocation(relayItemId)
+
+ suspend fun setDeviceIpVersion(ipVersion: Constraint<IpVersion>) =
+ managementService.setDeviceIpVersion(ipVersion)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt
index 90f98fceaa..2273ada5e0 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt
@@ -23,6 +23,7 @@ import net.mullvad.mullvadvpn.constant.WIREGUARD_PRESET_PORTS
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.DefaultDnsOptions
import net.mullvad.mullvadvpn.lib.model.DnsState
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
import net.mullvad.mullvadvpn.lib.model.Port
import net.mullvad.mullvadvpn.lib.model.QuantumResistantState
@@ -46,7 +47,7 @@ sealed interface VpnSettingsSideEffect {
@Suppress("TooManyFunctions")
class VpnSettingsViewModel(
private val repository: SettingsRepository,
- private val relayListRepository: RelayListRepository,
+ relayListRepository: RelayListRepository,
private val systemVpnSettingsUseCase: SystemVpnSettingsAvailableUseCase,
private val autoStartAndConnectOnBootRepository: AutoStartAndConnectOnBootRepository,
private val wireguardConstraintsRepository: WireguardConstraintsRepository,
@@ -83,6 +84,7 @@ class VpnSettingsViewModel(
availablePortRanges = portRanges,
systemVpnSettingsAvailable = systemVpnSettingsUseCase(),
autoStartAndConnectOnBoot = autoStartAndConnectOnBoot,
+ deviceIpVersion = settings?.getDeviceIpVersion() ?: Constraint.Any,
)
}
.stateIn(
@@ -122,14 +124,6 @@ class VpnSettingsViewModel(
}
}
- fun onToggleDaita(enable: Boolean) {
- viewModelScope.launch(dispatcher) {
- repository.setDaitaEnabled(enable).onLeft {
- _uiSideEffect.send(VpnSettingsSideEffect.ShowToast.GenericError)
- }
- }
- }
-
fun onDnsDialogDismissed() {
if (vmState.value.customDnsList.isEmpty()) {
onToggleCustomDns(enable = false)
@@ -251,6 +245,14 @@ class VpnSettingsViewModel(
}
}
+ fun onDeviceIpVersionSelected(ipVersion: Constraint<IpVersion>) {
+ viewModelScope.launch(dispatcher) {
+ wireguardConstraintsRepository.setDeviceIpVersion(ipVersion).onLeft {
+ _uiSideEffect.send(VpnSettingsSideEffect.ShowToast.GenericError)
+ }
+ }
+ }
+
private fun updateDefaultDnsOptionsViaRepository(contentBlockersOption: DefaultDnsOptions) =
viewModelScope.launch(dispatcher) {
repository
@@ -265,7 +267,7 @@ class VpnSettingsViewModel(
private fun List<String>.asInetAddressList(): List<InetAddress> {
return try {
map { InetAddress.getByName(it) }
- } catch (ex: UnknownHostException) {
+ } catch (_: UnknownHostException) {
Logger.e("Error parsing the DNS address list.")
emptyList()
}
@@ -290,6 +292,9 @@ class VpnSettingsViewModel(
private fun Settings.getWireguardPort() =
relaySettings.relayConstraints.wireguardConstraints.port
+ private fun Settings.getDeviceIpVersion() =
+ relaySettings.relayConstraints.wireguardConstraints.ipVersion
+
private fun InetAddress.isLocalAddress(): Boolean {
return isLinkLocalAddress || isSiteLocalAddress
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt
index e8ccf8f4a0..6e91294257 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.viewmodel
import net.mullvad.mullvadvpn.compose.state.VpnSettingsUiState
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.DefaultDnsOptions
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.Mtu
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
import net.mullvad.mullvadvpn.lib.model.Port
@@ -24,6 +25,7 @@ data class VpnSettingsViewModelState(
val availablePortRanges: List<PortRange>,
val systemVpnSettingsAvailable: Boolean,
val autoStartAndConnectOnBoot: Boolean,
+ val deviceIpVersion: Constraint<IpVersion>,
) {
val isCustomWireguardPort =
selectedWireguardPort is Constraint.Only &&
@@ -45,6 +47,7 @@ data class VpnSettingsViewModelState(
availablePortRanges,
systemVpnSettingsAvailable,
autoStartAndConnectOnBoot,
+ deviceIpVersion,
)
companion object {
@@ -64,6 +67,7 @@ data class VpnSettingsViewModelState(
availablePortRanges = emptyList(),
systemVpnSettingsAvailable = false,
autoStartAndConnectOnBoot = false,
+ deviceIpVersion = Constraint.Any,
)
}
}
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/SelectedLocationUseCaseTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/SelectedLocationUseCaseTest.kt
index deef7b7ab9..9974da6a17 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/SelectedLocationUseCaseTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/usecase/SelectedLocationUseCaseTest.kt
@@ -48,6 +48,7 @@ class SelectedLocationUseCaseTest {
isMultihopEnabled = true,
entryLocation = entryLocation,
port = Constraint.Any,
+ ipVersion = Constraint.Any,
)
selectedLocation.value = exitLocation
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/MultihopViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/MultihopViewModelTest.kt
index 34cb1353bb..c51d7e9f48 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/MultihopViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/MultihopViewModelTest.kt
@@ -48,6 +48,7 @@ class MultihopViewModelTest {
isMultihopEnabled = true,
entryLocation = Constraint.Any,
port = Constraint.Any,
+ ipVersion = Constraint.Any,
)
// Act, Assert
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SettingsViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SettingsViewModelTest.kt
index 7bc05df05c..b71d217408 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SettingsViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/SettingsViewModelTest.kt
@@ -108,6 +108,7 @@ class SettingsViewModelTest {
isMultihopEnabled = true,
entryLocation = Constraint.Any,
port = Constraint.Any,
+ ipVersion = Constraint.Any,
)
// Act, Assert
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt
index aae283e91e..9d7ed39622 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.viewmodel
import androidx.lifecycle.viewModelScope
import app.cash.turbine.test
import arrow.core.right
+import io.mockk.Awaits
import io.mockk.Runs
import io.mockk.coEvery
import io.mockk.coVerify
@@ -18,10 +19,10 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
-import mullvad_daemon.management_interface.daitaSettings
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.model.Constraint
import net.mullvad.mullvadvpn.lib.model.DaitaSettings
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.Mtu
import net.mullvad.mullvadvpn.lib.model.Port
import net.mullvad.mullvadvpn.lib.model.PortRange
@@ -163,6 +164,7 @@ class VpnSettingsViewModelTest {
every { mockRelaySettings.relayConstraints } returns mockRelayConstraints
every { mockRelayConstraints.wireguardConstraints } returns mockWireguardConstraints
every { mockWireguardConstraints.port } returns expectedPort
+ every { mockWireguardConstraints.ipVersion } returns Constraint.Any
every { mockSettings.tunnelOptions } returns
TunnelOptions(
wireguard =
@@ -193,6 +195,7 @@ class VpnSettingsViewModelTest {
port = wireguardPort,
isMultihopEnabled = false,
entryLocation = Constraint.Any,
+ ipVersion = Constraint.Any,
)
coEvery { mockWireguardConstraintsRepository.setWireguardPort(any()) } returns
Unit.right()
@@ -249,4 +252,42 @@ class VpnSettingsViewModelTest {
mockAutoStartAndConnectOnBootRepository.setAutoStartAndConnectOnBoot(targetState)
}
}
+
+ @Test
+ fun `when device ip version is IPv6 then UiState should be IPv6`() = runTest {
+ // Arrange
+ val ipVersion = Constraint.Only(IpVersion.IPV6)
+ val mockSettings = mockk<Settings>(relaxed = true)
+ every { mockSettings.relaySettings.relayConstraints.wireguardConstraints.ipVersion } returns
+ ipVersion
+ every { mockSettings.tunnelOptions.wireguard } returns
+ WireguardTunnelOptions(
+ mtu = Mtu(0),
+ quantumResistant = QuantumResistantState.Off,
+ daitaSettings = DaitaSettings(enabled = false, directOnly = false),
+ )
+ every { mockSettings.relaySettings.relayConstraints.wireguardConstraints.port } returns
+ Constraint.Any
+
+ // Act, Assert
+ viewModel.uiState.test {
+ // Default value
+ awaitItem()
+ mockSettingsUpdate.value = mockSettings
+ assertEquals(ipVersion, awaitItem().deviceIpVersion)
+ }
+ }
+
+ @Test
+ fun `calling onDeviceIpVersionSelected should call setDeviceIpVersion`() = runTest {
+ // Arrange
+ val targetState = Constraint.Only(IpVersion.IPV4)
+ coEvery { mockWireguardConstraintsRepository.setDeviceIpVersion(targetState) } just Awaits
+
+ // Act
+ viewModel.onDeviceIpVersionSelected(targetState)
+
+ // Assert
+ coVerify(exactly = 1) { mockWireguardConstraintsRepository.setDeviceIpVersion(targetState) }
+ }
}
diff --git a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt
index e529f29ae5..44447ee866 100644
--- a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt
+++ b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt
@@ -76,6 +76,7 @@ import net.mullvad.mullvadvpn.lib.model.GetAccountHistoryError
import net.mullvad.mullvadvpn.lib.model.GetDeviceListError
import net.mullvad.mullvadvpn.lib.model.GetDeviceStateError
import net.mullvad.mullvadvpn.lib.model.GetVersionInfoError
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.LoginAccountError
import net.mullvad.mullvadvpn.lib.model.LogoutAccountError
import net.mullvad.mullvadvpn.lib.model.NameAlreadyExists
@@ -125,6 +126,7 @@ import net.mullvad.mullvadvpn.lib.model.addresses
import net.mullvad.mullvadvpn.lib.model.customOptions
import net.mullvad.mullvadvpn.lib.model.enabled
import net.mullvad.mullvadvpn.lib.model.entryLocation
+import net.mullvad.mullvadvpn.lib.model.ipVersion
import net.mullvad.mullvadvpn.lib.model.isMultihopEnabled
import net.mullvad.mullvadvpn.lib.model.location
import net.mullvad.mullvadvpn.lib.model.ownership
@@ -784,6 +786,22 @@ class ManagementService(
.mapLeft(SetWireguardConstraintsError::Unknown)
.mapEmpty()
+ suspend fun setDeviceIpVersion(
+ ipVersion: Constraint<IpVersion>
+ ): Either<SetWireguardConstraintsError, Unit> =
+ Either.catch {
+ val relaySettings = getSettings().relaySettings
+ val updated =
+ RelaySettings.relayConstraints.wireguardConstraints.ipVersion.set(
+ relaySettings,
+ ipVersion,
+ )
+ grpc.setRelaySettings(updated.fromDomain())
+ }
+ .onLeft { Logger.e("Set multihop error") }
+ .mapLeft(SetWireguardConstraintsError::Unknown)
+ .mapEmpty()
+
private fun <A> Either<A, Empty>.mapEmpty() = map {}
private inline fun <B, C> Either<Throwable, B>.mapLeftStatus(
diff --git a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/FromDomain.kt b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/FromDomain.kt
index e4d3e84a4f..113a5fc847 100644
--- a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/FromDomain.kt
+++ b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/FromDomain.kt
@@ -13,6 +13,7 @@ import net.mullvad.mullvadvpn.lib.model.DefaultDnsOptions
import net.mullvad.mullvadvpn.lib.model.DnsOptions
import net.mullvad.mullvadvpn.lib.model.DnsState
import net.mullvad.mullvadvpn.lib.model.GeoLocationId
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.NewAccessMethodSetting
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
import net.mullvad.mullvadvpn.lib.model.ObfuscationSettings
@@ -135,6 +136,12 @@ internal fun WireguardConstraints.fromDomain(): ManagementInterface.WireguardCon
is Constraint.Only -> setPort(port.value.value)
}
}
+ .apply {
+ when (val ipVersion = this@fromDomain.ipVersion) {
+ is Constraint.Any -> clearIpVersion()
+ is Constraint.Only -> setIpVersion(ipVersion.value.fromDomain())
+ }
+ }
.build()
internal fun Ownership.fromDomain(): ManagementInterface.Ownership =
@@ -260,3 +267,9 @@ internal fun DaitaSettings.fromDomain(): ManagementInterface.DaitaSettings =
.setEnabled(enabled)
.setDirectOnly(directOnly)
.build()
+
+internal fun IpVersion.fromDomain(): ManagementInterface.IpVersion =
+ when (this) {
+ IpVersion.IPV4 -> ManagementInterface.IpVersion.V4
+ IpVersion.IPV6 -> ManagementInterface.IpVersion.V6
+ }
diff --git a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/ToDomain.kt b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/ToDomain.kt
index 717bf401f4..6ee772521b 100644
--- a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/ToDomain.kt
+++ b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/ToDomain.kt
@@ -41,6 +41,7 @@ import net.mullvad.mullvadvpn.lib.model.ErrorStateCause
import net.mullvad.mullvadvpn.lib.model.FeatureIndicator
import net.mullvad.mullvadvpn.lib.model.GeoIpLocation
import net.mullvad.mullvadvpn.lib.model.GeoLocationId
+import net.mullvad.mullvadvpn.lib.model.IpVersion
import net.mullvad.mullvadvpn.lib.model.Mtu
import net.mullvad.mullvadvpn.lib.model.ObfuscationEndpoint
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
@@ -374,6 +375,12 @@ internal fun ManagementInterface.WireguardConstraints.toDomain(): WireguardConst
},
isMultihopEnabled = useMultihop,
entryLocation = entryLocation.toDomain(),
+ ipVersion =
+ if (hasIpVersion()) {
+ Constraint.Only(ipVersion.toDomain())
+ } else {
+ Constraint.Any
+ },
)
internal fun ManagementInterface.Ownership.toDomain(): Constraint<Ownership> =
@@ -689,3 +696,10 @@ internal fun ManagementInterface.FeatureIndicator.toDomain() =
ManagementInterface.FeatureIndicator.UNRECOGNIZED ->
error("Feature not supported ${this.name}")
}
+
+internal fun ManagementInterface.IpVersion.toDomain() =
+ when (this) {
+ ManagementInterface.IpVersion.V4 -> IpVersion.IPV4
+ ManagementInterface.IpVersion.V6 -> IpVersion.IPV6
+ ManagementInterface.IpVersion.UNRECOGNIZED -> error("Not supported ${this.name}")
+ }
diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/IpVersion.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/IpVersion.kt
new file mode 100644
index 0000000000..176809244c
--- /dev/null
+++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/IpVersion.kt
@@ -0,0 +1,6 @@
+package net.mullvad.mullvadvpn.lib.model
+
+enum class IpVersion {
+ IPV4,
+ IPV6,
+}
diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/WireguardConstraints.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/WireguardConstraints.kt
index dcc3a957df..33887506a1 100644
--- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/WireguardConstraints.kt
+++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/WireguardConstraints.kt
@@ -7,6 +7,7 @@ data class WireguardConstraints(
val port: Constraint<Port>,
val isMultihopEnabled: Boolean,
val entryLocation: Constraint<RelayItemId>,
+ val ipVersion: Constraint<IpVersion>,
) {
companion object
}
diff --git a/android/lib/resource/src/main/res/values-da/strings.xml b/android/lib/resource/src/main/res/values-da/strings.xml
index f8be041d9e..d07ded8dc2 100644
--- a/android/lib/resource/src/main/res/values-da/strings.xml
+++ b/android/lib/resource/src/main/res/values-da/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Tilsluttet</string>
<string name="connecting_to_daemon">Opretter forbindelse til Mullvad-systemtjeneste...</string>
<string name="connection_details_in">Ind</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Ud</string>
<string name="continue_login">Fortsæt med login</string>
<string name="copied_logs_to_clipboard">Kopierede logfiler til udklipsholder</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Du har fjernet denne enhed. For at oprette forbindelse igen skal du logge ind igen.</string>
<string name="device_inactive_title">Enheden er inaktiv</string>
<string name="device_inactive_unblock_warning">Hvis du logger på, ophæves blokeringen af internettet på denne enhed.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Enhedsnavn</string>
<string name="device_name_info_first_paragraph">Dette er det navn, der er tildelt enheden. Hver enhed, der er logget på en Mullvad-konto, får et unikt navn, der hjælper dig med at identificere den, når du administrerer dine enheder i appen eller på webstedet.</string>
<string name="device_name_info_second_paragraph">Du kan have op til 5 enheder logget ind på én Mullvad-konto.</string>
diff --git a/android/lib/resource/src/main/res/values-de/strings.xml b/android/lib/resource/src/main/res/values-de/strings.xml
index 4bd5c18ad7..d9e0ed2933 100644
--- a/android/lib/resource/src/main/res/values-de/strings.xml
+++ b/android/lib/resource/src/main/res/values-de/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Verbunden</string>
<string name="connecting_to_daemon">Verbindung zum Mullvad-Systemdienst wird hergestellt...</string>
<string name="connection_details_in">Eingehend</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Ausgehend</string>
<string name="continue_login">Weiter mit Anmeldung</string>
<string name="copied_logs_to_clipboard">Protokolle in Zwischenablage kopiert</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Sie haben dieses Gerät entfernt. Um sich erneut zu verbinden, müssen Sie sich erneut anmelden.</string>
<string name="device_inactive_title">Gerät ist inaktiv</string>
<string name="device_inactive_unblock_warning">Wenn Sie mit der Anmeldung fortfahren, wird die Internetsperre auf diesem Gerät aufgehoben.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Gerätename</string>
<string name="device_name_info_first_paragraph">Dies ist der dem Gerät zugewiesene Name. Jedes Gerät, das in einem Mullvad-Konto angemeldet ist, erhält einen eindeutigen Namen, mit dem Sie es identifizieren können, wenn Sie Ihre Geräte in der App oder auf der Website verwalten.</string>
<string name="device_name_info_second_paragraph">Es sind pro Mullvad-Konto bis zu 5 angemeldete Geräte möglich.</string>
diff --git a/android/lib/resource/src/main/res/values-es/strings.xml b/android/lib/resource/src/main/res/values-es/strings.xml
index f606f2bdf1..e453d4d5d8 100644
--- a/android/lib/resource/src/main/res/values-es/strings.xml
+++ b/android/lib/resource/src/main/res/values-es/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Conectado</string>
<string name="connecting_to_daemon">Conectando al servicio del sistema Mullvad…</string>
<string name="connection_details_in">Entrada</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Salida</string>
<string name="continue_login">Iniciar sesión</string>
<string name="copied_logs_to_clipboard">Registros copiados en el portapapeles</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Ha quitado este dispositivo. Vuelva a iniciar la sesión para conectarse.</string>
<string name="device_inactive_title">El dispositivo está inactivo</string>
<string name="device_inactive_unblock_warning">Al iniciar la sesión, se desbloqueará el acceso a Internet en este dispositivo.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Nombre del dispositivo</string>
<string name="device_name_info_first_paragraph">Este es el nombre asignado al dispositivo. Cada dispositivo conectado a una cuenta de Mullvad recibe un nombre único que ayuda a identificarlo cuando gestiona sus dispositivos en la aplicación o en el sitio web.</string>
<string name="device_name_info_second_paragraph">Puede tener hasta 5 dispositivos conectados a una cuenta de Mullvad.</string>
diff --git a/android/lib/resource/src/main/res/values-fi/strings.xml b/android/lib/resource/src/main/res/values-fi/strings.xml
index d0a9fb8c53..ee65000e90 100644
--- a/android/lib/resource/src/main/res/values-fi/strings.xml
+++ b/android/lib/resource/src/main/res/values-fi/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Yhdistetty</string>
<string name="connecting_to_daemon">Yhdistetään Mullvad-järjestelmäpalveluun...</string>
<string name="connection_details_in">Saapuva</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Lähtevä</string>
<string name="continue_login">Jatka kirjautumista</string>
<string name="copied_logs_to_clipboard">Lokit kopioitu leikepöydälle</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Olet poistanut tämän laitteen. Jos haluat muodostaa yhteyden uudelleen, sinun täytyy kirjautua takaisin sisään.</string>
<string name="device_inactive_title">Laite ei ole aktiivinen</string>
<string name="device_inactive_unblock_warning">Kirjautumiseen siirtyminen purkaa internetin käytön eston tältä laitteelta.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Laitteen nimi</string>
<string name="device_name_info_first_paragraph">Tämä on laitteelle annettu nimi. Jokainen Mullvad-tilille kirjautunut laite saa yksilöllisen nimen, jonka avulla sen voi tunnistaa laitteiden hallinnassa sovelluksessa tai verkkosivustolla.</string>
<string name="device_name_info_second_paragraph">Yhdelle Mullvad-tilille voi olla kirjautuneena enintään viisi laitetta.</string>
diff --git a/android/lib/resource/src/main/res/values-fr/strings.xml b/android/lib/resource/src/main/res/values-fr/strings.xml
index 7640d861e6..adce2cbacf 100644
--- a/android/lib/resource/src/main/res/values-fr/strings.xml
+++ b/android/lib/resource/src/main/res/values-fr/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Connecté</string>
<string name="connecting_to_daemon">Connexion au service système Mullvad...</string>
<string name="connection_details_in">Entrante</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Sortante</string>
<string name="continue_login">Continuer avec la connexion</string>
<string name="copied_logs_to_clipboard">Journaux copiés dans le presse-papiers</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Vous avez supprimé cet appareil. Vous devrez vous reconnecter pour connecter cet appareil à nouveau.</string>
<string name="device_inactive_title">L\'appareil est inactif</string>
<string name="device_inactive_unblock_warning">Aller à la connexion débloquera la connexion Internet sur cet appareil.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Nom de l\'appareil</string>
<string name="device_name_info_first_paragraph">Il s\'agit du nom attribué à l\'appareil. Chaque appareil connecté à un compte Mullvad reçoit un nom unique qui vous aide à l\'identifier lorsque vous gérez vos appareils dans l\'application ou sur le site Web.</string>
<string name="device_name_info_second_paragraph">Vous pouvez connecter jusqu\'à 5 appareils au même compte Mullvad.</string>
diff --git a/android/lib/resource/src/main/res/values-it/strings.xml b/android/lib/resource/src/main/res/values-it/strings.xml
index aaf91a61cb..162768f29e 100644
--- a/android/lib/resource/src/main/res/values-it/strings.xml
+++ b/android/lib/resource/src/main/res/values-it/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Connesso</string>
<string name="connecting_to_daemon">Connessione al servizio del sistema Mullvad...</string>
<string name="connection_details_in">Ricezione</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Invio</string>
<string name="continue_login">Continua con il login</string>
<string name="copied_logs_to_clipboard">Log copiati negli appunti</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Hai rimosso questo dispositivo. Per riconnetterti, dovrai effettuare nuovamente il login.</string>
<string name="device_inactive_title">Il dispositivo è inattivo</string>
<string name="device_inactive_unblock_warning">Andare al login sbloccherà Internet su questo dispositivo.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Nome dispositivo</string>
<string name="device_name_info_first_paragraph">Questo è il nome assegnato al dispositivo. Ogni dispositivo connesso a un account Mullvad riceve un nome univoco che ti aiuta a identificarlo quando gestisci i tuoi dispositivi nell\'app o sul sito web.</string>
<string name="device_name_info_second_paragraph">Puoi avere fino a 5 dispositivi registrati su un account Mullvad.</string>
diff --git a/android/lib/resource/src/main/res/values-ja/strings.xml b/android/lib/resource/src/main/res/values-ja/strings.xml
index 13ae8988c5..620fa89d2c 100644
--- a/android/lib/resource/src/main/res/values-ja/strings.xml
+++ b/android/lib/resource/src/main/res/values-ja/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">接続済み</string>
<string name="connecting_to_daemon">Mullvad システムサービスに接続中...</string>
<string name="connection_details_in">内側</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">外側</string>
<string name="continue_login">ログインを続ける</string>
<string name="copied_logs_to_clipboard">ログをクリップボードにコピーしました</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">このデバイスを削除しました。再度接続するには、ログインし直す必要があります。</string>
<string name="device_inactive_title">デバイスが無効です</string>
<string name="device_inactive_unblock_warning">ログインに進むと、このデバイスのインターネットのブロックが解除されます。</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">デバイス名</string>
<string name="device_name_info_first_paragraph">これはデバイスに割り当てられる名前です。Mullvadアカウントにログインするデバイスごとに一意の名前が付けられるため、アプリまたはウェブサイトでデバイスを管理する際にデバイスを区別しやすくなります。</string>
<string name="device_name_info_second_paragraph">1つのMullvadアカウントで最大5台のデバイスにログインできます。</string>
diff --git a/android/lib/resource/src/main/res/values-ko/strings.xml b/android/lib/resource/src/main/res/values-ko/strings.xml
index 96382e5f17..75eb364d27 100644
--- a/android/lib/resource/src/main/res/values-ko/strings.xml
+++ b/android/lib/resource/src/main/res/values-ko/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">연결됨</string>
<string name="connecting_to_daemon">Mullvad 시스템 서비스에 연결하는 중...</string>
<string name="connection_details_in">인</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">아웃</string>
<string name="continue_login">로그인 계속하기</string>
<string name="copied_logs_to_clipboard">로그를 클립보드에 복사했습니다.</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">이 장치를 제거했습니다. 다시 연결하려면 다시 로그인해야 합니다.</string>
<string name="device_inactive_title">장치가 비활성 상태입니다.</string>
<string name="device_inactive_unblock_warning">로그인하면 이 장치에서 인터넷 차단이 해제됩니다.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">장치 이름</string>
<string name="device_name_info_first_paragraph">이것은 장치에 할당된 이름입니다. Mullvad 계정에 로그인된 각 장치에는 앱이나 웹사이트에서 장치를 관리할 때 장치를 보다 쉽게 식별할 수 있는 고유한 이름이 부여됩니다.</string>
<string name="device_name_info_second_paragraph">최대 5개의 장치에서 하나의 Mullvad 계정에 로그인할 수 있습니다.</string>
diff --git a/android/lib/resource/src/main/res/values-my/strings.xml b/android/lib/resource/src/main/res/values-my/strings.xml
index d4e64f3369..23cbf3eb9c 100644
--- a/android/lib/resource/src/main/res/values-my/strings.xml
+++ b/android/lib/resource/src/main/res/values-my/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">ချိတ်ဆက်ပြီး</string>
<string name="connecting_to_daemon">Mullvad စနစ် ဝန်ဆောင်မှုနှင့် ချိတ်ဆက်နေဆဲ...</string>
<string name="connection_details_in">အဝင်</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">အထွက်</string>
<string name="continue_login">ဆက်လက် ဝင်ရောက်ရန်</string>
<string name="copied_logs_to_clipboard">ကလစ်ဘုတ်တွင် မှတ်တမ်းများ ကူးယူပြီး</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">ဤစက်ကို ဖယ်ရှားပြီး ဖြစ်သည်။ ထပ်မံချိတ်ဆက်ရန်အတွက် ပြန်လည် ဝင်ရောက်ရန် လိုပါသည်။</string>
<string name="device_inactive_title">စက်သည် သက်ဝင်လုပ်ဆောင်မှု မရှိပါ</string>
<string name="device_inactive_unblock_warning">ဝင်ရောက်ရန်သွားခြင်းဖြင့် ဤစက်တွင် အင်တာနက်ကို ပိတ်ဆို့ထားမှုမှ ဖယ်ရှားပါလိမ့်မည်။</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">စက်အမည်</string>
<string name="device_name_info_first_paragraph">ဤအမည်မှာ စက်အတွက် သတ်မှတ်ထားသော အမည် ဖြစ်ပါသည်။ Mullvad အကောင့်တစ်ခုတွင် ဝင်ရောက်ထားသည့် စက်တစ်ခုစီသည် တစ်မူထူးခြားသည့် အမည်တစ်ခု ရရှိမည်ဖြစ်ပြီး အက်ပ် သို့မဟုတ် ဝက်ဘ်ဆိုက်ပေါ်တွင် သင့်စက်များကို စီမံသည့်အခါ သင်အနေဖြင့် ကွဲကွဲပြားပြားသိရှိအောင် ကူညီပေးပါသည်။</string>
<string name="device_name_info_second_paragraph">Mullvad အကောင့်တစ်ခုတွင် စက် 5 ခုအထိ ဝင်ရောက်ထားနိုင်ပါသည်။</string>
diff --git a/android/lib/resource/src/main/res/values-nb/strings.xml b/android/lib/resource/src/main/res/values-nb/strings.xml
index f3aacf6cfb..423513580d 100644
--- a/android/lib/resource/src/main/res/values-nb/strings.xml
+++ b/android/lib/resource/src/main/res/values-nb/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Tilkoblet</string>
<string name="connecting_to_daemon">Kobler til Mullvads systemtjeneste ...</string>
<string name="connection_details_in">Inngående</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Utgående</string>
<string name="continue_login">Fortsett med pålogging</string>
<string name="copied_logs_to_clipboard">Logger kopiert til utklippstavlen</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Du har fjernet denne enheten. For å koble til igjen, må du logge inn på nytt.</string>
<string name="device_inactive_title">Enheten er inaktiv</string>
<string name="device_inactive_unblock_warning">Å gå til pålogging vil oppheve blokkeringen av internettet på denne enheten.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Enhetsnavn</string>
<string name="device_name_info_first_paragraph">Dette er navnet som er tildelt enheten. Enhver enhet som er logget inn på en Mullvad-konto, får et unikt navn som gjør det enklere for deg å identifisere den når du administrerer enheten i appen eller på nettsiden.</string>
<string name="device_name_info_second_paragraph">Du kan ha opptil fem enheter logget inn på samme Mullvad-konto.</string>
diff --git a/android/lib/resource/src/main/res/values-nl/strings.xml b/android/lib/resource/src/main/res/values-nl/strings.xml
index 95a52ae7d1..e75b7001a4 100644
--- a/android/lib/resource/src/main/res/values-nl/strings.xml
+++ b/android/lib/resource/src/main/res/values-nl/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Verbonden</string>
<string name="connecting_to_daemon">Verbinden met Mullvad-systeemdienst...</string>
<string name="connection_details_in">In</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Uit</string>
<string name="continue_login">Doorgaan met aanmelden</string>
<string name="copied_logs_to_clipboard">Logs gekopieerd naar klembord</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">U hebt dit apparaat verwijderd. U moet zich opnieuw aanmelden om het opnieuw te verbinden.</string>
<string name="device_inactive_title">Apparaat is niet actief</string>
<string name="device_inactive_unblock_warning">Als u naar aanmelden gaat, wordt het blokkeren van internet op dit apparaat opgeheven.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Apparaatnaam</string>
<string name="device_name_info_first_paragraph">Dit is de naam die aan het apparaat is toegewezen. Elk apparaat dat is aangemeld op een Mullvad-account, krijgt een unieke naam waarmee u het kunt identificeren wanneer u uw apparaten beheert in de app of op de website.</string>
<string name="device_name_info_second_paragraph">U kunt maximaal 5 apparaten aangemeld hebben op één Mullvad-account.</string>
diff --git a/android/lib/resource/src/main/res/values-pl/strings.xml b/android/lib/resource/src/main/res/values-pl/strings.xml
index 2633bc6a19..4469e94248 100644
--- a/android/lib/resource/src/main/res/values-pl/strings.xml
+++ b/android/lib/resource/src/main/res/values-pl/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Połączono</string>
<string name="connecting_to_daemon">Łączenie z usługą systemową Mullvad...</string>
<string name="connection_details_in">Wejście</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Wyjście</string>
<string name="continue_login">Kontynuuj logowanie</string>
<string name="copied_logs_to_clipboard">Skopiowano dzienniki do schowka</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Urządzenie usunięto. Aby połączyć się ponownie, musisz się ponownie zalogować.</string>
<string name="device_inactive_title">Urządzenie nieaktywne</string>
<string name="device_inactive_unblock_warning">Przejście do logowania odblokuje Internet na tym urządzeniu.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Nazwa urządzenia</string>
<string name="device_name_info_first_paragraph">Jest to nazwa przypisana do urządzenia. Każde urządzenie zalogowane na koncie Mullvad otrzymuje unikalną nazwę, która pozwala zidentyfikować je podczas zarządzania urządzeniami w aplikacji lub za pośrednictwem witryny internetowej.</string>
<string name="device_name_info_second_paragraph">Na jednym koncie Mullvad może być zalogowanych maksymalnie 5 urządzeń.</string>
diff --git a/android/lib/resource/src/main/res/values-pt/strings.xml b/android/lib/resource/src/main/res/values-pt/strings.xml
index f7a0b1f0f0..99ed6ef2e4 100644
--- a/android/lib/resource/src/main/res/values-pt/strings.xml
+++ b/android/lib/resource/src/main/res/values-pt/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Ligado</string>
<string name="connecting_to_daemon">A ligar-se ao serviço de sistema Mulvad...</string>
<string name="connection_details_in">Entrada</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Saída</string>
<string name="continue_login">Continuar com a ligação</string>
<string name="copied_logs_to_clipboard">Registos copiados para a área de transferência</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Removeu este dispositivo. Para voltar a ligar o dispositivo, terá de voltar a iniciar a sessão.</string>
<string name="device_inactive_title">O dispositivo está desativado</string>
<string name="device_inactive_unblock_warning">Ir para a ligação irá desbloquear a Internet neste dispositivo.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Nome do dispositivo</string>
<string name="device_name_info_first_paragraph">Este é o nome atribuído ao dispositivo. Cada dispositivo com sessão iniciada numa conta Mullvad recebe um nome único que lhe ajuda a identificá-lo quando gere os seus dispositivos na app ou no site.</string>
<string name="device_name_info_second_paragraph">Pode ter até 5 dispositivos com sessão iniciada numa só conta Mullvad.</string>
diff --git a/android/lib/resource/src/main/res/values-ru/strings.xml b/android/lib/resource/src/main/res/values-ru/strings.xml
index 6ab83b6455..8505588367 100644
--- a/android/lib/resource/src/main/res/values-ru/strings.xml
+++ b/android/lib/resource/src/main/res/values-ru/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Подключено</string>
<string name="connecting_to_daemon">Подключение к системному сервису Mullvad...</string>
<string name="connection_details_in">Вход</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Выход</string>
<string name="continue_login">Войти</string>
<string name="copied_logs_to_clipboard">Журналы скопированы в буфер обмена</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Вы удалили это устройство. Чтобы снова подключиться, нужно будет выполнить вход.</string>
<string name="device_inactive_title">Устройство неактивно</string>
<string name="device_inactive_unblock_warning">Вход в профиль разблокирует Интернет на этом устройстве.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Имя устройства</string>
<string name="device_name_info_first_paragraph">Это имя, присвоенное устройству. Каждое устройство, подключенное к учетной записи Mullvad, получает уникальное имя, которое помогает вам идентифицировать его при управлении устройствами в приложении или на сайте.</string>
<string name="device_name_info_second_paragraph">К одной учетной записи Mullvad можно подключить до 5 устройств.</string>
diff --git a/android/lib/resource/src/main/res/values-sv/strings.xml b/android/lib/resource/src/main/res/values-sv/strings.xml
index 63463d3d08..26c1203317 100644
--- a/android/lib/resource/src/main/res/values-sv/strings.xml
+++ b/android/lib/resource/src/main/res/values-sv/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Ansluten</string>
<string name="connecting_to_daemon">Ansluter till Mullvads systemtjänst...</string>
<string name="connection_details_in">In</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Ut</string>
<string name="continue_login">Fortsätt med inloggning</string>
<string name="copied_logs_to_clipboard">Loggarna har kopierats till urklipp</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Du har tagit bort den här enheten. Du måste logga in igen för att återansluta.</string>
<string name="device_inactive_title">Enheten är inaktiv</string>
<string name="device_inactive_unblock_warning">Om du loggar in tas blockering av internet bort på den här enheten.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Enhetens namn</string>
<string name="device_name_info_first_paragraph">Det här är namnet som tilldelas enheten. Varje enhet som är inloggad på ett Mullvad-konto får ett unikt namn som hjälper dig att identifiera den när du hanterar dina enheter i appen eller på webbplatsen.</string>
<string name="device_name_info_second_paragraph">Upp till fem enheter kan vara inloggade på ett Mullvad-konto.</string>
diff --git a/android/lib/resource/src/main/res/values-th/strings.xml b/android/lib/resource/src/main/res/values-th/strings.xml
index 6d9a6a05b1..0a45d0997d 100644
--- a/android/lib/resource/src/main/res/values-th/strings.xml
+++ b/android/lib/resource/src/main/res/values-th/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">เชื่อมต่อแล้ว</string>
<string name="connecting_to_daemon">กำลังเชื่อมต่อบริการของระบบ Mullvad...</string>
<string name="connection_details_in">เข้า</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">ออก</string>
<string name="continue_login">เข้าสู่ระบบต่อ</string>
<string name="copied_logs_to_clipboard">คัดลอกบันทึกล็อกไปยังคลิปบอร์ดแล้ว</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">คุณได้ลบอุปกรณ์เครื่องนี้แล้ว หากต้องการเชื่อมต่ออีกครั้ง คุณจะต้องเข้าสู่ระบบใหม่อีกครั้ง</string>
<string name="device_inactive_title">อุปกรณ์ไม่ได้ใช้งาน</string>
<string name="device_inactive_unblock_warning">การไปที่ส่วนเข้าสู่ระบบจะปลดบล็อกอินเทอร์เน็ตบนอุปกรณ์เครื่องนี้</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">ชื่ออุปกรณ์</string>
<string name="device_name_info_first_paragraph">นี่เป็นชื่อที่มอบหมายให้กับอุปกรณ์ อุปกรณ์แต่ละเครื่องที่ลงชื่อเข้าใช้บนบัญชี Mullvad จะได้รับชื่อเฉพาะ ที่จะช่วยคุณระบุอุปกรณ์ ในขณะที่คุณจัดการอุปกรณ์ของคุณในแอปหรือบนเว็บไซต์</string>
<string name="device_name_info_second_paragraph">คุณสามารถลงชื่อเข้าใช้อุปกรณ์ได้สูงสุด 5 เครื่อง กับบัญชี Mullvad หนึ่งบัญชี</string>
diff --git a/android/lib/resource/src/main/res/values-tr/strings.xml b/android/lib/resource/src/main/res/values-tr/strings.xml
index 565d28eda5..87e78ff149 100644
--- a/android/lib/resource/src/main/res/values-tr/strings.xml
+++ b/android/lib/resource/src/main/res/values-tr/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">Bağlandı</string>
<string name="connecting_to_daemon">Mullvad sistem hizmetlerine bağlanılıyor...</string>
<string name="connection_details_in">Giriş</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">Çıkış</string>
<string name="continue_login">Giriş yapmak için devam et</string>
<string name="copied_logs_to_clipboard">Günlükler panoya kopyalandı</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">Bu cihazı kaldırdın. Tekrar bağlanmak için yeniden giriş yapmanız gerekecek.</string>
<string name="device_inactive_title">Cihaz etkin değil</string>
<string name="device_inactive_unblock_warning">Giriş yapmak bu cihazdaki internet engelini kaldıracaktır.</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">Cihaz adı</string>
<string name="device_name_info_first_paragraph">Bu, cihaza atanan addır. Mullvad hesabında oturum açan her cihaza, uygulamadaki veya web sitesindeki cihazlarınızı yönetirken tanımlamanıza yardımcı olacak benzersiz bir ad verilir.</string>
<string name="device_name_info_second_paragraph">Bir Mullvad hesabı ile en fazla 5 cihazda oturum açabilirsiniz.</string>
diff --git a/android/lib/resource/src/main/res/values-zh-rCN/strings.xml b/android/lib/resource/src/main/res/values-zh-rCN/strings.xml
index 8dbbe5d334..ab9fd330d0 100644
--- a/android/lib/resource/src/main/res/values-zh-rCN/strings.xml
+++ b/android/lib/resource/src/main/res/values-zh-rCN/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">已连接</string>
<string name="connecting_to_daemon">正在连接到 Mullvad 系统服务…</string>
<string name="connection_details_in">内部</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">外部</string>
<string name="continue_login">继续登录</string>
<string name="copied_logs_to_clipboard">已将日志复制到剪贴板</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">您已移除此设备。要重新连接,您需要重新登录。</string>
<string name="device_inactive_title">设备处于非活动状态</string>
<string name="device_inactive_unblock_warning">前往登录将在此设备上解除阻止互联网。</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">设备名称</string>
<string name="device_name_info_first_paragraph">这是为设备分配的名称。每台登录 Mulvad 帐户的设备都会获得一个唯一名称,有助于您在应用或网站上管理设备时识别各个设备。</string>
<string name="device_name_info_second_paragraph">一个 Mulvad 帐户最多可以登录 5 台设备。</string>
diff --git a/android/lib/resource/src/main/res/values-zh-rTW/strings.xml b/android/lib/resource/src/main/res/values-zh-rTW/strings.xml
index 582d2594ea..376b21d6b1 100644
--- a/android/lib/resource/src/main/res/values-zh-rTW/strings.xml
+++ b/android/lib/resource/src/main/res/values-zh-rTW/strings.xml
@@ -79,8 +79,6 @@
<string name="connected">已連線</string>
<string name="connecting_to_daemon">連線 Mullvad 系統服務中...</string>
<string name="connection_details_in">入境</string>
- <string name="connection_details_ipv4">IPv4</string>
- <string name="connection_details_ipv6">IPv6</string>
<string name="connection_details_out">出境</string>
<string name="continue_login">繼續登入</string>
<string name="copied_logs_to_clipboard">已將記錄複製到剪貼簿</string>
@@ -124,6 +122,8 @@
<string name="device_inactive_description">您已移除此裝置。若要重新連線,您需要重新登入。</string>
<string name="device_inactive_title">裝置處於非活動狀態</string>
<string name="device_inactive_unblock_warning">若前往登入,則會在此裝置上解除對網際網路的封鎖。</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
<string name="device_name">裝置名稱</string>
<string name="device_name_info_first_paragraph">這是系統指派給裝置的名稱。每台登入 Mulvad 帳戶的裝置都會獲得一個獨特名稱,有助於您在應用程式或網站上管理裝置時識別各台裝置。</string>
<string name="device_name_info_second_paragraph">一個 Mulvad 帳戶最多可以登入 5 台裝置。</string>
diff --git a/android/lib/resource/src/main/res/values/strings.xml b/android/lib/resource/src/main/res/values/strings.xml
index 5cb3436a85..26cd58e470 100644
--- a/android/lib/resource/src/main/res/values/strings.xml
+++ b/android/lib/resource/src/main/res/values/strings.xml
@@ -409,4 +409,7 @@
<string name="see_full_changelog">See full changelog</string>
<string name="changelog_empty">No changelog was added for this version</string>
<string name="wg_port_subtitle">Set %s obfuscation to \"Automatic\" or \"Off\" below to activate this setting.</string>
+ <string name="device_ip_version_title">Device IP version</string>
+ <string name="device_ip_version_ipv4">IPv4</string>
+ <string name="device_ip_version_ipv6">IPv6</string>
</resources>