summaryrefslogtreecommitdiffhomepage
path: root/android/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'android/app/src')
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/DnsDialogResult.kt2
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt35
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/DeleteCustomDnsUseCase.kt24
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DnsDialogViewModel.kt12
7 files changed, 63 insertions, 24 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 43c5559a38..13ef28dd23 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
@@ -411,7 +411,11 @@ class VpnSettingsScreenTest {
// Arrange
val mockedClickHandler: (Int?, String?) -> Unit = mockk(relaxed = true)
initScreen(
- state = VpnSettingsUiState.createDefault(isCustomDnsEnabled = true),
+ state =
+ VpnSettingsUiState.createDefault(
+ isCustomDnsEnabled = true,
+ customDnsItems = listOf(CustomDnsItem("1.1.1.1", false)),
+ ),
navigateToDns = mockedClickHandler,
)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/DnsDialogResult.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/DnsDialogResult.kt
index 45eb76cc85..b95c3ef72e 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/DnsDialogResult.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/DnsDialogResult.kt
@@ -4,7 +4,7 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
interface DnsDialogResult : Parcelable {
- @Parcelize data object Success : DnsDialogResult
+ @Parcelize data class Success(val isDnsListEmpty: Boolean) : DnsDialogResult
@Parcelize data object Error : DnsDialogResult
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt
index c2e94ded5b..6f9c8126c0 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt
@@ -51,8 +51,8 @@ fun Dns(resultNavigator: ResultBackNavigator<DnsDialogResult>) {
CollectSideEffectWithLifecycle(viewModel.uiSideEffect) {
when (it) {
- DnsDialogSideEffect.Complete ->
- resultNavigator.navigateBack(result = DnsDialogResult.Success)
+ is DnsDialogSideEffect.Complete ->
+ resultNavigator.navigateBack(result = DnsDialogResult.Success(it.isDnsListEmpty))
DnsDialogSideEffect.Error ->
resultNavigator.navigateBack(result = DnsDialogResult.Error)
}
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 d900f8e879..0de30c408a 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
@@ -158,7 +158,12 @@ fun VpnSettings(
dnsDialogResult.OnNavResultValue { result ->
when (result) {
- DnsDialogResult.Success -> vm.showApplySettingChangesWarningToast()
+ is DnsDialogResult.Success -> {
+ vm.showApplySettingChangesWarningToast()
+ if (result.isDnsListEmpty) {
+ vm.onToggleCustomDns(false)
+ }
+ }
DnsDialogResult.Cancel -> vm.onDnsDialogDismissed()
DnsDialogResult.Error -> {
vm.showGenericErrorToast()
@@ -466,19 +471,21 @@ fun VpnSettingsScreen(
)
}
- itemWithDivider {
- BaseCell(
- onCellClicked = { navigateToDns(null, null) },
- headlineContent = {
- Text(
- text = stringResource(id = R.string.add_a_server),
- color = MaterialTheme.colorScheme.onSurface,
- )
- },
- bodyView = {},
- background = MaterialTheme.colorScheme.surfaceContainerLow,
- startPadding = biggerPadding,
- )
+ if (state.customDnsItems.isNotEmpty()) {
+ itemWithDivider {
+ BaseCell(
+ onCellClicked = { navigateToDns(null, null) },
+ headlineContent = {
+ Text(
+ text = stringResource(id = R.string.add_a_server),
+ color = MaterialTheme.colorScheme.onSurface,
+ )
+ },
+ bodyView = {},
+ background = MaterialTheme.colorScheme.surfaceContainerLow,
+ startPadding = biggerPadding,
+ )
+ }
}
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
index a56541ee1a..5c147379b2 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
@@ -38,6 +38,7 @@ import net.mullvad.mullvadvpn.ui.MainActivity
import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoRepository
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
import net.mullvad.mullvadvpn.usecase.AccountExpiryInAppNotificationUseCase
+import net.mullvad.mullvadvpn.usecase.DeleteCustomDnsUseCase
import net.mullvad.mullvadvpn.usecase.EmptyPaymentUseCase
import net.mullvad.mullvadvpn.usecase.FilterChipUseCase
import net.mullvad.mullvadvpn.usecase.FilteredRelayListUseCase
@@ -167,6 +168,7 @@ val uiModule = module {
single { LastKnownLocationUseCase(get()) }
single { SelectedLocationUseCase(get(), get()) }
single { FilterChipUseCase(get(), get(), get(), get()) }
+ single { DeleteCustomDnsUseCase(get()) }
single { InAppNotificationController(get(), get(), get(), get(), get(), MainScope()) }
@@ -214,7 +216,7 @@ val uiModule = module {
viewModel { DeviceListViewModel(get(), get()) }
viewModel { DeviceRevokedViewModel(get(), get()) }
viewModel { MtuDialogViewModel(get(), get()) }
- viewModel { DnsDialogViewModel(get(), get(), get()) }
+ viewModel { DnsDialogViewModel(get(), get(), get(), get()) }
viewModel { WireguardCustomPortDialogViewModel(get()) }
viewModel { LoginViewModel(get(), get(), get()) }
viewModel { PrivacyDisclaimerViewModel(get(), IS_PLAY_BUILD) }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/DeleteCustomDnsUseCase.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/DeleteCustomDnsUseCase.kt
new file mode 100644
index 0000000000..fffa841306
--- /dev/null
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/DeleteCustomDnsUseCase.kt
@@ -0,0 +1,24 @@
+package net.mullvad.mullvadvpn.usecase
+
+import arrow.core.raise.either
+import arrow.core.raise.ensure
+import net.mullvad.mullvadvpn.lib.model.SetDnsOptionsError
+import net.mullvad.mullvadvpn.repository.SettingsRepository
+
+class DeleteCustomDnsUseCase(private val settingsRepository: SettingsRepository) {
+ suspend operator fun invoke(index: Int) =
+ either<SetDnsOptionsError, Int> {
+ val sizePriorToDeletion =
+ settingsRepository.settingsUpdates.value
+ ?.tunnelOptions
+ ?.dnsOptions
+ ?.customOptions
+ ?.addresses
+ ?.size ?: 0
+ ensure(sizePriorToDeletion > 0) {
+ SetDnsOptionsError.Unknown(IllegalStateException("No custom DNS entries"))
+ }
+ settingsRepository.deleteCustomDns(index).bind()
+ sizePriorToDeletion - 1
+ }
+}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DnsDialogViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DnsDialogViewModel.kt
index a009210318..ab067e8145 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DnsDialogViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DnsDialogViewModel.kt
@@ -22,10 +22,11 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.lib.model.Settings
import net.mullvad.mullvadvpn.repository.SettingsRepository
+import net.mullvad.mullvadvpn.usecase.DeleteCustomDnsUseCase
import org.apache.commons.validator.routines.InetAddressValidator
sealed interface DnsDialogSideEffect {
- data object Complete : DnsDialogSideEffect
+ data class Complete(val isDnsListEmpty: Boolean) : DnsDialogSideEffect
data object Error : DnsDialogSideEffect
}
@@ -52,6 +53,7 @@ class DnsDialogViewModel(
private val repository: SettingsRepository,
private val inetAddressValidator: InetAddressValidator,
savedStateHandle: SavedStateHandle,
+ private val deleteCustomDnsUseCase: DeleteCustomDnsUseCase,
private val dispatcher: CoroutineDispatcher = Dispatchers.IO,
) : ViewModel() {
private val navArgs = DnsDestination.argsFrom(savedStateHandle)
@@ -127,17 +129,17 @@ class DnsDialogViewModel(
result.fold(
{ _uiSideEffect.send(DnsDialogSideEffect.Error) },
- { _uiSideEffect.send(DnsDialogSideEffect.Complete) },
+ { _uiSideEffect.send(DnsDialogSideEffect.Complete(false)) },
)
}
fun onRemoveDnsClick(index: Int) =
viewModelScope.launch(dispatcher) {
- repository
- .deleteCustomDns(index)
+ deleteCustomDnsUseCase
+ .invoke(index)
.fold(
{ _uiSideEffect.send(DnsDialogSideEffect.Error) },
- { _uiSideEffect.send(DnsDialogSideEffect.Complete) },
+ { _uiSideEffect.send(DnsDialogSideEffect.Complete(it == 0)) },
)
}