@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user