diff options
| author | Albin <albin@mullvad.net> | 2023-07-28 11:17:05 +0200 |
|---|---|---|
| committer | Albin <albin@mullvad.net> | 2023-07-28 11:17:05 +0200 |
| commit | 6ea45204b49571fea6e8cbbf2a3f49b2818278fd (patch) | |
| tree | 606b8625cbf4454f7ecbf659d77ec7a26c14a113 | |
| parent | 7a1c9dba446651f06b00c80178407b34120cede9 (diff) | |
| parent | 463fca04ab97e09daa9d1de7ee7ffdebf93ad023 (diff) | |
| download | mullvadvpn-6ea45204b49571fea6e8cbbf2a3f49b2818278fd.tar.xz mullvadvpn-6ea45204b49571fea6e8cbbf2a3f49b2818278fd.zip | |
Merge branch 'move-vpn-service-to-its-own-module'
73 files changed, 311 insertions, 175 deletions
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 5d5144dcd1..1d467ddccd 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -208,6 +208,7 @@ play { } dependencies { + implementation(project(Dependencies.Mullvad.vpnService)) implementation(project(Dependencies.Mullvad.tileService)) implementation(project(Dependencies.Mullvad.commonLib)) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt index 25b2a187ad..80ffa2d1cd 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DeviceRemovalDialog.kt @@ -28,8 +28,8 @@ import androidx.compose.ui.unit.sp import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.component.HtmlText import net.mullvad.mullvadvpn.compose.component.textResource +import net.mullvad.mullvadvpn.lib.common.util.capitalizeFirstCharOfEachWord import net.mullvad.mullvadvpn.model.Device -import net.mullvad.mullvadvpn.util.capitalizeFirstCharOfEachWord @Composable fun ShowDeviceRemovalDialog(onDismiss: () -> Unit, onConfirm: () -> Unit, device: Device) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt index 4ec1792f48..ef68452ecf 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/DeviceListScreen.kt @@ -39,10 +39,10 @@ import net.mullvad.mullvadvpn.compose.theme.MullvadGreen import net.mullvad.mullvadvpn.compose.theme.MullvadGreen40 import net.mullvad.mullvadvpn.compose.theme.MullvadWhite import net.mullvad.mullvadvpn.compose.theme.MullvadWhite80 +import net.mullvad.mullvadvpn.lib.common.util.capitalizeFirstCharOfEachWord +import net.mullvad.mullvadvpn.lib.common.util.parseAsDateTime import net.mullvad.mullvadvpn.model.Device -import net.mullvad.mullvadvpn.util.capitalizeFirstCharOfEachWord import net.mullvad.mullvadvpn.util.formatDate -import net.mullvad.mullvadvpn.util.parseAsDateTime @Composable @Preview diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt index d0b460633b..c03d4cf723 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SettingsScreen.kt @@ -35,9 +35,9 @@ import net.mullvad.mullvadvpn.compose.extensions.itemWithDivider import net.mullvad.mullvadvpn.compose.state.SettingsUiState import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_TEST_TAG import net.mullvad.mullvadvpn.compose.theme.Dimens -import net.mullvad.mullvadvpn.constant.BuildTypes -import net.mullvad.mullvadvpn.ui.extension.openLink -import net.mullvad.mullvadvpn.util.appendHideNavOnReleaseBuild +import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.util.appendHideNavOnReleaseBuild +import net.mullvad.mullvadvpn.lib.common.util.openLink @OptIn(ExperimentalMaterial3Api::class) @Preview diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt index d67c6e1dfb..11dcaf5067 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/extension/ContextExtensions.kt @@ -1,34 +1,8 @@ package net.mullvad.mullvadvpn.ui.extension -import android.content.Context -import android.content.Intent -import android.net.Uri -import android.provider.Settings import androidx.fragment.app.Fragment -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.getInstalledPackagesList import net.mullvad.mullvadvpn.ui.MainActivity -private const val ALWAYS_ON_VPN_APP = "always_on_vpn_app" - -fun Context.openAccountPageInBrowser(authToken: String) { - startActivity( - Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.account_url) + "?token=$authToken")) - ) -} - -fun Context.getAlwaysOnVpnAppName(): String? { - return resolveAlwaysOnVpnPackageName() - ?.let { currentAlwaysOnVpn -> - packageManager.getInstalledPackagesList(0).singleOrNull { - it.packageName == currentAlwaysOnVpn && it.packageName != packageName - } - } - ?.applicationInfo - ?.loadLabel(packageManager) - ?.toString() -} - fun Fragment.requireMainActivity(): MainActivity { return if (this.activity is MainActivity) { this.activity as MainActivity @@ -38,18 +12,3 @@ fun Fragment.requireMainActivity(): MainActivity { ) } } - -// NOTE: This function will return the current Always-on VPN package's name. In case of either -// Always-on VPN being disabled or not being able to read the state, NULL will be returned. -fun Context.resolveAlwaysOnVpnPackageName(): String? { - return try { - Settings.Secure.getString(contentResolver, ALWAYS_ON_VPN_APP) - } catch (ex: SecurityException) { - null - } -} - -fun Context.openLink(uri: Uri) { - val intent = Intent(Intent.ACTION_VIEW, uri) - startActivity(intent) -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt index 06fdb37b79..bf6dc71b22 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/AccountFragment.kt @@ -20,7 +20,10 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.BuildConfig import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.util.JobTracker +import net.mullvad.mullvadvpn.lib.common.util.capitalizeFirstCharOfEachWord +import net.mullvad.mullvadvpn.lib.common.util.openAccountPageInBrowser import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.mullvadvpn.repository.AccountRepository import net.mullvad.mullvadvpn.repository.DeviceRepository @@ -29,7 +32,6 @@ import net.mullvad.mullvadvpn.ui.GroupedPasswordTransformationMethod import net.mullvad.mullvadvpn.ui.GroupedTransformationMethod import net.mullvad.mullvadvpn.ui.NavigationBarPainter import net.mullvad.mullvadvpn.ui.StatusBarPainter -import net.mullvad.mullvadvpn.ui.extension.openAccountPageInBrowser import net.mullvad.mullvadvpn.ui.extension.requireMainActivity import net.mullvad.mullvadvpn.ui.paintNavigationBar import net.mullvad.mullvadvpn.ui.paintStatusBar @@ -41,11 +43,9 @@ import net.mullvad.mullvadvpn.ui.widget.Button import net.mullvad.mullvadvpn.ui.widget.CopyableInformationView import net.mullvad.mullvadvpn.ui.widget.InformationView import net.mullvad.mullvadvpn.ui.widget.RedeemVoucherButton -import net.mullvad.mullvadvpn.util.JobTracker import net.mullvad.mullvadvpn.util.UNKNOWN_STATE_DEBOUNCE_DELAY_MILLISECONDS import net.mullvad.mullvadvpn.util.addDebounceForUnknownState import net.mullvad.mullvadvpn.util.callbackFlowFromNotifier -import net.mullvad.mullvadvpn.util.capitalizeFirstCharOfEachWord import net.mullvad.talpid.tunnel.ErrorStateCause import org.joda.time.DateTime import org.koin.android.ext.android.inject diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt index 725c70eeb6..a8bdc2d53a 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ConnectFragment.kt @@ -18,7 +18,8 @@ import net.mullvad.mullvadvpn.BuildConfig import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.screen.ConnectScreen import net.mullvad.mullvadvpn.compose.theme.AppTheme -import net.mullvad.mullvadvpn.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.mullvadvpn.repository.AccountRepository import net.mullvad.mullvadvpn.ui.NavigationBarPainter @@ -30,7 +31,6 @@ import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager import net.mullvad.mullvadvpn.ui.serviceconnection.authTokenCache import net.mullvad.mullvadvpn.ui.widget.HeaderBar import net.mullvad.mullvadvpn.ui.widget.NotificationBanner -import net.mullvad.mullvadvpn.util.JobTracker import net.mullvad.mullvadvpn.viewmodel.ConnectViewModel import net.mullvad.talpid.tunnel.ErrorStateCause import org.koin.android.ext.android.inject diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt index ba29326b3d..c02ed0b652 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/LoginFragment.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.ui.LoginState import net.mullvad.mullvadvpn.ui.NavigationBarPainter import net.mullvad.mullvadvpn.ui.extension.requireMainActivity @@ -24,7 +25,6 @@ import net.mullvad.mullvadvpn.ui.widget.AccountInput import net.mullvad.mullvadvpn.ui.widget.AccountLogin import net.mullvad.mullvadvpn.ui.widget.Button import net.mullvad.mullvadvpn.ui.widget.HeaderBar -import net.mullvad.mullvadvpn.util.JobTracker import net.mullvad.mullvadvpn.viewmodel.LoginViewModel import org.koin.androidx.viewmodel.ext.android.viewModel diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt index 18ac784f4b..954e9dcedf 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/OutOfTimeFragment.kt @@ -18,10 +18,11 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.BuildConfig import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.util.JobTracker +import net.mullvad.mullvadvpn.lib.common.util.openAccountPageInBrowser import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.mullvadvpn.repository.AccountRepository -import net.mullvad.mullvadvpn.ui.extension.openAccountPageInBrowser import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState import net.mullvad.mullvadvpn.ui.serviceconnection.authTokenCache @@ -30,7 +31,6 @@ import net.mullvad.mullvadvpn.ui.widget.Button import net.mullvad.mullvadvpn.ui.widget.HeaderBar import net.mullvad.mullvadvpn.ui.widget.RedeemVoucherButton import net.mullvad.mullvadvpn.ui.widget.SitePaymentButton -import net.mullvad.mullvadvpn.util.JobTracker import net.mullvad.mullvadvpn.util.callbackFlowFromNotifier import net.mullvad.talpid.tunnel.ActionAfterDisconnect import net.mullvad.talpid.tunnel.ErrorStateCause diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/PrivacyDisclaimerFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/PrivacyDisclaimerFragment.kt index 6bc0192c73..10d2e5e249 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/PrivacyDisclaimerFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/PrivacyDisclaimerFragment.kt @@ -11,11 +11,11 @@ import androidx.fragment.app.Fragment import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.screen.PrivacyDisclaimerScreen import net.mullvad.mullvadvpn.compose.theme.AppTheme +import net.mullvad.mullvadvpn.lib.common.util.appendHideNavOnReleaseBuild import net.mullvad.mullvadvpn.lib.endpoint.getApiEndpointConfigurationExtras import net.mullvad.mullvadvpn.ui.MainActivity import net.mullvad.mullvadvpn.ui.NavigationBarPainter import net.mullvad.mullvadvpn.ui.StatusBarPainter -import net.mullvad.mullvadvpn.util.appendHideNavOnReleaseBuild import net.mullvad.mullvadvpn.viewmodel.PrivacyDisclaimerViewModel import org.koin.android.ext.android.inject diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt index d38b905a21..4d5ca3c9b5 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ProblemReportFragment.kt @@ -21,9 +21,9 @@ import kotlin.properties.Delegates.observable import kotlinx.coroutines.CompletableDeferred import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.dataproxy.MullvadProblemReport +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.ui.CollapsibleTitleController import net.mullvad.mullvadvpn.ui.MainActivity -import net.mullvad.mullvadvpn.util.JobTracker class ProblemReportFragment : BaseFragment() { private val jobTracker = JobTracker() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt index a2c369bb15..59318a8268 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/RedeemVoucherDialogFragment.kt @@ -14,6 +14,7 @@ import android.widget.EditText import android.widget.TextView import androidx.fragment.app.DialogFragment import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.model.VoucherSubmissionError import net.mullvad.mullvadvpn.model.VoucherSubmissionResult import net.mullvad.mullvadvpn.repository.AccountRepository @@ -21,7 +22,6 @@ import net.mullvad.mullvadvpn.ui.MainActivity import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager import net.mullvad.mullvadvpn.ui.serviceconnection.VoucherRedeemer import net.mullvad.mullvadvpn.ui.widget.Button -import net.mullvad.mullvadvpn.util.JobTracker import net.mullvad.mullvadvpn.util.SegmentedInputFormatter import org.joda.time.DateTime import org.koin.android.ext.android.inject diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt index b655c007c6..e519526f52 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/ViewLogsFragment.kt @@ -8,8 +8,8 @@ import android.view.ViewGroup import android.widget.EditText import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.dataproxy.MullvadProblemReport +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.ui.MainActivity -import net.mullvad.mullvadvpn.util.JobTracker class ViewLogsFragment : BaseFragment() { private val jobTracker = JobTracker() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt index 13f951b04a..a995e4f5b4 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/WelcomeFragment.kt @@ -21,18 +21,18 @@ import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.BuildConfig import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.util.JobTracker +import net.mullvad.mullvadvpn.lib.common.util.openAccountPageInBrowser import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.mullvadvpn.repository.AccountRepository import net.mullvad.mullvadvpn.repository.DeviceRepository -import net.mullvad.mullvadvpn.ui.extension.openAccountPageInBrowser import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionState import net.mullvad.mullvadvpn.ui.serviceconnection.authTokenCache import net.mullvad.mullvadvpn.ui.widget.HeaderBar import net.mullvad.mullvadvpn.ui.widget.RedeemVoucherButton import net.mullvad.mullvadvpn.ui.widget.SitePaymentButton -import net.mullvad.mullvadvpn.util.JobTracker import net.mullvad.mullvadvpn.util.UNKNOWN_STATE_DEBOUNCE_DELAY_MILLISECONDS import net.mullvad.mullvadvpn.util.addDebounceForUnknownState import net.mullvad.mullvadvpn.util.callbackFlowFromNotifier diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/InAppNotification.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/InAppNotification.kt index af4d34e9c1..9ee7a02698 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/InAppNotification.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/InAppNotification.kt @@ -1,7 +1,7 @@ package net.mullvad.mullvadvpn.ui.notification +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.util.ChangeMonitor -import net.mullvad.mullvadvpn.util.JobTracker abstract class InAppNotification { private val changeMonitor = ChangeMonitor() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/TunnelStateNotification.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/TunnelStateNotification.kt index 01d8cfdacf..3c76a4d4eb 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/TunnelStateNotification.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/TunnelStateNotification.kt @@ -2,8 +2,8 @@ package net.mullvad.mullvadvpn.ui.notification import android.content.Context import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.lib.common.util.getErrorNotificationResources import net.mullvad.mullvadvpn.model.TunnelState -import net.mullvad.mullvadvpn.util.getErrorNotificationResources import net.mullvad.talpid.tunnel.ActionAfterDisconnect import net.mullvad.talpid.tunnel.ErrorState diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt index c37b5e5220..6e0e5f9846 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/notification/VersionInfoNotification.kt @@ -3,9 +3,9 @@ package net.mullvad.mullvadvpn.ui.notification import android.content.Context import net.mullvad.mullvadvpn.BuildConfig import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.util.appendHideNavOnReleaseBuild import net.mullvad.mullvadvpn.ui.VersionInfo -import net.mullvad.mullvadvpn.util.appendHideNavOnReleaseBuild class VersionInfoNotification(val isEnabled: Boolean, context: Context) : NotificationWithUrl( diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxy.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxy.kt index f31dfd7ce4..7470fc0712 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxy.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxy.kt @@ -9,8 +9,8 @@ import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.EventDispatcher import net.mullvad.mullvadvpn.lib.ipc.Request +import net.mullvad.mullvadvpn.lib.ipc.extensions.trySendRequest import net.mullvad.mullvadvpn.model.TunnelState -import net.mullvad.mullvadvpn.util.trySendRequest import net.mullvad.talpid.tunnel.ActionAfterDisconnect import net.mullvad.talpid.util.EventNotifier diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/CustomDns.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/CustomDns.kt index c9275429ca..b24cda9213 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/CustomDns.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/CustomDns.kt @@ -3,9 +3,9 @@ package net.mullvad.mullvadvpn.ui.serviceconnection import android.os.Messenger import java.net.InetAddress import net.mullvad.mullvadvpn.lib.ipc.Request +import net.mullvad.mullvadvpn.lib.ipc.extensions.trySendRequest import net.mullvad.mullvadvpn.model.DnsOptions import net.mullvad.mullvadvpn.model.DnsState -import net.mullvad.mullvadvpn.util.trySendRequest import net.mullvad.talpid.util.EventNotifier class CustomDns(private val connection: Messenger, private val settingsListener: SettingsListener) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt index ed3ca5a618..574f7a2004 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/RelayListListener.kt @@ -1,6 +1,7 @@ package net.mullvad.mullvadvpn.ui.serviceconnection import android.os.Messenger +import net.mullvad.mullvadvpn.lib.common.util.toGeographicLocationConstraint import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.EventDispatcher import net.mullvad.mullvadvpn.lib.ipc.Request @@ -14,7 +15,6 @@ import net.mullvad.mullvadvpn.relaylist.RelayCountry import net.mullvad.mullvadvpn.relaylist.RelayItem import net.mullvad.mullvadvpn.relaylist.findItemForLocation import net.mullvad.mullvadvpn.relaylist.toRelayCountries -import net.mullvad.mullvadvpn.util.toGeographicLocationConstraint class RelayListListener( private val connection: Messenger, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSource.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSource.kt index 3c048f31be..a9094ed011 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSource.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSource.kt @@ -6,7 +6,7 @@ import kotlinx.coroutines.flow.callbackFlow import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.EventDispatcher import net.mullvad.mullvadvpn.lib.ipc.Request -import net.mullvad.mullvadvpn.util.trySendRequest +import net.mullvad.mullvadvpn.lib.ipc.extensions.trySendRequest class ServiceConnectionDeviceDataSource( private val connection: Messenger, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Button.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Button.kt index 8a014a7ded..c2a5f3510b 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Button.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/Button.kt @@ -8,7 +8,7 @@ import android.view.View import android.widget.FrameLayout import android.widget.ImageView import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.util.JobTracker +import net.mullvad.mullvadvpn.lib.common.util.JobTracker open class Button : FrameLayout { enum class ButtonColor { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NotificationBanner.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NotificationBanner.kt index da37d1e36d..48cd07f5c2 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NotificationBanner.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/NotificationBanner.kt @@ -14,10 +14,10 @@ import android.widget.TextView import androidx.core.text.HtmlCompat import androidx.core.view.isVisible import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.ui.notification.InAppNotification import net.mullvad.mullvadvpn.ui.notification.InAppNotificationController import net.mullvad.mullvadvpn.ui.notification.StatusLevel -import net.mullvad.mullvadvpn.util.JobTracker class NotificationBanner : FrameLayout { private val jobTracker = JobTracker() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/RedeemVoucherButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/RedeemVoucherButton.kt index 885fceef2a..b6d5ddb88d 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/RedeemVoucherButton.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/widget/RedeemVoucherButton.kt @@ -3,8 +3,8 @@ package net.mullvad.mullvadvpn.ui.widget import android.content.Context import android.util.AttributeSet import androidx.fragment.app.FragmentManager +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.ui.fragment.RedeemVoucherDialogFragment -import net.mullvad.mullvadvpn.util.JobTracker class RedeemVoucherButton : Button { constructor(context: Context) : super(context) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt index 677d981417..4d0406cdc3 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Debouncer.kt @@ -2,6 +2,7 @@ package net.mullvad.mullvadvpn.util import kotlin.properties.Delegates.observable import kotlinx.coroutines.delay +import net.mullvad.mullvadvpn.lib.common.util.JobTracker // Helper to filter out bursts of events so that only the latest event in an interval is notified. // diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateCauseExtension.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateCauseExtension.kt deleted file mode 100644 index e98799d1d2..0000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateCauseExtension.kt +++ /dev/null @@ -1,30 +0,0 @@ -package net.mullvad.mullvadvpn.util - -import net.mullvad.mullvadvpn.R -import net.mullvad.talpid.tunnel.ErrorStateCause -import net.mullvad.talpid.tunnel.ParameterGenerationError - -fun ErrorStateCause.errorMessageId(): Int { - return when (this) { - is ErrorStateCause.InvalidDnsServers -> R.string.invalid_dns_servers - is ErrorStateCause.AuthFailed -> R.string.auth_failed - is ErrorStateCause.Ipv6Unavailable -> R.string.ipv6_unavailable - is ErrorStateCause.SetFirewallPolicyError -> R.string.set_firewall_policy_error - is ErrorStateCause.SetDnsError -> R.string.set_dns_error - is ErrorStateCause.StartTunnelError -> R.string.start_tunnel_error - is ErrorStateCause.IsOffline -> R.string.is_offline - is ErrorStateCause.TunnelParameterError -> { - when (error) { - ParameterGenerationError.NoMatchingRelay, - ParameterGenerationError.NoMatchingBridgeRelay -> { - R.string.no_matching_relay - } - ParameterGenerationError.NoWireguardKey -> R.string.no_wireguard_key - ParameterGenerationError.CustomTunnelHostResultionError -> { - R.string.custom_tunnel_host_resolution_error - } - } - } - is ErrorStateCause.VpnPermissionDenied -> R.string.vpn_permission_denied_error - } -} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SmartDeferred.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SmartDeferred.kt index 4035f5b182..45ee4a2a17 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SmartDeferred.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/SmartDeferred.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch +import net.mullvad.mullvadvpn.lib.common.util.JobTracker class SmartDeferred<T>(private val deferred: Deferred<T>) { private val jobTracker = JobTracker() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt index 0e4a115ed6..88337aea00 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt @@ -20,11 +20,11 @@ import kotlinx.coroutines.withTimeoutOrNull import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.state.DeviceListItemUiState import net.mullvad.mullvadvpn.compose.state.DeviceListUiState +import net.mullvad.mullvadvpn.lib.common.util.parseAsDateTime import net.mullvad.mullvadvpn.model.Device import net.mullvad.mullvadvpn.model.DeviceList import net.mullvad.mullvadvpn.model.RemoveDeviceResult import net.mullvad.mullvadvpn.repository.DeviceRepository -import net.mullvad.mullvadvpn.util.parseAsDateTime typealias DeviceId = String diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ConnectionProxyTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxyTest.kt index 12b713838a..52bbbee0a6 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ConnectionProxyTest.kt +++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ConnectionProxyTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.service +package net.mullvad.mullvadvpn.ui.serviceconnection import android.os.DeadObjectException import android.os.Looper @@ -19,7 +19,6 @@ import kotlin.test.assertEquals import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.EventDispatcher import net.mullvad.mullvadvpn.lib.ipc.Request -import net.mullvad.mullvadvpn.ui.serviceconnection.ConnectionProxy import org.junit.After import org.junit.Before import org.junit.Test diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ServiceConnectionDeviceDataSourceTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSourceTest.kt index 2b492ef5cd..50f930d2a5 100644 --- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/service/ServiceConnectionDeviceDataSourceTest.kt +++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnectionDeviceDataSourceTest.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.service +package net.mullvad.mullvadvpn.ui.serviceconnection import android.os.DeadObjectException import android.os.Looper @@ -13,11 +13,10 @@ import io.mockk.mockkObject import io.mockk.mockkStatic import io.mockk.unmockkAll import kotlin.reflect.KClass +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.EventDispatcher import net.mullvad.mullvadvpn.lib.ipc.Request -import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionDeviceDataSource -import net.mullvad.mullvadvpn.util.JobTracker import org.junit.After import org.junit.Before import org.junit.Test diff --git a/android/buildSrc/src/main/kotlin/Dependencies.kt b/android/buildSrc/src/main/kotlin/Dependencies.kt index d25ab0eaba..c97254b9d7 100644 --- a/android/buildSrc/src/main/kotlin/Dependencies.kt +++ b/android/buildSrc/src/main/kotlin/Dependencies.kt @@ -89,6 +89,7 @@ object Dependencies { } object Mullvad { + const val vpnService = ":service" const val tileService = ":tile" const val commonLib = ":lib:common" diff --git a/android/lib/common/build.gradle.kts b/android/lib/common/build.gradle.kts index b472dc5b09..4cc1dfe49c 100644 --- a/android/lib/common/build.gradle.kts +++ b/android/lib/common/build.gradle.kts @@ -30,8 +30,10 @@ android { dependencies { implementation(project(Dependencies.Mullvad.modelLib)) + implementation(project(Dependencies.Mullvad.resourceLib)) implementation(project(Dependencies.Mullvad.talpidLib)) + implementation(Dependencies.jodaTime) implementation(Dependencies.Kotlin.stdlib) implementation(Dependencies.KotlinX.coroutinesAndroid) } diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/Actions.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/Actions.kt new file mode 100644 index 0000000000..6d8dbf697f --- /dev/null +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/Actions.kt @@ -0,0 +1,5 @@ +package net.mullvad.mullvadvpn.lib.common.constant + +const val KEY_CONNECT_ACTION = "$MULLVAD_PACKAGE_NAME.connect_action" +const val KEY_DISCONNECT_ACTION = "$MULLVAD_PACKAGE_NAME.disconnect_action" +const val KEY_QUIT_ACTION = "$MULLVAD_PACKAGE_NAME.quit_action" diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/BuildTypes.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/BuildTypes.kt index 0a85fdce2e..cfe72339d9 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/BuildTypes.kt +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/BuildTypes.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.constant +package net.mullvad.mullvadvpn.lib.common.constant object BuildTypes { const val DEBUG = "debug" diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/Classes.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/Classes.kt new file mode 100644 index 0000000000..e8888cc3cd --- /dev/null +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/Classes.kt @@ -0,0 +1,5 @@ +package net.mullvad.mullvadvpn.lib.common.constant + +const val MULLVAD_PACKAGE_NAME = "net.mullvad.mullvadvpn" +const val MAIN_ACTIVITY_CLASS = "$MULLVAD_PACKAGE_NAME.ui.MainActivity" +const val VPN_SERVICE_CLASS = "$MULLVAD_PACKAGE_NAME.service.MullvadVpnService" diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ContextExtensions.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ContextExtensions.kt new file mode 100644 index 0000000000..b983e3538d --- /dev/null +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ContextExtensions.kt @@ -0,0 +1,43 @@ +package net.mullvad.mullvadvpn.lib.common.util + +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.provider.Settings +import net.mullvad.mullvadvpn.lib.common.R +import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.getInstalledPackagesList + +private const val ALWAYS_ON_VPN_APP = "always_on_vpn_app" + +fun Context.openAccountPageInBrowser(authToken: String) { + startActivity( + Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.account_url) + "?token=$authToken")) + ) +} + +fun Context.getAlwaysOnVpnAppName(): String? { + return resolveAlwaysOnVpnPackageName() + ?.let { currentAlwaysOnVpn -> + packageManager.getInstalledPackagesList(0).singleOrNull { + it.packageName == currentAlwaysOnVpn && it.packageName != packageName + } + } + ?.applicationInfo + ?.loadLabel(packageManager) + ?.toString() +} + +// NOTE: This function will return the current Always-on VPN package's name. In case of either +// Always-on VPN being disabled or not being able to read the state, NULL will be returned. +fun Context.resolveAlwaysOnVpnPackageName(): String? { + return try { + Settings.Secure.getString(contentResolver, ALWAYS_ON_VPN_APP) + } catch (ex: SecurityException) { + null + } +} + +fun Context.openLink(uri: Uri) { + val intent = Intent(Intent.ACTION_VIEW, uri) + startActivity(intent) +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorNotificationMessage.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorNotificationMessage.kt index 96b991fcf3..f009f4857b 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorNotificationMessage.kt +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorNotificationMessage.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.util +package net.mullvad.mullvadvpn.lib.common.util import android.content.res.Resources diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateExtension.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorStateExtension.kt index 54d676a9e7..f906ee8f6d 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/ErrorStateExtension.kt +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/ErrorStateExtension.kt @@ -1,10 +1,10 @@ -package net.mullvad.mullvadvpn.util +package net.mullvad.mullvadvpn.lib.common.util import android.content.Context -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.ui.extension.getAlwaysOnVpnAppName +import net.mullvad.mullvadvpn.lib.common.R import net.mullvad.talpid.tunnel.ErrorState import net.mullvad.talpid.tunnel.ErrorStateCause +import net.mullvad.talpid.tunnel.ParameterGenerationError import net.mullvad.talpid.util.addressString fun ErrorState.getErrorNotificationResources(context: Context): ErrorNotificationMessage { @@ -42,3 +42,28 @@ private fun resolveAlwaysOnVpnErrorNotificationMessage( ) } } + +fun ErrorStateCause.errorMessageId(): Int { + return when (this) { + is ErrorStateCause.InvalidDnsServers -> R.string.invalid_dns_servers + is ErrorStateCause.AuthFailed -> R.string.auth_failed + is ErrorStateCause.Ipv6Unavailable -> R.string.ipv6_unavailable + is ErrorStateCause.SetFirewallPolicyError -> R.string.set_firewall_policy_error + is ErrorStateCause.SetDnsError -> R.string.set_dns_error + is ErrorStateCause.StartTunnelError -> R.string.start_tunnel_error + is ErrorStateCause.IsOffline -> R.string.is_offline + is ErrorStateCause.TunnelParameterError -> { + when (error) { + ParameterGenerationError.NoMatchingRelay, + ParameterGenerationError.NoMatchingBridgeRelay -> { + R.string.no_matching_relay + } + ParameterGenerationError.NoWireguardKey -> R.string.no_wireguard_key + ParameterGenerationError.CustomTunnelHostResultionError -> { + R.string.custom_tunnel_host_resolution_error + } + } + } + is ErrorStateCause.VpnPermissionDenied -> R.string.vpn_permission_denied_error + } +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/Intermittent.kt index dc8ee67cf8..38b152b00a 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/Intermittent.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.util +package net.mullvad.mullvadvpn.lib.common.util import kotlin.properties.Delegates.observable import kotlinx.coroutines.Dispatchers diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/JobTracker.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/JobTracker.kt index fa027af4b1..edb76ed4ae 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/JobTracker.kt +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/JobTracker.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.util +package net.mullvad.mullvadvpn.lib.common.util import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/LocationConstraintExtensions.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/LocationConstraintExtensions.kt index c96a8b8247..d845e3aba9 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/LocationConstraintExtensions.kt +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/LocationConstraintExtensions.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.util +package net.mullvad.mullvadvpn.lib.common.util import net.mullvad.mullvadvpn.model.Constraint import net.mullvad.mullvadvpn.model.GeographicLocationConstraint diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/StringExtensions.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/StringExtensions.kt index 4fe7da3a8b..934ba1d635 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/StringExtensions.kt +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/util/StringExtensions.kt @@ -1,7 +1,7 @@ -package net.mullvad.mullvadvpn.util +package net.mullvad.mullvadvpn.lib.common.util -import net.mullvad.mullvadvpn.BuildConfig -import net.mullvad.mullvadvpn.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.BuildConfig +import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/MessengerExtensions.kt b/android/lib/ipc/src/main/kotlin/net/mullvad/mullvadvpn/lib/ipc/extensions/MessengerExtensions.kt index a2bd193b2f..26cade5cb4 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/util/MessengerExtensions.kt +++ b/android/lib/ipc/src/main/kotlin/net/mullvad/mullvadvpn/lib/ipc/extensions/MessengerExtensions.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.util +package net.mullvad.mullvadvpn.lib.ipc.extensions import android.os.DeadObjectException import android.os.Message diff --git a/android/service/build.gradle.kts b/android/service/build.gradle.kts new file mode 100644 index 0000000000..7052a0d4c4 --- /dev/null +++ b/android/service/build.gradle.kts @@ -0,0 +1,46 @@ +plugins { + id(Dependencies.Plugin.androidLibraryId) + id(Dependencies.Plugin.kotlinAndroidId) + id(Dependencies.Plugin.kotlinParcelizeId) +} + +android { + namespace = "net.mullvad.mullvadvpn.service" + compileSdk = Versions.Android.compileSdkVersion + + defaultConfig { + minSdk = Versions.Android.minSdkVersion + targetSdk = Versions.Android.targetSdkVersion + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = Versions.jvmTarget + } + + lint { + lintConfig = file("${rootProject.projectDir}/config/lint.xml") + abortOnError = true + warningsAsErrors = true + } +} + +dependencies { + implementation(project(Dependencies.Mullvad.commonLib)) + implementation(project(Dependencies.Mullvad.endpointLib)) + implementation(project(Dependencies.Mullvad.ipcLib)) + implementation(project(Dependencies.Mullvad.modelLib)) + implementation(project(Dependencies.Mullvad.resourceLib)) + implementation(project(Dependencies.Mullvad.talpidLib)) + + implementation(Dependencies.AndroidX.appcompat) + implementation(Dependencies.jodaTime) + implementation(Dependencies.Koin.core) + implementation(Dependencies.Koin.android) + implementation(Dependencies.Kotlin.stdlib) + implementation(Dependencies.KotlinX.coroutinesAndroid) +} diff --git a/android/service/src/main/AndroidManifest.xml b/android/service/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..d352c05c65 --- /dev/null +++ b/android/service/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android"> + <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> +</manifest> diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt index fcab12c6c9..4e121bc693 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/DaemonInstance.kt @@ -10,8 +10,8 @@ import kotlinx.coroutines.channels.ClosedReceiveChannelException import kotlinx.coroutines.channels.ReceiveChannel import kotlinx.coroutines.channels.actor import kotlinx.coroutines.channels.trySendBlocking +import net.mullvad.mullvadvpn.lib.common.util.Intermittent import net.mullvad.mullvadvpn.lib.endpoint.ApiEndpointConfiguration -import net.mullvad.mullvadvpn.util.Intermittent class DaemonInstance(private val vpnService: MullvadVpnService) { sealed class Command { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt index 8fb7108619..36d640c719 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/ForegroundNotificationManager.kt @@ -9,12 +9,12 @@ import kotlinx.coroutines.channels.actor import kotlinx.coroutines.channels.trySendBlocking import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onStart +import net.mullvad.mullvadvpn.lib.common.util.Intermittent +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.model.DeviceState import net.mullvad.mullvadvpn.model.TunnelState import net.mullvad.mullvadvpn.service.endpoint.ConnectionProxy import net.mullvad.mullvadvpn.service.notifications.TunnelStateNotification -import net.mullvad.mullvadvpn.util.Intermittent -import net.mullvad.mullvadvpn.util.JobTracker class ForegroundNotificationManager( val service: MullvadVpnService, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt index 089e13ef31..089e13ef31 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt index 0058b09e4f..9024eaad18 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt @@ -1,5 +1,6 @@ package net.mullvad.mullvadvpn.service +import android.annotation.SuppressLint import android.app.KeyguardManager import android.content.Context import android.content.Intent @@ -12,16 +13,19 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import net.mullvad.mullvadvpn.BuildConfig -import net.mullvad.mullvadvpn.di.vpnServiceModule +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.common.constant.KEY_QUIT_ACTION +import net.mullvad.mullvadvpn.lib.common.constant.MAIN_ACTIVITY_CLASS +import net.mullvad.mullvadvpn.lib.common.constant.MULLVAD_PACKAGE_NAME 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.vpnServiceModule import net.mullvad.mullvadvpn.service.endpoint.ServiceEndpoint import net.mullvad.mullvadvpn.service.notifications.AccountExpiryNotification -import net.mullvad.mullvadvpn.ui.MainActivity import net.mullvad.talpid.TalpidVpnService import org.koin.core.context.loadKoinModules @@ -29,10 +33,6 @@ class MullvadVpnService : TalpidVpnService() { companion object { private val TAG = "mullvad" - val KEY_CONNECT_ACTION = "net.mullvad.mullvadvpn.connect_action" - val KEY_DISCONNECT_ACTION = "net.mullvad.mullvadvpn.disconnect_action" - val KEY_QUIT_ACTION = "net.mullvad.mullvadvpn.quit_action" - init { System.loadLibrary("mullvad_jni") } @@ -70,6 +70,8 @@ class MullvadVpnService : TalpidVpnService() { private var apiEndpointConfiguration: ApiEndpointConfiguration = DefaultApiEndpointConfiguration() + // Suppressing since the tunnel state pref should be writted immediately. + @SuppressLint("ApplySharedPref") override fun onCreate() { super.onCreate() Log.d(TAG, "Initializing service") @@ -265,7 +267,8 @@ class MullvadVpnService : TalpidVpnService() { private fun openUi() { val intent = - Intent(this, MainActivity::class.java).apply { + Intent().apply { + setClassName(MULLVAD_PACKAGE_NAME, MAIN_ACTIVITY_CLASS) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/VpnServiceModule.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/di/VpnServiceModule.kt index 431023caa2..0a7d3dec39 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/VpnServiceModule.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/di/VpnServiceModule.kt @@ -1,4 +1,4 @@ -package net.mullvad.mullvadvpn.di +package net.mullvad.mullvadvpn.service.di import androidx.core.app.NotificationManagerCompat import org.koin.android.ext.koin.androidContext diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt index 01d8bcea83..ad8b96f9a5 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AccountCache.kt @@ -6,14 +6,14 @@ import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.ClosedReceiveChannelException import kotlinx.coroutines.channels.actor import kotlinx.coroutines.channels.trySendBlocking +import net.mullvad.mullvadvpn.lib.common.util.JobTracker +import net.mullvad.mullvadvpn.lib.common.util.parseAsDateTime import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.Request import net.mullvad.mullvadvpn.model.AccountCreationResult import net.mullvad.mullvadvpn.model.AccountExpiry import net.mullvad.mullvadvpn.model.AccountHistory import net.mullvad.mullvadvpn.model.GetAccountDataResult -import net.mullvad.mullvadvpn.util.JobTracker -import net.mullvad.mullvadvpn.util.parseAsDateTime import net.mullvad.talpid.util.EventNotifier class AccountCache(private val endpoint: ServiceEndpoint) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt index 767ac3e251..767ac3e251 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AppVersionInfoCache.kt diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt index 6506c0469d..6506c0469d 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/AuthTokenCache.kt diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ConnectionProxy.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ConnectionProxy.kt index a2c97a05bd..a2c97a05bd 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ConnectionProxy.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ConnectionProxy.kt diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt index fe8f55a66d..fe8f55a66d 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/DaemonDeviceDataSource.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/DaemonDeviceDataSource.kt index 5a0efc82fd..db264ed1fe 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/DaemonDeviceDataSource.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/DaemonDeviceDataSource.kt @@ -1,10 +1,10 @@ package net.mullvad.mullvadvpn.service.endpoint import kotlinx.coroutines.flow.collect +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.Request import net.mullvad.mullvadvpn.service.MullvadDaemon -import net.mullvad.mullvadvpn.util.JobTracker class DaemonDeviceDataSource(val endpoint: ServiceEndpoint) { private val tracker = JobTracker() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt index 819ea10d77..fb3a8637f6 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/LocationInfoCache.kt @@ -12,13 +12,13 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.receiveAsFlow +import net.mullvad.mullvadvpn.lib.common.util.toGeographicLocationConstraint import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.model.Constraint import net.mullvad.mullvadvpn.model.GeoIpLocation import net.mullvad.mullvadvpn.model.RelaySettings import net.mullvad.mullvadvpn.model.TunnelState -import net.mullvad.mullvadvpn.util.ExponentialBackoff -import net.mullvad.mullvadvpn.util.toGeographicLocationConstraint +import net.mullvad.mullvadvpn.service.util.ExponentialBackoff import net.mullvad.talpid.tunnel.ActionAfterDisconnect class LocationInfoCache(private val endpoint: ServiceEndpoint) { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt index 1abf64907c..1abf64907c 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/RelayListListener.kt diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt index cafb652014..1d6cb9f9a7 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt @@ -10,13 +10,13 @@ import kotlinx.coroutines.channels.ClosedReceiveChannelException import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.channels.actor import kotlinx.coroutines.channels.trySendBlocking +import net.mullvad.mullvadvpn.lib.common.util.Intermittent import net.mullvad.mullvadvpn.lib.ipc.DispatchingHandler import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.Request +import net.mullvad.mullvadvpn.lib.ipc.extensions.trySendEvent import net.mullvad.mullvadvpn.service.MullvadDaemon import net.mullvad.mullvadvpn.service.persistence.SplitTunnelingPersistence -import net.mullvad.mullvadvpn.util.Intermittent -import net.mullvad.mullvadvpn.util.trySendEvent import net.mullvad.talpid.ConnectivityListener const val SHOULD_LOG_DEAD_OBJECT_EXCEPTION = true diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt index 2863594cb9..2863594cb9 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SettingsListener.kt diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SplitTunneling.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SplitTunneling.kt index a683b1e4bf..a683b1e4bf 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SplitTunneling.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/SplitTunneling.kt diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt index a7003d6888..a7003d6888 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VoucherRedeemer.kt diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VpnPermission.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VpnPermission.kt index c86c471a3d..c753c13b36 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VpnPermission.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/VpnPermission.kt @@ -3,10 +3,11 @@ package net.mullvad.mullvadvpn.service.endpoint import android.content.Context import android.content.Intent import android.net.VpnService +import net.mullvad.mullvadvpn.lib.common.constant.MAIN_ACTIVITY_CLASS +import net.mullvad.mullvadvpn.lib.common.constant.MULLVAD_PACKAGE_NAME +import net.mullvad.mullvadvpn.lib.common.util.Intermittent import net.mullvad.mullvadvpn.lib.ipc.Event import net.mullvad.mullvadvpn.lib.ipc.Request -import net.mullvad.mullvadvpn.ui.MainActivity -import net.mullvad.mullvadvpn.util.Intermittent class VpnPermission(private val context: Context, private val endpoint: ServiceEndpoint) { private val isGranted = Intermittent<Boolean>() @@ -28,7 +29,8 @@ class VpnPermission(private val context: Context, private val endpoint: ServiceE isGranted.update(true) } else { val activityIntent = - Intent(context, MainActivity::class.java).apply { + Intent().apply { + setClassName(MULLVAD_PACKAGE_NAME, MAIN_ACTIVITY_CLASS) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt index adaebd5119..dcc97e8b11 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/AccountExpiryNotification.kt @@ -1,5 +1,6 @@ package net.mullvad.mullvadvpn.service.notifications +import android.annotation.SuppressLint import android.app.Notification import android.app.NotificationManager import android.app.PendingIntent @@ -9,17 +10,18 @@ import android.net.Uri import androidx.core.app.NotificationCompat import kotlin.properties.Delegates.observable import kotlinx.coroutines.delay -import net.mullvad.mullvadvpn.BuildConfig -import net.mullvad.mullvadvpn.R -import net.mullvad.mullvadvpn.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.constant.BuildTypes +import net.mullvad.mullvadvpn.lib.common.constant.MAIN_ACTIVITY_CLASS +import net.mullvad.mullvadvpn.lib.common.constant.MULLVAD_PACKAGE_NAME +import net.mullvad.mullvadvpn.lib.common.util.Intermittent +import net.mullvad.mullvadvpn.lib.common.util.JobTracker import net.mullvad.mullvadvpn.lib.common.util.SdkUtils import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.isNotificationPermissionGranted import net.mullvad.mullvadvpn.model.AccountExpiry +import net.mullvad.mullvadvpn.service.BuildConfig import net.mullvad.mullvadvpn.service.MullvadDaemon +import net.mullvad.mullvadvpn.service.R import net.mullvad.mullvadvpn.service.endpoint.AccountCache -import net.mullvad.mullvadvpn.ui.MainActivity -import net.mullvad.mullvadvpn.util.Intermittent -import net.mullvad.mullvadvpn.util.JobTracker import org.joda.time.DateTime import org.joda.time.Duration @@ -66,6 +68,8 @@ class AccountExpiryNotification( accountCache.onAccountExpiryChange.unsubscribe(this) } + // Suppressing since the permission check is done by calling a common util in another module. + @SuppressLint("MissingPermission") private suspend fun update(expiry: AccountExpiry) { val expiryDate = expiry.date() val durationUntilExpiry = expiryDate?.remainingTime() @@ -102,9 +106,11 @@ class AccountExpiryNotification( } val intent = if (BuildTypes.RELEASE == BuildConfig.BUILD_TYPE) { - Intent(context, MainActivity::class.java) - .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) - .setAction(Intent.ACTION_MAIN) + Intent().apply { + setClassName(MULLVAD_PACKAGE_NAME, MAIN_ACTIVITY_CLASS) + setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) + setAction(Intent.ACTION_MAIN) + } } else { Intent(Intent.ACTION_VIEW, url) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/NotificationChannel.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/NotificationChannel.kt index de557aaf22..d6e904e6ca 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/NotificationChannel.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/NotificationChannel.kt @@ -6,7 +6,7 @@ import android.content.Context import androidx.core.app.NotificationChannelCompat import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat -import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.service.R class NotificationChannel( val context: Context, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt index 81ed83ea44..b9691b6fa9 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotification.kt @@ -1,5 +1,6 @@ package net.mullvad.mullvadvpn.service.notifications +import android.annotation.SuppressLint import android.app.Notification import android.app.NotificationManager import android.app.PendingIntent @@ -7,11 +8,13 @@ import android.content.Context import android.content.Intent import androidx.core.app.NotificationCompat import kotlin.properties.Delegates.observable -import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.lib.common.constant.MAIN_ACTIVITY_CLASS +import net.mullvad.mullvadvpn.lib.common.constant.MULLVAD_PACKAGE_NAME import net.mullvad.mullvadvpn.lib.common.util.SdkUtils +import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.isNotificationPermissionGranted +import net.mullvad.mullvadvpn.lib.common.util.getErrorNotificationResources import net.mullvad.mullvadvpn.model.TunnelState -import net.mullvad.mullvadvpn.ui.MainActivity -import net.mullvad.mullvadvpn.util.getErrorNotificationResources +import net.mullvad.mullvadvpn.service.R import net.mullvad.talpid.tunnel.ActionAfterDisconnect import net.mullvad.talpid.tunnel.ErrorStateCause @@ -97,17 +100,25 @@ class TunnelStateNotification(val context: Context) { } } + // Suppressing since the permission check is done by calling a common util in another module. + @SuppressLint("MissingPermission") private fun update() { - if (visible && (!reconnecting || !showingReconnecting)) { + if ( + context.isNotificationPermissionGranted() && + visible && + (!reconnecting || !showingReconnecting) + ) { channel.notificationManager.notify(NOTIFICATION_ID, build()) } } fun build(): Notification { val intent = - Intent(context, MainActivity::class.java) - .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) - .setAction(Intent.ACTION_MAIN) + Intent().apply { + setClassName(MULLVAD_PACKAGE_NAME, MAIN_ACTIVITY_CLASS) + setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) + setAction(Intent.ACTION_MAIN) + } val pendingIntent = PendingIntent.getActivity(context, 1, intent, SdkUtils.getSupportedPendingIntentFlags()) val actions = @@ -128,7 +139,7 @@ class TunnelStateNotification(val context: Context) { private fun buildAction(): NotificationCompat.Action { val action = TunnelStateNotificationAction.from(tunnelState) val label = context.getString(action.text) - val intent = Intent(action.key).setPackage("net.mullvad.mullvadvpn") + val intent = Intent(action.key).setPackage(MULLVAD_PACKAGE_NAME) val pendingIntent = PendingIntent.getForegroundService( context, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt index 9ed9998054..c415940ea8 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/notifications/TunnelStateNotificationAction.kt @@ -1,8 +1,9 @@ package net.mullvad.mullvadvpn.service.notifications -import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.lib.common.constant.KEY_CONNECT_ACTION +import net.mullvad.mullvadvpn.lib.common.constant.KEY_DISCONNECT_ACTION import net.mullvad.mullvadvpn.model.TunnelState -import net.mullvad.mullvadvpn.service.MullvadVpnService +import net.mullvad.mullvadvpn.service.R import net.mullvad.talpid.tunnel.ActionAfterDisconnect enum class TunnelStateNotificationAction { @@ -45,8 +46,8 @@ enum class TunnelStateNotificationAction { val key get() = when (this) { - Connect -> MullvadVpnService.KEY_CONNECT_ACTION - else -> MullvadVpnService.KEY_DISCONNECT_ACTION + Connect -> KEY_CONNECT_ACTION + else -> KEY_DISCONNECT_ACTION } val icon diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/persistence/SplitTunnelingPersistence.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/persistence/SplitTunnelingPersistence.kt index 264304ab3f..264304ab3f 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/persistence/SplitTunnelingPersistence.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/persistence/SplitTunnelingPersistence.kt diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/util/ExponentialBackoff.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/util/ExponentialBackoff.kt new file mode 100644 index 0000000000..12e94a9241 --- /dev/null +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/util/ExponentialBackoff.kt @@ -0,0 +1,52 @@ +package net.mullvad.mullvadvpn.service.util + +// Calculates a series of delays that increase exponentially. +// +// The delays follow the formula: +// +// (base ^ retryAttempt) * scale +// +// but it is never larger than the specified cap value. +class ExponentialBackoff : Iterator<Long> { + private var unscaledValue = 1L + private var current = 1L + + var iteration = 1 + private set + + var base = 2L + var scale = 1000L + var cap = Long.MAX_VALUE + var count: Int? = null + + override fun hasNext(): Boolean { + val maxIterations = count + + if (maxIterations != null) { + return iteration < maxIterations + } else { + return true + } + } + + override fun next(): Long { + iteration += 1 + + if (current >= cap) { + return cap + } else { + val value = current + + unscaledValue *= base + current = Math.min(cap, scale * unscaledValue) + + return value + } + } + + fun reset() { + unscaledValue = 1L + current = 1L + iteration = 1 + } +} diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts index 65f4c2811e..6ddce2d9b1 100644 --- a/android/settings.gradle.kts +++ b/android/settings.gradle.kts @@ -1,5 +1,6 @@ include( ":app", + ":service", ":tile" ) include( diff --git a/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/MullvadTileService.kt b/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/MullvadTileService.kt index b29b7edfe0..5b327d91c2 100644 --- a/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/MullvadTileService.kt +++ b/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/MullvadTileService.kt @@ -15,6 +15,10 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeoutOrNull +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.common.constant.MULLVAD_PACKAGE_NAME +import net.mullvad.mullvadvpn.lib.common.constant.VPN_SERVICE_CLASS import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.setSubtitleIfSupported import net.mullvad.mullvadvpn.model.ServiceResult import net.mullvad.mullvadvpn.model.TunnelState @@ -74,7 +78,7 @@ class MullvadTileService : TileService() { private fun toggleTunnel() { val intent = Intent().apply { - setClassName(VPN_SERVICE_PACKAGE, VPN_SERVICE_CLASS) + setClassName(MULLVAD_PACKAGE_NAME, VPN_SERVICE_CLASS) action = if (qsTile.state == Tile.STATE_INACTIVE) { KEY_CONNECT_ACTION diff --git a/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/ServiceConnection.kt b/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/ServiceConnection.kt index c04820d177..9673b33e18 100644 --- a/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/ServiceConnection.kt +++ b/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/ServiceConnection.kt @@ -23,6 +23,8 @@ import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch +import net.mullvad.mullvadvpn.lib.common.constant.MULLVAD_PACKAGE_NAME +import net.mullvad.mullvadvpn.lib.common.constant.VPN_SERVICE_CLASS import net.mullvad.mullvadvpn.lib.common.util.DispatchingFlow import net.mullvad.mullvadvpn.lib.common.util.bindServiceFlow import net.mullvad.mullvadvpn.lib.common.util.dispatchTo @@ -79,7 +81,7 @@ class ServiceConnection(context: Context, scope: CoroutineScope) { } private suspend fun connect(context: Context) { - val intent = Intent().apply { setClassName(VPN_SERVICE_PACKAGE, VPN_SERVICE_CLASS) } + val intent = Intent().apply { setClassName(MULLVAD_PACKAGE_NAME, VPN_SERVICE_CLASS) } context .bindServiceFlow(intent) diff --git a/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/TileConstants.kt b/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/TileConstants.kt deleted file mode 100644 index 6229c1478b..0000000000 --- a/android/tile/src/main/kotlin/net/mullvad/mullvadvpn/tile/TileConstants.kt +++ /dev/null @@ -1,6 +0,0 @@ -package net.mullvad.mullvadvpn.tile - -internal const val VPN_SERVICE_PACKAGE = "net.mullvad.mullvadvpn" -internal const val VPN_SERVICE_CLASS = "$VPN_SERVICE_PACKAGE.service.MullvadVpnService" -internal const val KEY_CONNECT_ACTION = "$VPN_SERVICE_PACKAGE.connect_action" -internal const val KEY_DISCONNECT_ACTION = "$VPN_SERVICE_PACKAGE.disconnect_action" |
