diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/AppUpdateReceiver.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/AppUpdateReceiver.kt index 14f68ed..10aa7ef 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/AppUpdateReceiver.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/AppUpdateReceiver.kt @@ -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) { diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt index f5b37e0..89fd3d6 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt @@ -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) { 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 911db46..72ae2ce 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 @@ -86,7 +86,7 @@ class ServiceManager } } - private fun updateAutoTunnelTile() { + fun updateAutoTunnelTile() { if (autoTunnelTile.isCompleted) { autoTunnelTile.getCompleted().updateTileState() } else { diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/AutoTunnelControlTile.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/AutoTunnelControlTile.kt index 20dc8cc..08d111d 100644 --- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/AutoTunnelControlTile.kt +++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/AutoTunnelControlTile.kt @@ -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 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 ad7cb02..d5a1c5a 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 @@ -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 + 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) } } }