manager: Add KPM support functions and JNI interface

Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Co-authored-by: liankong <xhsw.new@qq.com>
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
ShirkNeko
2025-06-11 20:04:57 +08:00
committed by Rifat Azad
parent 6159cea2f7
commit b1b1a9e627
5 changed files with 88 additions and 1 deletions

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -85,4 +85,6 @@ bool set_su_enabled(bool enabled);
bool is_su_enabled();
bool is_KPM_enable();
#endif //KERNELSU_KSU_H

View File

@@ -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

View File

@@ -645,4 +645,72 @@ fun launchApp(packageName: String) {
fun restartApp(packageName: String) {
forceStopApp(packageName)
launchApp(packageName)
}
}
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<String>(), 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()
}