summaryrefslogtreecommitdiffhomepage
path: root/android/lib
diff options
context:
space:
mode:
authorDavid Göransson <david.goransson@mullvad.net>2024-11-18 14:23:05 +0100
committerDavid Göransson <david.goransson@mullvad.net>2024-11-27 09:00:18 +0100
commit1bb7fc7ebaa2837ed9f9d28c2bb5a6fd91033988 (patch)
treea83565926fb753a2dd9fd24f0e2bd07262e4507e /android/lib
parent0d155385e1cb7075012bd270de0398d83a438bc5 (diff)
downloadmullvadvpn-1bb7fc7ebaa2837ed9f9d28c2bb5a6fd91033988.tar.xz
mullvadvpn-1bb7fc7ebaa2837ed9f9d28c2bb5a6fd91033988.zip
Handle legacy always-on vpn profiles
Co-authored-by: Jonatan Rhodin <jonatan.rhodin@mullvad.net>
Diffstat (limited to 'android/lib')
-rw-r--r--android/lib/common/build.gradle.kts3
-rw-r--r--android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/IntentActions.kt2
-rw-r--r--android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ContextExtensions.kt13
-rw-r--r--android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorNotificationMessage.kt7
-rw-r--r--android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorStateExtension.kt77
-rw-r--r--android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/VpnServiceUtils.kt61
-rw-r--r--android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/mapper/ToDomain.kt127
-rw-r--r--android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ConnectError.kt2
-rw-r--r--android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ErrorStateCause.kt7
-rw-r--r--android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationAction.kt2
-rw-r--r--android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationTunnelState.kt6
-rw-r--r--android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/PrepareError.kt17
-rw-r--r--android/lib/resource/src/main/res/values-da/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-de/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-es/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-fi/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-fr/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-it/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-ja/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-ko/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-my/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-nb/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-nl/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-pl/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-pt/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-ru/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-sv/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-th/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-tr/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-zh-rCN/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values-zh-rTW/strings.xml4
-rw-r--r--android/lib/resource/src/main/res/values/strings.xml9
-rw-r--r--android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxy.kt5
-rw-r--r--android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VpnPermissionRepository.kt11
-rw-r--r--android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VpnProfileUseCase.kt11
-rw-r--r--android/lib/shared/src/test/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxyTest.kt14
-rw-r--r--android/lib/talpid/build.gradle.kts2
-rw-r--r--android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt18
-rw-r--r--android/lib/talpid/src/main/kotlin/net/mullvad/talpid/model/CreateTunResult.kt10
-rw-r--r--android/lib/talpid/src/main/kotlin/net/mullvad/talpid/util/InetAddressExt.kt10
40 files changed, 247 insertions, 243 deletions
diff --git a/android/lib/common/build.gradle.kts b/android/lib/common/build.gradle.kts
index 2c4fbe0233..c8554b52c7 100644
--- a/android/lib/common/build.gradle.kts
+++ b/android/lib/common/build.gradle.kts
@@ -31,10 +31,11 @@ android {
dependencies {
implementation(projects.lib.model)
implementation(projects.lib.resource)
- implementation(projects.lib.talpid)
+ implementation(libs.arrow)
implementation(libs.androidx.appcompat)
implementation(libs.jodatime)
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines.android)
+ implementation(libs.kermit)
}
diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/IntentActions.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/IntentActions.kt
index ea420f2d0a..76f71d82e3 100644
--- a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/IntentActions.kt
+++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/IntentActions.kt
@@ -3,4 +3,4 @@ package net.mullvad.mullvadvpn.lib.common.constant
// Actions
const val KEY_CONNECT_ACTION = "$MULLVAD_PACKAGE_NAME.connect_action"
const val KEY_DISCONNECT_ACTION = "$MULLVAD_PACKAGE_NAME.disconnect_action"
-const val KEY_REQUEST_VPN_PERMISSION = "$MULLVAD_PACKAGE_NAME.request_vpn_permission"
+const val KEY_REQUEST_VPN_PROFILE = "$MULLVAD_PACKAGE_NAME.request_vpn_profile"
diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ContextExtensions.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ContextExtensions.kt
index 7ea74edfaa..992ae9404d 100644
--- a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ContextExtensions.kt
+++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ContextExtensions.kt
@@ -4,7 +4,6 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import android.provider.Settings
-import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.getInstalledPackagesList
import net.mullvad.mullvadvpn.lib.model.WebsiteAuthToken
private const val ALWAYS_ON_VPN_APP = "always_on_vpn_app"
@@ -20,18 +19,6 @@ fun createAccountUri(accountUri: String, websiteAuthToken: WebsiteAuthToken?): U
return Uri.parse(urlString)
}
-fun Context.getAlwaysOnVpnAppName(): String? {
- return resolveAlwaysOnVpnPackageName()
- ?.let { currentAlwaysOnVpn ->
- packageManager.getInstalledPackagesList(0).singleOrNull {
- it.packageName == currentAlwaysOnVpn && it.packageName != packageName
- }
- }
- ?.applicationInfo
- ?.loadLabel(packageManager)
- ?.toString()
-}
-
// NOTE: This function will return the current Always-on VPN package's name. In case of either
// Always-on VPN being disabled or not being able to read the state, NULL will be returned.
fun Context.resolveAlwaysOnVpnPackageName(): String? {
diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorNotificationMessage.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorNotificationMessage.kt
deleted file mode 100644
index 4a5c902d96..0000000000
--- a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorNotificationMessage.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package net.mullvad.mullvadvpn.lib.common.util
-
-data class ErrorNotificationMessage(
- val titleResourceId: Int,
- val messageResourceId: Int,
- val optionalMessageArgument: String? = null,
-)
diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorStateExtension.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorStateExtension.kt
deleted file mode 100644
index a61ec10c17..0000000000
--- a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorStateExtension.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-package net.mullvad.mullvadvpn.lib.common.util
-
-import android.content.Context
-import net.mullvad.mullvadvpn.lib.common.R
-import net.mullvad.mullvadvpn.lib.model.AuthFailedError
-import net.mullvad.mullvadvpn.lib.model.ErrorState
-import net.mullvad.mullvadvpn.lib.model.ErrorStateCause
-import net.mullvad.mullvadvpn.lib.model.ParameterGenerationError
-import net.mullvad.talpid.util.addressString
-
-fun ErrorState.getErrorNotificationResources(context: Context): ErrorNotificationMessage {
- return when {
- cause is ErrorStateCause.InvalidDnsServers -> {
- ErrorNotificationMessage(
- R.string.blocking_internet,
- cause.errorMessageId(),
- (cause as ErrorStateCause.InvalidDnsServers).addresses.joinToString { address ->
- address.addressString()
- },
- )
- }
- cause is ErrorStateCause.VpnPermissionDenied -> {
- resolveAlwaysOnVpnErrorNotificationMessage(context.getAlwaysOnVpnAppName())
- }
- isBlocking -> ErrorNotificationMessage(R.string.blocking_internet, cause.errorMessageId())
- else -> ErrorNotificationMessage(R.string.critical_error, R.string.failed_to_block_internet)
- }
-}
-
-private fun resolveAlwaysOnVpnErrorNotificationMessage(
- alwaysOnVpnAppName: String?
-): ErrorNotificationMessage {
- return if (alwaysOnVpnAppName != null) {
- ErrorNotificationMessage(
- R.string.always_on_vpn_error_notification_title,
- R.string.always_on_vpn_error_notification_content,
- alwaysOnVpnAppName,
- )
- } else {
- ErrorNotificationMessage(
- R.string.vpn_permission_error_notification_title,
- R.string.vpn_permission_error_notification_message,
- )
- }
-}
-
-fun ErrorStateCause.errorMessageId(): Int =
- when (this) {
- is ErrorStateCause.InvalidDnsServers -> R.string.invalid_dns_servers
- is ErrorStateCause.AuthFailed -> error.errorMessageId()
- is ErrorStateCause.Ipv6Unavailable -> R.string.ipv6_unavailable
- is ErrorStateCause.FirewallPolicyError -> R.string.set_firewall_policy_error
- is ErrorStateCause.DnsError -> R.string.set_dns_error
- is ErrorStateCause.StartTunnelError -> R.string.start_tunnel_error
- is ErrorStateCause.IsOffline -> R.string.is_offline
- is ErrorStateCause.TunnelParameterError -> {
- when (error) {
- ParameterGenerationError.NoMatchingRelay,
- ParameterGenerationError.NoMatchingBridgeRelay -> {
- R.string.no_matching_relay
- }
- ParameterGenerationError.NoWireguardKey -> R.string.no_wireguard_key
- ParameterGenerationError.CustomTunnelHostResultionError -> {
- R.string.custom_tunnel_host_resolution_error
- }
- }
- }
- is ErrorStateCause.VpnPermissionDenied -> R.string.vpn_permission_denied_error
- }
-
-fun AuthFailedError.errorMessageId(): Int =
- when (this) {
- AuthFailedError.ExpiredAccount -> R.string.account_credit_has_expired
- AuthFailedError.InvalidAccount,
- AuthFailedError.TooManyConnections,
- AuthFailedError.Unknown -> R.string.auth_failed
- }
diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/VpnServiceUtils.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/VpnServiceUtils.kt
new file mode 100644
index 0000000000..59833cb396
--- /dev/null
+++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/VpnServiceUtils.kt
@@ -0,0 +1,61 @@
+package net.mullvad.mullvadvpn.lib.common.util
+
+import android.content.Context
+import android.content.Intent
+import android.net.VpnService.prepare
+import arrow.core.Either
+import arrow.core.flatten
+import arrow.core.left
+import arrow.core.right
+import co.touchlab.kermit.Logger
+import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.getInstalledPackagesList
+import net.mullvad.mullvadvpn.lib.model.PrepareError
+import net.mullvad.mullvadvpn.lib.model.Prepared
+
+/**
+ * Invoking VpnService.prepare() can result in 3 out comes:
+ * 1. IllegalStateException - There is a legacy VPN profile marked as always on
+ * 2. Intent
+ * - A: Can-prepare - Create Vpn profile
+ * - B: Always-on-VPN - Another Vpn Profile is marked as always on
+ * 3. null - The app has the VPN permission
+ *
+ * In case 1 and 2b, you don't know if you have a VPN profile or not.
+ */
+fun Context.prepareVpnSafe(): Either<PrepareError, Prepared> =
+ Either.catch {
+ val intent: Intent? = prepare(this)
+ intent
+ }
+ .mapLeft {
+ Logger.e("VpnService.prepare() failed: $it")
+ when (it) {
+ is IllegalStateException -> PrepareError.OtherLegacyAlwaysOnVpn
+ else -> throw it
+ }
+ }
+ .map { intent ->
+ if (intent == null) {
+ Prepared.right()
+ } else {
+ val alwaysOnVpnApp = getAlwaysOnVpnAppName()
+ if (alwaysOnVpnApp == null) {
+ PrepareError.NotPrepared(intent).left()
+ } else {
+ PrepareError.OtherAlwaysOnApp(alwaysOnVpnApp).left()
+ }
+ }
+ }
+ .flatten()
+
+fun Context.getAlwaysOnVpnAppName(): String? {
+ return resolveAlwaysOnVpnPackageName()
+ ?.let { currentAlwaysOnVpn ->
+ packageManager.getInstalledPackagesList(0).singleOrNull {
+ it.packageName == currentAlwaysOnVpn && it.packageName != packageName
+ }
+ }
+ ?.applicationInfo
+ ?.loadLabel(packageManager)
+ ?.toString()
+}
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 fe0222596b..0412871f43 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
@@ -35,6 +35,9 @@ import net.mullvad.mullvadvpn.lib.model.DnsState
import net.mullvad.mullvadvpn.lib.model.Endpoint
import net.mullvad.mullvadvpn.lib.model.ErrorState
import net.mullvad.mullvadvpn.lib.model.ErrorStateCause
+import net.mullvad.mullvadvpn.lib.model.ErrorStateCause.AuthFailed
+import net.mullvad.mullvadvpn.lib.model.ErrorStateCause.OtherAlwaysOnApp
+import net.mullvad.mullvadvpn.lib.model.ErrorStateCause.TunnelParameterError
import net.mullvad.mullvadvpn.lib.model.FeatureIndicator
import net.mullvad.mullvadvpn.lib.model.GeoIpLocation
import net.mullvad.mullvadvpn.lib.model.GeoLocationId
@@ -76,49 +79,78 @@ import org.joda.time.Instant
internal fun ManagementInterface.TunnelState.toDomain(): TunnelState =
when (stateCase!!) {
- ManagementInterface.TunnelState.StateCase.DISCONNECTED ->
- TunnelState.Disconnected(
- location =
- with(disconnected) {
- if (hasDisconnectedLocation()) {
- disconnectedLocation.toDomain()
- } else null
- }
- )
- ManagementInterface.TunnelState.StateCase.CONNECTING ->
- TunnelState.Connecting(
- endpoint = connecting.relayInfo.tunnelEndpoint.toDomain(),
- location =
- with(connecting.relayInfo) {
- if (hasLocation()) {
- location.toDomain()
- } else null
- },
- featureIndicators = connecting.featureIndicators.toDomain(),
- )
- ManagementInterface.TunnelState.StateCase.CONNECTED ->
- TunnelState.Connected(
- endpoint = connected.relayInfo.tunnelEndpoint.toDomain(),
- location =
- with(connected.relayInfo) {
- if (hasLocation()) {
- location.toDomain()
- } else {
- null
- }
- },
- featureIndicators = connected.featureIndicators.toDomain(),
- )
- ManagementInterface.TunnelState.StateCase.DISCONNECTING ->
- TunnelState.Disconnecting(
- actionAfterDisconnect = disconnecting.afterDisconnect.toDomain()
- )
- ManagementInterface.TunnelState.StateCase.ERROR ->
- TunnelState.Error(errorState = error.errorState.toDomain())
+ ManagementInterface.TunnelState.StateCase.DISCONNECTED -> disconnected.toDomain()
+ ManagementInterface.TunnelState.StateCase.CONNECTING -> connecting.toDomain()
+ ManagementInterface.TunnelState.StateCase.CONNECTED -> connected.toDomain()
+ ManagementInterface.TunnelState.StateCase.DISCONNECTING -> disconnecting.toDomain()
+ ManagementInterface.TunnelState.StateCase.ERROR -> error.toDomain()
ManagementInterface.TunnelState.StateCase.STATE_NOT_SET ->
TunnelState.Disconnected(location = disconnected.disconnectedLocation.toDomain())
}
+private fun ManagementInterface.TunnelState.Connecting.toDomain(): TunnelState.Connecting =
+ TunnelState.Connecting(
+ endpoint = relayInfo.tunnelEndpoint.toDomain(),
+ location =
+ if (relayInfo.hasLocation()) {
+ relayInfo.location.toDomain()
+ } else null,
+ featureIndicators = featureIndicators.toDomain(),
+ )
+
+private fun ManagementInterface.TunnelState.Disconnected.toDomain(): TunnelState.Disconnected =
+ TunnelState.Disconnected(
+ location =
+ if (hasDisconnectedLocation()) {
+ disconnectedLocation.toDomain()
+ } else null
+ )
+
+private fun ManagementInterface.TunnelState.Connected.toDomain(): TunnelState.Connected =
+ TunnelState.Connected(
+ endpoint = relayInfo.tunnelEndpoint.toDomain(),
+ location =
+ if (relayInfo.hasLocation()) {
+ relayInfo.location.toDomain()
+ } else {
+ null
+ },
+ featureIndicators = featureIndicators.toDomain(),
+ )
+
+private fun ManagementInterface.TunnelState.Disconnecting.toDomain(): TunnelState.Disconnecting =
+ TunnelState.Disconnecting(actionAfterDisconnect = afterDisconnect.toDomain())
+
+private fun ManagementInterface.TunnelState.Error.toDomain(): TunnelState.Error {
+ val otherAlwaysOnAppError =
+ errorState.let {
+ if (it.hasOtherAlwaysOnAppError()) {
+ OtherAlwaysOnApp(it.otherAlwaysOnAppError.appName)
+ } else {
+ null
+ }
+ }
+
+ val invalidDnsServers =
+ errorState.let {
+ if (it.hasInvalidDnsServersError()) {
+ ErrorStateCause.InvalidDnsServers(
+ it.invalidDnsServersError.ipAddrsList.toList().map { InetAddress.getByName(it) }
+ )
+ } else {
+ null
+ }
+ }
+
+ return TunnelState.Error(
+ errorState =
+ errorState.toDomain(
+ otherAlwaysOnApp = otherAlwaysOnAppError,
+ invalidDnsServers = invalidDnsServers,
+ )
+ )
+}
+
internal fun ManagementInterface.GeoIpLocation.toDomain(): GeoIpLocation =
GeoIpLocation(
ipv4 =
@@ -198,12 +230,15 @@ internal fun ManagementInterface.AfterDisconnect.toDomain(): ActionAfterDisconne
throw IllegalArgumentException("Unrecognized action after disconnect")
}
-internal fun ManagementInterface.ErrorState.toDomain(): ErrorState =
+internal fun ManagementInterface.ErrorState.toDomain(
+ otherAlwaysOnApp: ErrorStateCause.OtherAlwaysOnApp?,
+ invalidDnsServers: ErrorStateCause.InvalidDnsServers?,
+): ErrorState =
ErrorState(
cause =
when (cause!!) {
ManagementInterface.ErrorState.Cause.AUTH_FAILED ->
- ErrorStateCause.AuthFailed(authFailedError.toDomain())
+ AuthFailed(authFailedError.toDomain())
ManagementInterface.ErrorState.Cause.IPV6_UNAVAILABLE ->
ErrorStateCause.Ipv6Unavailable
ManagementInterface.ErrorState.Cause.SET_FIREWALL_POLICY_ERROR ->
@@ -212,16 +247,20 @@ internal fun ManagementInterface.ErrorState.toDomain(): ErrorState =
ManagementInterface.ErrorState.Cause.START_TUNNEL_ERROR ->
ErrorStateCause.StartTunnelError
ManagementInterface.ErrorState.Cause.TUNNEL_PARAMETER_ERROR ->
- ErrorStateCause.TunnelParameterError(parameterError.toDomain())
+ TunnelParameterError(parameterError.toDomain())
ManagementInterface.ErrorState.Cause.IS_OFFLINE -> ErrorStateCause.IsOffline
- ManagementInterface.ErrorState.Cause.VPN_PERMISSION_DENIED ->
- ErrorStateCause.VpnPermissionDenied
ManagementInterface.ErrorState.Cause.SPLIT_TUNNEL_ERROR ->
ErrorStateCause.StartTunnelError
ManagementInterface.ErrorState.Cause.UNRECOGNIZED,
ManagementInterface.ErrorState.Cause.NEED_FULL_DISK_PERMISSIONS,
ManagementInterface.ErrorState.Cause.CREATE_TUNNEL_DEVICE ->
throw IllegalArgumentException("Unrecognized error state cause")
+
+ ManagementInterface.ErrorState.Cause.NOT_PREPARED -> ErrorStateCause.NotPrepared
+ ManagementInterface.ErrorState.Cause.OTHER_ALWAYS_ON_APP -> otherAlwaysOnApp!!
+ ManagementInterface.ErrorState.Cause.OTHER_LEGACY_ALWAYS_ON_VPN ->
+ ErrorStateCause.OtherLegacyAlwaysOnApp
+ ManagementInterface.ErrorState.Cause.INVALID_DNS_SERVERS -> invalidDnsServers!!
},
isBlocking = !hasBlockingError(),
)
diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ConnectError.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ConnectError.kt
index 307a235314..6feeeee579 100644
--- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ConnectError.kt
+++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ConnectError.kt
@@ -3,5 +3,5 @@ package net.mullvad.mullvadvpn.lib.model
sealed interface ConnectError {
data class Unknown(val throwable: Throwable) : ConnectError
- data object NoVpnPermission : ConnectError
+ data class NotPrepared(val error: PrepareError) : ConnectError
}
diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ErrorStateCause.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ErrorStateCause.kt
index ef5947c89a..fdb7dd3a1a 100644
--- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ErrorStateCause.kt
+++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/ErrorStateCause.kt
@@ -17,7 +17,6 @@ sealed class ErrorStateCause {
data object DnsError : ErrorStateCause()
- // Regression
data class InvalidDnsServers(val addresses: List<InetAddress>) : ErrorStateCause()
data object StartTunnelError : ErrorStateCause()
@@ -26,7 +25,11 @@ sealed class ErrorStateCause {
data object IsOffline : ErrorStateCause()
- data object VpnPermissionDenied : ErrorStateCause()
+ data object NotPrepared : ErrorStateCause()
+
+ data class OtherAlwaysOnApp(val appName: String) : ErrorStateCause()
+
+ data object OtherLegacyAlwaysOnApp : ErrorStateCause()
}
sealed interface AuthFailedError {
diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationAction.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationAction.kt
index ec938a9fbf..141fe739f5 100644
--- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationAction.kt
+++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationAction.kt
@@ -15,6 +15,6 @@ sealed interface NotificationAction {
data object Dismiss : Tunnel
- data object RequestPermission : Tunnel
+ data object RequestVpnProfile : Tunnel
}
}
diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationTunnelState.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationTunnelState.kt
index fffe86c247..3ca573a839 100644
--- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationTunnelState.kt
+++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/NotificationTunnelState.kt
@@ -1,7 +1,7 @@
package net.mullvad.mullvadvpn.lib.model
sealed interface NotificationTunnelState {
- data class Disconnected(val hasVpnPermission: Boolean) : NotificationTunnelState
+ data class Disconnected(val prepareError: PrepareError?) : NotificationTunnelState
data object Connecting : NotificationTunnelState
@@ -18,7 +18,9 @@ sealed interface NotificationTunnelState {
data object VpnPermissionDenied : Error
- data object AlwaysOnVpn : Error
+ data class AlwaysOnVpn(val appName: String) : Error
+
+ data object LegacyLockdown : Error
data object Critical : Error
}
diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/PrepareError.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/PrepareError.kt
new file mode 100644
index 0000000000..8954c5f98a
--- /dev/null
+++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/PrepareError.kt
@@ -0,0 +1,17 @@
+package net.mullvad.mullvadvpn.lib.model
+
+import android.content.Intent
+
+sealed interface PrepareResult
+
+sealed interface PrepareError : PrepareResult {
+ // Result from VpnService.prepare() being invoked with legacy VPN app has always-on
+ data object OtherLegacyAlwaysOnVpn : PrepareError
+
+ // Prepare gives intent but there is other always VPN app
+ data class OtherAlwaysOnApp(val appName: String) : PrepareError
+
+ data class NotPrepared(val prepareIntent: Intent) : PrepareError
+}
+
+data object Prepared : PrepareResult
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 88c135c304..b3cc919ca4 100644
--- a/android/lib/resource/src/main/res/values-da/strings.xml
+++ b/android/lib/resource/src/main/res/values-da/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Alle placeringer</string>
<string name="all_providers">Alle udbydere</string>
<string name="always_on_vpn_error_notification_content">Kunne ikke starte tunnelforbindelse. Deaktiver Altid-til VPN for &lt;b&gt;%1$s&lt;/b&gt;.</string>
- <string name="always_on_vpn_error_notification_title">Altid-til VPN tildelt en anden app</string>
<string name="any">Enhver</string>
<string name="api_access_description">Administrer og tilføj brugerdefinerede metoder for at få adgang til Mullvad API.</string>
<string name="api_access_method_info_first_line">Appen skal kommunikere med en Mullvad API-server for at kunne logge dig på, hente serverlister og andre kritiske operationer.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Indtast kuponkode</string>
<string name="entry">Indgang</string>
<string name="error_occurred">Der opstod en fejl.</string>
- <string name="error_state">KUNNE IKKE SIKRE FORBINDELSEN</string>
<string name="exclude_applications">Ekskluderede applikationer</string>
<string name="exit">Udgang</string>
<string name="failed_to_block_internet">Kan ikke blokere al netværkstrafik. Udfør fejlfinding, eller indsend en problemrapport.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Kuponkode er ugyldig.</string>
<string name="ipv6_unavailable">Kunne ikke konfigurere IPv6. Deaktiver det i appen, eller aktiver det på din enhed.</string>
<string name="is_offline">Din enhed er offline. Tunnelen vil oprette forbindelse automatisk, når din enhed er online igen.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Altid-til VPN tildelt en anden app</string>
<string name="less_than_a_day_left">mindre end én dag tilbage</string>
<string name="less_than_one_day">mindre end én dag</string>
<string name="list_name">Listenavn</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Det ser ud til, at du har indtastet et kontonummer i stedet for en rabatkuponkode. Hvis du vil ændre den aktive konto, skal du først logge ud.</string>
<string name="voucher_success_title">Indløsning af kuponen lykkedes.</string>
<string name="vpn_permission_denied_error">VPN-tilladelse blev nægtet, da tunnelen blev oprettet. Prøv at oprette forbindelse igen.</string>
- <string name="vpn_permission_error_notification_message">Altid-til VPN er måske aktiveret for en anden app</string>
<string name="vpn_permission_error_notification_title">VPN-tilladelsesfejl</string>
<string name="we_will_look_into_this">Vi vil undersøge dette.</string>
<string name="wireguard_custon_port_title">Brugerdefineret</string>
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 fdaceb2899..74331acc9a 100644
--- a/android/lib/resource/src/main/res/values-de/strings.xml
+++ b/android/lib/resource/src/main/res/values-de/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Alle Standorte</string>
<string name="all_providers">Alle Anbieter</string>
<string name="always_on_vpn_error_notification_content">Tunnelverbindung kann nicht gestartet werden. Bitte deaktivieren Sie Always-on VPN für &lt;b&gt;%1$s&lt;/b&gt;, bevor Sie Mullvad VPN verwenden.</string>
- <string name="always_on_vpn_error_notification_title">Always-on VPN ist einer anderen App zugeordnet</string>
<string name="any">Beliebige</string>
<string name="api_access_description">Verwaltung und Hinzufügen benutzerdefinierter Methoden für den Zugriff auf die Mullvad-API.</string>
<string name="api_access_method_info_first_line">Die App muss mit einem Mullvad API-Server kommunizieren, um Sie anzumelden, Serverlisten abzurufen und andere wichtige Vorgänge durchzuführen.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Gutscheincode eingeben</string>
<string name="entry">Eingang</string>
<string name="error_occurred">Ein Fehler ist aufgetreten.</string>
- <string name="error_state">SICHERE VERBINDUNG KONNTE NICHT HERGESTELLT WERDEN</string>
<string name="exclude_applications">Ausgeschlossene Anwendungen</string>
<string name="exit">Ausgang</string>
<string name="failed_to_block_internet">Der Netzwerk-Traffic konnte nicht gänzlich blockiert werden. Bitte beheben Sie den Fehler oder senden Sie einen Problembericht.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Der Gutscheincode ist ungültig.</string>
<string name="ipv6_unavailable">IPv6 konnte nicht konfiguriert werden. Deaktivieren Sie es in der App oder aktivieren Sie es auf Ihrem Gerät.</string>
<string name="is_offline">Ihr Gerät ist offline. Der Tunnel wird automatisch verbunden, sobald Ihr Gerät wieder online ist.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Always-on VPN ist einer anderen App zugeordnet</string>
<string name="less_than_a_day_left">weniger als ein Tag übrig</string>
<string name="less_than_one_day">weniger als ein Tag</string>
<string name="list_name">Name der Liste</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Anscheinend haben Sie eine Kontonummer statt eines Gutscheincodes eingegeben. Wenn Sie das aktive Konto wechseln möchten, melden Sie sich bitte zuerst ab.</string>
<string name="voucher_success_title">Der Gutschein wurde erfolgreich eingelöst.</string>
<string name="vpn_permission_denied_error">VPN-Berechtigungen wurden beim Erstellen des Tunnels abgelehnt.</string>
- <string name="vpn_permission_error_notification_message">Always-on VPN könnte für eine andere App aktiviert sein</string>
<string name="vpn_permission_error_notification_title">VPN-Berechtigungsfehler</string>
<string name="we_will_look_into_this">Wir werden uns das anschauen.</string>
<string name="wireguard_custon_port_title">Benutzerdefiniert</string>
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 fb5981905b..512f3a1982 100644
--- a/android/lib/resource/src/main/res/values-es/strings.xml
+++ b/android/lib/resource/src/main/res/values-es/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Todas las ubicaciones</string>
<string name="all_providers">Todos los proveedores</string>
<string name="always_on_vpn_error_notification_content">No se puede iniciar la conexión de túnel. Deshabilite la VPN siempre activa en &lt;b&gt;%1$s&lt;/b&gt; antes de utilizar la VPN de Mullvad.</string>
- <string name="always_on_vpn_error_notification_title">La VPN siempre activa se ha asignado a otra aplicación</string>
<string name="any">Cualquiera</string>
<string name="api_access_description">Gestione y añada métodos personalizados para acceder a la API de Mullvad.</string>
<string name="api_access_method_info_first_line">La aplicación necesita comunicarse con un servidor API de Mullvad para iniciar su sesión, obtener las listas de servidores y otras operaciones críticas.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Escriba el código del cupón</string>
<string name="entry">Entrada</string>
<string name="error_occurred">Se produjo un error.</string>
- <string name="error_state">NO SE PUDO PROTEGER LA CONEXIÓN</string>
<string name="exclude_applications">Aplicaciones excluidas</string>
<string name="exit">Salida</string>
<string name="failed_to_block_internet">No se puede bloquear todo el tráfico de red. Intente solucionar el problema o envíe un informe de problemas.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">El código del cupón no es válido.</string>
<string name="ipv6_unavailable">No se pudo configurar IPv6. Desactívelo en la aplicación o actívelo en el dispositivo.</string>
<string name="is_offline">El dispositivo está sin conexión. El túnel se conectará automáticamente cuando el dispositivo vuelva a estar en línea.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">La VPN siempre activa se ha asignado a otra aplicación</string>
<string name="less_than_a_day_left">queda menos de un día</string>
<string name="less_than_one_day">menos de un día</string>
<string name="list_name">Nombre de la lista</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Parece que ha introducido un número de cuenta en lugar de un código de cupón. Si desea cambiar la cuenta activa, cierre primero la sesión.</string>
<string name="voucher_success_title">El cupón se canjeó correctamente.</string>
<string name="vpn_permission_denied_error">Se denegó el permiso para usar una conexión VPN al crear el túnel. Intente volver a establecer la conexión.</string>
- <string name="vpn_permission_error_notification_message">La VPN siempre activa podría estar habilitada en otra aplicación</string>
<string name="vpn_permission_error_notification_title">Error en la autorización de la VPN</string>
<string name="we_will_look_into_this">Revisaremos esto.</string>
<string name="wireguard_custon_port_title">Personalizado</string>
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 38e2a76a8d..6a10183e80 100644
--- a/android/lib/resource/src/main/res/values-fi/strings.xml
+++ b/android/lib/resource/src/main/res/values-fi/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Kaikki sijainnit</string>
<string name="all_providers">Kaikki palveluntarjoajat</string>
<string name="always_on_vpn_error_notification_content">Tunneliyhteyden käynnistäminen ei onnistu. Poista aina päällä oleva VPN käytöstä sovellukselle &lt;b&gt;%1$s&lt;/b&gt; ennen Mullvad VPN:n käyttämistä.</string>
- <string name="always_on_vpn_error_notification_title">Aina päällä oleva VPN on määritetty toiselle sovellukselle</string>
<string name="any">Mikä tahansa</string>
<string name="api_access_description">Hallitse ja lisää mukautettuja menetelmiä Mullvadin ohjelmointirajapinnan käyttämiseksi.</string>
<string name="api_access_method_info_first_line">Sovelluksen on kommunikoitava Mullvadin ohjelmointirajapinnan palvelimen kanssa, jotta sinut voidaan kirjata sisään, palvelinluetteloiden hakemiseksi sekä muiden tärkeiden toimintojen suorittamiseksi.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Syötä kuponkikoodi</string>
<string name="entry">Tulo</string>
<string name="error_occurred">Ilmeni virhe.</string>
- <string name="error_state">YHTEYDEN SUOJAAMINEN EPÄONNISTUI</string>
<string name="exclude_applications">Poissuljetut sovellukset</string>
<string name="exit">Lähtö</string>
<string name="failed_to_block_internet">Kaiken verkkoliikenteen estäminen ei onnistu. Käytä vianetsintää tai lähetä ongelmaraportti.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Kuponkikoodi ei kelpaa.</string>
<string name="ipv6_unavailable">IPv6:n määritys ei onnistunut. Poista se käytöstä sovelluksessa tai ota käyttöön laitteellasi.</string>
<string name="is_offline">Laitteesi on offline-tilassa. Kun laitteesi on taas online-tilassa, tunneli muodostaa yhteyden automaattisesti.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Aina päällä oleva VPN on määritetty toiselle sovellukselle</string>
<string name="less_than_a_day_left">alle vuorokausi jäljellä</string>
<string name="less_than_one_day">alle vuorokausi</string>
<string name="list_name">Luettelon nimi</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Näytät syöttäneen tilin numeron etusetelin koodin sijaan. Jos haluat vaihtaa tiliä, kirjaudu ensin ulos nykyiseltä tililtä.</string>
<string name="voucher_success_title">Kupongin lunastus onnistui.</string>
<string name="vpn_permission_denied_error">VPN-lupa evättiin tunnelia luotaessa. Yritä muodostaa yhteys uudelleen.</string>
- <string name="vpn_permission_error_notification_message">Aina päällä oleva VPN on mahdollisesti otettu käyttöön toiselle sovellukselle</string>
<string name="vpn_permission_error_notification_title">VPN-lupavirhe</string>
<string name="we_will_look_into_this">Tutkimme asiaa.</string>
<string name="wireguard_custon_port_title">Mukautettu</string>
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 cd70ac2701..8ea968806f 100644
--- a/android/lib/resource/src/main/res/values-fr/strings.xml
+++ b/android/lib/resource/src/main/res/values-fr/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Toutes les localisations</string>
<string name="all_providers">Tous les fournisseurs</string>
<string name="always_on_vpn_error_notification_content">Impossible de démarrer la connexion au tunnel. Veuillez désactiver « Toujours exiger un VPN « pour &lt;b&gt;%1$s&lt;/b&gt; avant d\'utiliser Mullvad VPN.</string>
- <string name="always_on_vpn_error_notification_title">« Toujours exiger un VPN » est assigné à une autre application</string>
<string name="any">N\'importe lequel</string>
<string name="api_access_description">Gérez et ajoutez des modes d\'accès personnalisés à l\'API Mullvad.</string>
<string name="api_access_method_info_first_line">L\'application doit communiquer avec un serveur d\'API Mullvad pour vous connecter, récupérer des listes de serveurs et effectuer d\'autres opérations critiques.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Saisir un code de bon</string>
<string name="entry">Entrée</string>
<string name="error_occurred">Une erreur est survenue.</string>
- <string name="error_state">ÉCHEC DE LA SÉCURISATION DE LA CONNEXION</string>
<string name="exclude_applications">Applications exclues</string>
<string name="exit">Sortie</string>
<string name="failed_to_block_internet">Impossible de bloquer tout le trafic réseau. Veuillez dépanner ou envoyer un rapport de problème.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Le code du bon n\'est pas valide.</string>
<string name="ipv6_unavailable">Impossible de configurer IPv6. Désactivez le protocole dans l\'application ou activez-le dans votre appareil.</string>
<string name="is_offline">Votre appareil est hors ligne. Le tunnel se connectera automatiquement une fois votre appareil à nouveau en ligne.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">« Toujours exiger un VPN » est assigné à une autre application</string>
<string name="less_than_a_day_left">moins d\'un jour restant</string>
<string name="less_than_one_day">moins d\'un jour</string>
<string name="list_name">Nom de la liste</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Vous semblez avoir saisi un numéro de compte plutôt qu\'un code de bon. Si vous souhaitez modifier le compte actif, veuillez d\'abord vous déconnecter.</string>
<string name="voucher_success_title">Le bon a bien été échangé.</string>
<string name="vpn_permission_denied_error">La permission VPN a été refusée lors de la création du tunnel. Veuillez essayer de vous reconnecter.</string>
- <string name="vpn_permission_error_notification_message">« Toujours exiger un VPN » est peut-être activé pour une autre application</string>
<string name="vpn_permission_error_notification_title">Erreur de permission VPN</string>
<string name="we_will_look_into_this">Nous allons nous pencher dessus.</string>
<string name="wireguard_custon_port_title">Personnalisé</string>
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 70a08dbf7c..629a1b12df 100644
--- a/android/lib/resource/src/main/res/values-it/strings.xml
+++ b/android/lib/resource/src/main/res/values-it/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Tutti i luoghi</string>
<string name="all_providers">Tutti i fornitori</string>
<string name="always_on_vpn_error_notification_content">Impossibile avviare la connessione tunnel. Disabilita VPN sempre attiva per &lt;b&gt;%1$s&lt;/b&gt; prima di utilizzare Mullvad VPN.</string>
- <string name="always_on_vpn_error_notification_title">VPN sempre attiva assegnata a un\'altra app</string>
<string name="any">Qualsiasi</string>
<string name="api_access_description">Gestisci e aggiungi metodi personalizzati per accedere all\'API Mullvad.</string>
<string name="api_access_method_info_first_line">L\'app deve comunicare con un server API Mullvad per accedere, recuperare elenchi di server e altre operazioni critiche.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Inserisci codice voucher</string>
<string name="entry">Ingresso</string>
<string name="error_occurred">Si è verificato un errore.</string>
- <string name="error_state">IMPOSSIBILE STABILIRE UNA CONNESSIONE PROTETTA</string>
<string name="exclude_applications">Applicazioni escluse</string>
<string name="exit">Uscita</string>
<string name="failed_to_block_internet">Impossibile bloccare tutto il traffico di rete. Consulta la risoluzione dei problemi o invia una segnalazione del problema.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Il codice voucher non è valido.</string>
<string name="ipv6_unavailable">Impossibile configurare IPv6. Disabilitalo nell\'app o abilitalo sul tuo dispositivo.</string>
<string name="is_offline">Il tuo dispositivo è offline. Il tunnel si connetterà automaticamente una volta che il tuo dispositivo sarà di nuovo online.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">VPN sempre attiva assegnata a un\'altra app</string>
<string name="less_than_a_day_left">meno di un giorno rimanente</string>
<string name="less_than_one_day">meno di un giorno</string>
<string name="list_name">Nome dell\'elenco</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Sembra che tu abbia inserito un numero di account anziché un codice voucher. Se desideri modificare l\'account attivo, effettua prima la disconnessione.</string>
<string name="voucher_success_title">Il voucher è stato riscattato correttamente.</string>
<string name="vpn_permission_denied_error">L\'autorizzazione VPN è stata negata durante la creazione del tunnel. Prova a connetterti di nuovo.</string>
- <string name="vpn_permission_error_notification_message">La VPN sempre attiva potrebbe essere abilitata per un\'altra app</string>
<string name="vpn_permission_error_notification_title">Errore di autorizzazione VPN</string>
<string name="we_will_look_into_this">Verificheremo.</string>
<string name="wireguard_custon_port_title">Personalizzato</string>
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 2fb24ebe8e..f7efc1af4a 100644
--- a/android/lib/resource/src/main/res/values-ja/strings.xml
+++ b/android/lib/resource/src/main/res/values-ja/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">すべての場所</string>
<string name="all_providers">すべてのプロバイダ</string>
<string name="always_on_vpn_error_notification_content">トンネル接続を開始できません。Mullvad VPNを使用する前に&lt;b&gt;%1$s&lt;/b&gt;のAlways-on VPNを無効にしてください。</string>
- <string name="always_on_vpn_error_notification_title">Always-on VPNは他のアプリに割り当てられています</string>
<string name="any">すべて</string>
<string name="api_access_description">Mullvad APIへのカスタムのアクセス方法を管理・追加します。</string>
<string name="api_access_method_info_first_line">アプリはユーザーのログイン、サーバーリストの取得、およびその他の重要な操作を行うためにMullvad APIサーバーと通信する必要があります。</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">バウチャーコードを入力</string>
<string name="entry">入口</string>
<string name="error_occurred">エラー発生。</string>
- <string name="error_state">セキュリティ保護接続を確立できませんでした</string>
<string name="exclude_applications">除外対象アプリケーション</string>
<string name="exit">出口</string>
<string name="failed_to_block_internet">すべてのネットワークトラフィックをブロックできません。問題に対処するか、問題の報告を送信してください。</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">バウチャーコードが無効です。</string>
<string name="ipv6_unavailable">IPv6を設定できませんでした。アプリで無効にするか、デバイスで有効にしてください。</string>
<string name="is_offline">デバイスがオフラインになっています。トンネルはデバイスがオンラインに戻ると自動的に接続されます。</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Always-on VPNは他のアプリに割り当てられています</string>
<string name="less_than_a_day_left">残り1日未満</string>
<string name="less_than_one_day">1日未満</string>
<string name="list_name">リスト名</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">バウチャーコードではなくアカウント番号を入力したようです。有効なアカウントを変更する場合は、先にログアウトしてください。</string>
<string name="voucher_success_title">バウチャーを正常に使用しました。</string>
<string name="vpn_permission_denied_error">トンネルを作成中にVPNへのアクセスが拒否されました。もう一度接続してみてください。</string>
- <string name="vpn_permission_error_notification_message">Always-on VPNが別のアプリで有効になっている可能性があります</string>
<string name="vpn_permission_error_notification_title">VPN許可エラー</string>
<string name="we_will_look_into_this">この問題を調査いたします。</string>
<string name="wireguard_custon_port_title">カスタム</string>
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 f8727aabbc..c6d2c3cf3f 100644
--- a/android/lib/resource/src/main/res/values-ko/strings.xml
+++ b/android/lib/resource/src/main/res/values-ko/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">모든 위치</string>
<string name="all_providers">모든 제공업체</string>
<string name="always_on_vpn_error_notification_content">터널 연결을 시작할 수 없습니다. Mullvad VPN을 사용하기 전에 &lt;b&gt;%1$s&lt;/b&gt;에 대한 상시 접속 VPN을 비활성화하세요.</string>
- <string name="always_on_vpn_error_notification_title">상시 접속 VPN이 다른 앱에 할당됨</string>
<string name="any">모두</string>
<string name="api_access_description">Mullvad API에 액세스하기 위한 사용자 지정 방법을 관리하고 추가합니다.</string>
<string name="api_access_method_info_first_line">이 앱은 로그인, 서버 목록 가져오기 및 기타 중요한 작업을 위해 Mullvad API 서버와 통신해야 합니다.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">바우처 코드 입력</string>
<string name="entry">시작</string>
<string name="error_occurred">오류가 발생했습니다.</string>
- <string name="error_state">보안 연결 실패</string>
<string name="exclude_applications">제외된 애플리케이션</string>
<string name="exit">종료</string>
<string name="failed_to_block_internet">모든 네트워크 트래픽을 차단할 수는 없습니다. 문제를 해결하거나 문제 보고서를 보내주세요.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">유효하지 않은 바우처 코드입니다.</string>
<string name="ipv6_unavailable">IPv6을 구성할 수 없습니다. 앱에서 비활성화하거나 장치에서 활성화하세요.</string>
<string name="is_offline">장치가 오프라인 상태입니다. 장치가 다시 온라인 상태가 되면 터널이 자동으로 연결됩니다.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">상시 접속 VPN이 다른 앱에 할당됨</string>
<string name="less_than_a_day_left">1일 이내</string>
<string name="less_than_one_day">1일 미만</string>
<string name="list_name">목록 이름</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">바우처 코드 대신 계정 번호를 입력한 것 같습니다. 활성 계정을 변경하려면 먼저 로그아웃하세요.</string>
<string name="voucher_success_title">바우처가 성공적으로 사용되었습니다.</string>
<string name="vpn_permission_denied_error">터널을 만드는 동안 VPN 사용 권한이 거부되었습니다. 다시 연결해 보세요.</string>
- <string name="vpn_permission_error_notification_message">상시 접속 VPN이 다른 앱에 활성화되었을 수 있습니다.</string>
<string name="vpn_permission_error_notification_title">VPN 권한 오류</string>
<string name="we_will_look_into_this">조사해보겠습니다.</string>
<string name="wireguard_custon_port_title">사용자 지정</string>
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 5c9cd497f2..a73a327cb9 100644
--- a/android/lib/resource/src/main/res/values-my/strings.xml
+++ b/android/lib/resource/src/main/res/values-my/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">တည်နေရာအာလုံး</string>
<string name="all_providers">ပံ့ပိုးသူအားလုံး</string>
<string name="always_on_vpn_error_notification_content">Tunnel ချိတ်ဆက်မှုကို စတင်၍ မရနိုင်ပါ။ Mullvad VPN ကို မသုံးမီ &lt;b&gt;%1$s&lt;/b&gt; အတွက် VPN အမြဲဖွင့်ထားမှုကို ပိတ်ပေးပါ။</string>
- <string name="always_on_vpn_error_notification_title">အမြဲဖွင့် VPN ကို အခြားအက်ပ်တစ်ခုသို့ သတ်မှတ်ထားပါသည်</string>
<string name="any">တစ်ခုခု</string>
<string name="api_access_description">Mullvad API ကို ရယူသုံးစွဲရန် စိတ်ကြိုက် နည်းလမ်းများကို ပေါင်းထည့်၍ စီမံပါ။</string>
<string name="api_access_method_info_first_line">Mullvad API ဆာဗာသို့ သင်ဝင်ရောက်ရန်၊ ဆာဗာစာရင်းများ ရယူရန်နှင့် အလွန်အရေးပါသည့် အခြားလုပ်ဆောင်မှုများအတွက် ဤအက်ပ်သည် ၎င်းနှင့်ဆက်သွယ်ရန် လိုအပ်ပါသည်။</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">ဘောက်ချာကုဒ် ဖြည့်သွင်းရန်</string>
<string name="entry">အဝင်</string>
<string name="error_occurred">ချို့ယွင်းချက် ဖြစ်ပေါ်ခဲ့ပါသည်။</string>
- <string name="error_state">ချိတ်ဆက်မှုကို ကာကွယ်ရန် မအောင်မြင်ပါ</string>
<string name="exclude_applications">အပလီကေးရှင်းများ ဖယ်ထားပြီး</string>
<string name="exit">အထွက်</string>
<string name="failed_to_block_internet">ကွန်ရက် ကူးလူးမှု အားလုံးကို ပိတ်ဆို့၍ မရနိုင်ပါ။ ပြစ်ချက် ရှာဖွေဖယ်ရှားပေးပါ သို့မဟုတ် ပြဿနာ ရီပို့တ်တစ်ခု ပေးပို့ပါ။</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">ဘောက်ချာကုဒ် မှားနေပါသည်။</string>
<string name="ipv6_unavailable">IPv6 ကို သတ်မှတ်ချိန်ညှိ၍ မရနိုင်ပါ။ အက်ပ်တွင် ၎င်းကို ပိတ်ပါ သို့မဟုတ် သင့်စက်တွင် ၎င်းကို ဖွင့်ပါ။</string>
<string name="is_offline">သင့်စက်သည် အော့ဖ်လိုင်း ဖြစ်နေပါသည်။ သင့်စက် အွန်လိုင်း ပြန်ဖြစ်သည်နှင့် Tunnel သည် အော်တို ချိတ်ဆက်သွားပါမည်။</string>
+ <string name="legacy_always_on_vpn_error_notification_title">အမြဲဖွင့် VPN ကို အခြားအက်ပ်တစ်ခုသို့ သတ်မှတ်ထားပါသည်</string>
<string name="less_than_a_day_left">တစ်ရက်အောက်သာ ကျန်တော့သည်</string>
<string name="less_than_one_day">တစ်ရက်အောက် နည်းသည်။</string>
<string name="list_name">စာရင်း အမည်</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">ဘောက်ချာကုဒ်အစား အကောင့်နံပါတ်တစ်ခုကို ထည့်သွင်းထားပုံရသည်။ အသုံးပြုနေသောအကောင့်ကို ပြောင်းလဲလိုပါက ဦးစွာ အကောင့်မှထွက်ပါ။</string>
<string name="voucher_success_title">ဘောက်ချာကို အောင်မြင်စွာ လဲယူခဲ့ပါသည်။</string>
<string name="vpn_permission_denied_error">Tunnel ဖန်တီးနေစဉ် VPN ခွင့်ပြုချက်ကို ပယ်ချခဲ့ပါသည်။ ထပ်မံချိတ်ဆက်ပေးပါ။</string>
- <string name="vpn_permission_error_notification_message">အမြဲဖွင့် VPN ကို နောက်ထပ်အက်ပ်အတွက် ဖွင့်ထားနိုင်ပါသည်</string>
<string name="vpn_permission_error_notification_title">VPN ခွင့်ပြုချက် ချို့ယွင်းချက်</string>
<string name="we_will_look_into_this">ဤသည်ကို စစ်ဆေးလိုက်ပါမည်။</string>
<string name="wireguard_custon_port_title">စိတ်ကြိုက်</string>
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 bef18f4629..01a2e1c0cf 100644
--- a/android/lib/resource/src/main/res/values-nb/strings.xml
+++ b/android/lib/resource/src/main/res/values-nb/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Alle steder</string>
<string name="all_providers">Alle leverandører</string>
<string name="always_on_vpn_error_notification_content">Kunne ikke starte tunneltilkobling. Deaktiver VPN som alltid er på, for &lt;b&gt;%1$s&lt;/b&gt; før du bruker Mullvad VPN.</string>
- <string name="always_on_vpn_error_notification_title">VPN som alltid er på, er tilordnet en annen app</string>
<string name="any">Hvilken som helst</string>
<string name="api_access_description">Administrer og legg til tilpassede metoder for tilgang til Mullvad API.</string>
<string name="api_access_method_info_first_line">Appen må kunne kommunisere med en Mullvad API-server for å logge deg inn, hente serverlister og utføre andre kritiske operasjoner.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Skriv inn kupongkode</string>
<string name="entry">Inngang</string>
<string name="error_occurred">Det oppstod en feil.</string>
- <string name="error_state">KUNNE IKKE OPPRETTE SIKKER TILKOBLING</string>
<string name="exclude_applications">Ekskluder applikasjoner</string>
<string name="exit">Utgang</string>
<string name="failed_to_block_internet">Kunne ikke blokkere all nettverkstrafikk. Feilsøk eller send inn en problemrapport.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Ugyldig kupongkode.</string>
<string name="ipv6_unavailable">Kunne ikke konfigurere IPv6. Deaktiver den i appen eller aktiver den på enheten din.</string>
<string name="is_offline">Enheten er frakoblet. Tunnelen vil koble til automatisk når enheten er tilkoblet internett igjen.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">VPN som alltid er på, er tilordnet en annen app</string>
<string name="less_than_a_day_left">mindre enn én dag igjen</string>
<string name="less_than_one_day">mindre enn én dag</string>
<string name="list_name">Listenavn</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Det ser ut til at du har oppgitt et kontonummer i stedet for en kupongkode. Hvis du vil endre den aktive kontoen, må du først logge ut.</string>
<string name="voucher_success_title">Kupongkoden er løst inn.</string>
<string name="vpn_permission_denied_error">VPN-tillatelse ble avvist under opprettelsen av tunnelen. Prøv å koble til igjen.</string>
- <string name="vpn_permission_error_notification_message">VPN som alltid er på, kan være aktivert for en annen app</string>
<string name="vpn_permission_error_notification_title">Feil med VPN-tillatelse</string>
<string name="we_will_look_into_this">Dette skal vi følge opp.</string>
<string name="wireguard_custon_port_title">Egendefinert</string>
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 e965388f40..84ee272e08 100644
--- a/android/lib/resource/src/main/res/values-nl/strings.xml
+++ b/android/lib/resource/src/main/res/values-nl/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Alle locaties</string>
<string name="all_providers">Alle aanbieders</string>
<string name="always_on_vpn_error_notification_content">Kan de tunnelverbinding niet starten. Schakel Altijd-aan VPN uit voor &lt;b&gt;%1$s&lt;/b&gt; voordat u Mullvad VPN gebruikt.</string>
- <string name="always_on_vpn_error_notification_title">Altijd-aan VPN toegewezen aan andere app</string>
<string name="any">Elke</string>
<string name="api_access_description">Beheer en voeg aangepaste methoden toe om toegang te krijgen tot de Mullvad-API.</string>
<string name="api_access_method_info_first_line">De app moet communiceren met een Mullvad-API-server om u aan te melden, serverlijsten op te halen en andere belangrijke handelingen uit te voeren.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Vouchercode invoeren</string>
<string name="entry">Ingang</string>
<string name="error_occurred">Er is een fout opgetreden.</string>
- <string name="error_state">VERBINDING BEVEILIGEN MISLUKT</string>
<string name="exclude_applications">Uitgesloten toepassingen</string>
<string name="exit">Uitgang</string>
<string name="failed_to_block_internet">Kan niet alle netwerkverkeer blokkeren. Los problemen op of stuur een probleemmelding.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Vouchercode is ongeldig.</string>
<string name="ipv6_unavailable">Kon IPv6 niet configureren. Schakel het uit in de app of schakel het in op uw apparaat.</string>
<string name="is_offline">Uw apparaat is offline. De tunnel wordt automatisch verbonden wanneer uw apparaat weer online is.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Altijd-aan VPN toegewezen aan andere app</string>
<string name="less_than_a_day_left">minder dan een dag over</string>
<string name="less_than_one_day">minder dan één dag</string>
<string name="list_name">Lijstnaam</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Het lijkt erop dat u een accountnummer hebt ingevoerd in plaats van een vouchercode. Als u het actieve account wilt wijzigen, meld u dan eerst af.</string>
<string name="voucher_success_title">Voucher is ingewisseld.</string>
<string name="vpn_permission_denied_error">VPN-toestemming is geweigerd tijdens maken van de tunnel. Probeer opnieuw verbinding te maken.</string>
- <string name="vpn_permission_error_notification_message">Altijd-aan VPN is mogelijk ingeschakeld voor een andere app</string>
<string name="vpn_permission_error_notification_title">VPN-machtigingsfout</string>
<string name="we_will_look_into_this">We gaan het bekijken.</string>
<string name="wireguard_custon_port_title">Aangepast</string>
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 9fd1e9de55..e19d2fddd4 100644
--- a/android/lib/resource/src/main/res/values-pl/strings.xml
+++ b/android/lib/resource/src/main/res/values-pl/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Wszystkie lokalizacje</string>
<string name="all_providers">Wszyscy dostawcy</string>
<string name="always_on_vpn_error_notification_content">Nie można uruchomić połączenia tunelowego. Przed rozpoczęciem użytkowania usługi Mullvad VPN wyłącz opcję „Zawsze włączony VPN” w &lt;b&gt;%1$s&lt;/b&gt;.</string>
- <string name="always_on_vpn_error_notification_title">Opcja „Zawsze włączony VPN” przypisana jest do innej aplikacji</string>
<string name="any">Dowolny</string>
<string name="api_access_description">Zarządzaj i dodawaj niestandardowe metody dostępu do interfejsu API Mullvad.</string>
<string name="api_access_method_info_first_line">Aplikacja musi komunikować się z serwerem API Mullvad, aby można było się zalogować, pobrać listy serwerów i wykonywać inne krytyczne operacje.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Wprowadź kod kuponu</string>
<string name="entry">Wejście</string>
<string name="error_occurred">Wystąpił błąd.</string>
- <string name="error_state">BŁĄD ZABEZPIECZANIA POŁĄCZENIA</string>
<string name="exclude_applications">Wykluczone aplikacje</string>
<string name="exit">Wyjście</string>
<string name="failed_to_block_internet">Nie można zablokować całego ruchu sieciowego. Rozwiąż problem lub wyślij zgłoszenie problemu.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Nieprawidłowy kod kuponu.</string>
<string name="ipv6_unavailable">Nie można skonfigurować protokołu IPv6. Wyłącz go w aplikacji lub włącz na urządzeniu.</string>
<string name="is_offline">Twoje urządzenie jest offline. Tunel zostanie automatycznie połączony, gdy urządzenie ponownie przejdzie w tryb online.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Opcja „Zawsze włączony VPN” przypisana jest do innej aplikacji</string>
<string name="less_than_a_day_left">pozostał mniej niż jeden dzień</string>
<string name="less_than_one_day">mniej niż jeden dzień</string>
<string name="list_name">Nazwa listy</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Wygląda na to, że wpisano numer konta zamiast kodu kuponu. Jeśli chcesz zmienić aktywne konto, najpierw się wyloguj.</string>
<string name="voucher_success_title">Kupon został zrealizowany.</string>
<string name="vpn_permission_denied_error">Uprawnienie VPN zostało odrzucone podczas tworzenia tunelu. Spróbuj połączyć się ponownie.</string>
- <string name="vpn_permission_error_notification_message">Opcja „Zawsze włączony VPN” może być włączona dla innej aplikacji</string>
<string name="vpn_permission_error_notification_title">Błąd uprawnienia VPN</string>
<string name="we_will_look_into_this">Sprawdzimy to.</string>
<string name="wireguard_custon_port_title">Niestandardowy</string>
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 34175af582..0e390b6a30 100644
--- a/android/lib/resource/src/main/res/values-pt/strings.xml
+++ b/android/lib/resource/src/main/res/values-pt/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Todas as localizações</string>
<string name="all_providers">Todos os fornecedores</string>
<string name="always_on_vpn_error_notification_content">Não foi possível iniciar a ligação de túnel. Desative a VPN sempre ligada para &lt;b&gt;%1$s&lt;/b&gt; antes de utilizar a Mullvad VPN.</string>
- <string name="always_on_vpn_error_notification_title">VPN sempre ligada atribuída a outra app</string>
<string name="any">Qualquer</string>
<string name="api_access_description">Gerir e adicionar métodos personalizados para aceder à Mullvad API.</string>
<string name="api_access_method_info_first_line">A app precisa de comunicar com um servidor da Mullvad API para iniciar a sua sessão, obter listas de servidores e outras operações críticas.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Introduza o código do voucher</string>
<string name="entry">Entrada</string>
<string name="error_occurred">Ocorreu um erro.</string>
- <string name="error_state">ERRO AO ESTABELECER LIGAÇÃO SEGURA</string>
<string name="exclude_applications">Aplicações excluídas</string>
<string name="exit">Saída</string>
<string name="failed_to_block_internet">Não foi possível bloquear todo o tráfego de rede. Experimente a resolução de problemas ou envie um relatório do problema.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Código do voucher inválido.</string>
<string name="ipv6_unavailable">Não foi possível configurar o IPv6. Desative-o ou ative-o no seu dispositivo.</string>
<string name="is_offline">O seu dispositivo está offline. O túnel irá ligar-se automaticamente assim que o seu dispositivo estiver novamente online.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">VPN sempre ligada atribuída a outra app</string>
<string name="less_than_a_day_left">menos de um dia restante</string>
<string name="less_than_one_day">menos de um dia</string>
<string name="list_name">Nome da lista</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Parece que introduziu um número de conta em vez de um código de voucher. Se pretender alterar a conta ativa, termine a sessão primeiro.</string>
<string name="voucher_success_title">O voucher foi reclamado com sucesso.</string>
<string name="vpn_permission_denied_error">A transmissão foi negada durante a criação do túnel. Tente fazer novamente a ligação.</string>
- <string name="vpn_permission_error_notification_message">A VPN sempre ligada pode estar ativada para outra app</string>
<string name="vpn_permission_error_notification_title">Erro de permissão da VPN</string>
<string name="we_will_look_into_this">Vamos analisar esta situação.</string>
<string name="wireguard_custon_port_title">Personalizado</string>
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 4d7e03a968..060597a298 100644
--- a/android/lib/resource/src/main/res/values-ru/strings.xml
+++ b/android/lib/resource/src/main/res/values-ru/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Все местоположения</string>
<string name="all_providers">Все провайдеры</string>
<string name="always_on_vpn_error_notification_content">Не удалось запустить туннельное подключение. Перед использованием Mullvad VPN отключите опцию «Постоянная VPN» для приложения &lt;b&gt;%1$s&lt;/b&gt;.</string>
- <string name="always_on_vpn_error_notification_title">Опция «Постоянная VPN» назначена другому приложению</string>
<string name="any">Все</string>
<string name="api_access_description">Добавление пользовательских методов для доступа к API Mullvad и управление ими.</string>
<string name="api_access_method_info_first_line">Приложение должно взаимодействовать с сервером API Mullvad для входа в учетную запись, получения списков серверов и других важных операций.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Введите код ваучера</string>
<string name="entry">Вход</string>
<string name="error_occurred">Произошла ошибка.</string>
- <string name="error_state">НЕ УДАЛОСЬ УСТАНОВИТЬ БЕЗОПАСНОЕ ПОДКЛЮЧЕНИЕ</string>
<string name="exclude_applications">Исключенные приложения</string>
<string name="exit">Выход</string>
<string name="failed_to_block_internet">Не удалось заблокировать весь сетевой трафик. Устраните неполадки или отправьте сообщение о проблеме.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Код ваучера недействителен.</string>
<string name="ipv6_unavailable">Не удается сконфигурировать IPv6. Отключите этот протокол в приложении или включите на устройстве.</string>
<string name="is_offline">Устройство отключено от Интернета. Туннельное подключение автоматически запустится, как только ваше устройство подключится к Интернету.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Опция «Постоянная VPN» назначена другому приложению</string>
<string name="less_than_a_day_left">осталось менее суток</string>
<string name="less_than_one_day">менее суток</string>
<string name="list_name">Имя списка</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Вы ввели номер учетной записи вместо кода ваучера. Чтобы изменить активную учетную запись, сначала выйдите из системы.</string>
<string name="voucher_success_title">Ваучер погашен.</string>
<string name="vpn_permission_denied_error">При создании туннеля в доступе к VPN было отказано. Попробуйте подключиться снова.</string>
- <string name="vpn_permission_error_notification_message">Опцию «Постоянная VPN» может быть включена для другого приложения</string>
<string name="vpn_permission_error_notification_title">Ошибка разрешения для VPN</string>
<string name="we_will_look_into_this">Мы рассмотрим эту проблему.</string>
<string name="wireguard_custon_port_title">Пользовательский</string>
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 a1f0557de7..35517f1c95 100644
--- a/android/lib/resource/src/main/res/values-sv/strings.xml
+++ b/android/lib/resource/src/main/res/values-sv/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Alla platser</string>
<string name="all_providers">Alla leverantörer</string>
<string name="always_on_vpn_error_notification_content">Det går inte att starta tunnelanslutning. Aktivera VPN som alltid är på för &lt;b&gt;%1$s&lt;/b&gt; innan du använder Mullvad VPN.</string>
- <string name="always_on_vpn_error_notification_title">VPN som alltid är på har tilldelats till annan app</string>
<string name="any">Valfri</string>
<string name="api_access_description">Hantera och lägg till anpassade metoder för att komma åt Mullvad API.</string>
<string name="api_access_method_info_first_line">Appen måste kommunicera med en Mullvad API-server för att logga in dig, hämta serverlistor och andra viktiga åtgärder.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Ange kupongkod</string>
<string name="entry">Ingång</string>
<string name="error_occurred">Ett fel har inträffat.</string>
- <string name="error_state">DET GICK INTE ATT SÄKRA ANSLUTNINGEN</string>
<string name="exclude_applications">Exkluderade applikationer</string>
<string name="exit">Utgång</string>
<string name="failed_to_block_internet">Det går inte att blockera all nätverkstrafik. Felsök eller skicka en problemrapport.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Kupongkoden är ogiltig.</string>
<string name="ipv6_unavailable">Det gick inte att konfigurera IPv6. Inaktivera det i appen eller aktivera det på din enhet.</string>
<string name="is_offline">Din enhet är offline. Tunneln ansluts automatiskt när din enhet är online igen.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">VPN som alltid är på har tilldelats till annan app</string>
<string name="less_than_a_day_left">mindre än en dag kvar</string>
<string name="less_than_one_day">mindre än en dag</string>
<string name="list_name">Listnamn</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Det verkar som om du angett ett kontonummer istället för en kupongkod. Logga först ut om du vill ändra den aktiva koden.</string>
<string name="voucher_success_title">Kupongen har lösts in.</string>
<string name="vpn_permission_denied_error">VPN-behörighet nekades när tunneln skapades. Försök att ansluta igen.</string>
- <string name="vpn_permission_error_notification_message">VPN som alltid är på kan ha aktiverats för annan app</string>
<string name="vpn_permission_error_notification_title">Behörighetsfel med VPN</string>
<string name="we_will_look_into_this">Vi kommer att undersöka detta.</string>
<string name="wireguard_custon_port_title">Anpassad</string>
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 9664d0a917..f91d3ed15c 100644
--- a/android/lib/resource/src/main/res/values-th/strings.xml
+++ b/android/lib/resource/src/main/res/values-th/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">ตำแหน่งที่ตั้งทั้งหมด</string>
<string name="all_providers">ผู้ให้บริการทั้งหมด</string>
<string name="always_on_vpn_error_notification_content">ไม่สามารถเริ่มการเชื่อมต่ออุโมงค์ได้ โปรดปิดใช้งาน Always-on VPN เป็นเวลา &lt;b&gt;%1$s&lt;/b&gt; ก่อนที่จะใช้งาน Mullvad VPN</string>
- <string name="always_on_vpn_error_notification_title">Always-on VPN ได้รับการมอบหมายไปยังแอปอื่นแล้ว</string>
<string name="any">อะไรก็ได้</string>
<string name="api_access_description">จัดการและเพิ่มวิธีแบบกำหนดเอง เพื่อเข้าถึง Mullvad API</string>
<string name="api_access_method_info_first_line">แอปจำเป็นต้องสื่อสารกับเซิร์ฟเวอร์ Mullvad API เพื่อนำคุณเข้าสู่ระบบ ดึงข้อมูลรายการเซิร์ฟเวอร์ และการดำเนินการที่สำคัญอื่นๆ</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">ป้อนรหัสบัตรกำนัล</string>
<string name="entry">เข้า</string>
<string name="error_occurred">เกิดข้อผิดพลาดขึ้น</string>
- <string name="error_state">ไม่สามารถเชื่อมต่ออย่างปลอดภัยได้</string>
<string name="exclude_applications">แอปพลิเคชันที่แยกออก</string>
<string name="exit">ออก</string>
<string name="failed_to_block_internet">ไม่สามารถบล็อกการรับส่งข้อมูลทางเครือข่ายทั้งหมดได้ โปรดแก้ไขปัญหาหรือส่งรายงานปัญหา</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">รหัสบัตรกำนัลไม่ถูกต้อง</string>
<string name="ipv6_unavailable">ไม่สามารถกำหนดค่า IPv6 ได้ โปรดปิดใช้งานรายการนี้ในแอป หรือเปิดใช้งานบนอุปกรณ์ของคุณ</string>
<string name="is_offline">อุปกรณ์ของคุณออฟไลน์อยู่ อุโมงค์จะเชื่อมต่อโดยอัตโนมัติ หลังจากที่อุปกรณ์ของคุณกลับมาออนไลน์</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Always-on VPN ได้รับการมอบหมายไปยังแอปอื่นแล้ว</string>
<string name="less_than_a_day_left">เหลือเวลาน้อยกว่าหนึ่งวัน</string>
<string name="less_than_one_day">น้อยกว่าหนึ่งวัน</string>
<string name="list_name">ชื่อรายการ</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">ดูเหมือนว่า คุณได้ป้อนหมายเลขบัญชีแทนรหัสบัตรกำนัล หากคุณต้องการเปลี่ยนบัญชีที่ใช้งานอยู่ โปรดออกจากระบบก่อน</string>
<string name="voucher_success_title">แลกบัตรกำนัลสำเร็จแล้ว</string>
<string name="vpn_permission_denied_error">การให้สิทธิ์ VPN ถูกปฏิเสธ ในขณะที่สร้างอุโมงค์ โปรดลองเชื่อมต่อใหม่อีกครั้ง</string>
- <string name="vpn_permission_error_notification_message">Always-on VPN อาจได้รับการเปิดใช้งานสำหรับแอปอื่น</string>
<string name="vpn_permission_error_notification_title">เกิดข้อผิดพลาดในการอนุญาต VPN</string>
<string name="we_will_look_into_this">เราจะตรวจสอบปัญหานี้</string>
<string name="wireguard_custon_port_title">กำหนดเอง</string>
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 cdb01b9d2f..2f7e1d1dad 100644
--- a/android/lib/resource/src/main/res/values-tr/strings.xml
+++ b/android/lib/resource/src/main/res/values-tr/strings.xml
@@ -22,7 +22,6 @@
<string name="all_locations">Tüm konumlar</string>
<string name="all_providers">Tüm hizmet sağlayıcılar</string>
<string name="always_on_vpn_error_notification_content">Tünel bağlantısı başlatılamıyor. Mullvad VPN\'i kullanmadan önce lütfen Her zaman açık VPN\'i &lt;b&gt;%1$s&lt;/b&gt; için devre dışı bırakın.</string>
- <string name="always_on_vpn_error_notification_title">Her zaman açık VPN başka bir uygulamaya atandı</string>
<string name="any">Tümü</string>
<string name="api_access_description">Mullvad API\'sine erişim için özel yöntemler ekleyip yönetin.</string>
<string name="api_access_method_info_first_line">Uygulamanın oturumunuzu açmak, sunucu listelerini almak ve diğer kritik işlemleri yapmak için bir Mullvad API sunucusuyla iletişim kurması gerekir.</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">Kupon kodunu girin</string>
<string name="entry">Giriş</string>
<string name="error_occurred">Bir hata oluştu.</string>
- <string name="error_state">GÜVENLİ BAĞLANTI OLUŞTURULAMADI</string>
<string name="exclude_applications">Hariç tutulan uygulamalar</string>
<string name="exit">Çıkış</string>
<string name="failed_to_block_internet">Tüm ağ trafiği engellenemiyor. Lütfen sorunu çözmeyi deneyin veya bir hata raporu gönderin.</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">Kupon kodu geçersiz.</string>
<string name="ipv6_unavailable">IPv6 yapılandırılamadı. IPv6\'yı uygulamada devre dışı bırakın veya cihazınızda etkinleştirin.</string>
<string name="is_offline">Cihazınız çevrimdışı. Cihazınız tekrar çevrimiçi olduğunda tünel otomatik olarak bağlanacak.</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Her zaman açık VPN başka bir uygulamaya atandı</string>
<string name="less_than_a_day_left">bir günden az kaldı</string>
<string name="less_than_one_day">bir günden az</string>
<string name="list_name">Liste adı</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">Kupon kodu yerine hesap numarası girdiniz. Aktif hesabı değiştirmek istiyorsanız lütfen önce çıkış yapın.</string>
<string name="voucher_success_title">Kupon başarıyla kullanıldı.</string>
<string name="vpn_permission_denied_error">Tünel oluşturulurken VPN izni reddedildi. Lütfen tekrar bağlanmayı deneyin.</string>
- <string name="vpn_permission_error_notification_message">Her zaman açık VPN başka bir uygulama için etkinleştirilebilir</string>
<string name="vpn_permission_error_notification_title">VPN izin hatası</string>
<string name="we_will_look_into_this">Bunu araştıracağız.</string>
<string name="wireguard_custon_port_title">Özel</string>
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 39306a64ae..f9c87e9191 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
@@ -22,7 +22,6 @@
<string name="all_locations">所有位置</string>
<string name="all_providers">所有提供商</string>
<string name="always_on_vpn_error_notification_content">无法启动隧道连接。在使用 Mullvad VPN 之前,请为 &lt;b&gt;%1$s&lt;/b&gt; 禁用“始终开启 VPN”。</string>
- <string name="always_on_vpn_error_notification_title">“始终开启 VPN”已分配给其他应用</string>
<string name="any">任何</string>
<string name="api_access_description">管理和添加访问 Mulvad API 的自定义方法。</string>
<string name="api_access_method_info_first_line">该应用需要与 Mulvad API 服务器通信,以便您登录、获取服务器列表和执行其他关键操作。</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">输入优惠码</string>
<string name="entry">入口</string>
<string name="error_occurred">出错了。</string>
- <string name="error_state">无法保护连接</string>
<string name="exclude_applications">排除的应用程序</string>
<string name="exit">出口</string>
<string name="failed_to_block_internet">无法阻止所有网络流量。请排查问题或发送问题报告。</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">该优惠券码无效。</string>
<string name="ipv6_unavailable">无法配置 IPv6。请在应用中将其禁用或在您的设备上将其启用。</string>
<string name="is_offline">您的设备已离线。在您的设备重新上线后,隧道将自动连接。</string>
+ <string name="legacy_always_on_vpn_error_notification_title">“始终开启 VPN”已分配给其他应用</string>
<string name="less_than_a_day_left">剩余时间不足 1 天</string>
<string name="less_than_one_day">不足 1 天</string>
<string name="list_name">列表名称</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">您输入的似乎是帐号,而不是代金券码。如果您想更改有效帐户,请先退出登录。</string>
<string name="voucher_success_title">优惠券已成功兑换。</string>
<string name="vpn_permission_denied_error">创建隧道时,VPN 权限被拒绝。请尝试重新连接。</string>
- <string name="vpn_permission_error_notification_message">可能为另一个应用启用了“始终开启 VPN”</string>
<string name="vpn_permission_error_notification_title">VPN 权限错误</string>
<string name="we_will_look_into_this">我们将对此进行调查。</string>
<string name="wireguard_custon_port_title">自定义</string>
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 8be3c88b59..6cd3b5d8fc 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
@@ -22,7 +22,6 @@
<string name="all_locations">所有位置</string>
<string name="all_providers">所有供應商</string>
<string name="always_on_vpn_error_notification_content">無法啟動通道連線。在使用 Mullvad VPN 之前,請先為 &lt;b&gt;%1$s&lt;/b&gt; 停用「始終啟用 VPN」。</string>
- <string name="always_on_vpn_error_notification_title">「始終啟用 VPN」已指派給其他應用程式</string>
<string name="any">任何</string>
<string name="api_access_description">管理並新增自訂方式以存取 Mullvad API。</string>
<string name="api_access_method_info_first_line">該應用程式需要與 Mulvad API 伺服器通訊,以便您登入、取得伺服器清單並執行其他重要作業。</string>
@@ -134,7 +133,6 @@
<string name="enter_voucher_code">輸入優惠券兌換碼</string>
<string name="entry">入口</string>
<string name="error_occurred">發生錯誤了。</string>
- <string name="error_state">保護連線失敗</string>
<string name="exclude_applications">已排除的應用程式</string>
<string name="exit">出口</string>
<string name="failed_to_block_internet">無法封鎖所有網路流量。請排除故障或傳送問題回報。</string>
@@ -170,6 +168,7 @@
<string name="invalid_voucher">憑證兌換碼無效。</string>
<string name="ipv6_unavailable">無法配置 IPv6。請在應用程式中將其停用,或是在您的裝置上啟用它。</string>
<string name="is_offline">您的裝置已離線。在您的裝置重新上線後,通道將自動連線。</string>
+ <string name="legacy_always_on_vpn_error_notification_title">「始終啟用 VPN」已指派給其他應用程式</string>
<string name="less_than_a_day_left">剩餘時間不足 1 天</string>
<string name="less_than_one_day">不足 1 天</string>
<string name="list_name">清單名稱</string>
@@ -334,7 +333,6 @@
<string name="voucher_is_account_number">您輸入的似乎是帳戶,而不是憑證代碼。如果您想變更有效帳戶,請先登出。</string>
<string name="voucher_success_title">憑證已成功兌換。</string>
<string name="vpn_permission_denied_error">建立通道時,VPN 權限被拒絕。請嘗試重新連線。</string>
- <string name="vpn_permission_error_notification_message">可能已為另一個應用程式啟用了「始終啟用 VPN」</string>
<string name="vpn_permission_error_notification_title">VPN 權限錯誤</string>
<string name="we_will_look_into_this">我們會對此進行調查。</string>
<string name="wireguard_custon_port_title">自訂</string>
diff --git a/android/lib/resource/src/main/res/values/strings.xml b/android/lib/resource/src/main/res/values/strings.xml
index 4625fb3b5f..fc2cf0cce1 100644
--- a/android/lib/resource/src/main/res/values/strings.xml
+++ b/android/lib/resource/src/main/res/values/strings.xml
@@ -105,7 +105,7 @@
<string name="edit_message">Edit message</string>
<string name="try_again">Try again</string>
<string name="blocked_connection">BLOCKED CONNECTION</string>
- <string name="error_state">FAILED TO SECURE CONNECTION</string>
+ <string name="error_state">FAILED TO CONNECT</string>
<string name="connected">Connected</string>
<string name="cancel">Cancel</string>
<string name="disconnect">Disconnect</string>
@@ -164,12 +164,15 @@
<string name="hide_account_number">Hide account number</string>
<string name="failed_to_remove_device">Failed to remove device</string>
<string name="changes_dialog_subtitle">Changes in this version:</string>
- <string name="always_on_vpn_error_notification_title">Always-on VPN assigned to other app</string>
+ <string name="always_on_vpn_error_notification_title">Always-on VPN assigned to %s</string>
<string name="always_on_vpn_error_notification_content">
<![CDATA[Unable to start tunnel connection. Please disable Always-on VPN for <b>%s</b> before using Mullvad VPN.]]>
</string>
+ <string name="legacy_always_on_vpn_error_notification_title">Always-on VPN assigned to other app</string>
+ <string name="legacy_always_on_vpn_error_notification_content">Unable to start tunnel connection. Please disable Always-on VPN before using Mullvad VPN.</string>
<string name="vpn_permission_error_notification_title">VPN permission error</string>
- <string name="vpn_permission_error_notification_message">Always-on VPN might be enabled for another app</string>
+ <string name="vpn_permission_error_notification_message">Please press connect to request VPN permission</string>
+
<string name="new_device_notification_title">NEW DEVICE CREATED</string>
<string name="new_device_notification_message">
<![CDATA[Welcome, this device is now called <b>%s</b>. For more details see the info button in Account.]]>
diff --git a/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxy.kt b/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxy.kt
index 2dbd15ec03..08a0a517f0 100644
--- a/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxy.kt
+++ b/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxy.kt
@@ -2,7 +2,6 @@ package net.mullvad.mullvadvpn.lib.shared
import arrow.core.Either
import arrow.core.raise.either
-import arrow.core.raise.ensure
import kotlinx.coroutines.flow.combine
import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService
import net.mullvad.mullvadvpn.lib.model.ConnectError
@@ -12,7 +11,7 @@ import net.mullvad.mullvadvpn.lib.model.TunnelState
class ConnectionProxy(
private val managementService: ManagementService,
translationRepository: RelayLocationTranslationRepository,
- private val vpnPermissionRepository: VpnPermissionRepository,
+ private val vpnProfileUseCase: VpnProfileUseCase,
) {
val tunnelState =
combine(managementService.tunnelState, translationRepository.translations) {
@@ -35,7 +34,7 @@ class ConnectionProxy(
copy(city = translations[city] ?: city, country = translations[country] ?: country)
suspend fun connect(): Either<ConnectError, Boolean> = either {
- ensure(vpnPermissionRepository.hasVpnPermission()) { ConnectError.NoVpnPermission }
+ vpnProfileUseCase.prepareVpn().mapLeft(ConnectError::NotPrepared).bind()
managementService.connect().bind()
}
diff --git a/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VpnPermissionRepository.kt b/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VpnPermissionRepository.kt
deleted file mode 100644
index b97c60316c..0000000000
--- a/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VpnPermissionRepository.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package net.mullvad.mullvadvpn.lib.shared
-
-import android.content.Context
-import android.net.VpnService
-import net.mullvad.mullvadvpn.lib.common.util.getAlwaysOnVpnAppName
-
-class VpnPermissionRepository(private val applicationContext: Context) {
- fun hasVpnPermission(): Boolean = VpnService.prepare(applicationContext) == null
-
- fun getAlwaysOnVpnAppName() = applicationContext.getAlwaysOnVpnAppName()
-}
diff --git a/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VpnProfileUseCase.kt b/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VpnProfileUseCase.kt
new file mode 100644
index 0000000000..cebac0be04
--- /dev/null
+++ b/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VpnProfileUseCase.kt
@@ -0,0 +1,11 @@
+package net.mullvad.mullvadvpn.lib.shared
+
+import android.content.Context
+import arrow.core.Either
+import net.mullvad.mullvadvpn.lib.common.util.prepareVpnSafe
+import net.mullvad.mullvadvpn.lib.model.PrepareError
+import net.mullvad.mullvadvpn.lib.model.Prepared
+
+class VpnProfileUseCase(private val applicationContext: Context) {
+ fun prepareVpn(): Either<PrepareError, Prepared> = applicationContext.prepareVpnSafe()
+}
diff --git a/android/lib/shared/src/test/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxyTest.kt b/android/lib/shared/src/test/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxyTest.kt
index 0652867105..24a14ce782 100644
--- a/android/lib/shared/src/test/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxyTest.kt
+++ b/android/lib/shared/src/test/kotlin/net/mullvad/mullvadvpn/lib/shared/ConnectionProxyTest.kt
@@ -1,31 +1,36 @@
package net.mullvad.mullvadvpn.lib.shared
+import android.content.Intent
+import arrow.core.left
+import arrow.core.right
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import io.mockk.unmockkAll
import kotlinx.coroutines.test.runTest
import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService
+import net.mullvad.mullvadvpn.lib.model.PrepareError
+import net.mullvad.mullvadvpn.lib.model.Prepared
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test
class ConnectionProxyTest {
private val mockManagementService: ManagementService = mockk(relaxed = true)
- private val mockVpnPermissionRepository: VpnPermissionRepository = mockk()
+ private val mockVpnPermissionRepository: VpnProfileUseCase = mockk()
private val mockTranslationRepository: RelayLocationTranslationRepository =
mockk(relaxed = true)
private val connectionProxy: ConnectionProxy =
ConnectionProxy(
managementService = mockManagementService,
- vpnPermissionRepository = mockVpnPermissionRepository,
+ vpnProfileUseCase = mockVpnPermissionRepository,
translationRepository = mockTranslationRepository,
)
@Test
fun `connect with vpn permission allowed should call managementService connect`() = runTest {
- every { mockVpnPermissionRepository.hasVpnPermission() } returns true
+ every { mockVpnPermissionRepository.prepareVpn() } returns Prepared.right()
connectionProxy.connect()
coVerify(exactly = 1) { mockManagementService.connect() }
}
@@ -33,7 +38,8 @@ class ConnectionProxyTest {
@Test
fun `connect with vpn permission not allowed should not call managementService connect`() =
runTest {
- every { mockVpnPermissionRepository.hasVpnPermission() } returns false
+ every { mockVpnPermissionRepository.prepareVpn() } returns
+ PrepareError.NotPrepared(Intent()).left()
connectionProxy.connect()
coVerify(exactly = 0) { mockManagementService.connect() }
}
diff --git a/android/lib/talpid/build.gradle.kts b/android/lib/talpid/build.gradle.kts
index c53c2add28..24ba625ff2 100644
--- a/android/lib/talpid/build.gradle.kts
+++ b/android/lib/talpid/build.gradle.kts
@@ -30,9 +30,11 @@ android {
dependencies {
implementation(projects.lib.model)
+ implementation(projects.lib.common)
implementation(libs.androidx.ktx)
implementation(libs.androidx.lifecycle.service)
+ implementation(libs.arrow)
implementation(libs.kermit)
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines.android)
diff --git a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
index dc1f8d23ca..74d44005cd 100644
--- a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
+++ b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/TalpidVpnService.kt
@@ -10,6 +10,8 @@ import java.net.Inet4Address
import java.net.Inet6Address
import java.net.InetAddress
import kotlin.properties.Delegates.observable
+import net.mullvad.mullvadvpn.lib.common.util.prepareVpnSafe
+import net.mullvad.mullvadvpn.lib.model.PrepareError
import net.mullvad.talpid.model.CreateTunResult
import net.mullvad.talpid.model.TunConfig
import net.mullvad.talpid.util.TalpidSdkUtils.setMeteredIfSupported
@@ -76,10 +78,11 @@ open class TalpidVpnService : LifecycleVpnService() {
// Function is to be cleaned up and lint suppression to be removed.
@Suppress("ReturnCount")
private fun createTun(config: TunConfig): CreateTunResult {
- if (prepare(this) != null) {
- // VPN permission wasn't granted
- return CreateTunResult.PermissionDenied
- }
+ prepareVpnSafe()
+ .mapLeft { it.toCreateTunResult() }
+ .onLeft {
+ return it
+ }
val invalidDnsServerAddresses = ArrayList<InetAddress>()
@@ -149,6 +152,13 @@ open class TalpidVpnService : LifecycleVpnService() {
return protect(socket)
}
+ private fun PrepareError.toCreateTunResult() =
+ when (this) {
+ is PrepareError.OtherLegacyAlwaysOnVpn -> CreateTunResult.OtherLegacyAlwaysOnVpn
+ is PrepareError.NotPrepared -> CreateTunResult.NotPrepared
+ is PrepareError.OtherAlwaysOnApp -> CreateTunResult.OtherAlwaysOnApp(appName)
+ }
+
private fun InetAddress.prefixLength(): Int =
when (this) {
is Inet4Address -> IPV4_PREFIX_LENGTH
diff --git a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/model/CreateTunResult.kt b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/model/CreateTunResult.kt
index 089112e3ab..3cd73685f7 100644
--- a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/model/CreateTunResult.kt
+++ b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/model/CreateTunResult.kt
@@ -17,7 +17,13 @@ sealed class CreateTunResult {
get() = true
}
- data object PermissionDenied : CreateTunResult()
-
+ // Establish error
data object TunnelDeviceError : CreateTunResult()
+
+ // Prepare errors
+ data object OtherLegacyAlwaysOnVpn : CreateTunResult()
+
+ data class OtherAlwaysOnApp(val appName: String) : CreateTunResult()
+
+ data object NotPrepared : CreateTunResult()
}
diff --git a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/util/InetAddressExt.kt b/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/util/InetAddressExt.kt
deleted file mode 100644
index d310deb884..0000000000
--- a/android/lib/talpid/src/main/kotlin/net/mullvad/talpid/util/InetAddressExt.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package net.mullvad.talpid.util
-
-import java.net.InetAddress
-
-fun InetAddress.addressString(): String {
- val hostNameAndAddress = this.toString().split('/', limit = 2)
- val address = hostNameAndAddress[1]
-
- return address
-}