diff --git a/manager/app/src/main/cpp/jni.cc b/manager/app/src/main/cpp/jni.cc
index 86258709..58d5c461 100644
--- a/manager/app/src/main/cpp/jni.cc
+++ b/manager/app/src/main/cpp/jni.cc
@@ -60,10 +60,49 @@ Java_me_weishu_kernelsu_Natives_allowRoot(JNIEnv *env, jclass clazz, jint uid, j
return allow_su(uid, allow);
}
-
-
extern "C"
JNIEXPORT jboolean JNICALL
Java_me_weishu_kernelsu_Natives_isSafeMode(JNIEnv *env, jclass clazz) {
return is_safe_mode();
+}
+
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_me_weishu_kernelsu_Natives_isAllowlistMode(JNIEnv *env, jclass clazz) {
+ return is_allowlist_mode();
+}
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_me_weishu_kernelsu_Natives_setAllowlistMode(JNIEnv *env, jclass clazz, jboolean is_allowlist) {
+ return set_allowlist_mode(is_allowlist);
+}
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_me_weishu_kernelsu_Natives_addUidToAllowlist(JNIEnv *env, jclass clazz, jint uid) {
+ return add_to_allow_list(uid);
+}
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_me_weishu_kernelsu_Natives_removeUidFromAllowlist(JNIEnv *env, jclass clazz, jint uid) {
+ return remove_from_allow_list(uid);
+}
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_me_weishu_kernelsu_Natives_addUidToDenylist(JNIEnv *env, jclass clazz, jint uid) {
+ return add_to_deny_list(uid);
+}
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_me_weishu_kernelsu_Natives_removeUidFromDenylist(JNIEnv *env, jclass clazz, jint uid) {
+ return remove_from_deny_list(uid);
+}
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_me_weishu_kernelsu_Natives_isUidInAllowlist(JNIEnv *env, jclass clazz, jint uid) {
+ return is_in_allow_list(uid);
+}
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_me_weishu_kernelsu_Natives_isUidInDenylist(JNIEnv *env, jclass clazz, jint uid) {
+ return is_in_deny_list(uid);
}
\ No newline at end of file
diff --git a/manager/app/src/main/cpp/ksu.cc b/manager/app/src/main/cpp/ksu.cc
index 8c473edc..76ab732d 100644
--- a/manager/app/src/main/cpp/ksu.cc
+++ b/manager/app/src/main/cpp/ksu.cc
@@ -18,10 +18,19 @@
#define CMD_GET_VERSION 2
#define CMD_ALLOW_SU 3
#define CMD_DENY_SU 4
-#define CMD_GET_ALLOW_LIST 5
+#define CMD_GET_SU_LIST 5
#define CMD_GET_DENY_LIST 6
#define CMD_CHECK_SAFEMODE 9
+#define CMD_GET_WORK_MODE 10
+#define CMD_SET_WORK_MODE 11
+#define CMD_IN_ALLOW_LIST 12
+#define CMD_IN_DENY_LIST 13
+#define CMD_ADD_ALLOW_LIST 14
+#define CMD_REMOVE_ALLOW_LIST 15
+#define CMD_ADD_DENY_LIST 16
+#define CMD_REMOVE_DENY_LIST 17
+
static bool ksuctl(int cmd, void* arg1, void* arg2) {
int32_t result = 0;
prctl(KERNEL_SU_OPTION, cmd, arg1, arg2, &result);
@@ -55,7 +64,7 @@ bool allow_su(int uid, bool allow) {
}
bool get_allow_list(int *uids, int *size) {
- return ksuctl(CMD_GET_ALLOW_LIST, uids, size);
+ return ksuctl(CMD_GET_SU_LIST, uids, size);
}
bool get_deny_list(int *uids, int *size) {
@@ -64,4 +73,40 @@ bool get_deny_list(int *uids, int *size) {
bool is_safe_mode() {
return ksuctl(CMD_CHECK_SAFEMODE, nullptr, nullptr);
+}
+
+bool is_allowlist_mode() {
+ int32_t mode = -1;
+ ksuctl(CMD_GET_WORK_MODE, &mode, nullptr);
+ // for kernel that doesn't support allowlist mode, return -1 and it is always allowlist mode
+ return mode <= 0;
+}
+
+bool set_allowlist_mode(bool allowlist_mode) {
+ int32_t mode = allowlist_mode ? 0 : 1;
+ return ksuctl(CMD_SET_WORK_MODE, &mode, nullptr);
+}
+
+bool is_in_allow_list(int uid) {
+ return ksuctl(CMD_IN_ALLOW_LIST, &uid, nullptr);
+}
+
+bool is_in_deny_list(int uid) {
+ return ksuctl(CMD_IN_DENY_LIST, &uid, nullptr);
+}
+
+bool add_to_allow_list(int uid) {
+ return ksuctl(CMD_ADD_ALLOW_LIST, &uid, nullptr);
+}
+
+bool remove_from_allow_list(int uid) {
+ return ksuctl(CMD_REMOVE_ALLOW_LIST, &uid, nullptr);
+}
+
+bool add_to_deny_list(int uid) {
+ return ksuctl(CMD_ADD_DENY_LIST, &uid, nullptr);
+}
+
+bool remove_from_deny_list(int uid) {
+ return ksuctl(CMD_REMOVE_DENY_LIST, &uid, nullptr);
}
\ 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 96841de8..a8b7b50b 100644
--- a/manager/app/src/main/cpp/ksu.h
+++ b/manager/app/src/main/cpp/ksu.h
@@ -17,4 +17,20 @@ bool get_deny_list(int *uids, int *size);
bool is_safe_mode();
+bool is_allowlist_mode();
+
+bool set_allowlist_mode(bool allowlist_mode);
+
+bool is_in_allow_list(int uid);
+
+bool is_in_deny_list(int uid);
+
+bool add_to_allow_list(int uid);
+
+bool remove_from_allow_list(int uid);
+
+bool add_to_deny_list(int uid);
+
+bool remove_from_deny_list(int uid);
+
#endif //KERNELSU_KSU_H
diff --git a/manager/app/src/main/java/me/weishu/kernelsu/Natives.java b/manager/app/src/main/java/me/weishu/kernelsu/Natives.java
index bed5713a..1af5de15 100644
--- a/manager/app/src/main/java/me/weishu/kernelsu/Natives.java
+++ b/manager/app/src/main/java/me/weishu/kernelsu/Natives.java
@@ -23,4 +23,20 @@ public final class Natives {
public static native boolean allowRoot(int uid, boolean allow);
public static native boolean isSafeMode();
+
+ public static native boolean isAllowlistMode();
+
+ public static native boolean setAllowlistMode(boolean isAllowlist);
+
+ public static native boolean isUidInAllowlist(int uid);
+
+ public static native boolean isUidInDenylist(int uid);
+
+ public static native boolean addUidToAllowlist(int uid);
+
+ public static native boolean removeUidFromAllowlist(int uid);
+
+ public static native boolean addUidToDenylist(int uid);
+
+ public static native boolean removeUidFromDenylist(int uid);
}
diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt
index 41ae849c..e7bce536 100644
--- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt
+++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt
@@ -76,23 +76,41 @@ fun AppProfileScreen(
})
}
) { paddingValues ->
- LoadingDialog()
-
- val showAboutDialog = remember { mutableStateOf(false) }
- AboutDialog(showAboutDialog)
Column(modifier = Modifier.padding(paddingValues)) {
- val context = LocalContext.current
val scope = rememberCoroutineScope()
+ val uid = icon.applicationInfo.uid
+ val isAllowlistModeInit = Natives.isAllowlistMode()
+
+ val isInAllowDenyListInit = if (isAllowlistModeInit) {
+ Natives.isUidInAllowlist(uid)
+ } else {
+ Natives.isUidInDenylist(uid)
+ }
+
GroupTitle(stringResource(id = R.string.app_profile_title0))
var allowlistMode by rememberSaveable {
- mutableStateOf(true)
+ mutableStateOf(isAllowlistModeInit)
+ }
+
+ var isInAllowDenyList by rememberSaveable {
+ mutableStateOf(isInAllowDenyListInit)
+ }
+
+ val setAllowlistFailedMsg = if (allowlistMode) {
+ stringResource(R.string.failed_to_set_allowlist_mode)
+ } else {
+ stringResource(R.string.failed_to_set_denylist_mode)
}
WorkingMode(allowlistMode) { checked ->
- allowlistMode = !allowlistMode
+ if (Natives.setAllowlistMode(checked)) {
+ allowlistMode = !allowlistMode
+ } else scope.launch {
+ snackbarHost.showSnackbar(setAllowlistFailedMsg)
+ }
}
Divider(thickness = Dp.Hairline)
@@ -122,7 +140,6 @@ fun AppProfileScreen(
}
val failMessage = stringResource(R.string.superuser_failed_to_grant_root)
- val uid = icon.applicationInfo.uid;
AppSwitch(
Icons.Filled.Security,
stringResource(id = R.string.app_profile_root_switch),
@@ -139,6 +156,11 @@ fun AppProfileScreen(
}
}
+ val failedToAddAllowListMsg = if (allowlistMode) {
+ stringResource(R.string.failed_to_add_to_allowlist)
+ } else {
+ stringResource(R.string.failed_to_add_to_denylist)
+ }
AppSwitch(
icon = Icons.Filled.List,
title = if (allowlistMode) {
@@ -146,9 +168,18 @@ fun AppProfileScreen(
} else {
stringResource(id = R.string.app_profile_denylist)
},
- checked = true
- ) {
-
+ checked = isInAllowDenyList
+ ) { checked ->
+ val success = if (allowlistMode) {
+ Natives.addUidToAllowlist(uid)
+ } else {
+ Natives.addUidToDenylist(uid)
+ }
+ if (success) {
+ isInAllowDenyList = checked
+ } else scope.launch {
+ snackbarHost.showSnackbar(failedToAddAllowListMsg.format(label))
+ }
}
Divider(thickness = Dp.Hairline)
diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml
index e4a3a3ff..b7f454d9 100644
--- a/manager/app/src/main/res/values/strings.xml
+++ b/manager/app/src/main/res/values/strings.xml
@@ -73,4 +73,8 @@
Denylist
Global
Working Mode
+ Failed to switch to allowlist mode
+ Failed to add %s to allowlist
+ Failed to add %s to denylist
+ Failed to switch to denylist mode