diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-11-21 01:58:51 +0000 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2020-11-24 11:56:00 +0000 |
| commit | c80e8e78bb37d7c1cae97ce4aae1164c889288e6 (patch) | |
| tree | 8617b9ab0b5a6a687a9f54cfbf5ac8a6bbbe53c9 /android | |
| parent | 13933a8fdebd0b4e5b5ce813f20fde2e6575db14 (diff) | |
| download | mullvadvpn-c80e8e78bb37d7c1cae97ce4aae1164c889288e6.tar.xz mullvadvpn-c80e8e78bb37d7c1cae97ce4aae1164c889288e6.zip | |
Create `DaemonInstance` helper actor
Diffstat (limited to 'android')
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt new file mode 100644 index 0000000000..291d9bb4cb --- /dev/null +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt @@ -0,0 +1,78 @@ +package net.mullvad.mullvadvpn.service + +import kotlin.properties.Delegates.observable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.ClosedReceiveChannelException +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.actor +import kotlinx.coroutines.channels.sendBlocking + +class DaemonInstance(val vpnService: MullvadVpnService, val listener: (MullvadDaemon?) -> Unit) { + private enum class Command { + START, + STOP, + } + + private val commandChannel = spawnActor() + + private var daemon by observable<MullvadDaemon?>(null) { _, _, newInstance -> + listener(newInstance) + } + + fun start() { + commandChannel.sendBlocking(Command.START) + } + + fun stop() { + commandChannel.sendBlocking(Command.STOP) + } + + fun onDestroy() { + commandChannel.close() + } + + private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) { + var isRunning = true + + while (isRunning) { + if (!waitForCommand(channel, Command.START)) { + break + } + + startDaemon() + + isRunning = waitForCommand(channel, Command.STOP) + + stopDaemon() + } + } + + private suspend fun waitForCommand( + channel: ReceiveChannel<Command>, + command: Command + ): Boolean { + try { + while (channel.receive() != command) { + // Wait for command + } + + return true + } catch (exception: ClosedReceiveChannelException) { + return false + } + } + + private fun startDaemon() { + daemon = MullvadDaemon(vpnService).apply { + onDaemonStopped = { + daemon = null + } + } + } + + private fun stopDaemon() { + daemon?.shutdown() + } +} |
