userspace: add feature get --config

* fix #2980
This commit is contained in:
YuKongA
2025-11-27 14:17:25 +08:00
committed by shirkneko
parent de04ea9db0
commit 46cfd936a0
4 changed files with 78 additions and 33 deletions

View File

@@ -31,6 +31,7 @@ import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material.icons.rounded.Update
import androidx.compose.material.icons.rounded.UploadFile
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
@@ -72,6 +73,7 @@ import com.sukisu.ultra.ui.util.execKsud
import com.sukisu.ultra.ui.util.getFeatureStatus
import com.sukisu.ultra.ui.util.getSuSFSFeatures
import com.sukisu.ultra.ui.util.rememberKpmAvailable
import com.sukisu.ultra.ui.util.getFeaturePersistValue
import top.yukonga.miuix.kmp.basic.Card
import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior
@@ -344,14 +346,15 @@ fun SettingPager(
stringResource(id = R.string.settings_mode_temp_enable),
stringResource(id = R.string.settings_mode_always_enable),
)
var enhancedSecurityMode by rememberSaveable {
mutableIntStateOf(
run {
val currentEnabled = Natives.isEnhancedSecurityEnabled()
val savedPersist = prefs.getInt("enhanced_security_mode", 0)
if (savedPersist == 2) 2 else if (currentEnabled) 1 else 0
}
)
val currentEnhancedEnabled = Natives.isEnhancedSecurityEnabled()
var enhancedSecurityMode by rememberSaveable { mutableIntStateOf(if (currentEnhancedEnabled) 1 else 0) }
val enhancedPersistValue by produceState(initialValue = null as Long?) {
value = getFeaturePersistValue("enhanced_security")
}
LaunchedEffect(enhancedPersistValue) {
enhancedPersistValue?.let { v ->
enhancedSecurityMode = if (v != 0L) 2 else if (currentEnhancedEnabled) 1 else 0
}
}
val enhancedStatus by produceState(initialValue = "") {
value = getFeatureStatus("enhanced_security")
@@ -403,14 +406,15 @@ fun SettingPager(
}
)
var suCompatMode by rememberSaveable {
mutableIntStateOf(
run {
val currentEnabled = Natives.isSuEnabled()
val savedPersist = prefs.getInt("su_compat_mode", 0)
if (savedPersist == 2) 2 else if (!currentEnabled) 1 else 0
}
)
val currentSuEnabled = Natives.isSuEnabled()
var suCompatMode by rememberSaveable { mutableIntStateOf(if (!currentSuEnabled) 1 else 0) }
val suPersistValue by produceState(initialValue = null as Long?) {
value = getFeaturePersistValue("su_compat")
}
LaunchedEffect(suPersistValue) {
suPersistValue?.let { v ->
suCompatMode = if (v == 0L) 2 else if (!currentSuEnabled) 1 else 0
}
}
val suStatus by produceState(initialValue = "") {
value = getFeatureStatus("su_compat")
@@ -462,14 +466,15 @@ fun SettingPager(
}
)
var kernelUmountMode by rememberSaveable {
mutableIntStateOf(
run {
val currentEnabled = Natives.isKernelUmountEnabled()
val savedPersist = prefs.getInt("kernel_umount_mode", 0)
if (savedPersist == 2) 2 else if (!currentEnabled) 1 else 0
}
)
val currentUmountEnabled = Natives.isKernelUmountEnabled()
var kernelUmountMode by rememberSaveable { mutableIntStateOf(if (!currentUmountEnabled) 1 else 0) }
val umountPersistValue by produceState(initialValue = null as Long?) {
value = getFeaturePersistValue("kernel_umount")
}
LaunchedEffect(umountPersistValue) {
umountPersistValue?.let { v ->
kernelUmountMode = if (v == 0L) 2 else if (!currentUmountEnabled) 1 else 0
}
}
val umountStatus by produceState(initialValue = "") {
value = getFeatureStatus("kernel_umount")
@@ -521,14 +526,15 @@ fun SettingPager(
}
)
var suLogMode by rememberSaveable {
mutableIntStateOf(
run {
val currentEnabled = Natives.isSuLogEnabled()
val savedPersist = prefs.getInt("sulog_mode", 0)
if (savedPersist == 2) 2 else if (!currentEnabled) 1 else 0
}
)
val currentsuLogEnabled = Natives.isSuLogEnabled()
var suLogMode by rememberSaveable { mutableIntStateOf(if (currentsuLogEnabled) 1 else 0) }
val suLogPersistValue by produceState(initialValue = null as Long?) {
value = getFeaturePersistValue("sulog_mode")
}
LaunchedEffect(suLogPersistValue) {
suLogPersistValue?.let { v ->
suLogMode = if (v != 0L) 2 else if (currentsuLogEnabled) 1 else 0
}
}
val suLogStatus by produceState(initialValue = "") {
value = getFeatureStatus("sulog")

View File

@@ -115,6 +115,14 @@ suspend fun getFeatureStatus(feature: String): String = withContext(Dispatchers.
out.firstOrNull()?.trim().orEmpty()
}
suspend fun getFeaturePersistValue(feature: String): Long? = withContext(Dispatchers.IO) {
val shell = getRootShell()
val out = shell.newJob()
.add("${getKsuDaemonPath()} feature get --config $feature").to(ArrayList<String>(), null).exec().out
val valueLine = out.firstOrNull { it.trim().startsWith("Value:") } ?: return@withContext null
valueLine.substringAfter("Value:").trim().toLongOrNull()
}
fun install() {
val start = SystemClock.elapsedRealtime()
val magiskboot = File(ksuApp.applicationInfo.nativeLibraryDir, "libmagiskboot.so").absolutePath

View File

@@ -347,6 +347,9 @@ enum Feature {
Get {
/// Feature ID or name (su_compat, kernel_umount)
id: String,
/// Read from config file
#[arg(long, default_value_t = false)]
config: bool,
},
/// Set feature value
@@ -620,7 +623,13 @@ pub fn run() -> Result<()> {
},
Commands::Feature { command } => match command {
Feature::Get { id } => crate::feature::get_feature(&id),
Feature::Get { id, config } => {
if config {
crate::feature::get_feature_config(&id)
} else {
crate::feature::get_feature(&id)
}
}
Feature::Set { id, value } => crate::feature::set_feature(&id, value),
Feature::List => {
crate::feature::list_features();

View File

@@ -198,6 +198,28 @@ pub fn get_feature(id: &str) -> Result<()> {
Ok(())
}
pub fn get_feature_config(id: &str) -> Result<()> {
let feature_id = parse_feature_id(id)?;
let features = load_binary_config()?;
let id_u32 = feature_id as u32;
println!("Feature: {} ({})", feature_id.name(), id_u32);
println!("Description: {}", feature_id.description());
if let Some(value) = features.get(&id_u32) {
println!("Value: {value}");
println!(
"Status: {}",
if *value != 0 { "enabled" } else { "disabled" }
);
} else {
println!("Not set in config");
}
Ok(())
}
pub fn set_feature(id: &str, value: u64) -> Result<()> {
let feature_id = parse_feature_id(id)?;