diff --git a/android/CHANGELOG.md b/android/CHANGELOG.md index 76be993cd6ec..8e84283b32e3 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 13ef28dd238c..073c81b6f801 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) -> 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 779b4792b423..2989dba047a0 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) -> 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 c9fd0257c028..ec069001ccbf 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, val systemVpnSettingsAvailable: Boolean, val autoStartAndConnectOnBoot: Boolean, + val deviceIpVersion: Constraint, ) { val isCustomWireguardPort = selectedWireguardPort is Constraint.Only && @@ -48,6 +50,7 @@ data class VpnSettingsUiState( availablePortRanges: List = emptyList(), systemVpnSettingsAvailable: Boolean = false, autoStartAndConnectOnBoot: Boolean = false, + deviceIpVersion: Constraint = 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 093b87cafcbc..f92367bcf622 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) = + 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 90f98fceaa8a..2273ada5e0d3 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) { + 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.asInetAddressList(): List { 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 e8ccf8f4a0d2..6e9129425718 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, val systemVpnSettingsAvailable: Boolean, val autoStartAndConnectOnBoot: Boolean, + val deviceIpVersion: Constraint, ) { 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 deef7b7ab9fb..9974da6a171b 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 34cb1353bbca..c51d7e9f48e0 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 7bc05df05c9c..b71d21740877 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 aae283e91ec4..9d7ed39622b2 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(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 e529f29ae51b..44447ee8666e 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 + ): Either = + 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 Either.mapEmpty() = map {} private inline fun Either.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 e4d3e84a4ff1..113a5fc84716 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 717bf401f4e7..6ee772521b3a 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 = @@ -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 000000000000..176809244ce4 --- /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 dcc3a957dfd2..33887506a137 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, val isMultihopEnabled: Boolean, val entryLocation: Constraint, + val ipVersion: Constraint, ) { 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 f8be041d9e70..d07ded8dc28d 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 @@ Tilsluttet Opretter forbindelse til Mullvad-systemtjeneste... Ind - IPv4 - IPv6 Ud Fortsæt med login Kopierede logfiler til udklipsholder @@ -124,6 +122,8 @@ Du har fjernet denne enhed. For at oprette forbindelse igen skal du logge ind igen. Enheden er inaktiv Hvis du logger på, ophæves blokeringen af internettet på denne enhed. + IPv4 + IPv6 Enhedsnavn 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. Du kan have op til 5 enheder logget ind på én Mullvad-konto. 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 4bd5c18ad7f4..d9e0ed293386 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 @@ Verbunden Verbindung zum Mullvad-Systemdienst wird hergestellt... Eingehend - IPv4 - IPv6 Ausgehend Weiter mit Anmeldung Protokolle in Zwischenablage kopiert @@ -124,6 +122,8 @@ Sie haben dieses Gerät entfernt. Um sich erneut zu verbinden, müssen Sie sich erneut anmelden. Gerät ist inaktiv Wenn Sie mit der Anmeldung fortfahren, wird die Internetsperre auf diesem Gerät aufgehoben. + IPv4 + IPv6 Gerätename 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. Es sind pro Mullvad-Konto bis zu 5 angemeldete Geräte möglich. 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 f606f2bdf1ad..e453d4d5d8e9 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 @@ Conectado Conectando al servicio del sistema Mullvad… Entrada - IPv4 - IPv6 Salida Iniciar sesión Registros copiados en el portapapeles @@ -124,6 +122,8 @@ Ha quitado este dispositivo. Vuelva a iniciar la sesión para conectarse. El dispositivo está inactivo Al iniciar la sesión, se desbloqueará el acceso a Internet en este dispositivo. + IPv4 + IPv6 Nombre del dispositivo 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. Puede tener hasta 5 dispositivos conectados a una cuenta de Mullvad. 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 d0a9fb8c536f..ee65000e90c1 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 @@ Yhdistetty Yhdistetään Mullvad-järjestelmäpalveluun... Saapuva - IPv4 - IPv6 Lähtevä Jatka kirjautumista Lokit kopioitu leikepöydälle @@ -124,6 +122,8 @@ Olet poistanut tämän laitteen. Jos haluat muodostaa yhteyden uudelleen, sinun täytyy kirjautua takaisin sisään. Laite ei ole aktiivinen Kirjautumiseen siirtyminen purkaa internetin käytön eston tältä laitteelta. + IPv4 + IPv6 Laitteen nimi 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. Yhdelle Mullvad-tilille voi olla kirjautuneena enintään viisi laitetta. 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 7640d861e65c..adce2cbacf29 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 @@ Connecté Connexion au service système Mullvad... Entrante - IPv4 - IPv6 Sortante Continuer avec la connexion Journaux copiés dans le presse-papiers @@ -124,6 +122,8 @@ Vous avez supprimé cet appareil. Vous devrez vous reconnecter pour connecter cet appareil à nouveau. L\'appareil est inactif Aller à la connexion débloquera la connexion Internet sur cet appareil. + IPv4 + IPv6 Nom de l\'appareil 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. Vous pouvez connecter jusqu\'à 5 appareils au même compte Mullvad. 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 aaf91a61cb71..162768f29ee1 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 @@ Connesso Connessione al servizio del sistema Mullvad... Ricezione - IPv4 - IPv6 Invio Continua con il login Log copiati negli appunti @@ -124,6 +122,8 @@ Hai rimosso questo dispositivo. Per riconnetterti, dovrai effettuare nuovamente il login. Il dispositivo è inattivo Andare al login sbloccherà Internet su questo dispositivo. + IPv4 + IPv6 Nome dispositivo 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. Puoi avere fino a 5 dispositivi registrati su un account Mullvad. 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 13ae8988c5b7..620fa89d2c28 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 @@ 接続済み Mullvad システムサービスに接続中... 内側 - IPv4 - IPv6 外側 ログインを続ける ログをクリップボードにコピーしました @@ -124,6 +122,8 @@ このデバイスを削除しました。再度接続するには、ログインし直す必要があります。 デバイスが無効です ログインに進むと、このデバイスのインターネットのブロックが解除されます。 + IPv4 + IPv6 デバイス名 これはデバイスに割り当てられる名前です。Mullvadアカウントにログインするデバイスごとに一意の名前が付けられるため、アプリまたはウェブサイトでデバイスを管理する際にデバイスを区別しやすくなります。 1つのMullvadアカウントで最大5台のデバイスにログインできます。 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 96382e5f17fa..75eb364d2724 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 @@ 연결됨 Mullvad 시스템 서비스에 연결하는 중... - IPv4 - IPv6 아웃 로그인 계속하기 로그를 클립보드에 복사했습니다. @@ -124,6 +122,8 @@ 이 장치를 제거했습니다. 다시 연결하려면 다시 로그인해야 합니다. 장치가 비활성 상태입니다. 로그인하면 이 장치에서 인터넷 차단이 해제됩니다. + IPv4 + IPv6 장치 이름 이것은 장치에 할당된 이름입니다. Mullvad 계정에 로그인된 각 장치에는 앱이나 웹사이트에서 장치를 관리할 때 장치를 보다 쉽게 식별할 수 있는 고유한 이름이 부여됩니다. 최대 5개의 장치에서 하나의 Mullvad 계정에 로그인할 수 있습니다. 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 d4e64f3369f2..23cbf3eb9c52 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 @@ ချိတ်ဆက်ပြီး Mullvad စနစ် ဝန်ဆောင်မှုနှင့် ချိတ်ဆက်နေဆဲ... အဝင် - IPv4 - IPv6 အထွက် ဆက်လက် ဝင်ရောက်ရန် ကလစ်ဘုတ်တွင် မှတ်တမ်းများ ကူးယူပြီး @@ -124,6 +122,8 @@ ဤစက်ကို ဖယ်ရှားပြီး ဖြစ်သည်။ ထပ်မံချိတ်ဆက်ရန်အတွက် ပြန်လည် ဝင်ရောက်ရန် လိုပါသည်။ စက်သည် သက်ဝင်လုပ်ဆောင်မှု မရှိပါ ဝင်ရောက်ရန်သွားခြင်းဖြင့် ဤစက်တွင် အင်တာနက်ကို ပိတ်ဆို့ထားမှုမှ ဖယ်ရှားပါလိမ့်မည်။ + IPv4 + IPv6 စက်အမည် ဤအမည်မှာ စက်အတွက် သတ်မှတ်ထားသော အမည် ဖြစ်ပါသည်။ Mullvad အကောင့်တစ်ခုတွင် ဝင်ရောက်ထားသည့် စက်တစ်ခုစီသည် တစ်မူထူးခြားသည့် အမည်တစ်ခု ရရှိမည်ဖြစ်ပြီး အက်ပ် သို့မဟုတ် ဝက်ဘ်ဆိုက်ပေါ်တွင် သင့်စက်များကို စီမံသည့်အခါ သင်အနေဖြင့် ကွဲကွဲပြားပြားသိရှိအောင် ကူညီပေးပါသည်။ Mullvad အကောင့်တစ်ခုတွင် စက် 5 ခုအထိ ဝင်ရောက်ထားနိုင်ပါသည်။ 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 f3aacf6cfb7a..423513580d34 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 @@ Tilkoblet Kobler til Mullvads systemtjeneste ... Inngående - IPv4 - IPv6 Utgående Fortsett med pålogging Logger kopiert til utklippstavlen @@ -124,6 +122,8 @@ Du har fjernet denne enheten. For å koble til igjen, må du logge inn på nytt. Enheten er inaktiv Å gå til pålogging vil oppheve blokkeringen av internettet på denne enheten. + IPv4 + IPv6 Enhetsnavn 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. Du kan ha opptil fem enheter logget inn på samme Mullvad-konto. 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 95a52ae7d1ee..e75b7001a4bf 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 @@ Verbonden Verbinden met Mullvad-systeemdienst... In - IPv4 - IPv6 Uit Doorgaan met aanmelden Logs gekopieerd naar klembord @@ -124,6 +122,8 @@ U hebt dit apparaat verwijderd. U moet zich opnieuw aanmelden om het opnieuw te verbinden. Apparaat is niet actief Als u naar aanmelden gaat, wordt het blokkeren van internet op dit apparaat opgeheven. + IPv4 + IPv6 Apparaatnaam 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. U kunt maximaal 5 apparaten aangemeld hebben op één Mullvad-account. 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 2633bc6a1918..4469e9424872 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 @@ Połączono Łączenie z usługą systemową Mullvad... Wejście - IPv4 - IPv6 Wyjście Kontynuuj logowanie Skopiowano dzienniki do schowka @@ -124,6 +122,8 @@ Urządzenie usunięto. Aby połączyć się ponownie, musisz się ponownie zalogować. Urządzenie nieaktywne Przejście do logowania odblokuje Internet na tym urządzeniu. + IPv4 + IPv6 Nazwa urządzenia 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. Na jednym koncie Mullvad może być zalogowanych maksymalnie 5 urządzeń. 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 f7a0b1f0f057..99ed6ef2e4a0 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 @@ Ligado A ligar-se ao serviço de sistema Mulvad... Entrada - IPv4 - IPv6 Saída Continuar com a ligação Registos copiados para a área de transferência @@ -124,6 +122,8 @@ Removeu este dispositivo. Para voltar a ligar o dispositivo, terá de voltar a iniciar a sessão. O dispositivo está desativado Ir para a ligação irá desbloquear a Internet neste dispositivo. + IPv4 + IPv6 Nome do dispositivo 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. Pode ter até 5 dispositivos com sessão iniciada numa só conta Mullvad. 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 6ab83b64553b..8505588367d2 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 @@ Подключено Подключение к системному сервису Mullvad... Вход - IPv4 - IPv6 Выход Войти Журналы скопированы в буфер обмена @@ -124,6 +122,8 @@ Вы удалили это устройство. Чтобы снова подключиться, нужно будет выполнить вход. Устройство неактивно Вход в профиль разблокирует Интернет на этом устройстве. + IPv4 + IPv6 Имя устройства Это имя, присвоенное устройству. Каждое устройство, подключенное к учетной записи Mullvad, получает уникальное имя, которое помогает вам идентифицировать его при управлении устройствами в приложении или на сайте. К одной учетной записи Mullvad можно подключить до 5 устройств. 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 63463d3d0842..26c120331771 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 @@ Ansluten Ansluter till Mullvads systemtjänst... In - IPv4 - IPv6 Ut Fortsätt med inloggning Loggarna har kopierats till urklipp @@ -124,6 +122,8 @@ Du har tagit bort den här enheten. Du måste logga in igen för att återansluta. Enheten är inaktiv Om du loggar in tas blockering av internet bort på den här enheten. + IPv4 + IPv6 Enhetens namn 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. Upp till fem enheter kan vara inloggade på ett Mullvad-konto. 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 6d9a6a05b134..0a45d0997d33 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 @@ เชื่อมต่อแล้ว กำลังเชื่อมต่อบริการของระบบ Mullvad... เข้า - IPv4 - IPv6 ออก เข้าสู่ระบบต่อ คัดลอกบันทึกล็อกไปยังคลิปบอร์ดแล้ว @@ -124,6 +122,8 @@ คุณได้ลบอุปกรณ์เครื่องนี้แล้ว หากต้องการเชื่อมต่ออีกครั้ง คุณจะต้องเข้าสู่ระบบใหม่อีกครั้ง อุปกรณ์ไม่ได้ใช้งาน การไปที่ส่วนเข้าสู่ระบบจะปลดบล็อกอินเทอร์เน็ตบนอุปกรณ์เครื่องนี้ + IPv4 + IPv6 ชื่ออุปกรณ์ นี่เป็นชื่อที่มอบหมายให้กับอุปกรณ์ อุปกรณ์แต่ละเครื่องที่ลงชื่อเข้าใช้บนบัญชี Mullvad จะได้รับชื่อเฉพาะ ที่จะช่วยคุณระบุอุปกรณ์ ในขณะที่คุณจัดการอุปกรณ์ของคุณในแอปหรือบนเว็บไซต์ คุณสามารถลงชื่อเข้าใช้อุปกรณ์ได้สูงสุด 5 เครื่อง กับบัญชี Mullvad หนึ่งบัญชี 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 565d28eda518..87e78ff14903 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 @@ Bağlandı Mullvad sistem hizmetlerine bağlanılıyor... Giriş - IPv4 - IPv6 Çıkış Giriş yapmak için devam et Günlükler panoya kopyalandı @@ -124,6 +122,8 @@ Bu cihazı kaldırdın. Tekrar bağlanmak için yeniden giriş yapmanız gerekecek. Cihaz etkin değil Giriş yapmak bu cihazdaki internet engelini kaldıracaktır. + IPv4 + IPv6 Cihaz adı 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. Bir Mullvad hesabı ile en fazla 5 cihazda oturum açabilirsiniz. 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 8dbbe5d334ab..ab9fd330d005 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 @@ 已连接 正在连接到 Mullvad 系统服务… 内部 - IPv4 - IPv6 外部 继续登录 已将日志复制到剪贴板 @@ -124,6 +122,8 @@ 您已移除此设备。要重新连接,您需要重新登录。 设备处于非活动状态 前往登录将在此设备上解除阻止互联网。 + IPv4 + IPv6 设备名称 这是为设备分配的名称。每台登录 Mulvad 帐户的设备都会获得一个唯一名称,有助于您在应用或网站上管理设备时识别各个设备。 一个 Mulvad 帐户最多可以登录 5 台设备。 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 582d2594ea93..376b21d6b132 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 @@ 已連線 連線 Mullvad 系統服務中... 入境 - IPv4 - IPv6 出境 繼續登入 已將記錄複製到剪貼簿 @@ -124,6 +122,8 @@ 您已移除此裝置。若要重新連線,您需要重新登入。 裝置處於非活動狀態 若前往登入,則會在此裝置上解除對網際網路的封鎖。 + IPv4 + IPv6 裝置名稱 這是系統指派給裝置的名稱。每台登入 Mulvad 帳戶的裝置都會獲得一個獨特名稱,有助於您在應用程式或網站上管理裝置時識別各台裝置。 一個 Mulvad 帳戶最多可以登入 5 台裝置。 diff --git a/android/lib/resource/src/main/res/values/strings.xml b/android/lib/resource/src/main/res/values/strings.xml index 5cb3436a8543..26cd58e4703e 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 @@ See full changelog No changelog was added for this version Set %s obfuscation to \"Automatic\" or \"Off\" below to activate this setting. + Device IP version + IPv4 + IPv6 diff --git a/desktop/packages/mullvad-vpn/locales/messages.pot b/desktop/packages/mullvad-vpn/locales/messages.pot index 8dbd347036e0..f199110840f7 100644 --- a/desktop/packages/mullvad-vpn/locales/messages.pot +++ b/desktop/packages/mullvad-vpn/locales/messages.pot @@ -2430,6 +2430,9 @@ msgstr "" msgid "Delete method?" msgstr "" +msgid "Device IP version" +msgstr "" + msgid "Disable \"%s\" below to activate these settings." msgstr ""