summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2024-12-13 09:56:13 +0100
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2024-12-13 09:56:13 +0100
commit87669a92c145e1fcca937c854fe734c486b686c8 (patch)
tree9d4e473a61bb533df272290e30519777dafc8218 /android
parentee7681efa8b0762f9d0284b10592f443165eb4fb (diff)
parentb95e54a41dfa3e5932e9385adbfe1209eafb45bc (diff)
downloadmullvadvpn-87669a92c145e1fcca937c854fe734c486b686c8.tar.xz
mullvadvpn-87669a92c145e1fcca937c854fe734c486b686c8.zip
Merge branch 'use-deeplink-to-do-vpnpermission-intent-droid-1110'
Diffstat (limited to 'android')
-rw-r--r--android/app/build.gradle.kts1
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt40
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/AppModule.kt4
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt6
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt69
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/MullvadAppViewModel.kt (renamed from android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/NoDaemonViewModel.kt)11
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnProfileViewModel.kt34
-rw-r--r--android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/ApiEndpointFromIntentHolder.kt10
-rw-r--r--android/lib/endpoint/src/release/kotlin/net/mullvad/mullvadvpn/lib/endpoint/ApiEndpointFromIntentHolder.kt11
-rw-r--r--android/lib/intent-provider/build.gradle.kts35
-rw-r--r--android/lib/intent-provider/src/main/AndroidManifest.xml1
-rw-r--r--android/lib/intent-provider/src/main/kotlin/net/mullvad/mullvadvpn/lib/intent/IntentProvider.kt16
-rw-r--r--android/service/build.gradle.kts1
-rw-r--r--android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt10
-rw-r--r--android/settings.gradle.kts1
15 files changed, 97 insertions, 153 deletions
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
index d62df34645..8e252e1fc6 100644
--- a/android/app/build.gradle.kts
+++ b/android/app/build.gradle.kts
@@ -328,7 +328,6 @@ dependencies {
implementation(projects.lib.common)
implementation(projects.lib.daemonGrpc)
implementation(projects.lib.endpoint)
- implementation(projects.lib.intentProvider)
implementation(projects.lib.map)
implementation(projects.lib.model)
implementation(projects.lib.payment)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt
index f52a4e8879..220cb50471 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/MullvadApp.kt
@@ -1,17 +1,14 @@
package net.mullvad.mullvadvpn.compose.screen
-import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.navigation.NavHostController
-import arrow.core.merge
import co.touchlab.kermit.Logger
import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.generated.NavGraphs
@@ -19,14 +16,8 @@ import com.ramcosta.composedestinations.generated.destinations.NoDaemonDestinati
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.rememberNavHostEngine
import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator
-import net.mullvad.mullvadvpn.compose.util.CreateVpnProfile
-import net.mullvad.mullvadvpn.lib.common.util.prepareVpnSafe
-import net.mullvad.mullvadvpn.lib.model.PrepareError
-import net.mullvad.mullvadvpn.lib.model.Prepared
import net.mullvad.mullvadvpn.viewmodel.DaemonScreenEvent
-import net.mullvad.mullvadvpn.viewmodel.NoDaemonViewModel
-import net.mullvad.mullvadvpn.viewmodel.VpnProfileSideEffect
-import net.mullvad.mullvadvpn.viewmodel.VpnProfileViewModel
+import net.mullvad.mullvadvpn.viewmodel.MullvadAppViewModel
import org.koin.androidx.compose.koinViewModel
@OptIn(ExperimentalComposeUiApi::class)
@@ -36,12 +27,11 @@ fun MullvadApp() {
val navHostController: NavHostController = engine.rememberNavController()
val navigator: DestinationsNavigator = navHostController.rememberDestinationsNavigator()
- val serviceVm = koinViewModel<NoDaemonViewModel>()
- val permissionVm = koinViewModel<VpnProfileViewModel>()
+ val mullvadAppViewModel = koinViewModel<MullvadAppViewModel>()
DisposableEffect(Unit) {
- navHostController.addOnDestinationChangedListener(serviceVm)
- onDispose { navHostController.removeOnDestinationChangedListener(serviceVm) }
+ navHostController.addOnDestinationChangedListener(mullvadAppViewModel)
+ onDispose { navHostController.removeOnDestinationChangedListener(mullvadAppViewModel) }
}
DestinationsNavHost(
@@ -56,7 +46,7 @@ fun MullvadApp() {
// Globally handle daemon dropped connection with NoDaemonScreen
LaunchedEffect(Unit) {
- serviceVm.uiSideEffect.collect {
+ mullvadAppViewModel.uiSideEffect.collect {
Logger.i { "DaemonScreenEvent: $it" }
when (it) {
DaemonScreenEvent.Show ->
@@ -66,24 +56,4 @@ fun MullvadApp() {
}
}
}
-
- // Ask for VPN Permission
- val launchVpnPermission =
- rememberLauncherForActivityResult(CreateVpnProfile()) { _ -> permissionVm.connect() }
- val context = LocalContext.current
- LaunchedEffect(Unit) {
- permissionVm.uiSideEffect.collect {
- if (it is VpnProfileSideEffect.RequestVpnProfile) {
- val prepareResult = context.prepareVpnSafe().merge()
- when (prepareResult) {
- is PrepareError.NotPrepared ->
- launchVpnPermission.launch(prepareResult.prepareIntent)
- // If legacy or other always on connect at let daemon generate a error state
- is PrepareError.OtherLegacyAlwaysOnVpn,
- is PrepareError.OtherAlwaysOnApp,
- Prepared -> permissionVm.connect()
- }
- }
- }
- }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/AppModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/AppModule.kt
index 9c52677dce..d7a1bfc8cb 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/AppModule.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/AppModule.kt
@@ -6,7 +6,7 @@ import net.mullvad.mullvadvpn.BuildConfig
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAME
import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAMED_ARGUMENT
import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService
-import net.mullvad.mullvadvpn.lib.intent.IntentProvider
+import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointFromIntentHolder
import net.mullvad.mullvadvpn.lib.model.BuildVersion
import net.mullvad.mullvadvpn.lib.shared.AccountRepository
import net.mullvad.mullvadvpn.lib.shared.ConnectionProxy
@@ -33,7 +33,7 @@ val appModule = module {
single { PrepareVpnUseCase(androidContext()) }
single { BuildVersion(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE) }
- single { IntentProvider() }
+ single { ApiEndpointFromIntentHolder() }
single { AccountRepository(get(), get(), MainScope()) }
single { DeviceRepository(get()) }
single { ConnectionProxy(get(), get(), get()) }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
index df35e54006..b111db10b2 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt
@@ -75,8 +75,8 @@ import net.mullvad.mullvadvpn.viewmodel.EditCustomListViewModel
import net.mullvad.mullvadvpn.viewmodel.FilterViewModel
import net.mullvad.mullvadvpn.viewmodel.LoginViewModel
import net.mullvad.mullvadvpn.viewmodel.MtuDialogViewModel
+import net.mullvad.mullvadvpn.viewmodel.MullvadAppViewModel
import net.mullvad.mullvadvpn.viewmodel.MultihopViewModel
-import net.mullvad.mullvadvpn.viewmodel.NoDaemonViewModel
import net.mullvad.mullvadvpn.viewmodel.OutOfTimeViewModel
import net.mullvad.mullvadvpn.viewmodel.PaymentViewModel
import net.mullvad.mullvadvpn.viewmodel.PrivacyDisclaimerViewModel
@@ -92,7 +92,6 @@ import net.mullvad.mullvadvpn.viewmodel.SplitTunnelingViewModel
import net.mullvad.mullvadvpn.viewmodel.Udp2TcpSettingsViewModel
import net.mullvad.mullvadvpn.viewmodel.ViewLogsViewModel
import net.mullvad.mullvadvpn.viewmodel.VoucherDialogViewModel
-import net.mullvad.mullvadvpn.viewmodel.VpnProfileViewModel
import net.mullvad.mullvadvpn.viewmodel.VpnSettingsViewModel
import net.mullvad.mullvadvpn.viewmodel.WelcomeViewModel
import net.mullvad.mullvadvpn.viewmodel.WireguardCustomPortDialogViewModel
@@ -237,7 +236,6 @@ val uiModule = module {
viewModel { DeleteCustomListConfirmationViewModel(get(), get()) }
viewModel { ServerIpOverridesViewModel(get(), get()) }
viewModel { ResetServerIpOverridesConfirmationViewModel(get()) }
- viewModel { VpnProfileViewModel(get(), get()) }
viewModel { ApiAccessListViewModel(get()) }
viewModel { EditApiAccessMethodViewModel(get(), get(), get()) }
viewModel { SaveApiAccessMethodViewModel(get(), get()) }
@@ -268,7 +266,7 @@ val uiModule = module {
viewModel { DaitaViewModel(get()) }
// This view model must be single so we correctly attach lifecycle and share it with activity
- single { NoDaemonViewModel(get()) }
+ single { MullvadAppViewModel(get(), get()) }
}
const val SELF_PACKAGE_NAME = "SELF_PACKAGE_NAME"
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 baf2da3b70..4007b09ecd 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
@@ -12,21 +12,31 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import arrow.core.merge
+import co.touchlab.kermit.Logger
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.compose.screen.MullvadApp
+import net.mullvad.mullvadvpn.compose.util.CreateVpnProfile
import net.mullvad.mullvadvpn.di.paymentModule
import net.mullvad.mullvadvpn.di.uiModule
+import net.mullvad.mullvadvpn.lib.common.constant.KEY_REQUEST_VPN_PROFILE
import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.requestNotificationPermissionIfMissing
+import net.mullvad.mullvadvpn.lib.common.util.prepareVpnSafe
import net.mullvad.mullvadvpn.lib.daemon.grpc.GrpcConnectivityState
import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService
-import net.mullvad.mullvadvpn.lib.intent.IntentProvider
+import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointFromIntentHolder
+import net.mullvad.mullvadvpn.lib.endpoint.getApiEndpointConfigurationExtras
+import net.mullvad.mullvadvpn.lib.model.PrepareError
+import net.mullvad.mullvadvpn.lib.model.Prepared
import net.mullvad.mullvadvpn.lib.theme.AppTheme
import net.mullvad.mullvadvpn.repository.PrivacyDisclaimerRepository
import net.mullvad.mullvadvpn.repository.SplashCompleteRepository
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager
-import net.mullvad.mullvadvpn.viewmodel.NoDaemonViewModel
+import net.mullvad.mullvadvpn.viewmodel.MullvadAppViewModel
import org.koin.android.ext.android.inject
import org.koin.android.scope.AndroidScopeComponent
import org.koin.androidx.scope.activityScope
@@ -40,9 +50,11 @@ class MainActivity : ComponentActivity(), AndroidScopeComponent {
// NotificationManager.areNotificationsEnabled is used to check the state rather than
// handling the callback value.
}
+ private val launchVpnPermission =
+ registerForActivityResult(CreateVpnProfile()) { _ -> mullvadAppViewModel.connect() }
- private val intentProvider by inject<IntentProvider>()
- private val noDaemonViewModel by inject<NoDaemonViewModel>()
+ private val apiEndpointFromIntentHolder by inject<ApiEndpointFromIntentHolder>()
+ private val mullvadAppViewModel by inject<MullvadAppViewModel>()
private val privacyDisclaimerRepository by inject<PrivacyDisclaimerRepository>()
private val serviceConnectionManager by inject<ServiceConnectionManager>()
private val splashCompleteRepository by inject<SplashCompleteRepository>()
@@ -53,7 +65,7 @@ class MainActivity : ComponentActivity(), AndroidScopeComponent {
override fun onCreate(savedInstanceState: Bundle?) {
loadKoinModules(listOf(uiModule, paymentModule))
- lifecycle.addObserver(noDaemonViewModel)
+ lifecycle.addObserver(mullvadAppViewModel)
installSplashScreen().setKeepOnScreenCondition {
val isReady = isReadyNextDraw
@@ -68,15 +80,14 @@ class MainActivity : ComponentActivity(), AndroidScopeComponent {
super.onCreate(savedInstanceState)
- // Needs to be before set content since we want to access the intent in compose
- if (savedInstanceState == null) {
- intentProvider.setStartIntent(intent)
- }
setContent { AppTheme { MullvadApp() } }
// This is to protect against tapjacking attacks
window.decorView.filterTouchesWhenObscured = true
+ // Needs to be before we start the service, since we need to access the intent there
+ lifecycleScope.launch { intents().collect(::handleIntent) }
+
// We use lifecycleScope here to get less start service in background exceptions
// Se this article for more information:
// https://medium.com/@lepicekmichal/android-background-service-without-hiccup-501e4479110f
@@ -103,11 +114,6 @@ class MainActivity : ComponentActivity(), AndroidScopeComponent {
}
}
- override fun onNewIntent(intent: Intent) {
- super.onNewIntent(intent)
- intentProvider.setStartIntent(intent)
- }
-
fun bindService() {
requestNotificationPermissionIfMissing(requestNotificationPermissionLauncher)
serviceConnectionManager.bind()
@@ -121,7 +127,40 @@ class MainActivity : ComponentActivity(), AndroidScopeComponent {
}
override fun onDestroy() {
- lifecycle.removeObserver(noDaemonViewModel)
+ lifecycle.removeObserver(mullvadAppViewModel)
super.onDestroy()
}
+
+ private fun handleIntent(intent: Intent) {
+ when (val action = intent.action) {
+ Intent.ACTION_MAIN ->
+ apiEndpointFromIntentHolder.setApiEndpointOverride(
+ intent.getApiEndpointConfigurationExtras()
+ )
+ KEY_REQUEST_VPN_PROFILE -> handleRequestVpnProfileIntent()
+ else -> Logger.w("Unhandled intent action: $action")
+ }
+ }
+
+ private fun handleRequestVpnProfileIntent() {
+ val prepareResult = prepareVpnSafe().merge()
+ when (prepareResult) {
+ is PrepareError.NotPrepared -> launchVpnPermission.launch(prepareResult.prepareIntent)
+ // If legacy or other always on connect at let daemon generate a error state
+ is PrepareError.OtherLegacyAlwaysOnVpn,
+ is PrepareError.OtherAlwaysOnApp,
+ Prepared -> mullvadAppViewModel.connect()
+ }
+ }
+
+ private fun ComponentActivity.intents() =
+ callbackFlow<Intent> {
+ send(intent)
+
+ val listener: (Intent) -> Unit = { trySend(it) }
+
+ addOnNewIntentListener(listener)
+
+ awaitClose { removeOnNewIntentListener(listener) }
+ }
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/NoDaemonViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/MullvadAppViewModel.kt
index a3f21f8ccf..91325402bd 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/NoDaemonViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/MullvadAppViewModel.kt
@@ -24,11 +24,14 @@ import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.lib.daemon.grpc.GrpcConnectivityState
import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService
+import net.mullvad.mullvadvpn.lib.shared.ConnectionProxy
private val noServiceDestinations = listOf(SplashDestination, PrivacyDisclaimerDestination)
-class NoDaemonViewModel(managementService: ManagementService) :
- ViewModel(), LifecycleEventObserver, NavController.OnDestinationChangedListener {
+class MullvadAppViewModel(
+ private val connectionProxy: ConnectionProxy,
+ managementService: ManagementService,
+) : ViewModel(), LifecycleEventObserver, NavController.OnDestinationChangedListener {
private val lifecycleFlow: MutableSharedFlow<Lifecycle.Event> = MutableSharedFlow()
private val destinationFlow: MutableSharedFlow<DestinationSpec> = MutableSharedFlow()
@@ -99,6 +102,10 @@ class NoDaemonViewModel(managementService: ManagementService) :
}
}
+ fun connect() {
+ viewModelScope.launch { connectionProxy.connectWithoutPermissionCheck() }
+ }
+
companion object {
private val SERVICE_DISCONNECT_DEBOUNCE = 2.seconds
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnProfileViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnProfileViewModel.kt
deleted file mode 100644
index cb1a2862bf..0000000000
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnProfileViewModel.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package net.mullvad.mullvadvpn.viewmodel
-
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.shareIn
-import kotlinx.coroutines.launch
-import net.mullvad.mullvadvpn.lib.common.constant.KEY_REQUEST_VPN_PROFILE
-import net.mullvad.mullvadvpn.lib.intent.IntentProvider
-import net.mullvad.mullvadvpn.lib.shared.ConnectionProxy
-
-class VpnProfileViewModel(
- intentProvider: IntentProvider,
- private val connectionProxy: ConnectionProxy,
-) : ViewModel() {
- val uiSideEffect: Flow<VpnProfileSideEffect> =
- intentProvider.intents
- .filter { it?.action == KEY_REQUEST_VPN_PROFILE }
- .distinctUntilChanged()
- .map { VpnProfileSideEffect.RequestVpnProfile }
- .shareIn(viewModelScope, SharingStarted.WhileSubscribed())
-
- fun connect() {
- viewModelScope.launch { connectionProxy.connectWithoutPermissionCheck() }
- }
-}
-
-sealed interface VpnProfileSideEffect {
- data object RequestVpnProfile : VpnProfileSideEffect
-}
diff --git a/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/ApiEndpointFromIntentHolder.kt b/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/ApiEndpointFromIntentHolder.kt
new file mode 100644
index 0000000000..2de7e829dd
--- /dev/null
+++ b/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/ApiEndpointFromIntentHolder.kt
@@ -0,0 +1,10 @@
+package net.mullvad.mullvadvpn.lib.endpoint
+
+class ApiEndpointFromIntentHolder {
+ var apiEndpointOverride: ApiEndpointOverride? = null
+ private set
+
+ fun setApiEndpointOverride(apiEndpointOverride: ApiEndpointOverride?) {
+ this.apiEndpointOverride = apiEndpointOverride
+ }
+}
diff --git a/android/lib/endpoint/src/release/kotlin/net/mullvad/mullvadvpn/lib/endpoint/ApiEndpointFromIntentHolder.kt b/android/lib/endpoint/src/release/kotlin/net/mullvad/mullvadvpn/lib/endpoint/ApiEndpointFromIntentHolder.kt
new file mode 100644
index 0000000000..9fa617276b
--- /dev/null
+++ b/android/lib/endpoint/src/release/kotlin/net/mullvad/mullvadvpn/lib/endpoint/ApiEndpointFromIntentHolder.kt
@@ -0,0 +1,11 @@
+package net.mullvad.mullvadvpn.lib.endpoint
+
+// Overridding the API endpoint is not supported in release builds
+class ApiEndpointFromIntentHolder {
+ val apiEndpointOverride: ApiEndpointOverride? = null
+
+ @Suppress("UnusedParameter")
+ fun setApiEndpointOverride(apiEndpointOverride: ApiEndpointOverride?) {
+ // No-op
+ }
+}
diff --git a/android/lib/intent-provider/build.gradle.kts b/android/lib/intent-provider/build.gradle.kts
deleted file mode 100644
index 66c9b6ff74..0000000000
--- a/android/lib/intent-provider/build.gradle.kts
+++ /dev/null
@@ -1,35 +0,0 @@
-plugins {
- alias(libs.plugins.android.library)
- alias(libs.plugins.kotlin.android)
- alias(libs.plugins.kotlin.parcelize)
-}
-
-android {
- namespace = "net.mullvad.mullvadvpn.lib.intent"
- compileSdk = Versions.compileSdkVersion
- buildToolsVersion = Versions.buildToolsVersion
-
- defaultConfig { minSdk = Versions.minSdkVersion }
-
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
- }
-
- kotlinOptions {
- jvmTarget = Versions.jvmTarget
- allWarningsAsErrors = true
- }
-
- lint {
- lintConfig = file("${rootProject.projectDir}/config/lint.xml")
- abortOnError = true
- warningsAsErrors = true
- }
- buildFeatures { buildConfig = true }
-}
-
-dependencies {
- implementation(libs.kotlin.stdlib)
- implementation(libs.kotlinx.coroutines.android)
-}
diff --git a/android/lib/intent-provider/src/main/AndroidManifest.xml b/android/lib/intent-provider/src/main/AndroidManifest.xml
deleted file mode 100644
index cc947c5679..0000000000
--- a/android/lib/intent-provider/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1 +0,0 @@
-<manifest />
diff --git a/android/lib/intent-provider/src/main/kotlin/net/mullvad/mullvadvpn/lib/intent/IntentProvider.kt b/android/lib/intent-provider/src/main/kotlin/net/mullvad/mullvadvpn/lib/intent/IntentProvider.kt
deleted file mode 100644
index 86ad970b5d..0000000000
--- a/android/lib/intent-provider/src/main/kotlin/net/mullvad/mullvadvpn/lib/intent/IntentProvider.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package net.mullvad.mullvadvpn.lib.intent
-
-import android.content.Intent
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-
-class IntentProvider {
- private val _intents = MutableStateFlow<Intent?>(null)
- val intents: Flow<Intent?> = _intents
-
- fun setStartIntent(intent: Intent?) {
- _intents.tryEmit(intent)
- }
-
- fun getLatestIntent(): Intent? = _intents.value
-}
diff --git a/android/service/build.gradle.kts b/android/service/build.gradle.kts
index 8d8ffd2219..717e2c6ef7 100644
--- a/android/service/build.gradle.kts
+++ b/android/service/build.gradle.kts
@@ -56,7 +56,6 @@ dependencies {
implementation(projects.lib.common)
implementation(projects.lib.daemonGrpc)
implementation(projects.lib.endpoint)
- implementation(projects.lib.intentProvider)
implementation(projects.lib.model)
implementation(projects.lib.shared)
implementation(projects.lib.talpid)
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 458f592f1b..e4c8eba3c6 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
@@ -17,8 +17,7 @@ import kotlinx.coroutines.runBlocking
import net.mullvad.mullvadvpn.lib.common.constant.KEY_CONNECT_ACTION
import net.mullvad.mullvadvpn.lib.common.constant.KEY_DISCONNECT_ACTION
import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService
-import net.mullvad.mullvadvpn.lib.endpoint.getApiEndpointConfigurationExtras
-import net.mullvad.mullvadvpn.lib.intent.IntentProvider
+import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointFromIntentHolder
import net.mullvad.mullvadvpn.lib.model.TunnelState
import net.mullvad.mullvadvpn.lib.shared.ConnectionProxy
import net.mullvad.mullvadvpn.service.di.vpnServiceModule
@@ -39,7 +38,7 @@ class MullvadVpnService : TalpidVpnService() {
private lateinit var managementService: ManagementService
private lateinit var migrateSplitTunneling: MigrateSplitTunneling
- private lateinit var intentProvider: IntentProvider
+ private lateinit var apiEndpointFromIntentHolder: ApiEndpointFromIntentHolder
private lateinit var connectionProxy: ConnectionProxy
private lateinit var daemonConfig: DaemonConfig
@@ -66,7 +65,7 @@ class MullvadVpnService : TalpidVpnService() {
daemonConfig = get()
migrateSplitTunneling = get()
- intentProvider = get()
+ apiEndpointFromIntentHolder = get()
connectionProxy = get()
}
@@ -77,8 +76,7 @@ class MullvadVpnService : TalpidVpnService() {
// If it is a debug build and we have an api override in the intent, use it
// This is for injecting hostname and port for our mock api tests
- val intentApiOverride =
- intentProvider.getLatestIntent()?.getApiEndpointConfigurationExtras()
+ val intentApiOverride = apiEndpointFromIntentHolder.apiEndpointOverride
val updatedConfig =
if (BuildConfig.DEBUG && intentApiOverride != null) {
daemonConfig.copy(apiEndpointOverride = intentApiOverride)
diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts
index 7aa90a373f..7e49d4cb92 100644
--- a/android/settings.gradle.kts
+++ b/android/settings.gradle.kts
@@ -21,7 +21,6 @@ include(
":lib:common-test",
":lib:daemon-grpc",
":lib:endpoint",
- ":lib:intent-provider",
":lib:map",
":lib:model",
":lib:payment",