summaryrefslogtreecommitdiffhomepage
path: root/android/service/src/main
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-06-13 21:59:40 +0200
committerDavid Lönnhager <david.l@mullvad.net>2024-06-24 17:36:16 +0200
commit02b302338d67cd341e2a69ed501aa3a2480f2d87 (patch)
treefdc9c72b99e71d1ee954a0cc668fa25d8c1700c1 /android/service/src/main
parent5809c7c669f7d5740d4c755433ff74f9405da2ed (diff)
downloadmullvadvpn-02b302338d67cd341e2a69ed501aa3a2480f2d87.tar.xz
mullvadvpn-02b302338d67cd341e2a69ed501aa3a2480f2d87.zip
Refactor daemon init and deinit on Android
Diffstat (limited to 'android/service/src/main')
-rw-r--r--android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt70
-rw-r--r--android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt49
2 files changed, 41 insertions, 78 deletions
diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
index 2c441483f6..cdaddec614 100644
--- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
+++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt
@@ -1,75 +1,13 @@
package net.mullvad.mullvadvpn.service
-import android.annotation.SuppressLint
-import android.content.Context
-import java.io.File
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.async
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.withContext
import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpoint
-import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointConfiguration
-import net.mullvad.mullvadvpn.service.migration.MigrateSplitTunneling
-
-private const val RELAYS_FILE = "relays.json"
-
-@SuppressLint("SdCardPath")
-class MullvadDaemon(
- vpnService: MullvadVpnService,
- rpcSocketFile: File,
- apiEndpointConfiguration: ApiEndpointConfiguration,
- migrateSplitTunneling: MigrateSplitTunneling
-) {
- // Used by JNI
- @Suppress("ProtectedMemberInFinalClass") protected var daemonInterfaceAddress = 0L
-
- private val shutdownSignal = Channel<Unit>()
+object MullvadDaemon {
init {
System.loadLibrary("mullvad_jni")
-
- prepareFiles(vpnService)
-
- migrateSplitTunneling.migrate()
-
- initialize(
- vpnService = vpnService,
- rpcSocketPath = rpcSocketFile.absolutePath,
- filesDirectory = vpnService.filesDir.absolutePath,
- cacheDirectory = vpnService.cacheDir.absolutePath,
- apiEndpoint = apiEndpointConfiguration.apiEndpoint()
- )
- }
-
- suspend fun shutdown() =
- withContext(Dispatchers.IO) {
- val shutdownSignal = async { shutdownSignal.receive() }
- shutdown(daemonInterfaceAddress)
- shutdownSignal.await()
- deinitialize()
- }
-
- private fun prepareFiles(context: Context) {
- val shouldOverwriteRelayList =
- lastUpdatedTime(context) > File(context.filesDir, RELAYS_FILE).lastModified()
-
- FileResourceExtractor(context).apply { extract(RELAYS_FILE, shouldOverwriteRelayList) }
}
- private fun lastUpdatedTime(context: Context): Long =
- context.packageManager.getPackageInfo(context.packageName, 0).lastUpdateTime
-
- // Used by JNI
- @Suppress("unused")
- private fun notifyDaemonStopped() {
- runBlocking {
- shutdownSignal.send(Unit)
- shutdownSignal.close()
- }
- }
-
- private external fun initialize(
+ external fun initialize(
vpnService: MullvadVpnService,
rpcSocketPath: String,
filesDirectory: String,
@@ -77,7 +15,5 @@ class MullvadDaemon(
apiEndpoint: ApiEndpoint?
)
- private external fun deinitialize()
-
- private external fun shutdown(daemonInterfaceAddress: Long)
+ external fun shutdown()
}
diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
index 87f6076c3f..8d806500c8 100644
--- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
+++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
@@ -1,6 +1,7 @@
package net.mullvad.mullvadvpn.service
import android.app.KeyguardManager
+import android.content.Context
import android.content.Intent
import android.os.Binder
import android.os.Build
@@ -18,6 +19,7 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
+import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAMED_ARGUMENT
import net.mullvad.mullvadvpn.lib.common.constant.KEY_CONNECT_ACTION
import net.mullvad.mullvadvpn.lib.common.constant.KEY_DISCONNECT_ACTION
@@ -40,12 +42,13 @@ import org.koin.android.ext.android.getKoin
import org.koin.core.context.loadKoinModules
import org.koin.core.qualifier.named
+private const val RELAYS_FILE = "relays.json"
+
class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
private val _shouldBeOnForeground = MutableStateFlow(false)
override val shouldBeOnForeground: StateFlow<Boolean> = _shouldBeOnForeground
private lateinit var keyguardManager: KeyguardManager
- private lateinit var daemonInstance: MullvadDaemon
private lateinit var apiEndpointConfiguration: ApiEndpointConfiguration
private lateinit var managementService: ManagementService
@@ -90,15 +93,11 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
// with intent from API)
lifecycleScope.launch(context = Dispatchers.IO) {
managementService.start()
- daemonInstance =
- MullvadDaemon(
- vpnService = this@MullvadVpnService,
- rpcSocketFile = rpcSocketFile,
- apiEndpointConfiguration =
- intentProvider.getLatestIntent()?.getApiEndpointConfigurationExtras()
- ?: apiEndpointConfiguration,
- migrateSplitTunneling = migrateSplitTunneling
- )
+
+ prepareFiles(this@MullvadVpnService)
+ migrateSplitTunneling.migrate()
+
+ startDaemon()
}
}
@@ -146,6 +145,24 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
return super.onBind(intent) ?: emptyBinder()
}
+ private fun startDaemon() {
+ val apiEndpointConfiguration =
+ if (Build.TYPE == BuildTypes.DEBUG) {
+ intentProvider.getLatestIntent()?.getApiEndpointConfigurationExtras()
+ ?: apiEndpointConfiguration
+ } else {
+ apiEndpointConfiguration
+ }
+
+ MullvadDaemon.initialize(
+ vpnService = this@MullvadVpnService,
+ rpcSocketPath = rpcSocketFile.absolutePath,
+ filesDirectory = filesDir.absolutePath,
+ cacheDirectory = cacheDir.absolutePath,
+ apiEndpoint = apiEndpointConfiguration.apiEndpoint()
+ )
+ }
+
private fun emptyBinder() =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Binder(this.toString())
@@ -193,7 +210,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
managementService.stop()
// Shutting down the daemon gracefully
- runBlocking { daemonInstance.shutdown() }
+ MullvadDaemon.shutdown()
super.onDestroy()
}
@@ -202,6 +219,16 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider {
return this?.action == SERVICE_INTERFACE
}
+ private fun prepareFiles(context: Context) {
+ val shouldOverwriteRelayList =
+ lastUpdatedTime(context) > File(context.filesDir, RELAYS_FILE).lastModified()
+
+ FileResourceExtractor(context).apply { extract(RELAYS_FILE, shouldOverwriteRelayList) }
+ }
+
+ private fun lastUpdatedTime(context: Context): Long =
+ context.packageManager.getPackageInfo(context.packageName, 0).lastUpdateTime
+
companion object {
init {
System.loadLibrary("mullvad_jni")