aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorHarsh Shandilya <me@msfjarvis.dev>2020-04-07 18:06:30 +0530
committerHarsh Shandilya <me@msfjarvis.dev>2020-04-10 00:09:25 +0530
commitd455536728d032932daedc9d9421fc5b59771764 (patch)
tree496b21f9d69be92c430b587ec8fb9bfdbe92bd0e
parentIntentReceiver: switch to coroutines (diff)
downloadwireguard-android-d455536728d032932daedc9d9421fc5b59771764.tar.xz
wireguard-android-d455536728d032932daedc9d9421fc5b59771764.zip
ui: move tunnel deletion to coroutines
Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
-rw-r--r--ui/src/main/java/com/wireguard/android/fragment/TunnelListFragment.kt25
-rw-r--r--ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt2
-rw-r--r--ui/src/main/java/com/wireguard/android/model/TunnelManager.kt14
3 files changed, 26 insertions, 15 deletions
diff --git a/ui/src/main/java/com/wireguard/android/fragment/TunnelListFragment.kt b/ui/src/main/java/com/wireguard/android/fragment/TunnelListFragment.kt
index a4980779..179d1a1c 100644
--- a/ui/src/main/java/com/wireguard/android/fragment/TunnelListFragment.kt
+++ b/ui/src/main/java/com/wireguard/android/fragment/TunnelListFragment.kt
@@ -36,6 +36,12 @@ import com.wireguard.android.widget.EdgeToEdge.setUpScrollingContent
import com.wireguard.android.widget.MultiselectableRelativeLayout
import com.wireguard.config.Config
import java9.util.concurrent.CompletableFuture
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.async
+import kotlinx.coroutines.awaitAll
+import kotlinx.coroutines.launch
import java.io.BufferedReader
import java.io.ByteArrayInputStream
import java.io.InputStreamReader
@@ -49,10 +55,13 @@ import java.util.zip.ZipInputStream
/**
* Fragment containing a list of known WireGuard tunnels. It allows creating and deleting tunnels.
*/
-class TunnelListFragment : BaseFragment() {
+class TunnelListFragment : BaseFragment(), CoroutineScope {
private val actionModeListener = ActionModeListener()
private var actionMode: ActionMode? = null
private var binding: TunnelListFragmentBinding? = null
+ private val job = Job()
+ override val coroutineContext
+ get() = job + Dispatchers.Main
private fun importTunnel(configText: String) {
try {
// Ensure the config text is parseable before proceeding…
@@ -215,6 +224,7 @@ class TunnelListFragment : BaseFragment() {
override fun onDestroyView() {
binding = null
+ job.cancel()
super.onDestroyView()
}
@@ -320,10 +330,15 @@ class TunnelListFragment : BaseFragment() {
Application.getTunnelManager().tunnels.thenAccept { tunnels ->
val tunnelsToDelete = ArrayList<ObservableTunnel>()
for (position in copyCheckedItems) tunnelsToDelete.add(tunnels[position])
- val futures = tunnelsToDelete.map { it.delete().toCompletableFuture() }.toTypedArray()
- CompletableFuture.allOf(*futures)
- .thenApply { futures.size }
- .whenComplete(this@TunnelListFragment::onTunnelDeletionFinished)
+ launch {
+ val exception = try {
+ tunnelsToDelete.map { async { it.delete() } }.toList().awaitAll()
+ null
+ } catch (e: Exception) {
+ e
+ }
+ onTunnelDeletionFinished(tunnelsToDelete.size, exception)
+ }
}
checkedItems.clear()
mode.finish()
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 969f6512..32e0fa9e 100644
--- a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt
+++ b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt
@@ -121,5 +121,5 @@ class ObservableTunnel internal constructor(
}
- fun delete(): CompletionStage<Void> = manager.delete(this)
+ suspend fun delete() = manager.delete(this)
}
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 a6cd6dd4..3d48082d 100644
--- a/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt
+++ b/ui/src/main/java/com/wireguard/android/model/TunnelManager.kt
@@ -61,14 +61,14 @@ class TunnelManager(private val configStore: ConfigStore) : BaseObservable() {
return getAsyncWorker().supplyAsync { configStore.create(name, config!!) }.thenApply { addToList(name, it, Tunnel.State.DOWN) }
}
- fun delete(tunnel: ObservableTunnel): CompletionStage<Void> {
+ suspend fun delete(tunnel: ObservableTunnel) {
val originalState = tunnel.state
val wasLastUsed = tunnel == lastUsedTunnel
// Make sure nothing touches the tunnel.
if (wasLastUsed)
lastUsedTunnel = null
tunnelMap.remove(tunnel)
- return getAsyncWorker().runAsync {
+ withContext(Dispatchers.Default) {
if (originalState == Tunnel.State.UP)
getBackend().setState(tunnel, Tunnel.State.DOWN, null)
try {
@@ -76,15 +76,11 @@ class TunnelManager(private val configStore: ConfigStore) : BaseObservable() {
} catch (e: Exception) {
if (originalState == Tunnel.State.UP)
getBackend().setState(tunnel, Tunnel.State.UP, tunnel.config)
+ tunnelMap.add(tunnel)
+ if (wasLastUsed)
+ lastUsedTunnel = tunnel
throw e
}
- }.whenComplete { _, e ->
- if (e == null)
- return@whenComplete
- // Failure, put the tunnel back.
- tunnelMap.add(tunnel)
- if (wasLastUsed)
- lastUsedTunnel = tunnel
}
}