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:
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 {