summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/DispatchingHandler.kt48
1 files changed, 48 insertions, 0 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/DispatchingHandler.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/DispatchingHandler.kt
new file mode 100644
index 0000000000..0f3820ff48
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/DispatchingHandler.kt
@@ -0,0 +1,48 @@
+package net.mullvad.mullvadvpn.ipc
+
+import android.os.Handler
+import android.os.Looper
+import android.os.Message
+import android.util.Log
+import java.util.concurrent.locks.ReentrantReadWriteLock
+import kotlin.concurrent.withLock
+import kotlin.reflect.KClass
+
+class DispatchingHandler<T : Any>(
+ looper: Looper,
+ private val extractor: (Message) -> T?
+) : Handler(looper) {
+ private val handlers = HashMap<KClass<out T>, (T) -> Unit>()
+ private val lock = ReentrantReadWriteLock()
+
+ fun <V : T> registerHandler(variant: KClass<V>, handler: (V) -> Unit) {
+ lock.writeLock().withLock {
+ handlers.put(variant) { instance ->
+ @Suppress("UNCHECKED_CAST")
+ handler(instance as V)
+ }
+ }
+ }
+
+ override fun handleMessage(message: Message) {
+ lock.readLock().withLock {
+ val instance = extractor(message)
+
+ if (instance != null) {
+ val handler = handlers.get(instance::class)
+
+ handler?.invoke(instance)
+ } else {
+ Log.e("mullvad", "Dispatching handler received an unexpected message")
+ }
+ }
+ }
+
+ fun onDestroy() {
+ lock.writeLock().withLock {
+ handlers.clear()
+ }
+
+ removeCallbacksAndMessages(null)
+ }
+}