ManagerIPC.kt (2202B) - raw
1 package me.rhunk.snapenhance.scripting.impl 2 3 import android.os.DeadObjectException 4 import me.rhunk.snapenhance.bridge.scripting.IPCListener 5 import me.rhunk.snapenhance.common.scripting.impl.IPCInterface 6 import me.rhunk.snapenhance.common.scripting.impl.Listener 7 import java.util.concurrent.ConcurrentHashMap 8 9 typealias IPCListeners = ConcurrentHashMap<String, MutableMap<String, MutableSet<IPCListener>>> // channel, eventName -> listeners 10 11 class ManagerIPC( 12 private val ipcListeners: IPCListeners = ConcurrentHashMap(), 13 ) : IPCInterface() { 14 companion object { 15 private const val TAG = "RemoteManagerIPC" 16 } 17 18 override fun on(eventName: String, listener: Listener) { 19 onBroadcast(context.moduleInfo.name, eventName, listener) 20 } 21 22 override fun emit(eventName: String, vararg args: String?): Int { 23 return broadcast(context.moduleInfo.name, eventName, *args) 24 } 25 26 override fun onBroadcast(channel: String, eventName: String, listener: Listener) { 27 ipcListeners.getOrPut(channel) { mutableMapOf() }.getOrPut(eventName) { mutableSetOf() }.add(object: IPCListener.Stub() { 28 override fun onMessage(args: Array<out String?>) { 29 try { 30 listener(args.toList()) 31 } catch (doe: DeadObjectException) { 32 ipcListeners[channel]?.get(eventName)?.remove(this) 33 } catch (t: Throwable) { 34 context.runtime.logger.error("Failed to receive message for channel: $channel, event: $eventName", t, TAG) 35 } 36 } 37 }) 38 } 39 40 override fun broadcast(channel: String, eventName: String, vararg args: String?): Int { 41 var dispatchCount = 0 42 ipcListeners[channel]?.get(eventName)?.toList()?.forEach { 43 try { 44 it.onMessage(args) 45 dispatchCount++ 46 } catch (doe: DeadObjectException) { 47 ipcListeners[channel]?.get(eventName)?.remove(it) 48 } catch (t: Throwable) { 49 context.runtime.logger.error("Failed to send message for channel: $channel, event: $eventName", t, TAG) 50 } 51 } 52 return dispatchCount 53 } 54 }