fix: service status out of sync
This fixes the status of service becoming out of sync with the user settings by getting service status from ActivityManager.
This commit is contained in:
parent
f894a3e0c9
commit
98da234ef9
|
@ -17,7 +17,7 @@ android {
|
||||||
|
|
||||||
val versionMajor = 1
|
val versionMajor = 1
|
||||||
val versionMinor = 1
|
val versionMinor = 1
|
||||||
val versionPatch = 3
|
val versionPatch = 4
|
||||||
val versionBuild = 0
|
val versionBuild = 0
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
|
|
@ -45,7 +45,6 @@ open class ForegroundService : Service() {
|
||||||
if (isServiceStarted) return
|
if (isServiceStarted) return
|
||||||
Timber.d("Starting ${this.javaClass.simpleName}")
|
Timber.d("Starting ${this.javaClass.simpleName}")
|
||||||
isServiceStarted = true
|
isServiceStarted = true
|
||||||
ServiceTracker.setServiceState(this, ServiceState.STARTED, this.javaClass)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun stopService(extras : Bundle?) {
|
protected open fun stopService(extras : Bundle?) {
|
||||||
|
@ -57,6 +56,5 @@ open class ForegroundService : Service() {
|
||||||
Timber.d("Service stopped without being started: ${e.message}")
|
Timber.d("Service stopped without being started: ${e.message}")
|
||||||
}
|
}
|
||||||
isServiceStarted = false
|
isServiceStarted = false
|
||||||
ServiceTracker.setServiceState(this, ServiceState.STOPPED, this.javaClass)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,29 +1,25 @@
|
||||||
package com.zaneschepke.wireguardautotunnel.service.foreground
|
package com.zaneschepke.wireguardautotunnel.service.foreground
|
||||||
|
|
||||||
|
import android.app.ActivityManager
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Context.ACTIVITY_SERVICE
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import com.zaneschepke.wireguardautotunnel.R
|
import com.zaneschepke.wireguardautotunnel.R
|
||||||
|
|
||||||
object ServiceTracker {
|
object ServiceTracker {
|
||||||
fun <T : Service> setServiceState(context: Context, state: ServiceState, cls : Class<T>) {
|
@Suppress("DEPRECATION")
|
||||||
val sharedPrefs = getPreferences(context)
|
private // Deprecated for third party Services.
|
||||||
sharedPrefs.edit().let {
|
fun <T> Context.isServiceRunning(service: Class<T>) =
|
||||||
it.putString(cls.simpleName, state.name)
|
(getSystemService(ACTIVITY_SERVICE) as ActivityManager)
|
||||||
it.apply()
|
.getRunningServices(Integer.MAX_VALUE)
|
||||||
}
|
.any { it.service.className == service.name }
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T : Service> getServiceState(context: Context, cls : Class<T>): ServiceState {
|
fun <T : Service> getServiceState(context: Context, cls : Class<T>): ServiceState {
|
||||||
val sharedPrefs = getPreferences(context)
|
val isServiceRunning = context.isServiceRunning(cls)
|
||||||
val value = sharedPrefs.getString(cls.simpleName, ServiceState.STOPPED.name)
|
return if(isServiceRunning) ServiceState.STARTED else ServiceState.STOPPED
|
||||||
return ServiceState.valueOf(value!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getPreferences(context: Context): SharedPreferences {
|
|
||||||
return context.getSharedPreferences(context.resources.getString(R.string.foreground_file), 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : Service> actionOnService(action: Action, application: Application, cls : Class<T>, extras : Map<String,String>? = null) {
|
fun <T : Service> actionOnService(action: Action, application: Application, cls : Class<T>, extras : Map<String,String>? = null) {
|
||||||
|
|
|
@ -131,12 +131,12 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||||
if(!settings.isNullOrEmpty()) {
|
if(!settings.isNullOrEmpty()) {
|
||||||
setting = settings[0]
|
setting = settings[0]
|
||||||
}
|
}
|
||||||
|
watchForWifiConnectivityChanges()
|
||||||
if(setting.isTunnelOnMobileDataEnabled) {
|
if(setting.isTunnelOnMobileDataEnabled) {
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
watchForMobileDataConnectivityChanges()
|
watchForMobileDataConnectivityChanges()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
watchForWifiConnectivityChanges()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,16 +171,18 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||||
isWifiConnected = true
|
isWifiConnected = true
|
||||||
}
|
}
|
||||||
is NetworkStatus.CapabilitiesChanged -> {
|
is NetworkStatus.CapabilitiesChanged -> {
|
||||||
|
Timber.d("Wifi capabilities changed")
|
||||||
isWifiConnected = true
|
isWifiConnected = true
|
||||||
if (!connecting && !disconnecting) {
|
if (!connecting && !disconnecting) {
|
||||||
|
Timber.d("Not connect and not disconnecting")
|
||||||
val ssid = wifiService.getNetworkName(it.networkCapabilities);
|
val ssid = wifiService.getNetworkName(it.networkCapabilities);
|
||||||
Timber.d("SSID: $ssid")
|
Timber.d("SSID: $ssid")
|
||||||
if ((setting.trustedNetworkSSIDs?.contains(ssid) == false) && vpnService.getState() == Tunnel.State.DOWN) {
|
if ((setting.trustedNetworkSSIDs?.contains(ssid) == false) && vpnService.getState() == Tunnel.State.DOWN) {
|
||||||
Timber.d("Starting VPN Tunnel for untrusted network: $ssid")
|
Timber.d("Starting VPN Tunnel for untrusted network: $ssid")
|
||||||
startVPN()
|
startVPN()
|
||||||
} else if (!disconnecting && vpnService.getState() == Tunnel.State.UP && (setting.trustedNetworkSSIDs?.contains(
|
} else if (!disconnecting && vpnService.getState() == Tunnel.State.UP && setting.trustedNetworkSSIDs.contains(
|
||||||
ssid
|
ssid
|
||||||
) == true)
|
)
|
||||||
) {
|
) {
|
||||||
Timber.d("Stopping VPN Tunnel for trusted network with ssid: $ssid")
|
Timber.d("Stopping VPN Tunnel for trusted network with ssid: $ssid")
|
||||||
stopVPN()
|
stopVPN()
|
||||||
|
@ -191,7 +193,10 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||||
isWifiConnected = false
|
isWifiConnected = false
|
||||||
Timber.d("Lost Wi-Fi connection")
|
Timber.d("Lost Wi-Fi connection")
|
||||||
if(setting.isTunnelOnMobileDataEnabled && vpnService.getState() == Tunnel.State.DOWN
|
if(setting.isTunnelOnMobileDataEnabled && vpnService.getState() == Tunnel.State.DOWN
|
||||||
&& isMobileDataConnected) startVPN()
|
&& isMobileDataConnected){
|
||||||
|
Timber.d("Wifi not available so starting vpn for mobile data")
|
||||||
|
startVPN()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.wireguard.config.Config
|
||||||
import com.zaneschepke.wireguardautotunnel.R
|
import com.zaneschepke.wireguardautotunnel.R
|
||||||
import com.zaneschepke.wireguardautotunnel.repository.Repository
|
import com.zaneschepke.wireguardautotunnel.repository.Repository
|
||||||
import com.zaneschepke.wireguardautotunnel.service.foreground.Action
|
import com.zaneschepke.wireguardautotunnel.service.foreground.Action
|
||||||
|
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceState
|
||||||
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceTracker
|
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceTracker
|
||||||
import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardConnectivityWatcherService
|
import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardConnectivityWatcherService
|
||||||
import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardTunnelService
|
import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardTunnelService
|
||||||
|
@ -23,6 +24,7 @@ import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,11 +50,26 @@ class MainViewModel @Inject constructor(private val application : Application,
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
settingsRepo.itemFlow.collect {
|
settingsRepo.itemFlow.collect {
|
||||||
val settings = it.first()
|
val settings = it.first()
|
||||||
|
validateWatcherServiceState(settings)
|
||||||
_settings.emit(settings)
|
_settings.emit(settings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun validateWatcherServiceState(settings: Settings) {
|
||||||
|
val watcherState = ServiceTracker.getServiceState(application, WireGuardConnectivityWatcherService::class.java)
|
||||||
|
if(settings.isAutoTunnelEnabled && watcherState == ServiceState.STOPPED && settings.defaultTunnel != null) {
|
||||||
|
startWatcherService(settings.defaultTunnel!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startWatcherService(tunnel : String) {
|
||||||
|
ServiceTracker.actionOnService(
|
||||||
|
Action.START, application,
|
||||||
|
WireGuardConnectivityWatcherService::class.java,
|
||||||
|
mapOf(application.resources.getString(R.string.tunnel_extras_key) to tunnel))
|
||||||
|
}
|
||||||
|
|
||||||
fun onDelete(tunnel : TunnelConfig) {
|
fun onDelete(tunnel : TunnelConfig) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
if(tunnelRepo.count() == 1L) {
|
if(tunnelRepo.count() == 1L) {
|
||||||
|
|
Loading…
Reference in New Issue