summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAlbin <albin@mullvad.net>2022-06-23 12:01:55 +0200
committerAlbin <albin@mullvad.net>2022-06-27 17:21:36 +0200
commit9cc4f6ffd7ef248a7794921de3c889ee0b7c5da7 (patch)
tree5154f4f383d4a282ce2341441791605e9916b006
parent6d7571d428c975f969f4bac18994734564b24c1e (diff)
downloadmullvadvpn-9cc4f6ffd7ef248a7794921de3c889ee0b7c5da7.tar.xz
mullvadvpn-9cc4f6ffd7ef248a7794921de3c889ee0b7c5da7.zip
Handle tile click when device is locked
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadTileService.kt48
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)