From b1b1a9e627ac969d8e46fe4bdbebf019e42628d3 Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Wed, 11 Jun 2025 20:04:57 +0800 Subject: [PATCH] manager: Add KPM support functions and JNI interface Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Co-authored-by: liankong Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> --- manager/app/src/main/cpp/jni.cc | 5 ++ manager/app/src/main/cpp/ksu.cc | 6 ++ manager/app/src/main/cpp/ksu.h | 2 + .../main/java/com/rifsxd/ksunext/Natives.kt | 6 ++ .../java/com/rifsxd/ksunext/ui/util/KsuCli.kt | 70 ++++++++++++++++++- 5 files changed, 88 insertions(+), 1 deletion(-) diff --git a/manager/app/src/main/cpp/jni.cc b/manager/app/src/main/cpp/jni.cc index 85867951..6d760177 100644 --- a/manager/app/src/main/cpp/jni.cc +++ b/manager/app/src/main/cpp/jni.cc @@ -313,3 +313,8 @@ JNIEXPORT jboolean JNICALL Java_com_rifsxd_ksunext_Natives_setSuEnabled(JNIEnv *env, jobject thiz, jboolean enabled) { return set_su_enabled(enabled); } + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_rifsxd_ksunext_Natives_isKPMEnabled(JNIEnv *env, jobject) { + return is_KPM_enable(); +} diff --git a/manager/app/src/main/cpp/ksu.cc b/manager/app/src/main/cpp/ksu.cc index 4d53bc1d..d043470e 100644 --- a/manager/app/src/main/cpp/ksu.cc +++ b/manager/app/src/main/cpp/ksu.cc @@ -30,6 +30,7 @@ #define CMD_IS_SU_ENABLED 14 #define CMD_ENABLE_SU 15 #define CMD_HOOK_MODE 16 +#define CMD_ENABLE_KPM 100 static bool ksuctl(int cmd, void* arg1, void* arg2) { int32_t result = 0; @@ -103,4 +104,9 @@ bool is_su_enabled() { // if ksuctl failed, we assume su is enabled, and it cannot be disabled. ksuctl(CMD_IS_SU_ENABLED, &enabled, nullptr); return enabled; +} + +bool is_KPM_enable() { + bool enabled = false; + return ksuctl(CMD_ENABLE_KPM, &enabled, nullptr), enabled; } \ No newline at end of file diff --git a/manager/app/src/main/cpp/ksu.h b/manager/app/src/main/cpp/ksu.h index 17394da5..3e49fe49 100644 --- a/manager/app/src/main/cpp/ksu.h +++ b/manager/app/src/main/cpp/ksu.h @@ -85,4 +85,6 @@ bool set_su_enabled(bool enabled); bool is_su_enabled(); +bool is_KPM_enable(); + #endif //KERNELSU_KSU_H diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/Natives.kt b/manager/app/src/main/java/com/rifsxd/ksunext/Natives.kt index 03296028..e709541f 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/Natives.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/Natives.kt @@ -81,6 +81,12 @@ object Natives { external fun isSuEnabled(): Boolean external fun setSuEnabled(enabled: Boolean): Boolean + /** + * Check if the KPM (Kernel Package Manager) is enabled. + * @return true if KPM is enabled, false otherwise. + */ + external fun isKPMEnabled(): Boolean + private const val NON_ROOT_DEFAULT_PROFILE_KEY = "$" private const val NOBODY_UID = 9999 diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt index c71cbd8f..22ae5c5b 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/util/KsuCli.kt @@ -645,4 +645,72 @@ fun launchApp(packageName: String) { fun restartApp(packageName: String) { forceStopApp(packageName) launchApp(packageName) -} \ No newline at end of file +} + +fun getKpmmgrPath(): String { + return ksuApp.applicationInfo.nativeLibraryDir + File.separator + "libkpmmgr.so" +} + + +fun loadKpmModule(path: String, args: String? = null): String { + val shell = getRootShell() + val cmd = "${getKpmmgrPath()} load $path ${args ?: ""}" + return ShellUtils.fastCmd(shell, cmd) +} + +fun unloadKpmModule(name: String): String { + val shell = getRootShell() + val cmd = "${getKpmmgrPath()} unload $name" + return ShellUtils.fastCmd(shell, cmd) +} + +fun getKpmModuleCount(): Int { + val shell = getRootShell() + val cmd = "${getKpmmgrPath()} num" + val result = ShellUtils.fastCmd(shell, cmd) + return result.trim().toIntOrNull() ?: 0 +} + +fun runCmd(shell : Shell, cmd : String) : String { + return shell.newJob() + .add(cmd) + .to(mutableListOf(), null) + .exec().out + .joinToString("\n") +} + +fun listKpmModules(): String { + val shell = getRootShell() + val cmd = "${getKpmmgrPath()} list" + return try { + runCmd(shell, cmd).trim() + } catch (e: Exception) { + Log.e(TAG, "Failed to list KPM modules", e) + "" + } +} + +fun getKpmModuleInfo(name: String): String { + val shell = getRootShell() + val cmd = "${getKpmmgrPath()} info $name" + return try { + runCmd(shell, cmd).trim() + } catch (e: Exception) { + Log.e(TAG, "Failed to get KPM module info: $name", e) + "" + } +} + +fun controlKpmModule(name: String, args: String? = null): Int { + val shell = getRootShell() + val cmd = """${getKpmmgrPath()} control $name "${args ?: ""}"""" + val result = runCmd(shell, cmd) + return result.trim().toIntOrNull() ?: -1 +} + +fun getKpmVersion(): String { + val shell = getRootShell() + val cmd = "${getKpmmgrPath()} version" + val result = ShellUtils.fastCmd(shell, cmd) + return result.trim() +}