diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt index 2ed40e6..5c586d1 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt @@ -115,7 +115,9 @@ fun SettingsScreen(viewModel: SettingsViewModel = hiltViewModel(), appViewModel: val onAutoTunnelClick = { if (!uiState.generalState.isLocationDisclosureShown) { navController.navigate(Route.LocationDisclosure) - } else navController.navigate(Route.AutoTunnel) + } else { + navController.navigate(Route.AutoTunnel) + } } SurfaceSelectionGroupButton( listOf( diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/AutoTunnelScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/AutoTunnelScreen.kt index 7da2c0d..ccf5832 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/AutoTunnelScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/AutoTunnelScreen.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.rememberScrollState @@ -21,7 +22,6 @@ import androidx.compose.material.icons.outlined.Security import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.SettingsEthernet import androidx.compose.material.icons.outlined.SignalCellular4Bar -import androidx.compose.material.icons.outlined.VpnKeyOff import androidx.compose.material.icons.outlined.Wifi import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme @@ -135,6 +135,7 @@ fun AutoTunnelScreen(uiState: AppUiState, viewModel: AutoTunnelViewModel = hiltV .fillMaxSize() .padding(padding) .verticalScroll(rememberScrollState()) + .imePadding() .padding(top = 24.dp.scaledHeight()) .padding(horizontal = 24.dp.scaledWidth()), ) { @@ -376,7 +377,7 @@ fun AutoTunnelScreen(uiState: AppUiState, viewModel: AutoTunnelViewModel = hiltV ForwardButton { navController.navigate(Route.AutoTunnelAdvanced) } }, ), - ) + ), ) } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/AdvancedScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/AdvancedScreen.kt index b1dd15e..6740502 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/AdvancedScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/AdvancedScreen.kt @@ -39,7 +39,6 @@ import com.zaneschepke.wireguardautotunnel.util.extensions.scaledWidth @Composable fun AdvancedScreen(appUiState: AppUiState, appViewModel: AppViewModel) { - var isDropDownExpanded by remember { mutableStateOf(false) } @@ -47,9 +46,9 @@ fun AdvancedScreen(appUiState: AppUiState, appViewModel: AppViewModel) { var selected by remember { mutableIntStateOf(appUiState.settings.debounceDelaySeconds) } LaunchedEffect(selected) { - if(selected == appUiState.settings.debounceDelaySeconds) return@LaunchedEffect + if (selected == appUiState.settings.debounceDelaySeconds) return@LaunchedEffect appViewModel.saveSettings(appUiState.settings.copy(debounceDelaySeconds = selected)) - if(appUiState.settings.isAutoTunnelEnabled) { + if (appUiState.settings.isAutoTunnelEnabled) { appViewModel.bounceAutoTunnel() } } @@ -86,32 +85,36 @@ fun AdvancedScreen(appUiState: AppUiState, appViewModel: AppViewModel) { trailing = { Row( horizontalArrangement = Arrangement.spacedBy(5.dp, Alignment.CenterHorizontally), - verticalAlignment = Alignment.CenterVertically) { + verticalAlignment = Alignment.CenterVertically, + ) { Text(text = selected.toString(), style = MaterialTheme.typography.bodyMedium) val icon = Icons.Default.ArrowDropDown Icon(icon, icon.name) } DropdownMenu( - modifier = Modifier.height(140.dp.scaledHeight()), + modifier = Modifier.height(250.dp.scaledHeight()), scrollState = rememberScrollState(), containerColor = MaterialTheme.colorScheme.surface, expanded = isDropDownExpanded, onDismissRequest = { isDropDownExpanded = false - }) { + }, + ) { (0..10).forEachIndexed { index, num -> - DropdownMenuItem(text = { - Text(text = num.toString()) - }, + DropdownMenuItem( + text = { + Text(text = num.toString()) + }, onClick = { isDropDownExpanded = false selected = num - }) + }, + ) } } }, - ) - ) + ), + ), ) } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/InterfaceActions.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/InterfaceActions.kt new file mode 100644 index 0000000..1200830 --- /dev/null +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/InterfaceActions.kt @@ -0,0 +1,7 @@ +package com.zaneschepke.wireguardautotunnel.ui.screens.settings.autotunnel.advanced + +enum class InterfaceActions { + TOGGLE_AMNEZIA_VALUES, + SET_AMNEZIA_COMPATIBILITY, + TOGGLE_SHOW_SCRIPTS, +} diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/PeerActions.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/PeerActions.kt new file mode 100644 index 0000000..e163ac3 --- /dev/null +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/autotunnel/advanced/PeerActions.kt @@ -0,0 +1,5 @@ +package com.zaneschepke.wireguardautotunnel.ui.screens.settings.autotunnel.advanced + +enum class PeerActions { + EXCLUDE_LAN, +} diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/TunnelOptionsScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/TunnelOptionsScreen.kt index d2520af..5993bcd 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/TunnelOptionsScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/TunnelOptionsScreen.kt @@ -3,12 +3,12 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.outlined.CallSplit -import androidx.compose.material.icons.outlined.Adjust import androidx.compose.material.icons.outlined.Bolt import androidx.compose.material.icons.outlined.Edit import androidx.compose.material.icons.outlined.Star @@ -32,28 +32,17 @@ import com.zaneschepke.wireguardautotunnel.ui.Route import com.zaneschepke.wireguardautotunnel.ui.common.button.ScaledSwitch import com.zaneschepke.wireguardautotunnel.ui.common.button.surface.SelectionItem import com.zaneschepke.wireguardautotunnel.ui.common.button.surface.SurfaceSelectionGroupButton -import com.zaneschepke.wireguardautotunnel.ui.common.label.GroupLabel import com.zaneschepke.wireguardautotunnel.ui.common.navigation.LocalNavController import com.zaneschepke.wireguardautotunnel.ui.common.navigation.TopNavBar import com.zaneschepke.wireguardautotunnel.ui.screens.settings.components.ForwardButton -import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.InterfaceProxy -import com.zaneschepke.wireguardautotunnel.util.extensions.isWgCompatibilityMode -import com.zaneschepke.wireguardautotunnel.util.extensions.resetAmneziaProperties import com.zaneschepke.wireguardautotunnel.util.extensions.scaledHeight import com.zaneschepke.wireguardautotunnel.util.extensions.scaledWidth -import com.zaneschepke.wireguardautotunnel.util.extensions.toAmneziaCompatibilityConfig @Composable fun OptionsScreen(appViewModel: AppViewModel, appUiState: AppUiState, tunnelId: Int) { val navController = LocalNavController.current val config = appUiState.tunnels.first { it.id == tunnelId } - // TODO optimize - - val amConfig = config.toAmConfig() - - val isAmneziaCompatibilityEnabled = amConfig.`interface`.isWgCompatibilityMode() - var currentText by remember { mutableStateOf("") } LaunchedEffect(config.tunnelNetworks) { @@ -71,6 +60,7 @@ fun OptionsScreen(appViewModel: AppViewModel, appUiState: AppUiState, tunnelId: Modifier .fillMaxSize() .padding(it) + .imePadding() .verticalScroll(rememberScrollState()) .padding(top = 24.dp.scaledHeight()) .padding(horizontal = 24.dp.scaledWidth()), @@ -152,38 +142,6 @@ fun OptionsScreen(appViewModel: AppViewModel, appUiState: AppUiState, tunnelId: ), ), ) - val amneziaClick = { - val proxy = InterfaceProxy.from(amConfig.`interface`) - val `interface` = if (!isAmneziaCompatibilityEnabled) proxy.toAmneziaCompatibilityConfig() else proxy.resetAmneziaProperties() - appViewModel.updateExistingTunnelConfig(config, `interface` = `interface`) - } - GroupLabel(stringResource(R.string.quick_actions)) - SurfaceSelectionGroupButton( - listOf( - SelectionItem( - Icons.Outlined.Adjust, - title = { - Text( - stringResource(R.string.enable_amnezia), - style = MaterialTheme.typography.bodyMedium.copy(MaterialTheme.colorScheme.onSurface), - ) - }, - description = { - Text( - stringResource(R.string.wg_compat_mode), - style = MaterialTheme.typography.bodySmall.copy(MaterialTheme.colorScheme.outline), - ) - }, - trailing = { - ScaledSwitch( - isAmneziaCompatibilityEnabled, - onClick = { amneziaClick() }, - ) - }, - onClick = { amneziaClick() }, - ), - ), - ) } } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/ConfigScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/ConfigScreen.kt index fb4e093..e0edbe7 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/ConfigScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/ConfigScreen.kt @@ -1,5 +1,6 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config +import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.focusGroup import androidx.compose.foundation.layout.Arrangement @@ -8,7 +9,9 @@ import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape @@ -19,7 +22,10 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Save import androidx.compose.material.icons.rounded.ContentCopy import androidx.compose.material.icons.rounded.Delete +import androidx.compose.material.icons.rounded.MoreVert import androidx.compose.material.icons.rounded.Refresh +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme @@ -30,15 +36,14 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.runtime.toMutableStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.shadow import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.platform.ClipboardManager @@ -56,18 +61,19 @@ import com.zaneschepke.wireguardautotunnel.R import com.zaneschepke.wireguardautotunnel.ui.AppUiState import com.zaneschepke.wireguardautotunnel.ui.AppViewModel import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationTextBox -import com.zaneschepke.wireguardautotunnel.ui.common.config.ConfigurationToggle import com.zaneschepke.wireguardautotunnel.ui.common.label.GroupLabel import com.zaneschepke.wireguardautotunnel.ui.common.navigation.LocalNavController import com.zaneschepke.wireguardautotunnel.ui.common.navigation.TopNavBar import com.zaneschepke.wireguardautotunnel.ui.common.prompt.AuthorizationPrompt import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController +import com.zaneschepke.wireguardautotunnel.ui.screens.settings.autotunnel.advanced.InterfaceActions +import com.zaneschepke.wireguardautotunnel.ui.screens.settings.autotunnel.advanced.PeerActions import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.InterfaceProxy import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.PeerProxy +import com.zaneschepke.wireguardautotunnel.ui.theme.iconSize import com.zaneschepke.wireguardautotunnel.util.Constants import com.zaneschepke.wireguardautotunnel.util.extensions.scaledHeight import com.zaneschepke.wireguardautotunnel.util.extensions.scaledWidth -import kotlinx.coroutines.launch import org.amnezia.awg.crypto.KeyPair @Composable @@ -77,21 +83,16 @@ fun ConfigScreen(appUiState: AppUiState, appViewModel: AppViewModel, tunnelId: I val clipboardManager: ClipboardManager = LocalClipboardManager.current val keyboardController = LocalSoftwareKeyboardController.current val navController = LocalNavController.current - val scope = rememberCoroutineScope() + + var isInterfaceDropDownExpanded by remember { + mutableStateOf(false) + } val popBackStack by appViewModel.popBackStack.collectAsStateWithLifecycle(false) - val tunnelConfig by remember { - derivedStateOf { - appUiState.tunnels.firstOrNull { it.id == tunnelId } - } - } + val tunnelConfig = appUiState.tunnels.firstOrNull { it.id == tunnelId } - val configPair by remember { - derivedStateOf { - Pair(tunnelConfig?.name ?: "", tunnelConfig?.toAmConfig()) - } - } + val configPair = Pair(tunnelConfig?.name ?: "", tunnelConfig?.toAmConfig()) var tunnelName by remember { mutableStateOf(configPair.first) @@ -173,6 +174,7 @@ fun ConfigScreen(appUiState: AppUiState, appViewModel: AppViewModel, tunnelId: I Modifier .fillMaxSize() .padding(padding) + .imePadding() .verticalScroll(rememberScrollState()) .padding(top = 24.dp.scaledHeight()) .padding(horizontal = 24.dp.scaledWidth()), @@ -188,35 +190,103 @@ fun ConfigScreen(appUiState: AppUiState, appViewModel: AppViewModel, tunnelId: I .padding(16.dp.scaledWidth()) .focusGroup(), ) { - GroupLabel( - stringResource(R.string.interface_), - ) - ConfigurationToggle( - stringResource(id = R.string.show_amnezia_properties), - checked = showAmneziaValues, - onCheckChanged = { - if (appUiState.settings.isKernelEnabled) { - snackbar.showMessage(context.getString(R.string.amnezia_kernel_message)) - } else { - showAmneziaValues = it + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = + Modifier.fillMaxWidth(), + ) { + GroupLabel( + stringResource(R.string.interface_), + ) + Column { + IconButton( + modifier = Modifier.size(iconSize), + onClick = { + isInterfaceDropDownExpanded = true + }, + ) { + val icon = Icons.Rounded.MoreVert + Icon(icon, icon.name) } - }, - ) - ConfigurationToggle( - stringResource(id = R.string.show_scripts), - checked = showScripts, - onCheckChanged = { checked -> - if (appUiState.settings.isKernelEnabled) { - showScripts = checked - } else { - scope.launch { - appViewModel.requestRoot().onSuccess { - showScripts = checked - } + DropdownMenu( + containerColor = MaterialTheme.colorScheme.surface, + expanded = isInterfaceDropDownExpanded, + modifier = Modifier.shadow(12.dp).background(MaterialTheme.colorScheme.surface), + onDismissRequest = { + isInterfaceDropDownExpanded = false + }, + ) { + val isAmneziaCompatibilitySet = interfaceState.isAmneziaCompatibilityModeSet() + InterfaceActions.entries.forEach { action -> + DropdownMenuItem( + text = { + Text( + text = when (action) { + InterfaceActions.TOGGLE_SHOW_SCRIPTS -> if (showScripts) { + stringResource(R.string.hide_scripts) + } else { + stringResource(R.string.show_scripts) + } + InterfaceActions.TOGGLE_AMNEZIA_VALUES -> if (showAmneziaValues) { + stringResource(R.string.hide_amnezia_properties) + } else { + stringResource(R.string.show_amnezia_properties) + } + + InterfaceActions.SET_AMNEZIA_COMPATIBILITY -> if (isAmneziaCompatibilitySet) { + stringResource(R.string.remove_amnezia_compatibility) + } else { + stringResource(R.string.enable_amnezia_compatibility) + } + }, + ) + }, + onClick = { + isInterfaceDropDownExpanded = false + when (action) { + InterfaceActions.TOGGLE_AMNEZIA_VALUES -> showAmneziaValues = !showAmneziaValues + InterfaceActions.TOGGLE_SHOW_SCRIPTS -> showScripts = !showScripts + InterfaceActions.SET_AMNEZIA_COMPATIBILITY -> if (isAmneziaCompatibilitySet) { + showAmneziaValues = false + interfaceState = interfaceState.resetAmneziaProperties() + } else { + showAmneziaValues = true + interfaceState = interfaceState.toAmneziaCompatibilityConfig() + } + } + }, + ) } } - }, - ) + } + } +// ConfigurationToggle( +// stringResource(id = R.string.show_amnezia_properties), +// checked = showAmneziaValues, +// onCheckChanged = { +// if (appUiState.settings.isKernelEnabled) { +// snackbar.showMessage(context.getString(R.string.amnezia_kernel_message)) +// } else { +// showAmneziaValues = it +// } +// }, +// ) +// ConfigurationToggle( +// stringResource(id = R.string.show_scripts), +// checked = showScripts, +// onCheckChanged = { checked -> +// if (appUiState.settings.isKernelEnabled) { +// showScripts = checked +// } else { +// scope.launch { +// appViewModel.requestRoot().onSuccess { +// showScripts = checked +// } +// } +// } +// }, +// ) ConfigurationTextBox( value = tunnelName, onValueChange = { tunnelName = it }, @@ -246,7 +316,7 @@ fun ConfigScreen(appUiState: AppUiState, appViewModel: AppViewModel, tunnelId: I trailingIcon = { IconButton( enabled = privateKeyEnabled, - modifier = Modifier.focusRequester(FocusRequester.Default), + modifier = Modifier.focusRequester(FocusRequester.Default).size(iconSize), onClick = { val keypair = KeyPair() interfaceState = interfaceState.copy( @@ -287,7 +357,7 @@ fun ConfigScreen(appUiState: AppUiState, appViewModel: AppViewModel, tunnelId: I }, trailingIcon = { IconButton( - modifier = Modifier.focusRequester(FocusRequester.Default), + modifier = Modifier.focusRequester(FocusRequester.Default).size(iconSize), onClick = { clipboardManager.setText( AnnotatedString(interfaceState.publicKey), @@ -540,13 +610,17 @@ fun ConfigScreen(appUiState: AppUiState, appViewModel: AppViewModel, tunnelId: I } } peersState.forEachIndexed { index, peer -> + var isPeerDropDownExpanded by remember { + mutableStateOf(false) + } + val isLanExcluded = peer.isLanExcluded() Surface( shape = RoundedCornerShape(12.dp), color = MaterialTheme.colorScheme.surface, ) { Column( horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.spacedBy(5.dp, Alignment.Top), + verticalArrangement = Arrangement.spacedBy(10.dp, Alignment.Top), modifier = Modifier .padding(16.dp.scaledWidth()) .focusGroup(), @@ -560,11 +634,65 @@ fun ConfigScreen(appUiState: AppUiState, appViewModel: AppViewModel, tunnelId: I GroupLabel( stringResource(R.string.peer), ) - IconButton(onClick = { - peersState.removeAt(index) - }) { - val icon = Icons.Rounded.Delete - Icon(icon, icon.name) + Row( + horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.End), + verticalAlignment = Alignment.CenterVertically, + ) { + IconButton( + modifier = Modifier.size(iconSize), + onClick = { + // TODO make a dialog to confirm this + peersState.removeAt(index) + }, + ) { + val icon = Icons.Rounded.Delete + Icon(icon, icon.name) + } + Column { + IconButton( + modifier = Modifier.size(iconSize), + onClick = { + isPeerDropDownExpanded = true + }, + ) { + val icon = Icons.Rounded.MoreVert + Icon(icon, icon.name) + } + DropdownMenu( + containerColor = MaterialTheme.colorScheme.surface, + expanded = isPeerDropDownExpanded, + modifier = Modifier.shadow(12.dp).background(MaterialTheme.colorScheme.surface), + onDismissRequest = { + isPeerDropDownExpanded = false + }, + ) { + PeerActions.entries.forEach { action -> + DropdownMenuItem( + text = { + Text( + text = when (action) { + PeerActions.EXCLUDE_LAN -> if (isLanExcluded) { + stringResource(R.string.include_lan) + } else { + stringResource(R.string.exclude_lan) + } + }, + ) + }, + onClick = { + isPeerDropDownExpanded = false + when (action) { + PeerActions.EXCLUDE_LAN -> if (isLanExcluded) { + peersState[index] = peer.includeLan() + } else { + peersState[index] = peer.excludeLan() + } + } + }, + ) + } + } + } } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/model/InterfaceProxy.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/model/InterfaceProxy.kt index a1b07fe..8cd68c5 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/model/InterfaceProxy.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/model/InterfaceProxy.kt @@ -3,6 +3,7 @@ package com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.mode import com.wireguard.config.Interface import com.zaneschepke.wireguardautotunnel.util.extensions.joinAndTrim import com.zaneschepke.wireguardautotunnel.util.extensions.toTrimmedList +import kotlin.ranges.contains data class InterfaceProxy( val privateKey: String = "", @@ -44,6 +45,46 @@ data class InterfaceProxy( }.build() } + fun toAmneziaCompatibilityConfig(): InterfaceProxy { + return copy( + junkPacketCount = "4", + junkPacketMinSize = "40", + junkPacketMaxSize = "70", + initPacketJunkSize = "0", + responsePacketJunkSize = "0", + initPacketMagicHeader = "1", + responsePacketMagicHeader = "2", + underloadPacketMagicHeader = "3", + transportPacketMagicHeader = "4", + ) + } + + fun resetAmneziaProperties(): InterfaceProxy { + return copy( + junkPacketCount = "", + junkPacketMinSize = "", + junkPacketMaxSize = "", + initPacketJunkSize = "", + responsePacketJunkSize = "", + initPacketMagicHeader = "", + responsePacketMagicHeader = "", + underloadPacketMagicHeader = "", + transportPacketMagicHeader = "", + ) + } + + fun isAmneziaCompatibilityModeSet(): Boolean { + return junkPacketCount.toIntOrNull() in 3..<5 && + junkPacketMinSize.toIntOrNull() == 40 && + junkPacketMaxSize.toIntOrNull() == 70 && + with(initPacketJunkSize.toIntOrNull()) { this == 0 || this == null } && + with(responsePacketJunkSize.toIntOrNull()) { this == 0 || this == null } && + initPacketMagicHeader.toLongOrNull() == 1L && + responsePacketMagicHeader.toLongOrNull() == 2L && + underloadPacketMagicHeader.toLongOrNull() == 3L && + transportPacketMagicHeader.toLongOrNull() == 4L + } + fun toAmInterface(): org.amnezia.awg.config.Interface { return org.amnezia.awg.config.Interface.Builder().apply { parseAddresses(addresses) diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/model/PeerProxy.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/model/PeerProxy.kt index cf992ae..7955f69 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/model/PeerProxy.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/tunneloptions/config/model/PeerProxy.kt @@ -8,7 +8,7 @@ data class PeerProxy( val preSharedKey: String = "", val persistentKeepalive: String = "", val endpoint: String = "", - val allowedIps: String = IPV4_WILDCARD.joinAndTrim(), + val allowedIps: String = ALL_IPS.joinAndTrim(), ) { fun toWgPeer(): Peer { return Peer.Builder().apply { @@ -29,6 +29,22 @@ data class PeerProxy( }.build() } + fun isLanExcluded(): Boolean { + return this.allowedIps.contains(IPV4_PUBLIC_NETWORKS.joinAndTrim()) + } + + fun includeLan(): PeerProxy { + return this.copy( + allowedIps = ALL_IPS.joinAndTrim(), + ) + } + + fun excludeLan(): PeerProxy { + return this.copy( + allowedIps = IPV4_PUBLIC_NETWORKS.joinAndTrim(), + ) + } + companion object { fun from(peer: Peer): PeerProxy { return PeerProxy( @@ -113,6 +129,6 @@ data class PeerProxy( "200.0.0.0/5", "208.0.0.0/4", ) - val IPV4_WILDCARD = setOf("0.0.0.0/0") + val ALL_IPS = setOf("0.0.0.0/0", "::/0") } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/extensions/TunnelExtensions.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/extensions/TunnelExtensions.kt index 7e813ab..e49ef3a 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/extensions/TunnelExtensions.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/extensions/TunnelExtensions.kt @@ -6,17 +6,14 @@ import com.wireguard.config.Peer import com.zaneschepke.wireguardautotunnel.service.tunnel.BackendState import com.zaneschepke.wireguardautotunnel.service.tunnel.HandshakeStatus import com.zaneschepke.wireguardautotunnel.service.tunnel.statistics.TunnelStatistics -import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.InterfaceProxy import com.zaneschepke.wireguardautotunnel.ui.theme.SilverTree import com.zaneschepke.wireguardautotunnel.ui.theme.Straw import com.zaneschepke.wireguardautotunnel.util.Constants import com.zaneschepke.wireguardautotunnel.util.NumberUtils import org.amnezia.awg.backend.Backend import org.amnezia.awg.config.Config -import org.amnezia.awg.config.Interface import timber.log.Timber import java.net.InetAddress -import kotlin.jvm.optionals.getOrNull fun TunnelStatistics.mapPeerStats(): Map { return this.getPeers().associateWith { key -> (this.peerStats(key)) } @@ -98,45 +95,3 @@ fun Backend.BackendState.asBackendState(): BackendState { fun BackendState.asAmBackendState(): Backend.BackendState { return Backend.BackendState.valueOf(this.name) } - -fun Interface.isWgCompatibilityMode(): Boolean { - return ( - junkPacketCount.getOrNull() in 3..<5 && - junkPacketMinSize.getOrNull() == 40 && - junkPacketMaxSize.getOrNull() == 70 && - with(initPacketJunkSize.getOrNull()) { this == 0 || this == null } && - with(responsePacketJunkSize.getOrNull()) { this == 0 || this == null } && - initPacketMagicHeader.getOrNull() == 1L && - responsePacketMagicHeader.getOrNull() == 2L && - underloadPacketMagicHeader.getOrNull() == 3L && - transportPacketMagicHeader.getOrNull() == 4L - ) -} - -fun InterfaceProxy.toAmneziaCompatibilityConfig(): InterfaceProxy { - return copy( - junkPacketCount = "4", - junkPacketMinSize = "40", - junkPacketMaxSize = "70", - initPacketJunkSize = "0", - responsePacketJunkSize = "0", - initPacketMagicHeader = "1", - responsePacketMagicHeader = "2", - underloadPacketMagicHeader = "3", - transportPacketMagicHeader = "4", - ) -} - -fun InterfaceProxy.resetAmneziaProperties(): InterfaceProxy { - return copy( - junkPacketCount = "", - junkPacketMinSize = "", - junkPacketMaxSize = "", - initPacketJunkSize = "", - responsePacketJunkSize = "", - initPacketMagicHeader = "", - responsePacketMagicHeader = "", - underloadPacketMagicHeader = "", - transportPacketMagicHeader = "", - ) -} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3c754f..926961f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -196,4 +196,10 @@ Quick actions Advanced settings Debounce delay + Hide Amnezia properties + Hide scripts + Enable Amnezia compatibility + Remove Amnezia compatibility + Exclude LAN + Include LAN