aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ui/src/main/java/com/wireguard/android/Application.kt1
-rw-r--r--ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt27
-rw-r--r--ui/src/main/java/com/wireguard/android/model/TunnelManager.kt39
3 files changed, 39 insertions, 28 deletions
diff --git a/ui/src/main/java/com/wireguard/android/Application.kt b/ui/src/main/java/com/wireguard/android/Application.kt
index a7bf3e75..d8a0142d 100644
--- a/ui/src/main/java/com/wireguard/android/Application.kt
+++ b/ui/src/main/java/com/wireguard/android/Application.kt
@@ -97,6 +97,7 @@ class Application : android.app.Application(), OnSharedPreferenceChangeListener,
companion object {
val USER_AGENT = String.format(Locale.ENGLISH, "WireGuard/%s (Android %d; %s; %s; %s %s; %s)", BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT, if (Build.SUPPORTED_ABIS.isNotEmpty()) Build.SUPPORTED_ABIS[0] else "unknown ABI", Build.BOARD, Build.MANUFACTURER, Build.MODEL, Build.FINGERPRINT)
+ val SingletonContext = CoroutineScope(Job() + Dispatchers.Default)
private const val TAG = "WireGuard/Application"
private lateinit var weakSelf: WeakReference<Application>
diff --git a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt
index 02227dab..ff8c142c 100644
--- a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt
+++ b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt
@@ -6,6 +6,7 @@ package com.wireguard.android.model
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
+import com.wireguard.android.Application
import com.wireguard.android.BR
import com.wireguard.android.backend.Statistics
import com.wireguard.android.backend.Tunnel
@@ -16,6 +17,8 @@ import java9.util.concurrent.CompletableFuture
import java9.util.concurrent.CompletionStage
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
+import kotlinx.coroutines.async
+import kotlinx.coroutines.launch
/**
* Encapsulates the volatile and nonvolatile state of a WireGuard tunnel.
@@ -32,10 +35,10 @@ class ObservableTunnel internal constructor(
@Bindable
override fun getName() = name
- fun setNameAsync(name: String): CompletionStage<String> = if (name != this.name)
+ suspend fun setNameAsync(name: String): String = if (name != this.name)
manager.setTunnelName(this, name)
else
- CompletableFuture.completedFuture(this.name)
+ this.name
fun onNameChanged(name: String): String {
this.name = name
@@ -59,38 +62,32 @@ class ObservableTunnel internal constructor(
return state
}
- fun setStateAsync(state: Tunnel.State): CompletionStage<Tunnel.State> = if (state != this.state)
+ suspend fun setStateAsync(state: Tunnel.State): Tunnel.State = if (state != this.state)
manager.setTunnelState(this, state)
else
- CompletableFuture.completedFuture(this.state)
+ this.state
@get:Bindable
var config = config
get() {
if (field == null)
- manager.getTunnelConfig(this).whenComplete(ExceptionLoggers.E)
+ Application.SingletonContext.launch { manager.getTunnelConfig(this@ObservableTunnel) }
return field
}
private set
- val configAsync: CompletionStage<Config>
- get() = if (config == null)
- manager.getTunnelConfig(this)
- else
- CompletableFuture.completedFuture(config)
-
- suspend fun getConfigAsync(): Deferred<Config> {
+ suspend fun getConfigAsync(): Config {
return if (config == null)
manager.getTunnelConfig(this)
else
- CompletableDeferred<Config>().apply { complete(config!!) }
+ config!!
}
- fun setConfigAsync(config: Config): CompletionStage<Config> = if (config != this.config)
+ suspend fun setConfigAsync(config: Config): Config = if (config != this.config)
manager.setTunnelConfig(this, config)
else
- CompletableFuture.completedFuture(this.config)
+ this.config!!
fun onConfigChanged(config: Config?): Config? {
this.config = config
diff --git a/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt b/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt
index 5d609f8c..3c797e27 100644
--- a/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt
+++ b/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt
@@ -202,15 +202,22 @@ class TunnelManager(private val configStore: ConfigStore) : BaseObservable() {
return newName!!
}
- fun setTunnelState(tunnel: ObservableTunnel, state: Tunnel.State): CompletionStage<Tunnel.State> = tunnel.configAsync
- .thenCompose { getAsyncWorker().supplyAsync { getBackend().setState(tunnel, state, it) } }
- .whenComplete { newState, e ->
- // Ensure onStateChanged is always called (failure or not), and with the correct state.
- tunnel.onStateChanged(if (e == null) newState else tunnel.state)
- if (e == null && newState == Tunnel.State.UP)
- lastUsedTunnel = tunnel
- saveState()
- }
+ suspend fun setTunnelState(tunnel: ObservableTunnel, state: Tunnel.State): Tunnel.State {
+ tunnel.getConfigAsync()
+ .apply {
+ val newState = try {
+ getBackend().setState(tunnel, state, this)
+ } catch (e: Exception){
+ tunnel.state
+ }
+ tunnel.onStateChanged(newState)
+ if (newState == Tunnel.State.UP) {
+ lastUsedTunnel = tunnel
+ }
+ saveState()
+ return newState
+ }
+ }
class IntentReceiver : BroadcastReceiver(), CoroutineScope {
override val coroutineContext
@@ -241,11 +248,17 @@ class TunnelManager(private val configStore: ConfigStore) : BaseObservable() {
}
}
- fun getTunnelState(tunnel: ObservableTunnel): CompletionStage<Tunnel.State> = getAsyncWorker()
- .supplyAsync { getBackend().getState(tunnel) }.thenApply(tunnel::onStateChanged)
+ suspend fun getTunnelState(tunnel: ObservableTunnel): Tunnel.State {
+ val state = withContext(Dispatchers.IO) { getBackend().getState(tunnel) }
+ tunnel.onStateChanged(state)
+ return state
+ }
- fun getTunnelStatistics(tunnel: ObservableTunnel): CompletionStage<Statistics> = getAsyncWorker()
- .supplyAsync { getBackend().getStatistics(tunnel) }.thenApply(tunnel::onStatisticsChanged)
+ suspend fun getTunnelStatistics(tunnel: ObservableTunnel): Statistics {
+ val statistics = withContext(Dispatchers.IO) { getBackend().getStatistics(tunnel) }
+ tunnel.onStatisticsChanged(statistics)
+ return statistics
+ }
companion object {
private const val KEY_LAST_USED_TUNNEL = "last_used_tunnel"