diff --git a/manager/app/src/main/assets/ksu_susfs_1.5.8 b/manager/app/src/main/assets/ksu_susfs_1.5.8 index 3e30376a..21df7ed0 100644 Binary files a/manager/app/src/main/assets/ksu_susfs_1.5.8 and b/manager/app/src/main/assets/ksu_susfs_1.5.8 differ diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigTabs.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigTabs.kt index 67f26bd4..dd350e3c 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigTabs.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigTabs.kt @@ -19,6 +19,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Folder import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material.icons.filled.Security import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Storage import androidx.compose.material3.Button @@ -27,6 +28,7 @@ import androidx.compose.material3.CardDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -34,6 +36,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import com.sukisu.ultra.R import com.sukisu.ultra.ui.screen.extensions.AddKstatPathItemCard import com.sukisu.ultra.ui.screen.extensions.EmptyStateCard @@ -42,6 +45,7 @@ import com.sukisu.ultra.ui.screen.extensions.KstatConfigItemCard import com.sukisu.ultra.ui.screen.extensions.PathItemCard import com.sukisu.ultra.ui.screen.extensions.SusMountHidingControlCard import com.sukisu.ultra.ui.util.SuSFSManager +import com.sukisu.ultra.ui.util.SuSFSManager.isSusVersion_1_5_8 /** * SUS路径内容组件 @@ -190,11 +194,13 @@ fun SusMountsContent( @Composable fun TryUmountContent( tryUmounts: Set, + umountForZygoteIsoService: Boolean, isLoading: Boolean, onAddUmount: () -> Unit, onRunUmount: () -> Unit, onRemoveUmount: (String) -> Unit, - onEditUmount: ((String) -> Unit)? = null + onEditUmount: ((String) -> Unit)? = null, + onToggleUmountForZygoteIsoService: (Boolean) -> Unit ) { Box(modifier = Modifier.fillMaxSize()) { LazyColumn( @@ -202,6 +208,60 @@ fun TryUmountContent( .fillMaxSize(), verticalArrangement = Arrangement.spacedBy(12.dp) ) { + if (isSusVersion_1_5_8()) { + item { + Card( + modifier = Modifier.fillMaxWidth(), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surface + ), + shape = RoundedCornerShape(12.dp) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(12.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Column( + modifier = Modifier.weight(1f) + ) { + Row( + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + imageVector = Icons.Default.Security, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(18.dp) + ) + Spacer(modifier = Modifier.width(8.dp)) + Text( + text = stringResource(R.string.umount_zygote_iso_service), + style = MaterialTheme.typography.titleMedium, + fontWeight = FontWeight.Medium, + color = MaterialTheme.colorScheme.onSurface + ) + } + Spacer(modifier = Modifier.height(6.dp)) + Text( + text = stringResource(R.string.umount_zygote_iso_service_description), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + lineHeight = 14.sp + ) + } + Switch( + checked = umountForZygoteIsoService, + onCheckedChange = onToggleUmountForZygoteIsoService, + enabled = !isLoading + ) + } + } + } + } + if (tryUmounts.isEmpty()) { item { EmptyStateCard( diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/SuSFSConfig.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/SuSFSConfig.kt index 831e26c8..7c6575f9 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/SuSFSConfig.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/SuSFSConfig.kt @@ -148,6 +148,8 @@ fun SuSFSConfigScreen( // SUS挂载隐藏控制状态 var hideSusMountsForAllProcs by remember { mutableStateOf(true) } + var umountForZygoteIsoService by remember { mutableStateOf(false) } + // Kstat配置相关状态 var kstatConfigs by remember { mutableStateOf(emptySet()) } var addKstatPaths by remember { mutableStateOf(emptySet()) } @@ -287,6 +289,7 @@ fun SuSFSConfigScreen( hideSusMountsForAllProcs = SuSFSManager.getHideSusMountsForAllProcs(context) enableHideBl = SuSFSManager.getEnableHideBl(context) enableCleanupResidue = SuSFSManager.getEnableCleanupResidue(context) + umountForZygoteIsoService = SuSFSManager.getUmountForZygoteIsoService(context) loadSlotInfo() } @@ -455,6 +458,7 @@ fun SuSFSConfigScreen( hideSusMountsForAllProcs = SuSFSManager.getHideSusMountsForAllProcs(context) enableHideBl = SuSFSManager.getEnableHideBl(context) enableCleanupResidue = SuSFSManager.getEnableCleanupResidue(context) + umountForZygoteIsoService = SuSFSManager.getUmountForZygoteIsoService(context) } isLoading = false showRestoreConfirmDialog = false @@ -1171,6 +1175,7 @@ fun SuSFSConfigScreen( SuSFSTab.TRY_UMOUNT -> { TryUmountContent( tryUmounts = tryUmounts, + umountForZygoteIsoService = umountForZygoteIsoService, isLoading = isLoading, onAddUmount = { showAddUmountDialog = true }, onRunUmount = { showRunUmountDialog = true }, @@ -1186,9 +1191,20 @@ fun SuSFSConfigScreen( onEditUmount = { umountEntry -> editingUmount = umountEntry showAddUmountDialog = true + }, + onToggleUmountForZygoteIsoService = { enabled -> + coroutineScope.launch { + isLoading = true + val success = SuSFSManager.setUmountForZygoteIsoService(context, enabled) + if (success) { + umountForZygoteIsoService = enabled + } + isLoading = false + } } ) } + SuSFSTab.KSTAT_CONFIG -> { KstatConfigContent( kstatConfigs = kstatConfigs, diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt index 1d76d8de..5284b066 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt @@ -41,6 +41,7 @@ object SuSFSManager { private const val KEY_HIDE_SUS_MOUNTS_FOR_ALL_PROCS = "hide_sus_mounts_for_all_procs" private const val KEY_ENABLE_CLEANUP_RESIDUE = "enable_cleanup_residue" private const val KEY_ENABLE_HIDE_BL = "enable_hide_bl" + private const val KEY_UMOUNT_FOR_ZYGOTE_ISO_SERVICE = "umount_for_zygote_iso_service" // 常量 @@ -134,7 +135,8 @@ object SuSFSManager { val hideSusMountsForAllProcs: Boolean, val support158: Boolean, val enableHideBl: Boolean, - val enableCleanupResidue: Boolean + val enableCleanupResidue: Boolean, + val umountForZygoteIsoService: Boolean ) { /** * 检查是否有需要自启动的配置 @@ -229,6 +231,7 @@ object SuSFSManager { support158 = isSusVersion_1_5_8(), enableHideBl = getEnableHideBl(context), enableCleanupResidue = getEnableCleanupResidue(context), + umountForZygoteIsoService = getUmountForZygoteIsoService(context), ) } @@ -291,6 +294,14 @@ object SuSFSManager { fun getEnableCleanupResidue(context: Context): Boolean = getPrefs(context).getBoolean(KEY_ENABLE_CLEANUP_RESIDUE, false) + // Zygote隔离服务卸载控制 + fun saveUmountForZygoteIsoService(context: Context, enabled: Boolean) = + getPrefs(context).edit { putBoolean(KEY_UMOUNT_FOR_ZYGOTE_ISO_SERVICE, enabled) } + + fun getUmountForZygoteIsoService(context: Context): Boolean = + getPrefs(context).getBoolean(KEY_UMOUNT_FOR_ZYGOTE_ISO_SERVICE, false) + + // 路径和配置管理 fun saveSusPaths(context: Context, paths: Set) = getPrefs(context).edit { putStringSet(KEY_SUS_PATHS, paths) } @@ -355,7 +366,8 @@ object SuSFSManager { KEY_ADD_KSTAT_PATHS to getAddKstatPaths(context), KEY_HIDE_SUS_MOUNTS_FOR_ALL_PROCS to getHideSusMountsForAllProcs(context), KEY_ENABLE_HIDE_BL to getEnableHideBl(context), - KEY_ENABLE_CLEANUP_RESIDUE to getEnableCleanupResidue(context) + KEY_ENABLE_CLEANUP_RESIDUE to getEnableCleanupResidue(context), + KEY_UMOUNT_FOR_ZYGOTE_ISO_SERVICE to getUmountForZygoteIsoService(context), ) } @@ -880,6 +892,29 @@ object SuSFSManager { suspend fun runTryUmount(context: Context): Boolean = executeSusfsCommand(context, "run_try_umount") + // Zygote隔离服务卸载控制 + suspend fun setUmountForZygoteIsoService(context: Context, enabled: Boolean): Boolean { + if (!isSusVersion_1_5_8()) { + return false + } + + val result = executeSusfsCommandWithOutput(context, "umount_for_zygote_iso_service ${if (enabled) 1 else 0}") + val success = result.isSuccess && result.output.isEmpty() + + if (success) { + saveUmountForZygoteIsoService(context, enabled) + if (isAutoStartEnabled(context)) updateMagiskModule(context) + showToast(context, if (enabled) + context.getString(R.string.umount_zygote_iso_service_enabled) + else + context.getString(R.string.umount_zygote_iso_service_disabled) + ) + } else { + showToast(context, context.getString(R.string.susfs_command_failed)) + } + return success + } + // 添加kstat配置 suspend fun addKstatStatically(context: Context, path: String, ino: String, dev: String, nlink: String, size: String, atime: String, atimeNsec: String, mtime: String, mtimeNsec: String, diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt index 9a1c136f..c75c0f00 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt @@ -372,10 +372,23 @@ object ScriptGenerator { appendLine() } + generateUmountZygoteIsoServiceSection(config.umountForZygoteIsoService, config.support158) + appendLine("echo \"$(get_current_time): Post-FS-Data脚本执行完成\" >> \"${'$'}LOG_FILE\"") } } + // 添加新的生成方法 + private fun StringBuilder.generateUmountZygoteIsoServiceSection(umountForZygoteIsoService: Boolean, support158: Boolean) { + if (support158) { + appendLine("# 设置Zygote隔离服务卸载状态") + val umountValue = if (umountForZygoteIsoService) 1 else 0 + appendLine("\"${'$'}SUSFS_BIN\" umount_for_zygote_iso_service $umountValue") + appendLine("echo \"$(get_current_time): Zygote隔离服务卸载设置为: ${if (umountForZygoteIsoService) "启用" else "禁用"}\" >> \"${'$'}LOG_FILE\"") + appendLine() + } + } + /** * 生成post-mount.sh脚本内容 */ diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index 9257a8fe..bd0b14ae 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -553,4 +553,8 @@ Kstat 配置更新 Kstat 路径更新 Susfs 完整克隆更新 + 卸载Zygote隔离服务 + 启用此选项将在系统启动时卸载Zygote隔离服务挂载点 + Zygote隔离服务卸载已启用 + Zygote隔离服务卸载已禁用 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index b10c3c47..54f0d5de 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -555,4 +555,8 @@ Kstat config update Kstat path update Susfs update full clone + Unmount Zygote Isolation Service + Enable this option to unmount Zygote isolation service mount points at system startup + Zygote isolation service unmount enabled + Zygote isolation service unmount disabled