fix(scripting): dead objects

- add no args emit
This commit is contained in:
rhunk 2023-09-17 02:50:44 +02:00
parent 08cd7917f3
commit e79aba8165
5 changed files with 40 additions and 12 deletions

View File

@ -1,13 +1,19 @@
package me.rhunk.snapenhance.scripting package me.rhunk.snapenhance.scripting
class IRemoteIPC : IPCInterface { import java.util.concurrent.ConcurrentHashMap
private val listeners = mutableMapOf<String, MutableSet<Listener>>()
class IRemoteIPC : IPCInterface() {
private val listeners = ConcurrentHashMap<String, MutableSet<Listener>>()
fun removeListener(eventName: String, listener: Listener) {
listeners[eventName]?.remove(listener)
}
override fun on(eventName: String, listener: Listener) { override fun on(eventName: String, listener: Listener) {
listeners.getOrPut(eventName) { mutableSetOf() }.add(listener) listeners.getOrPut(eventName) { mutableSetOf() }.add(listener)
} }
override fun emit(eventName: String, args: Array<out String?>) { override fun emit(eventName: String, args: Array<out String?>) {
listeners[eventName]?.forEach { it(args) } listeners[eventName]?.toList()?.forEach { it(args) }
} }
} }

View File

@ -1,6 +1,7 @@
package me.rhunk.snapenhance.scripting package me.rhunk.snapenhance.scripting
import android.net.Uri import android.net.Uri
import android.os.DeadObjectException
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import me.rhunk.snapenhance.RemoteSideContext import me.rhunk.snapenhance.RemoteSideContext
import me.rhunk.snapenhance.bridge.scripting.IPCListener import me.rhunk.snapenhance.bridge.scripting.IPCListener
@ -75,12 +76,24 @@ class RemoteScriptManager(
} }
override fun registerIPCListener(eventName: String, listener: IPCListener) { override fun registerIPCListener(eventName: String, listener: IPCListener) {
runtime.ipcManager.on(eventName) { args -> runtime.ipcManager.on(eventName, object: Listener {
listener.onMessage(args) override fun invoke(args: Array<out String?>) {
} try {
listener.onMessage(args)
} catch (e: DeadObjectException) {
(runtime.ipcManager as IRemoteIPC).removeListener(eventName, this)
} catch (t: Throwable) {
context.log.error("Failed to invoke $eventName", t)
}
}
})
} }
override fun sendIPCMessage(eventName: String, args: Array<out String>) { override fun sendIPCMessage(eventName: String, args: Array<out String>) {
runtime.ipcManager.emit(eventName, args) runCatching {
runtime.ipcManager.emit(eventName, *args)
}.onFailure {
context.log.error("Failed to send message for $eventName", it)
}
} }
} }

View File

@ -125,7 +125,7 @@ class SnapEnhance {
} }
}) })
scriptRuntime.ipcManager = object: IPCInterface { scriptRuntime.ipcManager = object: IPCInterface() {
override fun on(eventName: String, listener: Listener) { override fun on(eventName: String, listener: Listener) {
registerIPCListener(eventName, object: IPCListener.Stub() { registerIPCListener(eventName, object: IPCListener.Stub() {
override fun onMessage(args: Array<out String?>) { override fun onMessage(args: Array<out String?>) {

View File

@ -2,7 +2,10 @@ package me.rhunk.snapenhance.scripting
typealias Listener = (Array<out String?>) -> Unit typealias Listener = (Array<out String?>) -> Unit
interface IPCInterface { abstract class IPCInterface {
fun on(eventName: String, listener: Listener) abstract fun on(eventName: String, listener: Listener)
fun emit(eventName: String, args: Array<out String?>)
abstract fun emit(eventName: String, vararg args: String?)
fun emit(eventName: String) = emit(eventName, *emptyArray())
} }

View File

@ -13,7 +13,13 @@ class ScriptRuntime(
private val modules = mutableMapOf<String, JSModule>() private val modules = mutableMapOf<String, JSModule>()
fun eachModule(f: JSModule.() -> Unit) { fun eachModule(f: JSModule.() -> Unit) {
modules.values.forEach(f) modules.values.forEach { module ->
runCatching {
module.f()
}.onFailure {
logger.error("Failed to run module function in ${module.moduleInfo.name}", it)
}
}
} }
private fun readModuleInfo(reader: BufferedReader): ModuleInfo { private fun readModuleInfo(reader: BufferedReader): ModuleInfo {