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) {
if (intent.action != Intent.ACTION_MY_PACKAGE_REPLACED) return
serviceManager.updateTunnelTile()
serviceManager.updateAutoTunnelTile()
applicationScope.launch {
val settings = appDataRepository.settings.getSettings()
if (settings.isAutoTunnelEnabled) {

View File

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

View File

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

View File

@ -1,5 +1,7 @@
package com.zaneschepke.wireguardautotunnel.service.tile
import android.content.Intent
import android.os.IBinder
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
@ -9,6 +11,7 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@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() {
kotlin.runCatching {
qsTile.state = Tile.STATE_UNAVAILABLE

View File

@ -1,9 +1,10 @@
package com.zaneschepke.wireguardautotunnel.service.tile
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import com.zaneschepke.wireguardautotunnel.data.domain.TunnelConfig
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
import com.zaneschepke.wireguardautotunnel.module.ApplicationScope
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
@ -12,8 +13,8 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Provider
@AndroidEntryPoint
class TunnelControlTile : TileService() {
@ -21,7 +22,7 @@ class TunnelControlTile : TileService() {
lateinit var appDataRepository: AppDataRepository
@Inject
lateinit var tunnelService: Provider<TunnelService>
lateinit var tunnelService: TunnelService
@Inject
@ApplicationScope
@ -42,17 +43,20 @@ class TunnelControlTile : TileService() {
override fun onStartListening() {
super.onStartListening()
Timber.d("Start listening called")
serviceManager.tunnelControlTile.complete(this)
applicationScope.launch {
if (appDataRepository.tunnels.getAll().isEmpty()) return@launch setUnavailable()
updateTileState()
}
}
fun updateTileState() = applicationScope.launch {
val lastActive = appDataRepository.getStartTunnelConfig()
lastActive?.let {
updateTile(it)
if (appDataRepository.tunnels.getAll().isEmpty()) return@launch setUnavailable()
with(tunnelService.vpnState.value) {
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()
unlockAndRun {
applicationScope.launch {
val lastActive = appDataRepository.getStartTunnelConfig()
lastActive?.let { tunnel ->
if (tunnel.isActive) {
tunnelService.get().stopTunnel()
} else {
tunnelService.get().startTunnel(tunnel, true)
}
updateTileState()
if (tunnelService.vpnState.value.status.isUp()) return@launch tunnelService.stopTunnel()
appDataRepository.getStartTunnelConfig()?.let {
tunnelService.startTunnel(it, true)
}
}
}
@ -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 {
tunnelConfig?.let {
setTileDescription(it.name)
if (it.isActive) return setActive()
setInactive()
}
setTileDescription(name)
if (active) return setActive()
setInactive()
}.onFailure {
Timber.e(it)
}
}
}