diff options
| author | David Lönnhager <david.l@mullvad.net> | 2024-06-13 21:59:40 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-06-24 17:36:16 +0200 |
| commit | 02b302338d67cd341e2a69ed501aa3a2480f2d87 (patch) | |
| tree | fdc9c72b99e71d1ee954a0cc668fa25d8c1700c1 /android/service/src | |
| parent | 5809c7c669f7d5740d4c755433ff74f9405da2ed (diff) | |
| download | mullvadvpn-02b302338d67cd341e2a69ed501aa3a2480f2d87.tar.xz mullvadvpn-02b302338d67cd341e2a69ed501aa3a2480f2d87.zip | |
Refactor daemon init and deinit on Android
Diffstat (limited to 'android/service/src')
| -rw-r--r-- | android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt | 70 | ||||
| -rw-r--r-- | android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt | 49 |
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") |
