diff options
| author | Albin <albin@mullvad.net> | 2022-12-13 10:37:16 +0100 |
|---|---|---|
| committer | Albin <albin@mullvad.net> | 2023-01-10 15:32:33 +0100 |
| commit | 3cf1466817025198bc3138774a724d49bb857914 (patch) | |
| tree | 38018dca3ea02ac5af85c946edde976430d5c5e1 /android/app/src | |
| parent | ca8878aa238a5c8e3be1f326ce98e238ffe87388 (diff) | |
| download | mullvadvpn-3cf1466817025198bc3138774a724d49bb857914.tar.xz mullvadvpn-3cf1466817025198bc3138774a724d49bb857914.zip | |
Add option to use custom api endpoint in debug builds
Diffstat (limited to 'android/app/src')
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) } |
