commit e79aba81653d50c218a37f9d5e1975cfd49f3d69
parent 08cd7917f334c9e9ae9b92948af32fb645001eed
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Sun, 17 Sep 2023 02:50:44 +0200

fix(scripting): dead objects
- add no args emit

Diffstat:
Mapp/src/main/kotlin/me/rhunk/snapenhance/scripting/IRemoteIPC.kt | 12+++++++++---
Mapp/src/main/kotlin/me/rhunk/snapenhance/scripting/RemoteScriptManager.kt | 21+++++++++++++++++----
Mcore/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt | 2+-
Mcore/src/main/kotlin/me/rhunk/snapenhance/scripting/IPCInterface.kt | 9++++++---
Mcore/src/main/kotlin/me/rhunk/snapenhance/scripting/ScriptRuntime.kt | 8+++++++-
5 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/scripting/IRemoteIPC.kt b/app/src/main/kotlin/me/rhunk/snapenhance/scripting/IRemoteIPC.kt @@ -1,13 +1,19 @@ package me.rhunk.snapenhance.scripting -class IRemoteIPC : IPCInterface { - private val listeners = mutableMapOf<String, MutableSet<Listener>>() +import java.util.concurrent.ConcurrentHashMap + +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) { listeners.getOrPut(eventName) { mutableSetOf() }.add(listener) } override fun emit(eventName: String, args: Array<out String?>) { - listeners[eventName]?.forEach { it(args) } + listeners[eventName]?.toList()?.forEach { it(args) } } } \ No newline at end of file diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/scripting/RemoteScriptManager.kt b/app/src/main/kotlin/me/rhunk/snapenhance/scripting/RemoteScriptManager.kt @@ -1,6 +1,7 @@ package me.rhunk.snapenhance.scripting import android.net.Uri +import android.os.DeadObjectException import androidx.documentfile.provider.DocumentFile import me.rhunk.snapenhance.RemoteSideContext import me.rhunk.snapenhance.bridge.scripting.IPCListener @@ -75,12 +76,24 @@ class RemoteScriptManager( } override fun registerIPCListener(eventName: String, listener: IPCListener) { - runtime.ipcManager.on(eventName) { args -> - listener.onMessage(args) - } + runtime.ipcManager.on(eventName, object: Listener { + 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>) { - runtime.ipcManager.emit(eventName, args) + runCatching { + runtime.ipcManager.emit(eventName, *args) + }.onFailure { + context.log.error("Failed to send message for $eventName", it) + } } } \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt b/core/src/main/kotlin/me/rhunk/snapenhance/SnapEnhance.kt @@ -125,7 +125,7 @@ class SnapEnhance { } }) - scriptRuntime.ipcManager = object: IPCInterface { + scriptRuntime.ipcManager = object: IPCInterface() { override fun on(eventName: String, listener: Listener) { registerIPCListener(eventName, object: IPCListener.Stub() { override fun onMessage(args: Array<out String?>) { diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/scripting/IPCInterface.kt b/core/src/main/kotlin/me/rhunk/snapenhance/scripting/IPCInterface.kt @@ -2,7 +2,10 @@ package me.rhunk.snapenhance.scripting typealias Listener = (Array<out String?>) -> Unit -interface IPCInterface { - fun on(eventName: String, listener: Listener) - fun emit(eventName: String, args: Array<out String?>) +abstract class IPCInterface { + abstract fun on(eventName: String, listener: Listener) + + abstract fun emit(eventName: String, vararg args: String?) + + fun emit(eventName: String) = emit(eventName, *emptyArray()) } \ No newline at end of file diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/scripting/ScriptRuntime.kt b/core/src/main/kotlin/me/rhunk/snapenhance/scripting/ScriptRuntime.kt @@ -13,7 +13,13 @@ class ScriptRuntime( private val modules = mutableMapOf<String, JSModule>() 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 {