diff options
Diffstat (limited to 'android/app/src')
| -rw-r--r-- | android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt index 7913ae9edf..1342f28507 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt @@ -5,13 +5,17 @@ import android.graphics.drawable.Icon import android.os.Build import android.service.quicksettings.Tile import android.service.quicksettings.TileService +import android.util.Log import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.Job import kotlinx.coroutines.MainScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withTimeoutOrNull import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.ipc.ServiceConnection import net.mullvad.mullvadvpn.model.ServiceResult @@ -33,14 +37,33 @@ class MullvadTileService : TileService() { } override fun onClick() { - val intent = Intent(this, MullvadVpnService::class.java).apply { - action = if (qsTile.state == Tile.STATE_ACTIVE) { - MullvadVpnService.KEY_DISCONNECT_ACTION - } else { - MullvadVpnService.KEY_CONNECT_ACTION + // Workaround for the reported bug: https://issuetracker.google.com/issues/236862865 + suspend fun isUnlockStatusPropagatedWithinTimeout( + unlockTimeoutMillis: Long, + unlockCheckDelayMillis: Long + ): Boolean { + return withTimeoutOrNull(unlockTimeoutMillis) { + while (isLocked) { + delay(unlockCheckDelayMillis) + } + return@withTimeoutOrNull true + } ?: false + } + + unlockAndRun { + runBlocking { + val isUnlockStatusPropagated = isUnlockStatusPropagatedWithinTimeout( + unlockTimeoutMillis = 1000L, + unlockCheckDelayMillis = 100L + ) + + if (isUnlockStatusPropagated) { + toggleTunnel() + } else { + Log.e("mullvad", "Unable to toggle tunnel state") + } } } - startForegroundService(intent) } override fun onStartListening() { @@ -51,6 +74,19 @@ class MullvadTileService : TileService() { listenerJob?.cancel() } + private fun toggleTunnel() { + val intent = Intent(this, MullvadVpnService::class.java).apply { + action = if (qsTile.state == Tile.STATE_INACTIVE) { + MullvadVpnService.KEY_CONNECT_ACTION + } else { + MullvadVpnService.KEY_DISCONNECT_ACTION + } + } + + // Always start as foreground in case tile is out-of-sync. + startForegroundService(intent) + } + @OptIn(FlowPreview::class) private suspend fun listenToTunnelState() { ServiceConnection(this@MullvadTileService, scope) |
