From a34b56a9caaa241477c0d4504022914a202db09c Mon Sep 17 00:00:00 2001 From: Albin Date: Thu, 12 Oct 2023 14:00:21 +0200 Subject: [PATCH 1/3] Add infra dimension to vpn service --- .github/workflows/android-app.yml | 2 +- android/service/build.gradle.kts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/android-app.yml b/.github/workflows/android-app.yml index e13c98746bf2..2f769c1e7eaf 100644 --- a/.github/workflows/android-app.yml +++ b/.github/workflows/android-app.yml @@ -204,7 +204,7 @@ jobs: arguments: | testDebugUnitTest -x :test:arch:testDebugUnitTest :app:testOssProdDebugUnitTest - :service:testOssDebugUnitTest + :service:testOssProdDebugUnitTest gradle-version: wrapper build-root-directory: android execution-only-caches: true diff --git a/android/service/build.gradle.kts b/android/service/build.gradle.kts index bbdb862cf30e..156a35a3d8c4 100644 --- a/android/service/build.gradle.kts +++ b/android/service/build.gradle.kts @@ -24,10 +24,17 @@ android { } flavorDimensions += FlavorDimensions.BILLING + flavorDimensions += FlavorDimensions.INFRASTRUCTURE productFlavors { create(Flavors.OSS) { dimension = FlavorDimensions.BILLING } create(Flavors.PLAY) { dimension = FlavorDimensions.BILLING } + create(Flavors.PROD) { + dimension = FlavorDimensions.INFRASTRUCTURE + isDefault = true + } + create(Flavors.DEVMOLE) { dimension = FlavorDimensions.INFRASTRUCTURE } + create(Flavors.STAGEMOLE) { dimension = FlavorDimensions.INFRASTRUCTURE } } } From 65c8c9544fe5ef26960be51643e8d48eff07692c Mon Sep 17 00:00:00 2001 From: Albin Date: Mon, 16 Oct 2023 09:12:23 +0200 Subject: [PATCH 2/3] Refactor custom api endpoint config --- .../CustomApiEndpointConfiguration.kt | 8 ------- .../CustomApiEndpointConfiguration.kt | 21 +++++++++++++++++++ .../mullvadvpn/test/mockapi/MockApiTest.kt | 18 +++++++--------- 3 files changed, 28 insertions(+), 19 deletions(-) delete mode 100644 android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt create mode 100644 android/lib/endpoint/src/main/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt diff --git a/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt b/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt deleted file mode 100644 index 5fb8db5fe12a..000000000000 --- a/android/lib/endpoint/src/debug/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt +++ /dev/null @@ -1,8 +0,0 @@ -package net.mullvad.mullvadvpn.lib.endpoint - -import kotlinx.parcelize.Parcelize - -@Parcelize -data class CustomApiEndpointConfiguration(val apiEndpoint: ApiEndpoint) : ApiEndpointConfiguration { - override fun apiEndpoint() = apiEndpoint -} diff --git a/android/lib/endpoint/src/main/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt b/android/lib/endpoint/src/main/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt new file mode 100644 index 000000000000..ba79bdff62a6 --- /dev/null +++ b/android/lib/endpoint/src/main/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt @@ -0,0 +1,21 @@ +package net.mullvad.mullvadvpn.lib.endpoint + +import java.net.InetSocketAddress +import kotlinx.parcelize.Parcelize + +@Parcelize +data class CustomApiEndpointConfiguration( + val hostname: String, + val port: Int, + val disableAddressCache: Boolean = false, + val disableTls: Boolean = false, + val forceDirectConnection: Boolean = false +) : ApiEndpointConfiguration { + override fun apiEndpoint() = + ApiEndpoint( + address = InetSocketAddress(hostname, port), + disableAddressCache = disableAddressCache, + disableTls = disableTls, + forceDirectConnection = forceDirectConnection + ) +} diff --git a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt index bb5c20eebbe3..f699b3cadc5b 100644 --- a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt +++ b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/MockApiTest.kt @@ -9,8 +9,6 @@ import androidx.test.rule.GrantPermissionRule import androidx.test.runner.AndroidJUnit4 import androidx.test.uiautomator.UiDevice import java.net.InetAddress -import java.net.InetSocketAddress -import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpoint import net.mullvad.mullvadvpn.lib.endpoint.CustomApiEndpointConfiguration import net.mullvad.mullvadvpn.test.common.interactor.AppInteractor import net.mullvad.mullvadvpn.test.common.rule.CaptureScreenshotOnFailedTestRule @@ -57,14 +55,12 @@ abstract class MockApiTest { } private fun createEndpoint(port: Int): CustomApiEndpointConfiguration { - val mockApiSocket = InetSocketAddress(InetAddress.getLocalHost(), port) - val api = - ApiEndpoint( - address = mockApiSocket, - disableAddressCache = true, - disableTls = true, - forceDirectConnection = true - ) - return CustomApiEndpointConfiguration(api) + return CustomApiEndpointConfiguration( + InetAddress.getLocalHost().hostName, + port, + disableAddressCache = true, + disableTls = true, + forceDirectConnection = true + ) } } From 55099af85627d4898b54e2ec48da6bdffa68c302 Mon Sep 17 00:00:00 2001 From: Albin Date: Mon, 16 Oct 2023 09:17:32 +0200 Subject: [PATCH 3/3] Use flavor configuration to set api endpoint --- .../CustomApiEndpointConfiguration.kt | 2 ++ android/service/build.gradle.kts | 12 ++++++++++-- .../mullvadvpn/service/MullvadVpnService.kt | 19 ++++++++++++------- .../service/di/ApiEndpointModule.kt | 19 +++++++++++++++++++ 4 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/di/ApiEndpointModule.kt diff --git a/android/lib/endpoint/src/main/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt b/android/lib/endpoint/src/main/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt index ba79bdff62a6..9d2ba2420f36 100644 --- a/android/lib/endpoint/src/main/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt +++ b/android/lib/endpoint/src/main/kotlin/net/mullvad/mullvadvpn/lib/endpoint/CustomApiEndpointConfiguration.kt @@ -3,6 +3,8 @@ package net.mullvad.mullvadvpn.lib.endpoint import java.net.InetSocketAddress import kotlinx.parcelize.Parcelize +const val CUSTOM_ENDPOINT_HTTPS_PORT = 443 + @Parcelize data class CustomApiEndpointConfiguration( val hostname: String, diff --git a/android/service/build.gradle.kts b/android/service/build.gradle.kts index 156a35a3d8c4..6b9c76f0b352 100644 --- a/android/service/build.gradle.kts +++ b/android/service/build.gradle.kts @@ -32,9 +32,17 @@ android { create(Flavors.PROD) { dimension = FlavorDimensions.INFRASTRUCTURE isDefault = true + // Not used for production builds. + buildConfigField("String", "API_ENDPOINT", "\"\"") + } + create(Flavors.DEVMOLE) { + dimension = FlavorDimensions.INFRASTRUCTURE + buildConfigField("String", "API_ENDPOINT", "\"api.devmole.eu\"") + } + create(Flavors.STAGEMOLE) { + dimension = FlavorDimensions.INFRASTRUCTURE + buildConfigField("String", "API_ENDPOINT", "\"api.stagemole.eu\"") } - create(Flavors.DEVMOLE) { dimension = FlavorDimensions.INFRASTRUCTURE } - create(Flavors.STAGEMOLE) { dimension = FlavorDimensions.INFRASTRUCTURE } } } 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 cd05d5cc7139..e714295d9c46 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,14 +17,15 @@ import net.mullvad.mullvadvpn.lib.common.constant.KEY_DISCONNECT_ACTION import net.mullvad.mullvadvpn.lib.common.constant.KEY_QUIT_ACTION import net.mullvad.mullvadvpn.lib.common.constant.MAIN_ACTIVITY_CLASS import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointConfiguration -import net.mullvad.mullvadvpn.lib.endpoint.DefaultApiEndpointConfiguration import net.mullvad.mullvadvpn.lib.endpoint.getApiEndpointConfigurationExtras import net.mullvad.mullvadvpn.model.Settings import net.mullvad.mullvadvpn.model.TunnelState +import net.mullvad.mullvadvpn.service.di.apiEndpointModule import net.mullvad.mullvadvpn.service.di.vpnServiceModule import net.mullvad.mullvadvpn.service.endpoint.ServiceEndpoint import net.mullvad.mullvadvpn.service.notifications.AccountExpiryNotification import net.mullvad.talpid.TalpidVpnService +import org.koin.android.ext.android.get import org.koin.core.context.loadKoinModules class MullvadVpnService : TalpidVpnService() { @@ -58,8 +59,7 @@ class MullvadVpnService : TalpidVpnService() { endpoint.settingsListener.settings?.let { settings -> handlePendingAction(settings) } } - private var apiEndpointConfiguration: ApiEndpointConfiguration = - DefaultApiEndpointConfiguration() + private lateinit var apiEndpointConfiguration: ApiEndpointConfiguration // Suppressing since the tunnel state pref should be writted immediately. @SuppressLint("ApplySharedPref") @@ -67,7 +67,7 @@ class MullvadVpnService : TalpidVpnService() { super.onCreate() Log.d(TAG, "Initializing service") - loadKoinModules(vpnServiceModule) + loadKoinModules(listOf(vpnServiceModule, apiEndpointModule)) daemonInstance = DaemonInstance(this) keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager @@ -103,9 +103,14 @@ class MullvadVpnService : TalpidVpnService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { Log.d(TAG, "Starting service") - if (BuildConfig.DEBUG) { - intent?.getApiEndpointConfigurationExtras()?.let { apiEndpointConfiguration = it } - } + val intentProvidedConfiguration = + if (BuildConfig.DEBUG) { + intent?.getApiEndpointConfigurationExtras() + } else { + null + } + + apiEndpointConfiguration = intentProvidedConfiguration ?: get() daemonInstance.apply { intermittentDaemon.registerListener(this@MullvadVpnService) { daemon -> diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/di/ApiEndpointModule.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/di/ApiEndpointModule.kt new file mode 100644 index 000000000000..4d86559bc68c --- /dev/null +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/di/ApiEndpointModule.kt @@ -0,0 +1,19 @@ +package net.mullvad.mullvadvpn.service.di + +import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointConfiguration +import net.mullvad.mullvadvpn.lib.endpoint.CUSTOM_ENDPOINT_HTTPS_PORT +import net.mullvad.mullvadvpn.lib.endpoint.CustomApiEndpointConfiguration +import net.mullvad.mullvadvpn.lib.endpoint.DefaultApiEndpointConfiguration +import net.mullvad.mullvadvpn.service.BuildConfig +import org.koin.dsl.bind +import org.koin.dsl.module + +val apiEndpointModule = module { + single { + if (BuildConfig.FLAVOR_infrastructure != "prod") { + CustomApiEndpointConfiguration(BuildConfig.API_ENDPOINT, CUSTOM_ENDPOINT_HTTPS_PORT) + } else { + DefaultApiEndpointConfiguration() + } + } bind ApiEndpointConfiguration::class +}