diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt index 332f6a42..cd723468 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt @@ -41,6 +41,13 @@ fun getRootShell(globalMnt: Boolean = false): Shell { } } +inline fun withNewRootShell( + globalMnt: Boolean = false, + block: Shell.() -> T +): T { + return createRootShell(globalMnt).use(block) +} + fun createRootShell(globalMnt: Boolean = false): Shell { Shell.enableVerboseLogging = BuildConfig.DEBUG val builder = Shell.Builder.create() @@ -66,8 +73,13 @@ fun createRootShell(globalMnt: Boolean = false): Shell { } fun execKsud(args: String, newShell: Boolean = false): Boolean { - val shell = if (newShell) createRootShell() else getRootShell() - return ShellUtils.fastCmdResult(shell, "${getKsuDaemonPath()} $args") + return if (newShell) { + withNewRootShell { + ShellUtils.fastCmdResult(this, "${getKsuDaemonPath()} $args") + } + } else { + ShellUtils.fastCmdResult(getRootShell(), "${getKsuDaemonPath()} $args") + } } fun install() { @@ -128,8 +140,6 @@ fun installModule( } val cmd = "module install ${file.absolutePath}" - val shell = createRootShell() - val stdoutCallback: CallbackList = object : CallbackList() { override fun onAddElement(s: String?) { onStdout(s ?: "") @@ -142,9 +152,9 @@ fun installModule( } } - val result = - shell.newJob().add("${getKsuDaemonPath()} $cmd").to(stdoutCallback, stderrCallback) - .exec() + val result = withNewRootShell { + newJob().add("${getKsuDaemonPath()} $cmd").to(stdoutCallback, stderrCallback).exec() + } Log.i("KernelSU", "install module $uri result: $result") file.delete() @@ -157,7 +167,6 @@ fun installModule( fun restoreBoot( onFinish: (Boolean, Int) -> Unit, onStdout: (String) -> Unit, onStderr: (String) -> Unit ): Boolean { - val shell = createRootShell() val magiskboot = File(ksuApp.applicationInfo.nativeLibraryDir, "libmagiskboot.so") val stdoutCallback: CallbackList = object : CallbackList() { @@ -172,10 +181,11 @@ fun restoreBoot( } } - val result = - shell.newJob().add("${getKsuDaemonPath()} boot-restore -f --magiskboot $magiskboot") + val result = withNewRootShell { + newJob().add("${getKsuDaemonPath()} boot-restore -f --magiskboot $magiskboot") .to(stdoutCallback, stderrCallback) .exec() + } onFinish(result.isSuccess, result.code) return result.isSuccess @@ -255,8 +265,6 @@ fun installBoot( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) cmd += " -o $downloadsDir" - val shell = createRootShell() - val stdoutCallback: CallbackList = object : CallbackList() { override fun onAddElement(s: String?) { onStdout(s ?: "") @@ -269,8 +277,9 @@ fun installBoot( } } - val result = - shell.newJob().add("${getKsuDaemonPath()} $cmd").to(stdoutCallback, stderrCallback).exec() + val result = withNewRootShell { + newJob().add("${getKsuDaemonPath()} $cmd").to(stdoutCallback, stderrCallback).exec() + } Log.i("KernelSU", "install boot result: ${result.isSuccess}") bootFile?.delete() diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/SELinuxChecker.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/SELinuxChecker.kt index d51fd91e..78346dd9 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/SELinuxChecker.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/SELinuxChecker.kt @@ -12,7 +12,9 @@ fun getSELinuxStatus(): String { .build("sh") val list = ArrayList() - val result = shell.newJob().add("getenforce").to(list, list).exec() + val result = shell.use { + it.newJob().add("getenforce").to(list, list).exec() + } val output = result.out.joinToString("\n").trim() if (result.isSuccess) { diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/SuFilePathHandler.java b/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/SuFilePathHandler.java index 824cac1f..84a37c84 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/SuFilePathHandler.java +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/SuFilePathHandler.java @@ -84,14 +84,14 @@ public final class SuFilePathHandler implements WebViewAssetLoader.PathHandler { * which files can be loaded. * @throws IllegalArgumentException if the directory is not allowed. */ - public SuFilePathHandler(@NonNull Context context, @NonNull File directory) { + public SuFilePathHandler(@NonNull Context context, @NonNull File directory, Shell rootShell) { try { mDirectory = new File(getCanonicalDirPath(directory)); if (!isAllowedInternalStorageDir(context)) { throw new IllegalArgumentException("The given directory \"" + directory + "\" doesn't exist under an allowed app internal storage directory"); } - mShell = KsuCliKt.createRootShell(true); + mShell = rootShell; } catch (IOException e) { throw new IllegalArgumentException( "Failed to resolve the canonical path for the given directory: " diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebUIActivity.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebUIActivity.kt index 9d2fe8a8..eccb002a 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebUIActivity.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebUIActivity.kt @@ -10,12 +10,16 @@ import android.webkit.WebView import android.webkit.WebViewClient import androidx.activity.ComponentActivity import androidx.webkit.WebViewAssetLoader +import com.topjohnwu.superuser.Shell +import me.weishu.kernelsu.ui.util.createRootShell import java.io.File @SuppressLint("SetJavaScriptEnabled") -class WebUIActivity : ComponentActivity() { +class WebUIActivity : ComponentActivity() { private lateinit var webviewInterface: WebViewInterface + private var rootShell: Shell? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val moduleId = intent.getStringExtra("id")!! @@ -26,11 +30,12 @@ class WebUIActivity : ComponentActivity() { WebView.setWebContentsDebuggingEnabled(prefs.getBoolean("enable_web_debugging", false)) val webRoot = File("/data/adb/modules/${moduleId}/webroot") + val rootShell = createRootShell(true).also { this.rootShell = it } val webViewAssetLoader = WebViewAssetLoader.Builder() .setDomain("mui.kernelsu.org") .addPathHandler( "/", - SuFilePathHandler(this, webRoot) + SuFilePathHandler(this, webRoot, rootShell) ) .build() @@ -55,4 +60,9 @@ class WebUIActivity : ComponentActivity() { setContentView(webView) } + + override fun onDestroy() { + super.onDestroy() + runCatching { rootShell?.close() } + } } \ No newline at end of file diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebViewInterface.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebViewInterface.kt index 8e5a3dac..4b6a3c8f 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebViewInterface.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/webui/WebViewInterface.kt @@ -15,6 +15,7 @@ import androidx.core.view.WindowInsetsControllerCompat import com.topjohnwu.superuser.CallbackList import com.topjohnwu.superuser.ShellUtils import me.weishu.kernelsu.ui.util.createRootShell +import me.weishu.kernelsu.ui.util.withNewRootShell import org.json.JSONArray import org.json.JSONObject import java.util.concurrent.CompletableFuture @@ -23,8 +24,7 @@ class WebViewInterface(val context: Context, private val webView: WebView) { @JavascriptInterface fun exec(cmd: String): String { - val shell = createRootShell(true) - return ShellUtils.fastCmd(shell, cmd) + return withNewRootShell(true) { ShellUtils.fastCmd(this, cmd) } } @JavascriptInterface @@ -59,8 +59,9 @@ class WebViewInterface(val context: Context, private val webView: WebView) { processOptions(finalCommand, options) finalCommand.append(cmd) - val shell = createRootShell(true) - val result = shell.newJob().add(finalCommand.toString()).to(ArrayList(), ArrayList()).exec() + val result = withNewRootShell(true) { + newJob().add(finalCommand.toString()).to(ArrayList(), ArrayList()).exec() + } val stdout = result.out.joinToString(separator = "\n") val stderr = result.err.joinToString(separator = "\n") @@ -144,6 +145,8 @@ class WebViewInterface(val context: Context, private val webView: WebView) { webView.loadUrl(emitErrCode) } } + }.whenComplete { _, _ -> + runCatching { shell.close() } } }