diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1bb9ea6..2400539 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -17,7 +17,7 @@ android { val versionMajor = 2 val versionMinor = 4 - val versionPatch = 2 + val versionPatch = 3 val versionBuild = 0 defaultConfig { diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt index bdd6c40..39204da 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt @@ -4,6 +4,7 @@ import android.app.Application import android.content.Context import android.content.pm.PackageManager import com.google.firebase.crashlytics.FirebaseCrashlytics +import com.google.mlkit.common.MlKit import com.zaneschepke.wireguardautotunnel.repository.Repository import com.zaneschepke.wireguardautotunnel.service.tunnel.model.Settings import dagger.hilt.android.HiltAndroidApp @@ -22,6 +23,11 @@ class WireGuardAutoTunnel : Application() { FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(false); Timber.plant(Timber.DebugTree()) } + try { + MlKit.initialize(this) + } catch (e : Exception) { + Timber.e(e.message) + } settingsRepo.init() } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/Action.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/Action.kt index 1ccbfdf..e76f7ae 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/Action.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/Action.kt @@ -2,5 +2,6 @@ package com.zaneschepke.wireguardautotunnel.service.foreground enum class Action { START, + START_FOREGROUND, STOP } \ No newline at end of file diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ForegroundService.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ForegroundService.kt index eb94d66..cbaf9af 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ForegroundService.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ForegroundService.kt @@ -22,7 +22,7 @@ open class ForegroundService : Service() { val action = intent.action Timber.d("using an intent with action $action") when (action) { - Action.START.name -> startService(intent.extras) + Action.START.name, Action.START_FOREGROUND.name -> startService(intent.extras) Action.STOP.name -> stopService(intent.extras) "android.net.VpnService" -> { Timber.d("Always-on VPN starting service") diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt index c410643..816eea5 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt @@ -1,7 +1,6 @@ package com.zaneschepke.wireguardautotunnel.service.foreground import android.app.ActivityManager -import android.app.Application import android.app.Service import android.content.Context import android.content.Context.ACTIVITY_SERVICE @@ -9,7 +8,6 @@ import android.content.Intent import com.google.firebase.crashlytics.ktx.crashlytics import com.google.firebase.ktx.Firebase import com.zaneschepke.wireguardautotunnel.R -import timber.log.Timber object ServiceManager { @Suppress("DEPRECATION") @@ -36,13 +34,11 @@ object ServiceManager { intent.component?.javaClass try { when(action) { + Action.START_FOREGROUND -> { + context.startForegroundService(intent) + } Action.START -> { - try { - context.startForegroundService(intent) - } catch (e : Exception) { - Timber.e("Unable to start service foreground ${e.message}") - context.startService(intent) - } + context.startService(intent) } Action.STOP -> context.startService(intent) } @@ -66,6 +62,22 @@ object ServiceManager { ) } + fun startVpnServiceForeground(context : Context, tunnelConfig : String) { + actionOnService( + Action.START_FOREGROUND, + context, + WireGuardTunnelService::class.java, + mapOf(context.getString(R.string.tunnel_extras_key) to tunnelConfig)) + } + + private fun startWatcherServiceForeground(context : Context, tunnelConfig : String) { + actionOnService( + Action.START, context, + WireGuardConnectivityWatcherService::class.java, mapOf(context. + getString(R.string.tunnel_extras_key) to + tunnelConfig)) + } + fun startWatcherService(context : Context, tunnelConfig : String) { actionOnService( Action.START, context, @@ -87,4 +99,12 @@ object ServiceManager { ServiceState.STOPPED -> startWatcherService(context, tunnelConfig) } } + + fun toggleWatcherServiceForeground(context: Context, tunnelConfig : String) { + when(getServiceState( context, + WireGuardConnectivityWatcherService::class.java,)) { + ServiceState.STARTED -> stopWatcherService(context) + ServiceState.STOPPED -> startWatcherServiceForeground(context, tunnelConfig) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt index 4dac1a2..e24faec 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt @@ -59,8 +59,16 @@ class WireGuardConnectivityWatcherService : ForegroundService() { private val tag = this.javaClass.name; + override fun onCreate() { + super.onCreate() + CoroutineScope(Dispatchers.Main).launch { + launchWatcherNotification() + } + } + override fun startService(extras: Bundle?) { super.startService(extras) + launchWatcherNotification() val tunnelId = extras?.getString(getString(R.string.tunnel_extras_key)) if (tunnelId != null) { this.tunnelConfig = tunnelId @@ -68,7 +76,6 @@ class WireGuardConnectivityWatcherService : ForegroundService() { // we need this lock so our service gets not affected by Doze Mode initWakeLock() cancelWatcherJob() - launchWatcherNotification() if(this::tunnelConfig.isInitialized) { startWatcherJob() } else { @@ -181,7 +188,7 @@ class WireGuardConnectivityWatcherService : ForegroundService() { } private suspend fun manageVpn() { - while(watcherJob.isActive) { + while(true) { if(setting.isTunnelOnMobileDataEnabled && !isWifiConnected && isMobileDataConnected diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt index a43d2c8..b875591 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt @@ -37,8 +37,16 @@ class WireGuardTunnelService : ForegroundService() { private var tunnelName : String = "" + override fun onCreate() { + super.onCreate() + CoroutineScope(Dispatchers.Main).launch { + launchVpnStartingNotification() + } + } + override fun startService(extras : Bundle?) { super.startService(extras) + launchVpnStartingNotification() val tunnelConfigString = extras?.getString(getString(R.string.tunnel_extras_key)) cancelJob() job = CoroutineScope(Dispatchers.IO).launch { @@ -47,7 +55,6 @@ class WireGuardTunnelService : ForegroundService() { val tunnelConfig = TunnelConfig.from(tunnelConfigString) tunnelName = tunnelConfig.name vpnService.startTunnel(tunnelConfig) - launchVpnStartingNotification() } catch (e : Exception) { Timber.e("Problem starting tunnel: ${e.message}") stopService(extras) @@ -61,7 +68,6 @@ class WireGuardTunnelService : ForegroundService() { val tunnelConfig = TunnelConfig.from(setting.defaultTunnel!!) tunnelName = tunnelConfig.name vpnService.startTunnel(tunnelConfig) - launchVpnStartingNotification() } } } @@ -100,7 +106,7 @@ class WireGuardTunnelService : ForegroundService() { override fun stopService(extras : Bundle?) { super.stopService(extras) - CoroutineScope(Dispatchers.IO).launch() { + CoroutineScope(Dispatchers.IO).launch { vpnService.stopTunnel() } cancelJob() diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt index aa211de..65e8469 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt @@ -66,7 +66,7 @@ class TunnelControlTile : TileService() { if(vpnService.getState() == Tunnel.State.UP) { ServiceManager.stopVpnService(this@TunnelControlTile) } else { - ServiceManager.startVpnService(this@TunnelControlTile, tunnel.toString()) + ServiceManager.startVpnServiceForeground(this@TunnelControlTile, tunnel.toString()) } } } catch (e : Exception) { @@ -100,7 +100,7 @@ class TunnelControlTile : TileService() { if (!settings.isNullOrEmpty()) { val setting = settings.first() if(setting.isAutoTunnelEnabled) { - ServiceManager.toggleWatcherService(this@TunnelControlTile, tunnelConfig) + ServiceManager.toggleWatcherServiceForeground(this@TunnelControlTile, tunnelConfig) } } } diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt index 162c497..afa9303 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt @@ -17,7 +17,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons @@ -103,6 +102,7 @@ fun MainScreen( val state by viewModel.state.collectAsStateWithLifecycle(Tunnel.State.DOWN) val tunnelName by viewModel.tunnelName.collectAsStateWithLifecycle("") + // Nested scroll for control FAB val nestedScrollConnection = remember { object : NestedScrollConnection { @@ -242,7 +242,8 @@ fun MainScreen( ) { LazyColumn( - modifier = Modifier.fillMaxSize() + modifier = Modifier + .fillMaxSize() .nestedScroll(nestedScrollConnection), ) { itemsIndexed(tunnels.toList()) { index, tunnel -> diff --git a/build.gradle.kts b/build.gradle.kts index f9d7e05..f2df859 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ buildscript { } plugins { - id("com.android.application") version "8.2.0-beta01" apply false + id("com.android.application") version "8.2.0-beta03" apply false id("org.jetbrains.kotlin.android") version "1.8.22" apply false id("com.google.dagger.hilt.android") version "2.44" apply false kotlin("plugin.serialization") version "1.8.22" apply false