summaryrefslogtreecommitdiffhomepage
path: root/android/src/main
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-11-21 01:58:51 +0000
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2020-11-24 11:56:00 +0000
commitc80e8e78bb37d7c1cae97ce4aae1164c889288e6 (patch)
tree8617b9ab0b5a6a687a9f54cfbf5ac8a6bbbe53c9 /android/src/main
parent13933a8fdebd0b4e5b5ce813f20fde2e6575db14 (diff)
downloadmullvadvpn-c80e8e78bb37d7c1cae97ce4aae1164c889288e6.tar.xz
mullvadvpn-c80e8e78bb37d7c1cae97ce4aae1164c889288e6.zip
Create `DaemonInstance` helper actor
Diffstat (limited to 'android/src/main')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt78
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()
+ }
+}