manager: add support for setting default non root profile.
This commit is contained in:
@@ -87,6 +87,8 @@ Java_me_weishu_kernelsu_Natives_getAppProfile(JNIEnv *env, jobject, jstring pkg,
|
|||||||
env->ReleaseStringUTFChars(pkg, cpkg);
|
env->ReleaseStringUTFChars(pkg, cpkg);
|
||||||
|
|
||||||
app_profile profile = {};
|
app_profile profile = {};
|
||||||
|
profile.version = KSU_APP_PROFILE_VER;
|
||||||
|
|
||||||
strcpy(profile.key, key);
|
strcpy(profile.key, key);
|
||||||
profile.current_uid = uid;
|
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);
|
auto umountModules = env->GetBooleanField(profile, umountModulesField);
|
||||||
|
|
||||||
app_profile p = {};
|
app_profile p = {};
|
||||||
strcpy(p.key, p_key);
|
p.version = KSU_APP_PROFILE_VER;
|
||||||
|
|
||||||
|
strcpy(p.key, p_key);
|
||||||
p.allow_su = allowSu;
|
p.allow_su = allowSu;
|
||||||
p.current_uid = currentUid;
|
p.current_uid = currentUid;
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,11 @@ bool become_manager(const char *);
|
|||||||
|
|
||||||
int get_version();
|
int get_version();
|
||||||
|
|
||||||
bool allow_su(int uid, bool allow);
|
|
||||||
|
|
||||||
bool get_allow_list(int *uids, int *size);
|
bool get_allow_list(int *uids, int *size);
|
||||||
|
|
||||||
bool get_deny_list(int *uids, int *size);
|
|
||||||
|
|
||||||
bool is_safe_mode();
|
bool is_safe_mode();
|
||||||
|
|
||||||
|
#define KSU_APP_PROFILE_VER 1
|
||||||
#define KSU_MAX_PACKAGE_NAME 256
|
#define KSU_MAX_PACKAGE_NAME 256
|
||||||
// NGROUPS_MAX for Linux is 65535 generally, but we only supports 32 groups.
|
// NGROUPS_MAX for Linux is 65535 generally, but we only supports 32 groups.
|
||||||
#define KSU_MAX_GROUPS 32
|
#define KSU_MAX_GROUPS 32
|
||||||
@@ -26,6 +23,8 @@ using p_key_t = char[KSU_MAX_PACKAGE_NAME];
|
|||||||
|
|
||||||
struct app_profile {
|
struct app_profile {
|
||||||
|
|
||||||
|
int32_t version;
|
||||||
|
|
||||||
// this is usually the package of the app, but can be other value for special apps
|
// this is usually the package of the app, but can be other value for special apps
|
||||||
p_key_t key;
|
p_key_t key;
|
||||||
int32_t current_uid;
|
int32_t current_uid;
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ import kotlinx.parcelize.Parcelize
|
|||||||
*/
|
*/
|
||||||
object Natives {
|
object Natives {
|
||||||
// minimal supported kernel version
|
// minimal supported kernel version
|
||||||
// 10915: allowlist breaking change
|
// 10915: allowlist breaking change, add app profile
|
||||||
const val MINIMAL_SUPPORTED_KERNEL = 10916
|
// 10929: app profile struct add 'version' field
|
||||||
|
const val MINIMAL_SUPPORTED_KERNEL = 10929
|
||||||
|
|
||||||
init {
|
init {
|
||||||
System.loadLibrary("kernelsu")
|
System.loadLibrary("kernelsu")
|
||||||
@@ -38,6 +39,27 @@ object Natives {
|
|||||||
external fun getAppProfile(key: String?, uid: Int): Profile
|
external fun getAppProfile(key: String?, uid: Int): Profile
|
||||||
external fun setAppProfile(profile: Profile?): Boolean
|
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 {
|
fun requireNewKernel(): Boolean {
|
||||||
return version < MINIMAL_SUPPORTED_KERNEL
|
return version < MINIMAL_SUPPORTED_KERNEL
|
||||||
}
|
}
|
||||||
@@ -73,6 +95,7 @@ object Natives {
|
|||||||
Global,
|
Global,
|
||||||
Individual,
|
Individual,
|
||||||
}
|
}
|
||||||
constructor(): this("")
|
|
||||||
|
constructor() : this("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||||||
fun SwitchItem(
|
fun SwitchItem(
|
||||||
icon: ImageVector? = null,
|
icon: ImageVector? = null,
|
||||||
title: String,
|
title: String,
|
||||||
|
summary: String? = null,
|
||||||
checked: Boolean,
|
checked: Boolean,
|
||||||
onCheckedChange: (Boolean) -> Unit
|
onCheckedChange: (Boolean) -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -25,6 +26,11 @@ fun SwitchItem(
|
|||||||
trailingContent = {
|
trailingContent = {
|
||||||
Switch(checked = checked, onCheckedChange = onCheckedChange)
|
Switch(checked = checked, onCheckedChange = onCheckedChange)
|
||||||
},
|
},
|
||||||
|
supportingContent = {
|
||||||
|
if (summary != null) {
|
||||||
|
Text(summary)
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,12 @@ import androidx.compose.foundation.clickable
|
|||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
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.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
@@ -18,9 +22,11 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import me.weishu.kernelsu.BuildConfig
|
import me.weishu.kernelsu.BuildConfig
|
||||||
|
import me.weishu.kernelsu.Natives
|
||||||
import me.weishu.kernelsu.R
|
import me.weishu.kernelsu.R
|
||||||
import me.weishu.kernelsu.ui.component.AboutDialog
|
import me.weishu.kernelsu.ui.component.AboutDialog
|
||||||
import me.weishu.kernelsu.ui.component.LoadingDialog
|
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.LocalDialogHost
|
||||||
import me.weishu.kernelsu.ui.util.getBugreportFile
|
import me.weishu.kernelsu.ui.util.getBugreportFile
|
||||||
|
|
||||||
@@ -49,7 +55,23 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val dialogHost = LocalDialogHost.current
|
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(
|
ListItem(
|
||||||
|
leadingContent = { Icon(Icons.Filled.BugReport, stringResource(id = R.string.send_log)) },
|
||||||
headlineContent = { Text(stringResource(id = R.string.send_log)) },
|
headlineContent = { Text(stringResource(id = R.string.send_log)) },
|
||||||
modifier = Modifier.clickable {
|
modifier = Modifier.clickable {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@@ -83,6 +105,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
|
|
||||||
val about = stringResource(id = R.string.about)
|
val about = stringResource(id = R.string.about)
|
||||||
ListItem(
|
ListItem(
|
||||||
|
leadingContent = { Icon(Icons.Filled.ContactPage, stringResource(id = R.string.about)) },
|
||||||
headlineContent = { Text(about) },
|
headlineContent = { Text(about) },
|
||||||
modifier = Modifier.clickable {
|
modifier = Modifier.clickable {
|
||||||
showAboutDialog.value = true
|
showAboutDialog.value = true
|
||||||
|
|||||||
@@ -61,7 +61,10 @@
|
|||||||
<string name="home_support_title">支持开发</string>
|
<string name="home_support_title">支持开发</string>
|
||||||
<string name="home_support_content">KernelSU 将保持免费和开源,向开发者捐赠以表示支持。</string>
|
<string name="home_support_content">KernelSU 将保持免费和开源,向开发者捐赠以表示支持。</string>
|
||||||
<string name="about_source_code"><![CDATA[在 %1$s 查看源码<br/>加入我们的 %2$s 频道<br/>加入我们的 <b><a href="https://pd.qq.com/s/8lipl1brp">QQ 频道</a></b>]]></string>
|
<string name="about_source_code"><![CDATA[在 %1$s 查看源码<br/>加入我们的 %2$s 频道<br/>加入我们的 <b><a href="https://pd.qq.com/s/8lipl1brp">QQ 频道</a></b>]]></string>
|
||||||
|
<string name="profile_unmount_modules">卸载模块</string>
|
||||||
<string name="require_kernel_version">当前内核版本 %d 过低,管理器无法正常工作,请升级内核版本至 %d 或以上!</string>
|
<string name="require_kernel_version">当前内核版本 %d 过低,管理器无法正常工作,请升级内核版本至 %d 或以上!</string>
|
||||||
|
<string name="settings_umount_modules_default">默认卸载模块</string>
|
||||||
|
<string name="settings_umount_modules_default_summary">App Profile 中卸载模块的全局默认值,如果启用,将会为没有设置 Profile 的应用移除所有模块针对系统的修改</string>
|
||||||
<string name="app_profile_title1">应用</string>
|
<string name="app_profile_title1">应用</string>
|
||||||
<string name="app_profile_title0">全局</string>
|
<string name="app_profile_title0">全局</string>
|
||||||
<string name="app_profile_allowlist">白名单</string>
|
<string name="app_profile_allowlist">白名单</string>
|
||||||
|
|||||||
@@ -79,4 +79,6 @@
|
|||||||
<string name="failed_to_update_root_profile">Failed to update root profile for %s</string>
|
<string name="failed_to_update_root_profile">Failed to update root profile for %s</string>
|
||||||
<string name="failed_to_update_app_profile">Failed to update app profile for %s</string>
|
<string name="failed_to_update_app_profile">Failed to update app profile for %s</string>
|
||||||
<string name="require_kernel_version">The current kernel version %d is too low for the manager to function properly. Please upgrade to version %d or higher!</string>
|
<string name="require_kernel_version">The current kernel version %d is too low for the manager to function properly. Please upgrade to version %d or higher!</string>
|
||||||
|
<string name="settings_umount_modules_default">Umount modules by default</string>
|
||||||
|
<string name="settings_umount_modules_default_summary">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.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user