summaryrefslogtreecommitdiffhomepage
path: root/android/app/src
diff options
context:
space:
mode:
authorAlbin <albin@mullvad.net>2022-12-13 10:37:16 +0100
committerAlbin <albin@mullvad.net>2023-01-10 15:32:33 +0100
commit3cf1466817025198bc3138774a724d49bb857914 (patch)
tree38018dca3ea02ac5af85c946edde976430d5c5e1 /android/app/src
parentca8878aa238a5c8e3be1f326ce98e238ffe87388 (diff)
downloadmullvadvpn-3cf1466817025198bc3138774a724d49bb857914.tar.xz
mullvadvpn-3cf1466817025198bc3138774a724d49bb857914.zip
Add option to use custom api endpoint in debug builds
Diffstat (limited to 'android/app/src')
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt56
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt12
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt33
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt8
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt13
5 files changed, 81 insertions, 41 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt
index 0d1750f625..67ec721a52 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt
@@ -2,6 +2,8 @@ package net.mullvad.mullvadvpn.service
import java.io.File
import kotlin.properties.Delegates.observable
+import kotlin.reflect.KClass
+import kotlin.reflect.safeCast
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel
@@ -9,14 +11,17 @@ import kotlinx.coroutines.channels.ClosedReceiveChannelException
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.channels.trySendBlocking
+import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointConfiguration
import net.mullvad.mullvadvpn.util.Intermittent
private const val RELAYS_FILE = "relays.json"
-class DaemonInstance(val vpnService: MullvadVpnService) {
- private enum class Command {
- START,
- STOP,
+class DaemonInstance(
+ val vpnService: MullvadVpnService
+) {
+ sealed class Command {
+ data class Start(val apiEndpointConfiguration: ApiEndpointConfiguration) : Command()
+ object Stop : Command()
}
private val commandChannel = spawnActor()
@@ -27,12 +32,12 @@ class DaemonInstance(val vpnService: MullvadVpnService) {
val intermittentDaemon = Intermittent<MullvadDaemon>()
- fun start() {
- commandChannel.trySendBlocking(Command.START)
+ fun start(apiEndpointConfiguration: ApiEndpointConfiguration) {
+ commandChannel.trySendBlocking(Command.Start(apiEndpointConfiguration))
}
fun stop() {
- commandChannel.trySendBlocking(Command.STOP)
+ commandChannel.trySendBlocking(Command.Stop)
}
fun onDestroy() {
@@ -46,30 +51,25 @@ class DaemonInstance(val vpnService: MullvadVpnService) {
prepareFiles()
while (isRunning) {
- if (!waitForCommand(channel, Command.START)) {
- break
- }
-
- startDaemon()
-
- isRunning = waitForCommand(channel, Command.STOP)
-
+ val startCommand = waitForCommand(channel, Command.Start::class) ?: break
+ startDaemon(startCommand.apiEndpointConfiguration)
+ isRunning = waitForCommand(channel, Command.Stop::class) is Command.Stop
stopDaemon()
}
}
- private suspend fun waitForCommand(
+ private suspend fun <T : Command> waitForCommand(
channel: ReceiveChannel<Command>,
- command: Command
- ): Boolean {
- try {
- while (channel.receive() != command) {
- // Wait for command
- }
-
- return true
+ command: KClass<T>
+ ): T? {
+ return try {
+ var receivedCommand: T?
+ do {
+ receivedCommand = command.safeCast(channel.receive())
+ } while (receivedCommand == null)
+ receivedCommand
} catch (exception: ClosedReceiveChannelException) {
- return false
+ null
}
}
@@ -91,8 +91,10 @@ class DaemonInstance(val vpnService: MullvadVpnService) {
}
}
- private suspend fun startDaemon() {
- val newDaemon = MullvadDaemon(vpnService).apply {
+ private suspend fun startDaemon(
+ apiEndpointConfiguration: ApiEndpointConfiguration
+ ) {
+ val newDaemon = MullvadDaemon(vpnService, apiEndpointConfiguration).apply {
onDaemonStopped = {
intermittentDaemon.spawnUpdate(null)
daemon = null
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
index cd92a27472..6d82ee617c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.service
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpoint
+import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointConfiguration
import net.mullvad.mullvadvpn.model.AppVersionInfo
import net.mullvad.mullvadvpn.model.Device
import net.mullvad.mullvadvpn.model.DeviceEvent
@@ -21,7 +22,10 @@ import net.mullvad.mullvadvpn.model.TunnelState
import net.mullvad.mullvadvpn.model.VoucherSubmissionResult
import net.mullvad.talpid.util.EventNotifier
-class MullvadDaemon(vpnService: MullvadVpnService) {
+class MullvadDaemon(
+ vpnService: MullvadVpnService,
+ apiEndpointConfiguration: ApiEndpointConfiguration
+) {
protected var daemonInterfaceAddress = 0L
val onSettingsChange = EventNotifier<Settings?>(null)
@@ -39,8 +43,12 @@ class MullvadDaemon(vpnService: MullvadVpnService) {
init {
System.loadLibrary("mullvad_jni")
+
initialize(
- vpnService, vpnService.cacheDir.absolutePath, vpnService.filesDir.absolutePath, null
+ vpnService = vpnService,
+ cacheDirectory = vpnService.cacheDir.absolutePath,
+ resourceDirectory = vpnService.filesDir.absolutePath,
+ apiEndpoint = apiEndpointConfiguration.apiEndpoint()
)
onSettingsChange.notify(getSettings())
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
index 4753294376..c35125c326 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
@@ -12,7 +12,11 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
+import net.mullvad.mullvadvpn.BuildConfig
import net.mullvad.mullvadvpn.di.vpnServiceModule
+import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointConfiguration
+import net.mullvad.mullvadvpn.lib.endpoint.DefaultApiEndpointConfiguration
+import net.mullvad.mullvadvpn.lib.endpoint.getApiEndpointConfigurationExtras
import net.mullvad.mullvadvpn.model.Settings
import net.mullvad.mullvadvpn.model.TunnelState
import net.mullvad.mullvadvpn.service.endpoint.ServiceEndpoint
@@ -64,11 +68,15 @@ class MullvadVpnService : TalpidVpnService() {
}
}
+ private var apiEndpointConfiguration: ApiEndpointConfiguration =
+ DefaultApiEndpointConfiguration()
+
override fun onCreate() {
super.onCreate()
Log.d(TAG, "Initializing service")
loadKoinModules(vpnServiceModule)
+
daemonInstance = DaemonInstance(this)
keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
@@ -97,14 +105,6 @@ class MullvadVpnService : TalpidVpnService() {
endpoint.accountCache
)
- daemonInstance.apply {
- intermittentDaemon.registerListener(this@MullvadVpnService) { daemon ->
- handleDaemonInstance(daemon)
- }
-
- start()
- }
-
// Remove any leftover tunnel state persistence data
getSharedPreferences("tunnel_state", MODE_PRIVATE)
.edit()
@@ -114,6 +114,21 @@ class MullvadVpnService : TalpidVpnService() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "Starting service")
+
+ if (BuildConfig.DEBUG) {
+ intent?.getApiEndpointConfigurationExtras()?.let {
+ apiEndpointConfiguration = it
+ }
+ }
+
+ daemonInstance.apply {
+ intermittentDaemon.registerListener(this@MullvadVpnService) { daemon ->
+ handleDaemonInstance(daemon)
+ }
+
+ start(apiEndpointConfiguration)
+ }
+
val startResult = super.onStartCommand(intent, flags, startId)
var quitCommand = false
@@ -231,7 +246,7 @@ class MullvadVpnService : TalpidVpnService() {
daemonInstance.apply {
stop()
- start()
+ start(apiEndpointConfiguration)
}
} else {
Log.d(TAG, "Ignoring restart because onDestroy has executed")
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt
index becf82a69e..fc53d94aaf 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt
@@ -22,7 +22,6 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
@@ -34,6 +33,7 @@ import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.compose.component.ChangelogDialog
import net.mullvad.mullvadvpn.dataproxy.MullvadProblemReport
import net.mullvad.mullvadvpn.di.uiModule
+import net.mullvad.mullvadvpn.lib.endpoint.getApiEndpointConfigurationExtras
import net.mullvad.mullvadvpn.model.AccountExpiry
import net.mullvad.mullvadvpn.model.DeviceState
import net.mullvad.mullvadvpn.ui.fragments.DeviceRevokedFragment
@@ -103,7 +103,11 @@ open class MainActivity : FragmentActivity() {
override fun onStart() {
Log.d("mullvad", "Starting main activity")
super.onStart()
- serviceConnectionManager.bind(vpnPermissionRequestHandler = ::requestVpnPermission)
+
+ serviceConnectionManager.bind(
+ vpnPermissionRequestHandler = ::requestVpnPermission,
+ apiEndpointConfiguration = intent?.getApiEndpointConfigurationExtras()
+ )
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt
index e1654476b8..f912f765a8 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionManager.kt
@@ -8,6 +8,9 @@ import android.os.Messenger
import android.util.Log
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
+import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointConfiguration
+import net.mullvad.mullvadvpn.lib.endpoint.BuildConfig
+import net.mullvad.mullvadvpn.lib.endpoint.putApiEndpointConfigurationExtra
import net.mullvad.mullvadvpn.service.MullvadVpnService
import net.mullvad.talpid.util.EventNotifier
@@ -47,9 +50,17 @@ class ServiceConnectionManager(
}
}
- fun bind(vpnPermissionRequestHandler: () -> Unit) {
+ fun bind(
+ vpnPermissionRequestHandler: () -> Unit,
+ apiEndpointConfiguration: ApiEndpointConfiguration?
+ ) {
this.vpnPermissionRequestHandler = vpnPermissionRequestHandler
val intent = Intent(context, MullvadVpnService::class.java)
+
+ if (BuildConfig.DEBUG && apiEndpointConfiguration != null) {
+ intent.putApiEndpointConfigurationExtra(apiEndpointConfiguration)
+ }
+
context.startService(intent)
context.bindService(intent, serviceConnection, 0)
}