diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-05-26 13:27:07 +0200 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-06-07 17:51:06 +0200 |
| commit | 1c4a871027d35483f91d6e89bb96c3af97ab7efc (patch) | |
| tree | 878afd14101440f50d10107d5e40286aa0aa1b2a | |
| parent | bec151855c5e93d73515c7d848db4566c700c747 (diff) | |
| download | mullvadvpn-1c4a871027d35483f91d6e89bb96c3af97ab7efc.tar.xz mullvadvpn-1c4a871027d35483f91d6e89bb96c3af97ab7efc.zip | |
Add ui for quantum resistant connection and setting
- Show if quantum resistant connection is used in connect fragment
- Add option for quantum resistant connection in vpn settings
- Listen for quantum resistant state in vpn settings
15 files changed, 186 insertions, 47 deletions
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 f18ba6a801..046e773bc7 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 @@ -44,6 +44,9 @@ class VpnSettingsScreenTest { toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow() ) } + composeTestRule + .onNodeWithTag(LAZY_LIST_TEST_TAG) + .performScrollToNode(hasTestTag(LAZY_LIST_LAST_ITEM_TEST_TAG)) // Assert composeTestRule.apply { @@ -348,6 +351,9 @@ class VpnSettingsScreenTest { toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow() ) } + composeTestRule + .onNodeWithTag(LAZY_LIST_TEST_TAG) + .performScrollToNode(hasTestTag(LAZY_LIST_LAST_ITEM_TEST_TAG)) // Assert composeTestRule.apply { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/BaseCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/BaseCell.kt index ff8771452d..58ab44daaa 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/BaseCell.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/BaseCell.kt @@ -27,7 +27,7 @@ import net.mullvad.mullvadvpn.compose.theme.Dimens @Preview @Composable -fun PreviewBaseCell() { +private fun PreviewBaseCell() { AppTheme { SpacedColumn { BaseCell( diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/MtuComposeCell.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/MtuComposeCell.kt index 6cc8eccdc3..b7fe9ee7a1 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/MtuComposeCell.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/MtuComposeCell.kt @@ -20,7 +20,7 @@ import net.mullvad.mullvadvpn.constant.MTU_MIN_VALUE @Preview @Composable -fun MtuComposeCellPreview() { +private fun PreviewMtuComposeCell() { AppTheme { MtuComposeCell(mtuValue = "1300", onEditMtu = {}) } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/QuantumResistanceInfoDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/QuantumResistanceInfoDialog.kt new file mode 100644 index 0000000000..faae3fd9f7 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/QuantumResistanceInfoDialog.kt @@ -0,0 +1,14 @@ +package net.mullvad.mullvadvpn.compose.dialog + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import net.mullvad.mullvadvpn.R + +@Composable +fun QuantumResistanceInfoDialog(onDismiss: () -> Unit) { + InfoDialog( + message = stringResource(id = R.string.quantum_resistant_info_first_paragaph), + additionalInfo = stringResource(id = R.string.quantum_resistant_info_second_paragaph), + onDismiss = onDismiss + ) +} 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 1414a32899..9ac2a761ff 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 @@ -64,12 +64,14 @@ import net.mullvad.mullvadvpn.compose.dialog.LocalNetworkSharingInfoDialog import net.mullvad.mullvadvpn.compose.dialog.MalwareInfoDialog import net.mullvad.mullvadvpn.compose.dialog.MtuDialog import net.mullvad.mullvadvpn.compose.dialog.ObfuscationInfoDialog +import net.mullvad.mullvadvpn.compose.dialog.QuantumResistanceInfoDialog import net.mullvad.mullvadvpn.compose.extensions.itemWithDivider import net.mullvad.mullvadvpn.compose.state.VpnSettingsUiState import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_LAST_ITEM_TEST_TAG import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_TEST_TAG import net.mullvad.mullvadvpn.compose.theme.AppTheme import net.mullvad.mullvadvpn.compose.theme.Dimens +import net.mullvad.mullvadvpn.model.QuantumResistantState import net.mullvad.mullvadvpn.model.SelectedObfuscation import net.mullvad.mullvadvpn.viewmodel.CustomDnsItem @@ -113,7 +115,9 @@ private fun PreviewVpnSettings() { toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow(), onStopEvent = {}, onSelectObfuscationSetting = {}, - onObfuscationInfoClick = {} + onObfuscationInfoClick = {}, + onSelectQuantumResistanceSetting = {}, + onQuantumResistanceInfoClicked = {} ) } } @@ -151,7 +155,9 @@ fun VpnSettingsScreen( onStopEvent: () -> Unit = {}, toastMessagesSharedFlow: SharedFlow<String>, onSelectObfuscationSetting: (selectedObfuscation: SelectedObfuscation) -> Unit = {}, - onObfuscationInfoClick: () -> Unit = {} + onObfuscationInfoClick: () -> Unit = {}, + onSelectQuantumResistanceSetting: (quantumResistant: Boolean?) -> Unit = {}, + onQuantumResistanceInfoClicked: () -> Unit = {} ) { val cellVerticalSpacing = dimensionResource(id = R.dimen.cell_label_vertical_padding) val cellHorizontalSpacing = dimensionResource(id = R.dimen.cell_left_padding) @@ -191,6 +197,9 @@ fun VpnSettingsScreen( is VpnSettingsUiState.ObfuscationInfoDialogUiState -> { ObfuscationInfoDialog(onDismissInfoClick) } + is VpnSettingsUiState.QuantumResistanceInfoDialogUiState -> { + QuantumResistanceInfoDialog(onDismissInfoClick) + } else -> { // NOOP } @@ -381,6 +390,35 @@ fun VpnSettingsScreen( ) } + itemWithDivider { + Spacer(modifier = Modifier.height(cellVerticalSpacing)) + InformationComposeCell( + title = stringResource(R.string.quantum_resistant_title), + onInfoClicked = { onQuantumResistanceInfoClicked() } + ) + } + itemWithDivider { + SelectableCell( + title = stringResource(id = R.string.automatic), + isSelected = uiState.quantumResistant == QuantumResistantState.Auto, + onCellClicked = { onSelectQuantumResistanceSetting(QuantumResistantState.Auto) } + ) + } + itemWithDivider { + SelectableCell( + title = stringResource(id = R.string.on), + isSelected = uiState.quantumResistant == QuantumResistantState.On, + onCellClicked = { onSelectQuantumResistanceSetting(QuantumResistantState.On) } + ) + } + itemWithDivider { + SelectableCell( + title = stringResource(id = R.string.off), + isSelected = uiState.quantumResistant == QuantumResistantState.Off, + onCellClicked = { onSelectQuantumResistanceSetting(QuantumResistantState.Off) } + ) + } + item { Spacer(modifier = Modifier.height(cellVerticalSpacing)) HeaderSwitchComposeCell( 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 f5315278ab..c2c7d074fd 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 @@ -14,6 +14,7 @@ sealed interface VpnSettingsUiState { val contentBlockersOptions: DefaultDnsOptions val isAllowLanEnabled: Boolean val selectedObfuscation: SelectedObfuscation + val quantumResistant: Boolean? data class DefaultUiState( override val mtu: String = "", @@ -23,7 +24,8 @@ sealed interface VpnSettingsUiState { override val isAllowLanEnabled: Boolean = false, override val customDnsItems: List<CustomDnsItem> = listOf(), override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), - override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off + override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off, + override val quantumResistant: Boolean? = null ) : VpnSettingsUiState data class MtuDialogUiState( @@ -35,7 +37,8 @@ sealed interface VpnSettingsUiState { override val customDnsItems: List<CustomDnsItem> = listOf(), override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), val mtuEditValue: String, - override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off + override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off, + override val quantumResistant: Boolean? = null ) : VpnSettingsUiState data class DnsDialogUiState( @@ -47,7 +50,8 @@ sealed interface VpnSettingsUiState { override val customDnsItems: List<CustomDnsItem> = listOf(), override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), val stagedDns: StagedDns, - override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off + override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off, + override val quantumResistant: Boolean? = null ) : VpnSettingsUiState data class LocalNetworkSharingInfoDialogUiState( @@ -58,7 +62,8 @@ sealed interface VpnSettingsUiState { override val isAllowLanEnabled: Boolean = false, override val customDnsItems: List<CustomDnsItem> = listOf(), override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), - override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off + override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off, + override val quantumResistant: Boolean? = null ) : VpnSettingsUiState data class ContentBlockersInfoDialogUiState( @@ -69,7 +74,8 @@ sealed interface VpnSettingsUiState { override val isAllowLanEnabled: Boolean = false, override val customDnsItems: List<CustomDnsItem> = listOf(), override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), - override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off + override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off, + override val quantumResistant: Boolean? = null ) : VpnSettingsUiState data class CustomDnsInfoDialogUiState( @@ -80,7 +86,8 @@ sealed interface VpnSettingsUiState { override val isAllowLanEnabled: Boolean = false, override val customDnsItems: List<CustomDnsItem> = listOf(), override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), - override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off + override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off, + override val quantumResistant: Boolean? = null ) : VpnSettingsUiState data class MalwareInfoDialogUiState( @@ -91,7 +98,8 @@ sealed interface VpnSettingsUiState { override val isAllowLanEnabled: Boolean = false, override val customDnsItems: List<CustomDnsItem> = listOf(), override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), - override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off + override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off, + override val quantumResistant: Boolean? = null ) : VpnSettingsUiState data class ObfuscationInfoDialogUiState( @@ -102,6 +110,19 @@ sealed interface VpnSettingsUiState { override val isAllowLanEnabled: Boolean = false, override val customDnsItems: List<CustomDnsItem> = listOf(), override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), - override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off + override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off, + override val quantumResistant: Boolean? = null + ) : VpnSettingsUiState + + data class QuantumResistanceInfoDialogUiState( + override val mtu: String = "", + override val isAutoConnectEnabled: Boolean = false, + override val isLocalNetworkSharingEnabled: Boolean = false, + override val isCustomDnsEnabled: Boolean = false, + override val isAllowLanEnabled: Boolean = false, + override val customDnsItems: List<CustomDnsItem> = listOf(), + override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), + override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off, + override val quantumResistant: Boolean? = null ) : VpnSettingsUiState } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt index b46bfbf64b..c9bd699c12 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt @@ -85,6 +85,8 @@ sealed class Request : Message.RequestMessage() { @Parcelize data class SetObfuscationSettings(val settings: ObfuscationSettings?) : Request() + @Parcelize data class SetWireGuardQuantumResistant(val quantumResistant: Boolean?) : Request() + companion object { private const val MESSAGE_KEY = "request" diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SettingsRepository.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SettingsRepository.kt index c0b9215d37..cde1c698ca 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SettingsRepository.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SettingsRepository.kt @@ -54,6 +54,10 @@ class SettingsRepository( serviceConnectionManager.settingsListener()?.wireguardMtu = value } + fun setWireguardQuantumResistant(value: Boolean?) { + serviceConnectionManager.settingsListener()?.wireguardQuantumResistant = value + } + fun setObfuscationOptions(value: ObfuscationSettings) { serviceConnectionManager.settingsListener()?.obfuscationSettings = value } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt index 7606e7709c..cd0da7a3fc 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt @@ -1,5 +1,6 @@ package net.mullvad.mullvadvpn.service.endpoint +import android.util.Log import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.channels.Channel @@ -59,6 +60,11 @@ class SettingsListener(endpoint: ServiceEndpoint) { registerHandler(Request.SetObfuscationSettings::class) { request -> commandChannel.trySendBlocking(Command.SetObfuscationSettings(request.settings)) } + + registerHandler(Request.SetWireGuardQuantumResistant::class) { request -> + // TODO + Log.d("Remove this", "Set quantum resistant ${request.quantumResistant}") + } } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectionStatus.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectionStatus.kt index d2b413f1d0..c59b603547 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectionStatus.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/ConnectionStatus.kt @@ -7,7 +7,7 @@ import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.talpid.tunnel.ActionAfterDisconnect -class ConnectionStatus(val parentView: View, context: Context) { +class ConnectionStatus(parentView: View, context: Context) { private val spinner: View = parentView.findViewById(R.id.connecting_spinner) private val text: TextView = parentView.findViewById(R.id.connection_status) @@ -20,13 +20,13 @@ class ConnectionStatus(val parentView: View, context: Context) { is TunnelState.Disconnecting -> { when (state.actionAfterDisconnect) { ActionAfterDisconnect.Nothing -> disconnected() - ActionAfterDisconnect.Block -> connected() - ActionAfterDisconnect.Reconnect -> connecting() + ActionAfterDisconnect.Block -> connected(false) + ActionAfterDisconnect.Reconnect -> connecting(state.isSecured()) } } is TunnelState.Disconnected -> disconnected() - is TunnelState.Connecting -> connecting() - is TunnelState.Connected -> connected() + is TunnelState.Connecting -> connecting(state.endpoint?.quantumResistant == true) + is TunnelState.Connected -> connected(state.endpoint.quantumResistant) is TunnelState.Error -> errorState(state.errorState.isBlocking) } } @@ -38,18 +38,30 @@ class ConnectionStatus(val parentView: View, context: Context) { text.setText(R.string.unsecured_connection) } - private fun connecting() { + private fun connecting(isQuantumResistant: Boolean) { spinner.visibility = View.VISIBLE text.setTextColor(connectingTextColor) - text.setText(R.string.creating_secure_connection) + text.setText( + if (isQuantumResistant) { + R.string.quantum_creating_secure_connection + } else { + R.string.creating_secure_connection + } + ) } - private fun connected() { + private fun connected(isQuantumResistant: Boolean) { spinner.visibility = View.GONE text.setTextColor(securedTextColor) - text.setText(R.string.secure_connection) + text.setText( + if (isQuantumResistant) { + R.string.quantum_secure_connection + } else { + R.string.secure_connection + } + ) } private fun errorState(isBlocking: Boolean) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt index a299ce357a..6f689ff2c4 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt @@ -55,24 +55,12 @@ class VpnSettingsFragment : BaseFragment() { onStopEvent = vm::onStopEvent, toastMessagesSharedFlow = vm.toastMessages, onSelectObfuscationSetting = vm::onSelectObfuscationSetting, - onObfuscationInfoClick = vm::onObfuscationInfoClick + onObfuscationInfoClick = vm::onObfuscationInfoClick, + onSelectQuantumResistanceSetting = vm::onSelectQuantumResistanceSetting, + onQuantumResistanceInfoClicked = vm::onQuantumResistanceInfoClicked ) } } } } - - private fun openSplitTunnelingFragment() { - parentFragmentManager.beginTransaction().apply { - setCustomAnimations( - R.anim.fragment_enter_from_right, - R.anim.fragment_exit_to_left, - R.anim.fragment_half_enter_from_left, - R.anim.fragment_exit_to_right - ) - replace(R.id.main_fragment, SplitTunnelingFragment()) - addToBackStack(null) - commitAllowingStateLoss() - } - } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt index 70e9721afc..5cfb4f1f0b 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/SettingsListener.kt @@ -35,6 +35,12 @@ class SettingsListener(private val connection: Messenger, eventDispatcher: Event connection.send(Request.SetWireGuardMtu(value).message) } + var wireguardQuantumResistant: Boolean? + get() = settingsNotifier.latestEvent?.tunnelOptions?.wireguard?.quantumResistant + set(value) { + connection.send(Request.SetWireGuardQuantumResistant(value).message) + } + var obfuscationSettings: ObfuscationSettings? get() = settingsNotifier.latestEvent?.obfuscationSettings set(value) { 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 77d95823a6..b8ff734287 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 @@ -55,7 +55,8 @@ class VpnSettingsViewModel( isAllowLanEnabled = settings?.allowLan ?: false, selectedObfuscation = settings?.selectedObfuscationSettings() ?: SelectedObfuscation.Off, - dialogState = dialogState + dialogState = dialogState, + quantumResistant = settings?.quantumResistant() ) } .stateIn( @@ -305,6 +306,16 @@ class VpnSettingsViewModel( dialogState.update { VpnSettingsDialogState.ObfuscationInfoDialog } } + fun onSelectQuantumResistanceSetting(quantumResistant: Boolean?) { + viewModelScope.launch(dispatcher) { + repository.setWireguardQuantumResistant(quantumResistant) + } + } + + fun onQuantumResistanceInfoClicked() { + dialogState.update { VpnSettingsDialogState.QuantumResistanceInfoDialog } + } + private fun updateDefaultDnsOptionsViaRepository(contentBlockersOption: DefaultDnsOptions) = viewModelScope.launch(dispatcher) { repository.setDnsOptions( @@ -341,6 +352,8 @@ class VpnSettingsViewModel( private fun Settings.mtuString() = tunnelOptions.wireguard.mtu?.toString() ?: EMPTY_STRING + private fun Settings.quantumResistant() = tunnelOptions.wireguard.quantumResistant + private fun Settings.isCustomDnsEnabled() = tunnelOptions.dnsOptions.state == DnsState.Custom private fun Settings.addresses() = tunnelOptions.dnsOptions.customOptions.addresses 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 05ca44feb7..86f0c980eb 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 @@ -13,7 +13,8 @@ data class VpnSettingsViewModelState( val customDnsList: List<CustomDnsItem>, val contentBlockersOptions: DefaultDnsOptions, val selectedObfuscation: SelectedObfuscation, - val dialogState: VpnSettingsDialogState + val dialogState: VpnSettingsDialogState, + val quantumResistant: Boolean? ) { fun toUiState(): VpnSettingsUiState { return when (dialogState) { @@ -27,7 +28,8 @@ data class VpnSettingsViewModelState( customDnsItems = customDnsList, contentBlockersOptions = contentBlockersOptions, mtuEditValue = dialogState.mtuEditValue, - selectedObfuscation = selectedObfuscation + selectedObfuscation = selectedObfuscation, + quantumResistant = quantumResistant ) is VpnSettingsDialogState.DnsDialog -> VpnSettingsUiState.DnsDialogUiState( @@ -39,7 +41,8 @@ data class VpnSettingsViewModelState( customDnsItems = customDnsList, contentBlockersOptions = contentBlockersOptions, stagedDns = dialogState.stagedDns, - selectedObfuscation = selectedObfuscation + selectedObfuscation = selectedObfuscation, + quantumResistant = quantumResistant ) is VpnSettingsDialogState.LocalNetworkSharingInfoDialog -> VpnSettingsUiState.LocalNetworkSharingInfoDialogUiState( @@ -49,7 +52,8 @@ data class VpnSettingsViewModelState( isCustomDnsEnabled = isCustomDnsEnabled, isAllowLanEnabled = isAllowLanEnabled, customDnsItems = customDnsList, - contentBlockersOptions = contentBlockersOptions + contentBlockersOptions = contentBlockersOptions, + quantumResistant = quantumResistant ) is VpnSettingsDialogState.ContentBlockersInfoDialog -> VpnSettingsUiState.ContentBlockersInfoDialogUiState( @@ -60,7 +64,8 @@ data class VpnSettingsViewModelState( isAllowLanEnabled = isAllowLanEnabled, customDnsItems = customDnsList, contentBlockersOptions = contentBlockersOptions, - selectedObfuscation = selectedObfuscation + selectedObfuscation = selectedObfuscation, + quantumResistant = quantumResistant ) is VpnSettingsDialogState.CustomDnsInfoDialog -> VpnSettingsUiState.CustomDnsInfoDialogUiState( @@ -70,7 +75,8 @@ data class VpnSettingsViewModelState( isCustomDnsEnabled = isCustomDnsEnabled, isAllowLanEnabled = isAllowLanEnabled, customDnsItems = customDnsList, - contentBlockersOptions = contentBlockersOptions + contentBlockersOptions = contentBlockersOptions, + quantumResistant = quantumResistant ) is VpnSettingsDialogState.MalwareInfoDialog -> VpnSettingsUiState.MalwareInfoDialogUiState( @@ -81,7 +87,8 @@ data class VpnSettingsViewModelState( isAllowLanEnabled = isAllowLanEnabled, customDnsItems = customDnsList, contentBlockersOptions = contentBlockersOptions, - selectedObfuscation = selectedObfuscation + selectedObfuscation = selectedObfuscation, + quantumResistant = quantumResistant ) is VpnSettingsDialogState.ObfuscationInfoDialog -> VpnSettingsUiState.ObfuscationInfoDialogUiState( @@ -90,8 +97,20 @@ data class VpnSettingsViewModelState( isAllowLanEnabled = isAllowLanEnabled, customDnsItems = customDnsList, contentBlockersOptions = contentBlockersOptions, - selectedObfuscation = selectedObfuscation + selectedObfuscation = selectedObfuscation, + quantumResistant = quantumResistant ) + is VpnSettingsDialogState.QuantumResistanceInfoDialog -> { + VpnSettingsUiState.QuantumResistanceInfoDialogUiState( + mtu = mtuValue, + isCustomDnsEnabled = isCustomDnsEnabled, + isAllowLanEnabled = isAllowLanEnabled, + customDnsItems = customDnsList, + contentBlockersOptions = contentBlockersOptions, + selectedObfuscation = selectedObfuscation, + quantumResistant = quantumResistant + ) + } else -> VpnSettingsUiState.DefaultUiState( mtu = mtuValue, @@ -101,7 +120,8 @@ data class VpnSettingsViewModelState( isAllowLanEnabled = isAllowLanEnabled, customDnsItems = customDnsList, contentBlockersOptions = contentBlockersOptions, - selectedObfuscation = selectedObfuscation + selectedObfuscation = selectedObfuscation, + quantumResistant = quantumResistant ) } } @@ -119,7 +139,8 @@ data class VpnSettingsViewModelState( contentBlockersOptions = DefaultDnsOptions(), isAllowLanEnabled = false, dialogState = VpnSettingsDialogState.NoDialog, - selectedObfuscation = SelectedObfuscation.Auto + selectedObfuscation = SelectedObfuscation.Auto, + quantumResistant = null ) } } @@ -140,6 +161,8 @@ sealed class VpnSettingsDialogState { object MalwareInfoDialog : VpnSettingsDialogState() object ObfuscationInfoDialog : VpnSettingsDialogState() + + object QuantumResistanceInfoDialog : VpnSettingsDialogState() } sealed interface StagedDns { diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 7354d40a11..e6cb2f84ce 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -196,4 +196,10 @@ <string name="created_x">Created: %s</string> <string name="local_network_sharing_info">This feature allows access to other devices on the local network, such as for sharing, printing, streaming, etc.</string> <string name="local_network_sharing_additional_info">It does this by allowing network communication outside the tunnel to local multicast and broadcast ranges as well as to and from these private IP ranges:</string> + <string name="quantum_resistant_title">Quantum-resistant tunnel</string> + <string name="quantum_resistant_info_first_paragaph">This feature makes the WireGuard tunnel resistant to potential attacks from quantum computers.</string> + <string name="quantum_resistant_info_second_paragaph">It does this by performing an extra key exchange using a quantum safe algorithm and mixing the result into WireGuard’s regular encryption. This extra step uses approximately 500 kiB of traffic every time a new tunnel is established.</string> + <string name="on">On</string> + <string name="quantum_creating_secure_connection">CREATING QUANTUM SECURE CONNECTION</string> + <string name="quantum_secure_connection">QUANTUM SECURE CONNECTION</string> </resources> |
