diff options
6 files changed, 124 insertions, 39 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AdvancedSettingScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AdvancedSettingScreen.kt index 2f918a2647..110a20aa09 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AdvancedSettingScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/AdvancedSettingScreen.kt @@ -70,12 +70,17 @@ private fun PreviewAdvancedSettings() { onCancelMtuDialogClicked = {}, onSplitTunnelingNavigationClick = {}, onToggleDnsClick = {}, + onToggleBlockAds = {}, + onToggleBlockTrackers = {}, + onToggleBlockMalware = {}, + onToggleBlockAdultContent = {}, + onToggleBlockGambling = {}, onDnsClick = {}, onDnsInputChange = {}, onSaveDnsClick = {}, onRemoveDnsClick = {}, onCancelDnsDialogClick = {}, - onContentsBlockerInfoClicked = {}, + onContentsBlockersInfoClicked = {}, onMalwareInfoClicked = {}, onDismissInfoClicked = {}, onBackClick = {} @@ -94,12 +99,17 @@ fun AdvancedSettingScreen( onCancelMtuDialogClicked: () -> Unit = {}, onSplitTunnelingNavigationClick: () -> Unit = {}, onToggleDnsClick: (Boolean) -> Unit = {}, + onToggleBlockAds: (Boolean) -> Unit = {}, + onToggleBlockTrackers: (Boolean) -> Unit = {}, + onToggleBlockMalware: (Boolean) -> Unit = {}, + onToggleBlockAdultContent: (Boolean) -> Unit = {}, + onToggleBlockGambling: (Boolean) -> Unit = {}, onDnsClick: (index: Int?) -> Unit = {}, onDnsInputChange: (String) -> Unit = {}, onSaveDnsClick: () -> Unit = {}, onRemoveDnsClick: () -> Unit = {}, onCancelDnsDialogClick: () -> Unit = {}, - onContentsBlockerInfoClicked: () -> Unit = {}, + onContentsBlockersInfoClicked: () -> Unit = {}, onMalwareInfoClicked: () -> Unit = {}, onDismissInfoClicked: () -> Unit = {}, onBackClick: () -> Unit = {} @@ -189,7 +199,8 @@ fun AdvancedSettingScreen( ExpandableComposeCell( title = stringResource(R.string.dns_content_blockers_title), isExpanded = !expandContentBlockersState, - onInfoClicked = { onContentsBlockerInfoClicked() }, + isEnabled = !uiState.isCustomDnsEnabled, + onInfoClicked = { onContentsBlockersInfoClicked() }, onCellClicked = { expandContentBlockersState = !expandContentBlockersState } ) } @@ -198,27 +209,27 @@ fun AdvancedSettingScreen( itemWithDivider { SwitchComposeCell( title = stringResource(R.string.block_ads_title), - isEnabled = true, - isToggled = false, - onCellClicked = {}, + isToggled = uiState.contentBlockersOptions.blockAds, + isEnabled = !uiState.isCustomDnsEnabled, + onCellClicked = { onToggleBlockAds(it) }, background = MullvadBlue20 ) } itemWithDivider { SwitchComposeCell( title = stringResource(R.string.block_trackers_title), - isEnabled = true, - isToggled = false, - onCellClicked = {}, + isToggled = uiState.contentBlockersOptions.blockTrackers, + isEnabled = !uiState.isCustomDnsEnabled, + onCellClicked = { onToggleBlockTrackers(it) }, background = MullvadBlue20 ) } itemWithDivider { SwitchComposeCell( title = stringResource(R.string.block_malware_title), - isEnabled = true, - isToggled = false, - onCellClicked = {}, + isToggled = uiState.contentBlockersOptions.blockMalware, + isEnabled = !uiState.isCustomDnsEnabled, + onCellClicked = { onToggleBlockMalware(it) }, onInfoClicked = { onMalwareInfoClicked() }, background = MullvadBlue20 ) @@ -226,18 +237,18 @@ fun AdvancedSettingScreen( itemWithDivider { SwitchComposeCell( title = stringResource(R.string.block_gambling_title), - isEnabled = true, - isToggled = false, - onCellClicked = {}, + isToggled = uiState.contentBlockersOptions.blockGambling, + isEnabled = !uiState.isCustomDnsEnabled, + onCellClicked = { onToggleBlockGambling(it) }, background = MullvadBlue20 ) } itemWithDivider { SwitchComposeCell( title = stringResource(R.string.block_adult_content_title), - isEnabled = true, - isToggled = false, - onCellClicked = {}, + isToggled = uiState.contentBlockersOptions.blockAdultContent, + isEnabled = !uiState.isCustomDnsEnabled, + onCellClicked = { onToggleBlockAdultContent(it) }, background = MullvadBlue20 ) } @@ -261,8 +272,8 @@ fun AdvancedSettingScreen( Spacer(modifier = Modifier.height(cellVerticalSpacing)) SwitchComposeCell( title = stringResource(R.string.enable_custom_dns), - isEnabled = true, isToggled = uiState.isCustomDnsEnabled, + isEnabled = uiState.contentBlockersOptions.isAnyBlockerEnabled().not(), onCellClicked = { newValue -> onToggleDnsClick(newValue) } ) } @@ -298,7 +309,8 @@ fun AdvancedSettingScreen( item { CustomDnsCellSubtitle( - isCellClickable = true, + isCellClickable = + uiState.contentBlockersOptions.isAnyBlockerEnabled().not(), modifier = Modifier.background(MullvadDarkBlue) .padding( diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/AdvancedSettingsUiState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/AdvancedSettingsUiState.kt index 659559f887..71b608b51b 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/AdvancedSettingsUiState.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/AdvancedSettingsUiState.kt @@ -1,5 +1,6 @@ package net.mullvad.mullvadvpn.compose.state +import net.mullvad.mullvadvpn.model.DefaultDnsOptions import net.mullvad.mullvadvpn.viewmodel.CustomDnsItem import net.mullvad.mullvadvpn.viewmodel.StagedDns @@ -7,13 +8,15 @@ sealed interface AdvancedSettingsUiState { val mtu: String val isCustomDnsEnabled: Boolean val customDnsItems: List<CustomDnsItem> + val contentBlockersOptions: DefaultDnsOptions val isAllowLanEnabled: Boolean data class DefaultUiState( override val mtu: String = "", override val isCustomDnsEnabled: Boolean = false, override val isAllowLanEnabled: Boolean = false, - override val customDnsItems: List<CustomDnsItem> = listOf() + override val customDnsItems: List<CustomDnsItem> = listOf(), + override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions() ) : AdvancedSettingsUiState data class MtuDialogUiState( @@ -21,6 +24,7 @@ sealed interface AdvancedSettingsUiState { override val isCustomDnsEnabled: Boolean = false, override val isAllowLanEnabled: Boolean = false, override val customDnsItems: List<CustomDnsItem> = listOf(), + override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), val mtuEditValue: String ) : AdvancedSettingsUiState @@ -29,6 +33,7 @@ sealed interface AdvancedSettingsUiState { override val isCustomDnsEnabled: Boolean = false, override val isAllowLanEnabled: Boolean = false, override val customDnsItems: List<CustomDnsItem> = listOf(), + override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(), val stagedDns: StagedDns ) : AdvancedSettingsUiState @@ -36,13 +41,15 @@ sealed interface AdvancedSettingsUiState { override val mtu: String = "", override val isCustomDnsEnabled: Boolean = false, override val isAllowLanEnabled: Boolean = false, - override val customDnsItems: List<CustomDnsItem> = listOf() + override val customDnsItems: List<CustomDnsItem> = listOf(), + override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions() ) : AdvancedSettingsUiState data class MalwareInfoDialogUiState( override val mtu: String = "", override val isCustomDnsEnabled: Boolean = false, override val isAllowLanEnabled: Boolean = false, - override val customDnsItems: List<CustomDnsItem> = listOf() + override val customDnsItems: List<CustomDnsItem> = listOf(), + override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions() ) : AdvancedSettingsUiState } 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 6eef99ecce..1e00efc3c5 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 @@ -32,7 +32,11 @@ class SettingsRepository( .onStart { serviceConnectionManager.settingsListener()?.settingsNotifier?.latestEvent } .stateIn(CoroutineScope(dispatcher), SharingStarted.WhileSubscribed(), null) - fun setDnsOptions(isCustomDnsEnabled: Boolean, dnsList: List<InetAddress>) { + fun setDnsOptions( + isCustomDnsEnabled: Boolean, + dnsList: List<InetAddress>, + contentBlockersOptions: DefaultDnsOptions + ) { serviceConnectionManager .customDns() ?.setDnsOptions( @@ -40,7 +44,7 @@ class SettingsRepository( DnsOptions( state = if (isCustomDnsEnabled) DnsState.Custom else DnsState.Default, customOptions = CustomDnsOptions(ArrayList(dnsList)), - defaultOptions = DefaultDnsOptions() + defaultOptions = contentBlockersOptions ) ) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AdvancedFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AdvancedFragment.kt index 069f041a86..6eee351e78 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AdvancedFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AdvancedFragment.kt @@ -33,14 +33,19 @@ class AdvancedFragment : BaseFragment() { onCancelMtuDialogClicked = vm::onCancelDialogClick, onSplitTunnelingNavigationClick = ::openSplitTunnelingFragment, onToggleDnsClick = vm::onToggleDnsClick, + onToggleBlockAds = vm::onToggleBlockAds, + onToggleBlockTrackers = vm::onToggleBlockTrackers, + onToggleBlockMalware = vm::onToggleBlockMalware, + onToggleBlockAdultContent = vm::onToggleBlockAdultContent, + onToggleBlockGambling = vm::onToggleBlockGambling, onDnsClick = vm::onDnsClick, onDnsInputChange = vm::onDnsInputChange, onSaveDnsClick = vm::onSaveDnsClick, onRemoveDnsClick = vm::onRemoveDnsClick, onCancelDnsDialogClick = vm::onCancelDialogClick, - onContentsBlockerInfoClicked = vm::onContentsBlockerInfoClicked, - onMalwareInfoClicked = vm::onMalwareInfoClicked, - onDismissInfoClicked = vm::onDismissInfoClicked, + onContentsBlockersInfoClicked = vm::onContentsBlockerInfoClick, + onMalwareInfoClicked = vm::onMalwareInfoClick, + onDismissInfoClicked = vm::onDismissInfoClick, onBackClick = { activity?.onBackPressed() } ) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModel.kt index 4a04a5af5a..17679b6e29 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModel.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.compose.state.AdvancedSettingsUiState +import net.mullvad.mullvadvpn.model.DefaultDnsOptions import net.mullvad.mullvadvpn.model.DnsState import net.mullvad.mullvadvpn.model.Settings import net.mullvad.mullvadvpn.repository.SettingsRepository @@ -35,6 +36,8 @@ class AdvancedSettingsViewModel( mtuValue = settings?.mtuString() ?: "", isCustomDnsEnabled = settings?.isCustomDnsEnabled() ?: false, customDnsList = settings?.addresses()?.asStringAddressList() ?: listOf(), + contentBlockersOptions = settings?.contentBlockersSettings() + ?: DefaultDnsOptions(), isAllowLanEnabled = settings?.allowLan ?: false, dialogState = dialogState ) @@ -83,15 +86,15 @@ class AdvancedSettingsViewModel( hideDialog() } - fun onContentsBlockerInfoClicked() { + fun onContentsBlockerInfoClick() { dialogState.update { AdvancedSettingsDialogState.ContentBlockersInfoDialog } } - fun onMalwareInfoClicked() { + fun onMalwareInfoClick() { dialogState.update { AdvancedSettingsDialogState.MalwareInfoDialog } } - fun onDismissInfoClicked() { + fun onDismissInfoClick() { hideDialog() } @@ -177,7 +180,11 @@ class AdvancedSettingsViewModel( } } - repository.setDnsOptions(isCustomDnsEnabled = true, dnsList = updatedList) + repository.setDnsOptions( + isCustomDnsEnabled = true, + dnsList = updatedList, + contentBlockersOptions = vmState.value.contentBlockersOptions + ) hideDialog() } @@ -186,10 +193,41 @@ class AdvancedSettingsViewModel( viewModelScope.launch(dispatcher) { repository.setDnsOptions( isEnabled, - dnsList = vmState.value.customDnsList.map { it.address }.asInetAddressList() + dnsList = vmState.value.customDnsList.map { it.address }.asInetAddressList(), + contentBlockersOptions = vmState.value.contentBlockersOptions ) } + fun onToggleBlockAds(isEnabled: Boolean) { + updateDefaultDnsOptionsViaRepository( + vmState.value.contentBlockersOptions.copy(blockAds = isEnabled) + ) + } + + fun onToggleBlockTrackers(isEnabled: Boolean) { + updateDefaultDnsOptionsViaRepository( + vmState.value.contentBlockersOptions.copy(blockTrackers = isEnabled) + ) + } + + fun onToggleBlockMalware(isEnabled: Boolean) { + updateDefaultDnsOptionsViaRepository( + vmState.value.contentBlockersOptions.copy(blockMalware = isEnabled) + ) + } + + fun onToggleBlockAdultContent(isEnabled: Boolean) { + updateDefaultDnsOptionsViaRepository( + vmState.value.contentBlockersOptions.copy(blockAdultContent = isEnabled) + ) + } + + fun onToggleBlockGambling(isEnabled: Boolean) { + updateDefaultDnsOptionsViaRepository( + vmState.value.contentBlockersOptions.copy(blockGambling = isEnabled) + ) + } + fun onRemoveDnsClick() = viewModelScope.launch(dispatcher) { val dialog = @@ -204,12 +242,21 @@ class AdvancedSettingsViewModel( repository.setDnsOptions( isCustomDnsEnabled = vmState.value.isCustomDnsEnabled && updatedList.isNotEmpty(), - dnsList = updatedList + dnsList = updatedList, + contentBlockersOptions = vmState.value.contentBlockersOptions ) - hideDialog() } + private fun updateDefaultDnsOptionsViaRepository(contentBlockersOption: DefaultDnsOptions) = + viewModelScope.launch(dispatcher) { + repository.setDnsOptions( + isCustomDnsEnabled = vmState.value.isCustomDnsEnabled, + dnsList = vmState.value.customDnsList.map { it.address }.asInetAddressList(), + contentBlockersOptions = contentBlockersOption + ) + } + private fun hideDialog() { dialogState.update { AdvancedSettingsDialogState.NoDialog } } @@ -241,6 +288,8 @@ class AdvancedSettingsViewModel( private fun Settings.addresses() = tunnelOptions.dnsOptions.customOptions.addresses + private fun Settings.contentBlockersSettings() = tunnelOptions.dnsOptions.defaultOptions + private fun String.isValidIp(): Boolean { return inetAddressValidator.isValid(this) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModelState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModelState.kt index 5f5171584d..109e518ad5 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModelState.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/AdvancedSettingsViewModelState.kt @@ -1,12 +1,14 @@ package net.mullvad.mullvadvpn.viewmodel import net.mullvad.mullvadvpn.compose.state.AdvancedSettingsUiState +import net.mullvad.mullvadvpn.model.DefaultDnsOptions data class AdvancedSettingsViewModelState( val mtuValue: String, val isCustomDnsEnabled: Boolean, val isAllowLanEnabled: Boolean, val customDnsList: List<CustomDnsItem>, + val contentBlockersOptions: DefaultDnsOptions, val dialogState: AdvancedSettingsDialogState ) { fun toUiState(): AdvancedSettingsUiState { @@ -17,7 +19,8 @@ data class AdvancedSettingsViewModelState( isCustomDnsEnabled = isCustomDnsEnabled, isAllowLanEnabled = isAllowLanEnabled, customDnsItems = customDnsList, - mtuEditValue = dialogState.mtuEditValue, + contentBlockersOptions = contentBlockersOptions, + mtuEditValue = dialogState.mtuEditValue ) is AdvancedSettingsDialogState.DnsDialog -> AdvancedSettingsUiState.DnsDialogUiState( @@ -25,21 +28,24 @@ data class AdvancedSettingsViewModelState( isCustomDnsEnabled = isCustomDnsEnabled, isAllowLanEnabled = isAllowLanEnabled, customDnsItems = customDnsList, - stagedDns = dialogState.stagedDns, + contentBlockersOptions = contentBlockersOptions, + stagedDns = dialogState.stagedDns ) is AdvancedSettingsDialogState.ContentBlockersInfoDialog -> AdvancedSettingsUiState.ContentBlockersInfoDialogUiState( mtu = mtuValue, isCustomDnsEnabled = isCustomDnsEnabled, isAllowLanEnabled = isAllowLanEnabled, - customDnsItems = customDnsList + customDnsItems = customDnsList, + contentBlockersOptions = contentBlockersOptions ) is AdvancedSettingsDialogState.MalwareInfoDialog -> AdvancedSettingsUiState.MalwareInfoDialogUiState( mtu = mtuValue, isCustomDnsEnabled = isCustomDnsEnabled, isAllowLanEnabled = isAllowLanEnabled, - customDnsItems = customDnsList + customDnsItems = customDnsList, + contentBlockersOptions = contentBlockersOptions ) else -> AdvancedSettingsUiState.DefaultUiState( @@ -47,6 +53,7 @@ data class AdvancedSettingsViewModelState( isCustomDnsEnabled = isCustomDnsEnabled, isAllowLanEnabled = isAllowLanEnabled, customDnsItems = customDnsList, + contentBlockersOptions = contentBlockersOptions ) } } @@ -59,6 +66,7 @@ data class AdvancedSettingsViewModelState( mtuValue = EMPTY_STRING, isCustomDnsEnabled = false, customDnsList = listOf(), + contentBlockersOptions = DefaultDnsOptions(), isAllowLanEnabled = false, dialogState = AdvancedSettingsDialogState.NoDialog ) |
