fix: improve tile sync

#491
This commit is contained in:
Zane Schepke 2024-12-31 00:17:34 -05:00
parent 4dc91b5fae
commit c8ac40d370
5 changed files with 50 additions and 22 deletions

View File

@ -32,6 +32,8 @@ class AppUpdateReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
if (intent.action != Intent.ACTION_MY_PACKAGE_REPLACED) return if (intent.action != Intent.ACTION_MY_PACKAGE_REPLACED) return
serviceManager.updateTunnelTile()
serviceManager.updateAutoTunnelTile()
applicationScope.launch { applicationScope.launch {
val settings = appDataRepository.settings.getSettings() val settings = appDataRepository.settings.getSettings()
if (settings.isAutoTunnelEnabled) { if (settings.isAutoTunnelEnabled) {

View File

@ -32,6 +32,8 @@ class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
if (Intent.ACTION_BOOT_COMPLETED != intent.action) return if (Intent.ACTION_BOOT_COMPLETED != intent.action) return
serviceManager.updateTunnelTile()
serviceManager.updateAutoTunnelTile()
applicationScope.launch { applicationScope.launch {
with(appDataRepository.settings.getSettings()) { with(appDataRepository.settings.getSettings()) {
if (isRestoreOnBootEnabled) { if (isRestoreOnBootEnabled) {

View File

@ -86,7 +86,7 @@ class ServiceManager
} }
} }
private fun updateAutoTunnelTile() { fun updateAutoTunnelTile() {
if (autoTunnelTile.isCompleted) { if (autoTunnelTile.isCompleted) {
autoTunnelTile.getCompleted().updateTileState() autoTunnelTile.getCompleted().updateTileState()
} else { } else {

View File

@ -1,5 +1,7 @@
package com.zaneschepke.wireguardautotunnel.service.tile package com.zaneschepke.wireguardautotunnel.service.tile
import android.content.Intent
import android.os.IBinder
import android.service.quicksettings.Tile import android.service.quicksettings.Tile
import android.service.quicksettings.TileService import android.service.quicksettings.TileService
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
@ -9,6 +11,7 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
@ -77,6 +80,17 @@ class AutoTunnelControlTile : TileService() {
} }
} }
/* This works around an annoying unsolved frameworks bug some people are hitting. */
override fun onBind(intent: Intent): IBinder? {
var ret: IBinder? = null
try {
ret = super.onBind(intent)
} catch (_: Throwable) {
Timber.e("Failed to bind to TunnelControlTile")
}
return ret
}
private fun setUnavailable() { private fun setUnavailable() {
kotlin.runCatching { kotlin.runCatching {
qsTile.state = Tile.STATE_UNAVAILABLE qsTile.state = Tile.STATE_UNAVAILABLE

View File

@ -1,9 +1,10 @@
package com.zaneschepke.wireguardautotunnel.service.tile package com.zaneschepke.wireguardautotunnel.service.tile
import android.content.Intent
import android.os.Build import android.os.Build
import android.os.IBinder
import android.service.quicksettings.Tile import android.service.quicksettings.Tile
import android.service.quicksettings.TileService import android.service.quicksettings.TileService
import com.zaneschepke.wireguardautotunnel.data.domain.TunnelConfig
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
import com.zaneschepke.wireguardautotunnel.module.ApplicationScope import com.zaneschepke.wireguardautotunnel.module.ApplicationScope
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
@ -12,8 +13,8 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Provider
@AndroidEntryPoint @AndroidEntryPoint
class TunnelControlTile : TileService() { class TunnelControlTile : TileService() {
@ -21,7 +22,7 @@ class TunnelControlTile : TileService() {
lateinit var appDataRepository: AppDataRepository lateinit var appDataRepository: AppDataRepository
@Inject @Inject
lateinit var tunnelService: Provider<TunnelService> lateinit var tunnelService: TunnelService
@Inject @Inject
@ApplicationScope @ApplicationScope
@ -42,17 +43,20 @@ class TunnelControlTile : TileService() {
override fun onStartListening() { override fun onStartListening() {
super.onStartListening() super.onStartListening()
Timber.d("Start listening called")
serviceManager.tunnelControlTile.complete(this) serviceManager.tunnelControlTile.complete(this)
applicationScope.launch { applicationScope.launch {
if (appDataRepository.tunnels.getAll().isEmpty()) return@launch setUnavailable()
updateTileState() updateTileState()
} }
} }
fun updateTileState() = applicationScope.launch { fun updateTileState() = applicationScope.launch {
val lastActive = appDataRepository.getStartTunnelConfig() if (appDataRepository.tunnels.getAll().isEmpty()) return@launch setUnavailable()
lastActive?.let { with(tunnelService.vpnState.value) {
updateTile(it) if (status.isUp() && tunnelConfig != null) return@launch updateTile(tunnelConfig.name, true)
}
appDataRepository.getStartTunnelConfig()?.let {
updateTile(it.name, false)
} }
} }
@ -60,14 +64,9 @@ class TunnelControlTile : TileService() {
super.onClick() super.onClick()
unlockAndRun { unlockAndRun {
applicationScope.launch { applicationScope.launch {
val lastActive = appDataRepository.getStartTunnelConfig() if (tunnelService.vpnState.value.status.isUp()) return@launch tunnelService.stopTunnel()
lastActive?.let { tunnel -> appDataRepository.getStartTunnelConfig()?.let {
if (tunnel.isActive) { tunnelService.startTunnel(it, true)
tunnelService.get().stopTunnel()
} else {
tunnelService.get().startTunnel(tunnel, true)
}
updateTileState()
} }
} }
} }
@ -107,13 +106,24 @@ class TunnelControlTile : TileService() {
} }
} }
private fun updateTile(tunnelConfig: TunnelConfig?) { /* This works around an annoying unsolved frameworks bug some people are hitting. */
override fun onBind(intent: Intent): IBinder? {
var ret: IBinder? = null
try {
ret = super.onBind(intent)
} catch (_: Throwable) {
Timber.e("Failed to bind to TunnelControlTile")
}
return ret
}
private fun updateTile(name: String, active: Boolean) {
kotlin.runCatching { kotlin.runCatching {
tunnelConfig?.let { setTileDescription(name)
setTileDescription(it.name) if (active) return setActive()
if (it.isActive) return setActive() setInactive()
setInactive() }.onFailure {
} Timber.e(it)
} }
} }
} }