add module config, migrate managedFeatures (#2965)

Co-authored-by: YuKongA <70465933+YuKongA@users.noreply.github.com>
This commit is contained in:
Ylarod
2025-11-20 21:50:34 +08:00
committed by ShirkNeko
parent de6b2794b7
commit 5a6ab43ea4
11 changed files with 914 additions and 54 deletions

View File

@@ -11,12 +11,10 @@ import androidx.compose.animation.*
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowForward
import androidx.compose.material.icons.automirrored.filled.Undo
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.rounded.EnhancedEncryption
@@ -56,7 +54,6 @@ import com.sukisu.ultra.ui.theme.CardConfig.cardAlpha
import com.sukisu.ultra.ui.theme.getCardColors
import com.sukisu.ultra.ui.theme.getCardElevation
import com.sukisu.ultra.ui.util.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -151,11 +148,28 @@ fun SettingScreen(navigator: DestinationsNavigator) {
}
)
}
val enhancedStatus by produceState(initialValue = "") {
value = getFeatureStatus("enhanced_security")
}
val enhancedSummary = when (enhancedStatus) {
"unsupported" -> stringResource(id = R.string.feature_status_unsupported_summary)
"managed" -> stringResource(id = R.string.feature_status_managed_summary)
else -> stringResource(id = R.string.settings_enable_enhanced_security_summary)
}
SuperDropdown(
icon = Icons.Rounded.EnhancedEncryption,
title = stringResource(id = R.string.settings_enable_enhanced_security),
summary = stringResource(id = R.string.settings_enable_enhanced_security_summary),
summary = enhancedSummary,
items = modeItems,
leftAction = {
Icon(
Icons.Rounded.EnhancedEncryption,
modifier = Modifier.padding(end = 16.dp),
contentDescription = stringResource(id = R.string.settings_enable_enhanced_security),
tint = MaterialTheme.colorScheme.onBackground
)
},
enabled = enhancedStatus == "supported",
selectedIndex = enhancedSecurityMode,
onSelectedIndexChange = { index ->
when (index) {
@@ -194,11 +208,28 @@ fun SettingScreen(navigator: DestinationsNavigator) {
}
)
}
val suStatus by produceState(initialValue = "") {
value = getFeatureStatus("su_compat")
}
val suSummary = when (suStatus) {
"unsupported" -> stringResource(id = R.string.feature_status_unsupported_summary)
"managed" -> stringResource(id = R.string.feature_status_managed_summary)
else -> stringResource(id = R.string.settings_disable_su_summary)
}
SuperDropdown(
icon = Icons.Rounded.RemoveModerator,
title = stringResource(id = R.string.settings_disable_su),
summary = stringResource(id = R.string.settings_disable_su_summary),
summary = suSummary,
items = modeItems,
leftAction = {
Icon(
Icons.Rounded.RemoveModerator,
modifier = Modifier.padding(end = 16.dp),
contentDescription = stringResource(id = R.string.settings_disable_su),
tint = MaterialTheme.colorScheme.onBackground
)
},
enabled = suStatus == "supported",
selectedIndex = suCompatMode,
onSelectedIndexChange = { index ->
when (index) {
@@ -237,11 +268,28 @@ fun SettingScreen(navigator: DestinationsNavigator) {
}
)
}
val umountStatus by produceState(initialValue = "") {
value = getFeatureStatus("kernel_umount")
}
val umountSummary = when (umountStatus) {
"unsupported" -> stringResource(id = R.string.feature_status_unsupported_summary)
"managed" -> stringResource(id = R.string.feature_status_managed_summary)
else -> stringResource(id = R.string.settings_disable_kernel_umount_summary)
}
SuperDropdown(
icon = Icons.Rounded.RemoveCircle,
title = stringResource(id = R.string.settings_disable_kernel_umount),
summary = stringResource(id = R.string.settings_disable_kernel_umount_summary),
summary = umountSummary,
items = modeItems,
leftAction = {
Icon(
Icons.Rounded.RemoveCircle,
modifier = Modifier.padding(end = 16.dp),
contentDescription = stringResource(id = R.string.settings_disable_kernel_umount),
tint = MaterialTheme.colorScheme.onBackground
)
},
enabled = umountStatus == "supported",
selectedIndex = kernelUmountMode,
onSelectedIndexChange = { index ->
when (index) {
@@ -271,28 +319,44 @@ fun SettingScreen(navigator: DestinationsNavigator) {
}
)
var kernelSuLogMode by rememberSaveable {
var suLogMode by rememberSaveable {
mutableIntStateOf(
run {
val currentEnabled = Natives.isSuLogEnabled()
val savedPersist = prefs.getInt("kernel_sulog_mode", 0)
val savedPersist = prefs.getInt("sulog_mode", 0)
if (savedPersist == 2) 2 else if (!currentEnabled) 1 else 0
}
)
}
val suLogStatus by produceState(initialValue = "") {
value = getFeatureStatus("sulog")
}
val suLogSummary = when (suLogStatus) {
"unsupported" -> stringResource(id = R.string.feature_status_unsupported_summary)
"managed" -> stringResource(id = R.string.feature_status_managed_summary)
else -> stringResource(id = R.string.settings_disable_sulog_summary)
}
SuperDropdown(
icon = Icons.Filled.NoAccounts,
title = stringResource(id = R.string.settings_disable_sulog),
summary = stringResource(id = R.string.settings_disable_sulog_summary),
summary = suLogSummary,
items = modeItems,
selectedIndex = kernelSuLogMode,
leftAction = {
Icon(
Icons.Rounded.RemoveCircle,
modifier = Modifier.padding(end = 16.dp),
contentDescription = stringResource(id = R.string.settings_disable_sulog),
tint = MaterialTheme.colorScheme.onBackground
)
},
enabled = suLogStatus == "supported",
selectedIndex = suLogMode,
onSelectedIndexChange = { index ->
when (index) {
// Default: enable and save to persist
0 -> if (Natives.setSuLogEnabled(true)) {
execKsud("feature save", true)
prefs.edit { putInt("kernel_sulog_mode", 0) }
kernelSuLogMode = 0
prefs.edit { putInt("sulog_mode", 0) }
suLogMode = 0
isSuLogEnabled = true
}
@@ -300,8 +364,8 @@ fun SettingScreen(navigator: DestinationsNavigator) {
1 -> if (Natives.setSuLogEnabled(true)) {
execKsud("feature save", true)
if (Natives.setSuLogEnabled(false)) {
prefs.edit { putInt("kernel_sulog_mode", 0) }
kernelSuLogMode = 1
prefs.edit { putInt("sulog_mode", 0) }
suLogMode = 1
isSuLogEnabled = false
}
}
@@ -309,8 +373,8 @@ fun SettingScreen(navigator: DestinationsNavigator) {
// Permanently disable: disable and save
2 -> if (Natives.setSuLogEnabled(false)) {
execKsud("feature save", true)
prefs.edit { putInt("kernel_sulog_mode", 2) }
kernelSuLogMode = 2
prefs.edit { putInt("sulog_mode", 2) }
suLogMode = 2
isSuLogEnabled = false
}
}

View File

@@ -97,6 +97,13 @@ fun execKsud(args: String, newShell: Boolean = false): Boolean {
}
}
suspend fun getFeatureStatus(feature: String): String = withContext(Dispatchers.IO) {
val shell = getRootShell()
val out = shell.newJob()
.add("${getKsuDaemonPath()} feature check $feature").to(ArrayList<String>(), null).exec().out
out.firstOrNull()?.trim().orEmpty()
}
fun install() {
val start = SystemClock.elapsedRealtime()
val magiskboot = File(ksuApp.applicationInfo.nativeLibraryDir, "libmagiskboot.so").absolutePath
@@ -107,8 +114,8 @@ fun install() {
fun listModules(): String {
val shell = getRootShell()
val out =
shell.newJob().add("${getKsuDaemonPath()} module list").to(ArrayList(), null).exec().out
val out = shell.newJob()
.add("${getKsuDaemonPath()} module list").to(ArrayList(), null).exec().out
return out.joinToString("\n").ifBlank { "[]" }
}

View File

@@ -168,6 +168,8 @@
<string name="settings_disable_kernel_umount_summary">关闭 KernelSU 控制的内核级 umount 行为。</string>
<string name="settings_enable_enhanced_security">增强安全性</string>
<string name="settings_enable_enhanced_security_summary">使用更严格的安全策略。</string>
<string name="feature_status_unsupported_summary">内核不支持此功能。</string>
<string name="feature_status_managed_summary">此功能由模块管理。</string>
<string name="settings_mode_default">默认</string>
<string name="settings_mode_temp_enable">临时启用</string>
<string name="settings_mode_always_enable">始终启用</string>

View File

@@ -170,6 +170,8 @@
<string name="settings_disable_kernel_umount_summary">Disable kernel-level umount behavior controlled by KernelSU.</string>
<string name="settings_enable_enhanced_security">Enable enhanced security</string>
<string name="settings_enable_enhanced_security_summary">Enable stricter security policies.</string>
<string name="feature_status_unsupported_summary">Kernel does not support this feature.</string>
<string name="feature_status_managed_summary">This feature is managed by a module.</string>
<string name="settings_mode_default">Default</string>
<string name="settings_mode_temp_enable">Temporarily enable</string>
<string name="settings_mode_always_enable">Permanently enable</string>