diff --git a/manager/app/src/main/cpp/jni.cc b/manager/app/src/main/cpp/jni.cc index be5ce544..681c0138 100644 --- a/manager/app/src/main/cpp/jni.cc +++ b/manager/app/src/main/cpp/jni.cc @@ -87,6 +87,8 @@ Java_me_weishu_kernelsu_Natives_getAppProfile(JNIEnv *env, jobject, jstring pkg, env->ReleaseStringUTFChars(pkg, cpkg); app_profile profile = {}; + profile.version = KSU_APP_PROFILE_VER; + strcpy(profile.key, key); profile.current_uid = uid; @@ -197,8 +199,9 @@ Java_me_weishu_kernelsu_Natives_setAppProfile(JNIEnv *env, jobject clazz, jobjec auto umountModules = env->GetBooleanField(profile, umountModulesField); app_profile p = {}; - strcpy(p.key, p_key); + p.version = KSU_APP_PROFILE_VER; + strcpy(p.key, p_key); p.allow_su = allowSu; p.current_uid = currentUid; diff --git a/manager/app/src/main/cpp/ksu.h b/manager/app/src/main/cpp/ksu.h index 0926fa55..b7dec766 100644 --- a/manager/app/src/main/cpp/ksu.h +++ b/manager/app/src/main/cpp/ksu.h @@ -9,14 +9,11 @@ bool become_manager(const char *); int get_version(); -bool allow_su(int uid, bool allow); - bool get_allow_list(int *uids, int *size); -bool get_deny_list(int *uids, int *size); - bool is_safe_mode(); +#define KSU_APP_PROFILE_VER 1 #define KSU_MAX_PACKAGE_NAME 256 // NGROUPS_MAX for Linux is 65535 generally, but we only supports 32 groups. #define KSU_MAX_GROUPS 32 @@ -26,6 +23,8 @@ using p_key_t = char[KSU_MAX_PACKAGE_NAME]; struct app_profile { + int32_t version; + // this is usually the package of the app, but can be other value for special apps p_key_t key; int32_t current_uid; diff --git a/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt b/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt index 9e87acd0..c32a1bd5 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt @@ -11,8 +11,9 @@ import kotlinx.parcelize.Parcelize */ object Natives { // minimal supported kernel version - // 10915: allowlist breaking change - const val MINIMAL_SUPPORTED_KERNEL = 10916 + // 10915: allowlist breaking change, add app profile + // 10929: app profile struct add 'version' field + const val MINIMAL_SUPPORTED_KERNEL = 10929 init { System.loadLibrary("kernelsu") @@ -38,6 +39,27 @@ object Natives { external fun getAppProfile(key: String?, uid: Int): Profile external fun setAppProfile(profile: Profile?): Boolean + private const val NON_ROOT_DEFAULT_PROFILE_KEY = "$" + private const val ROOT_DEFAULT_PROFILE_KEY = "#" + private const val NOBODY_UID = 9999 + + fun setDefaultUmountModules(umountModules: Boolean): Boolean { + Profile( + NON_ROOT_DEFAULT_PROFILE_KEY, + NOBODY_UID, + false, + umountModules = umountModules + ).let { + return setAppProfile(it) + } + } + + fun isDefaultUmountModules(): Boolean { + getAppProfile(NON_ROOT_DEFAULT_PROFILE_KEY, NOBODY_UID).let { + return it.umountModules + } + } + fun requireNewKernel(): Boolean { return version < MINIMAL_SUPPORTED_KERNEL } @@ -73,6 +95,7 @@ object Natives { Global, Individual, } - constructor(): this("") + + constructor() : this("") } } \ No newline at end of file diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/component/SettingsItem.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/component/SettingsItem.kt index ab62136e..7143b23e 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/component/SettingsItem.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/component/SettingsItem.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.graphics.vector.ImageVector fun SwitchItem( icon: ImageVector? = null, title: String, + summary: String? = null, checked: Boolean, onCheckedChange: (Boolean) -> Unit ) { @@ -25,6 +26,11 @@ fun SwitchItem( trailingContent = { Switch(checked = checked, onCheckedChange = onCheckedChange) }, + supportingContent = { + if (summary != null) { + Text(summary) + } + } ) } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt index 88477319..03216b5e 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt @@ -6,8 +6,12 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.BugReport +import androidx.compose.material.icons.filled.ContactPage +import androidx.compose.material.icons.filled.RemoveModerator import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -18,9 +22,11 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import me.weishu.kernelsu.BuildConfig +import me.weishu.kernelsu.Natives import me.weishu.kernelsu.R import me.weishu.kernelsu.ui.component.AboutDialog import me.weishu.kernelsu.ui.component.LoadingDialog +import me.weishu.kernelsu.ui.component.SwitchItem import me.weishu.kernelsu.ui.util.LocalDialogHost import me.weishu.kernelsu.ui.util.getBugreportFile @@ -49,7 +55,23 @@ fun SettingScreen(navigator: DestinationsNavigator) { val context = LocalContext.current val scope = rememberCoroutineScope() val dialogHost = LocalDialogHost.current + + var umountChecked by rememberSaveable { + mutableStateOf(Natives.isDefaultUmountModules()) + } + SwitchItem( + icon = Icons.Filled.RemoveModerator, + title = stringResource(id = R.string.settings_umount_modules_default), + summary = stringResource(id = R.string.settings_umount_modules_default_summary), + checked = umountChecked + ) { + if (Natives.setDefaultUmountModules(it)) { + umountChecked = it + } + } + ListItem( + leadingContent = { Icon(Icons.Filled.BugReport, stringResource(id = R.string.send_log)) }, headlineContent = { Text(stringResource(id = R.string.send_log)) }, modifier = Modifier.clickable { scope.launch { @@ -83,6 +105,7 @@ fun SettingScreen(navigator: DestinationsNavigator) { val about = stringResource(id = R.string.about) ListItem( + leadingContent = { Icon(Icons.Filled.ContactPage, stringResource(id = R.string.about)) }, headlineContent = { Text(about) }, modifier = Modifier.clickable { showAboutDialog.value = true diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index 96d85297..db885b8a 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -61,7 +61,10 @@ 支持开发 KernelSU 将保持免费和开源,向开发者捐赠以表示支持。 加入我们的 %2$s 频道
加入我们的 QQ 频道]]>
+ 卸载模块 当前内核版本 %d 过低,管理器无法正常工作,请升级内核版本至 %d 或以上! + 默认卸载模块 + App Profile 中卸载模块的全局默认值,如果启用,将会为没有设置 Profile 的应用移除所有模块针对系统的修改 应用 全局 白名单 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index a2ada6c8..a9965745 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -79,4 +79,6 @@ Failed to update root profile for %s Failed to update app profile for %s The current kernel version %d is too low for the manager to function properly. Please upgrade to version %d or higher! + Umount modules by default + The global default value for uninstalling modules in App Profiles. If enabled, it will remove all module modifications to the system for applications that do not have a Profile set.