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 3d4e0e48b4
commit e3ef521de5
11 changed files with 881 additions and 46 deletions

View File

@@ -24,6 +24,7 @@ import androidx.compose.material.icons.rounded.DeveloperMode
import androidx.compose.material.icons.rounded.EnhancedEncryption
import androidx.compose.material.icons.rounded.Fence
import androidx.compose.material.icons.rounded.FolderDelete
import androidx.compose.material.icons.rounded.Palette
import androidx.compose.material.icons.rounded.RemoveCircle
import androidx.compose.material.icons.rounded.RemoveModerator
import androidx.compose.material.icons.rounded.RestartAlt
@@ -33,6 +34,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
@@ -66,6 +68,7 @@ import com.sukisu.ultra.ui.component.SendLogDialog
import com.sukisu.ultra.ui.component.UninstallDialog
import com.sukisu.ultra.ui.component.rememberLoadingDialog
import com.sukisu.ultra.ui.util.execKsud
import com.sukisu.ultra.ui.util.getFeatureStatus
import com.sukisu.ultra.ui.util.rememberKpmAvailable
import top.yukonga.miuix.kmp.basic.Card
import top.yukonga.miuix.kmp.basic.Icon
@@ -317,9 +320,17 @@ fun SettingPager(
}
)
}
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(
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(
@@ -329,6 +340,7 @@ fun SettingPager(
tint = colorScheme.onBackground
)
},
enabled = enhancedStatus == "supported",
selectedIndex = enhancedSecurityMode,
onSelectedIndexChange = { index ->
when (index) {
@@ -367,9 +379,17 @@ fun SettingPager(
}
)
}
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(
title = stringResource(id = R.string.settings_disable_su),
summary = stringResource(id = R.string.settings_disable_su_summary),
summary = suSummary,
items = modeItems,
leftAction = {
Icon(
@@ -379,6 +399,7 @@ fun SettingPager(
tint = colorScheme.onBackground
)
},
enabled = suStatus == "supported",
selectedIndex = suCompatMode,
onSelectedIndexChange = { index ->
when (index) {
@@ -417,9 +438,17 @@ fun SettingPager(
}
)
}
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(
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(
@@ -429,6 +458,7 @@ fun SettingPager(
tint = colorScheme.onBackground
)
},
enabled = umountStatus == "supported",
selectedIndex = kernelUmountMode,
onSelectedIndexChange = { index ->
when (index) {
@@ -458,7 +488,7 @@ fun SettingPager(
}
)
var SuLogMode by rememberSaveable {
var suLogMode by rememberSaveable {
mutableIntStateOf(
run {
val currentEnabled = Natives.isSuLogEnabled()
@@ -467,9 +497,17 @@ fun SettingPager(
}
)
}
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(
title = stringResource(id = R.string.settings_disable_sulog),
summary = stringResource(id = R.string.settings_disable_sulog_summary),
summary = suLogSummary,
items = modeItems,
leftAction = {
Icon(
@@ -479,14 +517,15 @@ fun SettingPager(
tint = colorScheme.onBackground
)
},
selectedIndex = SuLogMode,
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("sulog_mode", 0) }
SuLogMode = 0
suLogMode = 0
isSuLogEnabled = true
}
@@ -495,7 +534,7 @@ fun SettingPager(
execKsud("feature save", true)
if (Natives.setSuLogEnabled(false)) {
prefs.edit { putInt("sulog_mode", 0) }
SuLogMode = 1
suLogMode = 1
isSuLogEnabled = false
}
}
@@ -504,7 +543,7 @@ fun SettingPager(
2 -> if (Natives.setSuLogEnabled(false)) {
execKsud("feature save", true)
prefs.edit { putInt("sulog_mode", 2) }
SuLogMode = 2
suLogMode = 2
isSuLogEnabled = false
}
}

View File

@@ -108,6 +108,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
@@ -118,8 +125,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

@@ -144,6 +144,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

@@ -148,6 +148,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>