perf(scripting): parcel file descriptor

This commit is contained in:
rhunk
2024-05-01 02:52:55 +02:00
parent 51869e56a8
commit ba8b50ef40
4 changed files with 27 additions and 10 deletions

View File

@@ -1,6 +1,8 @@
package me.rhunk.snapenhance.scripting package me.rhunk.snapenhance.scripting
import android.annotation.SuppressLint
import android.net.Uri import android.net.Uri
import android.os.ParcelFileDescriptor
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.AutoReloadListener import me.rhunk.snapenhance.bridge.scripting.AutoReloadListener
@@ -11,6 +13,7 @@ import me.rhunk.snapenhance.common.scripting.bindings.BindingSide
import me.rhunk.snapenhance.common.scripting.impl.ConfigInterface import me.rhunk.snapenhance.common.scripting.impl.ConfigInterface
import me.rhunk.snapenhance.common.scripting.impl.ConfigTransactionType import me.rhunk.snapenhance.common.scripting.impl.ConfigTransactionType
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
import me.rhunk.snapenhance.core.util.ktx.toParcelFileDescriptor
import me.rhunk.snapenhance.scripting.impl.IPCListeners import me.rhunk.snapenhance.scripting.impl.IPCListeners
import me.rhunk.snapenhance.scripting.impl.ManagerIPC import me.rhunk.snapenhance.scripting.impl.ManagerIPC
import me.rhunk.snapenhance.scripting.impl.ManagerScriptConfig import me.rhunk.snapenhance.scripting.impl.ManagerScriptConfig
@@ -49,8 +52,10 @@ class RemoteScriptManager(
getScriptFileNames().forEach { name -> getScriptFileNames().forEach { name ->
runCatching { runCatching {
getScriptInputStream(name) { stream -> getScriptInputStream(name) { stream ->
runtime.getModuleInfo(stream!!).also { info -> stream?.use {
cachedModuleInfo[name] = info runtime.getModuleInfo(it).also { info ->
cachedModuleInfo[name] = info
}
} }
} }
}.onFailure { }.onFailure {
@@ -92,9 +97,10 @@ class RemoteScriptManager(
runtime.unload(scriptPath) runtime.unload(scriptPath)
} }
@SuppressLint("Recycle")
private fun <R> getScriptInputStream(name: String, callback: (InputStream?) -> R): R { private fun <R> getScriptInputStream(name: String, callback: (InputStream?) -> R): R {
val file = getScriptsFolder()?.findFile(name) ?: return callback(null) val file = getScriptsFolder()?.findFile(name) ?: return callback(null)
return context.androidContext.contentResolver.openInputStream(file.uri)?.use(callback) ?: callback(null) return context.androidContext.contentResolver.openInputStream(file.uri)?.let(callback) ?: callback(null)
} }
fun getModuleDataFolder(moduleFileName: String): File { fun getModuleDataFolder(moduleFileName: String): File {
@@ -123,15 +129,14 @@ class RemoteScriptManager(
}.getOrDefault(emptyList()) }.getOrDefault(emptyList())
} }
override fun getScriptContent(moduleName: String): String? { override fun getScriptContent(moduleName: String): ParcelFileDescriptor? {
if (moduleName.startsWith("composer/")) { if (moduleName.startsWith("composer/")) {
return runCatching { return runCatching {
context.androidContext.assets.open("composer/${moduleName.removePrefix("composer/")}").use { context.androidContext.assets.open("composer/${moduleName.removePrefix("composer/")}")
it.bufferedReader().readText() .toParcelFileDescriptor(context.coroutineScope)
}
}.getOrNull() }.getOrNull()
} }
return getScriptInputStream(moduleName) { it?.bufferedReader()?.readText() } return getScriptInputStream(moduleName) { it?.toParcelFileDescriptor(context.coroutineScope) }
} }
override fun registerIPCListener(channel: String, eventName: String, listener: IPCListener) { override fun registerIPCListener(channel: String, eventName: String, listener: IPCListener) {

View File

@@ -6,7 +6,7 @@ import me.rhunk.snapenhance.bridge.scripting.AutoReloadListener;
interface IScripting { interface IScripting {
List<String> getEnabledScripts(); List<String> getEnabledScripts();
@nullable String getScriptContent(String path); @nullable ParcelFileDescriptor getScriptContent(String path);
oneway void registerIPCListener(String channel, String eventName, IPCListener listener); oneway void registerIPCListener(String channel, String eventName, IPCListener listener);

View File

@@ -1,6 +1,7 @@
package me.rhunk.snapenhance.common.scripting package me.rhunk.snapenhance.common.scripting
import android.content.Context import android.content.Context
import android.os.ParcelFileDescriptor
import me.rhunk.snapenhance.bridge.scripting.IScripting import me.rhunk.snapenhance.bridge.scripting.IScripting
import me.rhunk.snapenhance.common.logger.AbstractLogger import me.rhunk.snapenhance.common.logger.AbstractLogger
import me.rhunk.snapenhance.common.scripting.type.ModuleInfo import me.rhunk.snapenhance.common.scripting.type.ModuleInfo
@@ -80,6 +81,12 @@ open class ScriptRuntime(
modules.remove(scriptPath) modules.remove(scriptPath)
} }
fun load(scriptPath: String, pfd: ParcelFileDescriptor) {
load(scriptPath, ParcelFileDescriptor.AutoCloseInputStream(pfd).use {
it.readBytes().toString(Charsets.UTF_8)
})
}
fun load(scriptPath: String, content: String): JSModule? { fun load(scriptPath: String, content: String): JSModule? {
logger.info("Loading module $scriptPath") logger.info("Loading module $scriptPath")
return runCatching { return runCatching {

View File

@@ -1,5 +1,6 @@
package me.rhunk.snapenhance.core.features.impl.experiments package me.rhunk.snapenhance.core.features.impl.experiments
import android.os.ParcelFileDescriptor
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@@ -186,7 +187,11 @@ class ComposerHooks: Feature("ComposerHooks", loadParams = FeatureLoadParams.ACT
} }
private fun loadHooks() { private fun loadHooks() {
val loaderScript = context.scriptRuntime.scripting.getScriptContent("composer/loader.js") ?: run { val loaderScript = context.scriptRuntime.scripting.getScriptContent("composer/loader.js")?.let { pfd ->
ParcelFileDescriptor.AutoCloseInputStream(pfd).use {
it.readBytes().toString(Charsets.UTF_8)
}
} ?: run {
context.log.error("Failed to load composer loader script") context.log.error("Failed to load composer loader script")
return return
} }