From 2c1beac1ca1b2500947b8ce6a3aafd2f69cb4c1f Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Sun, 23 Nov 2025 23:51:40 +0800 Subject: [PATCH] manager: Updated the susfs binary file - made the umount manager publicly available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - and removed the “try umount” functionality - susfs interface and fixed path issues (on Android 16). --- manager/app/src/main/assets/ksu_susfs_2.0.0 | Bin 21048 -> 20088 bytes .../com/sukisu/ultra/ui/screen/Settings.kt | 21 +- .../com/sukisu/ultra/ui/susfs/SuSFSConfig.kt | 179 +++++++----------- .../ui/susfs/component/SuSFSConfigDialogs.kt | 120 ------------ .../ui/susfs/component/SuSFSConfigTabs.kt | 130 +------------ .../ultra/ui/susfs/util/SuSFSManager.kt | 108 ++++------- .../ultra/ui/susfs/util/SuSFSModuleScripts.kt | 15 -- .../main/jniLibs/arm64-v8a/libksu_susfs.so | Bin 21048 -> 20088 bytes .../app/src/main/res/values-idn/strings.xml | 14 -- .../app/src/main/res/values-in/strings.xml | 15 -- .../app/src/main/res/values-ja/strings.xml | 15 -- .../app/src/main/res/values-ru/strings.xml | 15 -- .../app/src/main/res/values-tr/strings.xml | 15 -- .../app/src/main/res/values-uk/strings.xml | 14 -- .../app/src/main/res/values-vi/strings.xml | 15 -- .../src/main/res/values-zh-rCN/strings.xml | 15 -- .../src/main/res/values-zh-rHK/strings.xml | 15 -- .../src/main/res/values-zh-rTW/strings.xml | 15 -- manager/app/src/main/res/values/strings.xml | 15 -- 19 files changed, 118 insertions(+), 618 deletions(-) diff --git a/manager/app/src/main/assets/ksu_susfs_2.0.0 b/manager/app/src/main/assets/ksu_susfs_2.0.0 index 854b3a19f3f2e0611092100494234fd4e074ab0f..b020e7a6ad16ca2d3810fabb259c230e4f323099 100644 GIT binary patch delta 6305 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 NM83NzmaHw&{RfWC{U!ha delta 7102 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 G=6?Ztw?k()) } var susLoopPaths by remember { mutableStateOf(emptySet()) } var susMaps by remember { mutableStateOf(emptySet()) } - var tryUmounts by remember { mutableStateOf(emptySet()) } var androidDataPath by remember { mutableStateOf("") } var sdcardPath by remember { mutableStateOf("") } @@ -123,7 +121,6 @@ fun SuSFSConfigScreen( var showAddLoopPathDialog by remember { mutableStateOf(false) } var showAddSusMapDialog by remember { mutableStateOf(false) } var showAddAppPathDialog by remember { mutableStateOf(false) } - var showAddUmountDialog by remember { mutableStateOf(false) } var showAddKstatStaticallyDialog by remember { mutableStateOf(false) } var showAddKstatDialog by remember { mutableStateOf(false) } @@ -131,7 +128,6 @@ fun SuSFSConfigScreen( var editingPath by remember { mutableStateOf(null) } var editingLoopPath by remember { mutableStateOf(null) } var editingSusMap by remember { mutableStateOf(null) } - var editingUmount by remember { mutableStateOf(null) } var editingKstatConfig by remember { mutableStateOf(null) } var editingKstatPath by remember { mutableStateOf(null) } @@ -139,7 +135,6 @@ fun SuSFSConfigScreen( var showResetPathsDialog by remember { mutableStateOf(false) } var showResetLoopPathsDialog by remember { mutableStateOf(false) } var showResetSusMapsDialog by remember { mutableStateOf(false) } - var showResetUmountsDialog by remember { mutableStateOf(false) } var showResetKstatDialog by remember { mutableStateOf(false) } // 备份还原相关状态 @@ -299,7 +294,6 @@ fun SuSFSConfigScreen( susPaths = SuSFSManager.getSusPaths(context) susLoopPaths = SuSFSManager.getSusLoopPaths(context) susMaps = SuSFSManager.getSusMaps(context) - tryUmounts = SuSFSManager.getTryUmounts(context) androidDataPath = SuSFSManager.getAndroidDataPath(context) sdcardPath = SuSFSManager.getSdcardPath(context) kstatConfigs = SuSFSManager.getKstatConfigs(context) @@ -471,7 +465,6 @@ fun SuSFSConfigScreen( susPaths = SuSFSManager.getSusPaths(context) susLoopPaths = SuSFSManager.getSusLoopPaths(context) susMaps = SuSFSManager.getSusMaps(context) - tryUmounts = SuSFSManager.getTryUmounts(context) androidDataPath = SuSFSManager.getAndroidDataPath(context) sdcardPath = SuSFSManager.getSdcardPath(context) kstatConfigs = SuSFSManager.getKstatConfigs(context) @@ -642,33 +635,6 @@ fun SuSFSConfigScreen( existingSusPaths = susPaths ) - AddTryUmountDialog( - showDialog = showAddUmountDialog, - onDismiss = { - showAddUmountDialog = false - editingUmount = null - }, - onConfirm = { path, mode -> - coroutineScope.launch { - isLoading = true - val success = if (editingUmount != null) { - SuSFSManager.editTryUmount(context, editingUmount!!, path, mode) - } else { - SuSFSManager.addTryUmount(context, path, mode) - } - if (success) { - tryUmounts = SuSFSManager.getTryUmounts(context) - } - isLoading = false - showAddUmountDialog = false - editingUmount = null - } - }, - isLoading = isLoading, - initialPath = editingUmount?.split("|")?.get(0) ?: "", - initialMode = editingUmount?.split("|")?.get(1)?.toIntOrNull() ?: 0 - ) - AddKstatStaticallyDialog( showDialog = showAddKstatStaticallyDialog, onDismiss = { @@ -829,27 +795,6 @@ fun SuSFSConfigScreen( isDestructive = true ) - ConfirmDialog( - showDialog = showResetUmountsDialog, - onDismiss = { showResetUmountsDialog = false }, - onConfirm = { - coroutineScope.launch { - isLoading = true - SuSFSManager.saveTryUmounts(context, emptySet()) - tryUmounts = emptySet() - if (SuSFSManager.isAutoStartEnabled(context)) { - SuSFSManager.configureAutoStart(context, true) - } - isLoading = false - showResetUmountsDialog = false - } - }, - titleRes = R.string.susfs_reset_umounts_title, - messageRes = R.string.susfs_reset_umounts_message, - isLoading = isLoading, - isDestructive = true - ) - ConfirmDialog( showDialog = showResetKstatDialog, onDismiss = { showResetKstatDialog = false }, @@ -1049,28 +994,6 @@ fun SuSFSConfigScreen( } } - SuSFSTab.TRY_UMOUNT -> { - OutlinedButton( - onClick = { showResetUmountsDialog = true }, - enabled = !isLoading && tryUmounts.isNotEmpty(), - shape = RoundedCornerShape(8.dp), - modifier = Modifier - .fillMaxWidth() - .height(40.dp) - ) { - Icon( - imageVector = Icons.Default.RestoreFromTrash, - contentDescription = null, - modifier = Modifier.size(16.dp) - ) - Spacer(modifier = Modifier.width(6.dp)) - Text( - stringResource(R.string.susfs_reset_umounts_title), - fontWeight = FontWeight.Medium - ) - } - } - SuSFSTab.KSTAT_CONFIG -> { OutlinedButton( onClick = { showResetKstatDialog = true }, @@ -1260,6 +1183,18 @@ fun SuSFSConfigScreen( } isLoading = false } + }, + umountForZygoteIsoService = umountForZygoteIsoService, + onUmountForZygoteIsoServiceChange = { enabled -> + coroutineScope.launch { + isLoading = true + val success = + SuSFSManager.setUmountForZygoteIsoService(context, enabled) + if (success) { + umountForZygoteIsoService = enabled + } + isLoading = false + } } ) } @@ -1326,39 +1261,6 @@ fun SuSFSConfigScreen( ) } - SuSFSTab.TRY_UMOUNT -> { - TryUmountContent( - tryUmounts = tryUmounts, - umountForZygoteIsoService = umountForZygoteIsoService, - isLoading = isLoading, - onAddUmount = { showAddUmountDialog = true }, - onRemoveUmount = { umountEntry -> - coroutineScope.launch { - isLoading = true - if (SuSFSManager.removeTryUmount(context, umountEntry)) { - tryUmounts = SuSFSManager.getTryUmounts(context) - } - isLoading = false - } - }, - 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, @@ -1470,7 +1372,9 @@ private fun BasicSettingsContent( enableAvcLogSpoofing: Boolean, onEnableAvcLogSpoofingChange: (Boolean) -> Unit, hideSusMountsForAllProcs: Boolean, - onHideSusMountsForAllProcsChange: (Boolean) -> Unit + onHideSusMountsForAllProcsChange: (Boolean) -> Unit, + umountForZygoteIsoService: Boolean, + onUmountForZygoteIsoServiceChange: (Boolean) -> Unit ) { var scriptLocationExpanded by remember { mutableStateOf(false) } val isAbDevice = produceState(initialValue = false) { @@ -1856,6 +1760,59 @@ private fun BasicSettingsContent( ) } + // 卸载 Zygote 隔离服务开关(仅在1.5.8+版本显示) + if (isSusVersion158) { + 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 = onUmountForZygoteIsoServiceChange, + enabled = !isLoading + ) + } + } + } + // 槽位信息按钮 if (isAbDevice) { Card( diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/component/SuSFSConfigDialogs.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/component/SuSFSConfigDialogs.kt index 41a0c4ce..fee0562c 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/component/SuSFSConfigDialogs.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/component/SuSFSConfigDialogs.kt @@ -401,126 +401,6 @@ fun AppIcon( } -/** - * 添加尝试卸载对话框 - */ -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun AddTryUmountDialog( - showDialog: Boolean, - onDismiss: () -> Unit, - onConfirm: (String, Int) -> Unit, - isLoading: Boolean, - initialPath: String = "", - initialMode: Int = 0 -) { - var newUmountPath by remember { mutableStateOf("") } - var newUmountMode by remember { mutableIntStateOf(0) } - var umountModeExpanded by remember { mutableStateOf(false) } - - // 当对话框显示时,设置初始值 - LaunchedEffect(showDialog, initialPath, initialMode) { - if (showDialog) { - newUmountPath = initialPath - newUmountMode = initialMode - } - } - - if (showDialog) { - AlertDialog( - onDismissRequest = onDismiss, - title = { - Text( - stringResource(if (initialPath.isNotEmpty()) R.string.susfs_edit_try_umount else R.string.susfs_add_try_umount), - style = MaterialTheme.typography.titleLarge, - fontWeight = FontWeight.Bold - ) - }, - text = { - Column( - verticalArrangement = Arrangement.spacedBy(12.dp) - ) { - OutlinedTextField( - value = newUmountPath, - onValueChange = { newUmountPath = it }, - label = { Text(stringResource(R.string.susfs_path_label)) }, - placeholder = { Text(stringResource(R.string.susfs_path_placeholder)) }, - modifier = Modifier.fillMaxWidth(), - shape = RoundedCornerShape(8.dp) - ) - - ExposedDropdownMenuBox( - expanded = umountModeExpanded, - onExpandedChange = { umountModeExpanded = !umountModeExpanded } - ) { - OutlinedTextField( - value = if (newUmountMode == 0) - stringResource(R.string.susfs_umount_mode_normal) - else - stringResource(R.string.susfs_umount_mode_detach), - onValueChange = { }, - readOnly = true, - label = { Text(stringResource(R.string.susfs_umount_mode_label)) }, - trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = umountModeExpanded) }, - modifier = Modifier - .fillMaxWidth() - .menuAnchor(ExposedDropdownMenuAnchorType.PrimaryEditable, true), - shape = RoundedCornerShape(8.dp) - ) - ExposedDropdownMenu( - expanded = umountModeExpanded, - onDismissRequest = { umountModeExpanded = false } - ) { - DropdownMenuItem( - text = { Text(stringResource(R.string.susfs_umount_mode_normal)) }, - onClick = { - newUmountMode = 0 - umountModeExpanded = false - } - ) - DropdownMenuItem( - text = { Text(stringResource(R.string.susfs_umount_mode_detach)) }, - onClick = { - newUmountMode = 1 - umountModeExpanded = false - } - ) - } - } - } - }, - confirmButton = { - Button( - onClick = { - if (newUmountPath.isNotBlank()) { - onConfirm(newUmountPath.trim(), newUmountMode) - newUmountPath = "" - newUmountMode = 0 - } - }, - enabled = newUmountPath.isNotBlank() && !isLoading, - shape = RoundedCornerShape(8.dp) - ) { - Text(stringResource(if (initialPath.isNotEmpty()) R.string.susfs_save else R.string.add)) - } - }, - dismissButton = { - TextButton( - onClick = { - onDismiss() - newUmountPath = "" - newUmountMode = 0 - }, - shape = RoundedCornerShape(8.dp) - ) { - Text(stringResource(R.string.cancel)) - } - }, - shape = RoundedCornerShape(12.dp) - ) - } -} - /** * 添加Kstat静态配置对话框 */ diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/component/SuSFSConfigTabs.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/component/SuSFSConfigTabs.kt index 16a52b09..cb9d597c 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/component/SuSFSConfigTabs.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/component/SuSFSConfigTabs.kt @@ -52,7 +52,7 @@ fun SusPathsContent( val (appPathGroups, otherPaths) = remember(susPaths) { val appPathRegex = Regex(".*/Android/data/([^/]+)/?.*") - val uidPathRegex = Regex("/sys/fs/cgroup/uid_([0-9]+)") + val uidPathRegex = Regex("/sys/fs/cgroup(?:/[^/]+)*/uid_([0-9]+)") val appPathMap = mutableMapOf>() val uidToPackageMap = mutableMapOf() val others = mutableListOf() @@ -420,134 +420,6 @@ fun SusMapsContent( } } -/** - * 尝试卸载内容组件 - */ -@Composable -fun TryUmountContent( - tryUmounts: Set, - umountForZygoteIsoService: Boolean, - isLoading: Boolean, - onAddUmount: () -> Unit, - onRemoveUmount: (String) -> Unit, - onEditUmount: ((String) -> Unit)? = null, - onToggleUmountForZygoteIsoService: (Boolean) -> Unit -) { - Box(modifier = Modifier.fillMaxSize()) { - LazyColumn( - modifier = Modifier.fillMaxSize(), - verticalArrangement = Arrangement.spacedBy(12.dp) - ) { - if (isSusVersion158()) { - 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( - message = stringResource(R.string.susfs_no_umounts_configured) - ) - } - } else { - items(tryUmounts.toList()) { umountEntry -> - val parts = umountEntry.split("|") - val path = if (parts.isNotEmpty()) parts[0] else umountEntry - val mode = if (parts.size > 1) parts[1] else "0" - val modeText = if (mode == "0") - stringResource(R.string.susfs_umount_mode_normal_short) - else - stringResource(R.string.susfs_umount_mode_detach_short) - - PathItemCard( - path = path, - icon = Icons.Default.Storage, - additionalInfo = stringResource(R.string.susfs_umount_mode_display, modeText, mode), - onDelete = { onRemoveUmount(umountEntry) }, - onEdit = if (onEditUmount != null) { { onEditUmount(umountEntry) } } else null, - isLoading = isLoading - ) - } - } - - item { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 16.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Button( - onClick = onAddUmount, - modifier = Modifier - .weight(1f) - .height(48.dp), - shape = RoundedCornerShape(8.dp) - ) { - Icon( - imageVector = Icons.Default.Add, - contentDescription = null, - modifier = Modifier.size(24.dp) - ) - Spacer(modifier = Modifier.width(8.dp)) - Text(text = stringResource(R.string.add)) - } - } - } - } - } -} - /** * Kstat配置内容组件 */ diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/util/SuSFSManager.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/util/SuSFSManager.kt index d7c2c880..813a3ea1 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/util/SuSFSManager.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/util/SuSFSManager.kt @@ -23,6 +23,7 @@ import com.sukisu.ultra.ui.util.getRootShell import com.sukisu.ultra.ui.util.getSuSFSVersion import com.sukisu.ultra.ui.util.getSuSFSFeatures import com.sukisu.ultra.ui.viewmodel.SuperUserViewModel +import com.topjohnwu.superuser.io.SuFile import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll @@ -44,7 +45,6 @@ object SuSFSManager { private const val KEY_SUS_LOOP_PATHS = "sus_loop_paths" private const val KEY_SUS_MAPS = "sus_maps" - private const val KEY_TRY_UMOUNTS = "try_umounts" private const val KEY_ANDROID_DATA_PATH = "android_data_path" private const val KEY_SDCARD_PATH = "sdcard_path" private const val KEY_ENABLE_LOG = "enable_log" @@ -70,7 +70,7 @@ object SuSFSManager { const val MAX_SUSFS_VERSION = "2.0.0" private const val BACKUP_FILE_EXTENSION = ".susfs_backup" private const val MEDIA_DATA_PATH = "/data/media/0/Android/data" - private const val CGROUP_UID_PATH_PREFIX = "/sys/fs/cgroup/uid_" + private const val CGROUP_BASE_PATH = "/sys/fs/cgroup" data class SlotInfo(val slotName: String, val uname: String, val buildTime: String) data class CommandResult(val isSuccess: Boolean, val output: String, val errorOutput: String = "") @@ -156,7 +156,6 @@ object SuSFSManager { val susPaths: Set, val susLoopPaths: Set, val susMaps: Set, - val tryUmounts: Set, val androidDataPath: String, val sdcardPath: String, val enableLog: Boolean, @@ -178,7 +177,6 @@ object SuSFSManager { susPaths.isNotEmpty() || susLoopPaths.isNotEmpty() || susMaps.isNotEmpty() || - tryUmounts.isNotEmpty() || kstatConfigs.isNotEmpty() || addKstatPaths.isNotEmpty() } @@ -268,7 +266,6 @@ object SuSFSManager { susPaths = getSusPaths(context), susLoopPaths = getSusLoopPaths(context), susMaps = getSusMaps(context), - tryUmounts = getTryUmounts(context), androidDataPath = getAndroidDataPath(context), sdcardPath = getSdcardPath(context), enableLog = getEnableLogState(context), @@ -377,12 +374,6 @@ object SuSFSManager { fun getSusMaps(context: Context): Set = getPrefs(context).getStringSet(KEY_SUS_MAPS, emptySet()) ?: emptySet() - fun saveTryUmounts(context: Context, umounts: Set) = - getPrefs(context).edit { putStringSet(KEY_TRY_UMOUNTS, umounts) } - - fun getTryUmounts(context: Context): Set = - getPrefs(context).getStringSet(KEY_TRY_UMOUNTS, emptySet()) ?: emptySet() - fun saveKstatConfigs(context: Context, configs: Set) = getPrefs(context).edit { putStringSet(KEY_KSTAT_CONFIGS, configs) } @@ -484,7 +475,44 @@ object SuSFSManager { } } - private fun buildUidPath(uid: Int): String = "$CGROUP_UID_PATH_PREFIX$uid" + private fun checkPathExists(path: String): Boolean { + return try { + val shell = try { + getRootShell() + } catch (_: Exception) { + null + } + + val file = if (shell != null) { + SuFile(path).apply { setShell(shell) } + } else { + File(path) + } + + file.exists() && file.isDirectory + } catch (_: Exception) { + false + } + } + + private fun buildUidPath(uid: Int): String { + val possiblePaths = listOf( + "$CGROUP_BASE_PATH/uid_$uid", + "$CGROUP_BASE_PATH/apps/uid_$uid", + "$CGROUP_BASE_PATH/system/uid_$uid", + "$CGROUP_BASE_PATH/freezer/uid_$uid", + "$CGROUP_BASE_PATH/memory/uid_$uid", + "$CGROUP_BASE_PATH/cpuset/uid_$uid", + "$CGROUP_BASE_PATH/cpu/uid_$uid" + ) + + for (path in possiblePaths) { + if (checkPathExists(path)) { + return path + } + } + return possiblePaths[0] + } // 快捷添加应用路径 @@ -537,7 +565,6 @@ object SuSFSManager { KEY_SUS_PATHS to getSusPaths(context), KEY_SUS_LOOP_PATHS to getSusLoopPaths(context), KEY_SUS_MAPS to getSusMaps(context), - KEY_TRY_UMOUNTS to getTryUmounts(context), KEY_ANDROID_DATA_PATH to getAndroidDataPath(context), KEY_SDCARD_PATH to getSdcardPath(context), KEY_ENABLE_LOG to getEnableLogState(context), @@ -849,7 +876,6 @@ object SuSFSManager { val featureMap = mapOf( "CONFIG_KSU_SUSFS_SUS_PATH" to context.getString(R.string.sus_path_feature_label), - "CONFIG_KSU_SUSFS_TRY_UMOUNT" to context.getString(R.string.try_umount_feature_label), "CONFIG_KSU_SUSFS_SPOOF_UNAME" to context.getString(R.string.spoof_uname_feature_label), "CONFIG_KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG" to context.getString(R.string.spoof_cmdline_feature_label), "CONFIG_KSU_SUSFS_OPEN_REDIRECT" to context.getString(R.string.open_redirect_feature_label), @@ -877,7 +903,6 @@ object SuSFSManager { private fun getDefaultDisabledFeatures(context: Context): List { val defaultFeatures = listOf( "sus_path_feature_label" to context.getString(R.string.sus_path_feature_label), - "try_umount_feature_label" to context.getString(R.string.try_umount_feature_label), "spoof_uname_feature_label" to context.getString(R.string.spoof_uname_feature_label), "spoof_cmdline_feature_label" to context.getString(R.string.spoof_cmdline_feature_label), "open_redirect_feature_label" to context.getString(R.string.open_redirect_feature_label), @@ -1167,59 +1192,6 @@ object SuSFSManager { } } - // 添加尝试卸载 - suspend fun addTryUmount(context: Context, path: String, mode: Int): Boolean { - val commandSuccess = executeSusfsCommand(context, "add_try_umount '$path' $mode") - saveTryUmounts(context, getTryUmounts(context) + "$path|$mode") - if (isAutoStartEnabled(context)) updateMagiskModule(context) - - showToast(context, if (commandSuccess) { - context.getString(R.string.susfs_try_umount_added_success, path) - } else { - context.getString(R.string.susfs_try_umount_added_saved, path) - }) - return true - } - - suspend fun removeTryUmount(context: Context, umountEntry: String): Boolean { - saveTryUmounts(context, getTryUmounts(context) - umountEntry) - if (isAutoStartEnabled(context)) updateMagiskModule(context) - val path = umountEntry.split("|").firstOrNull() ?: umountEntry - showToast(context, "Removed Try to uninstall: $path") - return true - } - - // 编辑尝试卸载 - suspend fun editTryUmount(context: Context, oldEntry: String, newPath: String, newMode: Int): Boolean { - return try { - val currentUmounts = getTryUmounts(context).toMutableSet() - if (!currentUmounts.remove(oldEntry)) { - showToast(context, "Original umount entry not found: $oldEntry") - return false - } - - saveTryUmounts(context, currentUmounts) - - val success = addTryUmount(context, newPath, newMode) - - if (success) { - showToast(context, "Try umount updated: $oldEntry -> $newPath|$newMode") - return true - } else { - // 如果添加新条目失败,恢复旧条目 - currentUmounts.add(oldEntry) - saveTryUmounts(context, currentUmounts) - if (isAutoStartEnabled(context)) updateMagiskModule(context) - showToast(context, "Failed to update umount entry, reverted to original") - return false - } - } catch (e: Exception) { - e.printStackTrace() - showToast(context, "Error updating try umount: ${e.message}") - false - } - } - // Zygote隔离服务卸载控制 suspend fun setUmountForZygoteIsoService(context: Context, enabled: Boolean): Boolean { if (!isSusVersion158()) { diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/util/SuSFSModuleScripts.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/util/SuSFSModuleScripts.kt index 68427897..ce13eb96 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/util/SuSFSModuleScripts.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/susfs/util/SuSFSModuleScripts.kt @@ -429,21 +429,6 @@ object ScriptGenerator { appendLine(generateBinaryCheck(config.targetPath)) appendLine() - // 添加尝试卸载 - if (config.tryUmounts.isNotEmpty()) { - appendLine("# 添加尝试卸载") - config.tryUmounts.forEach { umount -> - val parts = umount.split("|") - if (parts.size == 2) { - val path = parts[0] - val mode = parts[1] - appendLine($$"\"$SUSFS_BIN\" add_try_umount '$$path' $$mode") - appendLine($$"echo \"$(get_current_time): 添加尝试卸载: $$path (模式: $$mode)\" >> \"$LOG_FILE\"") - } - } - appendLine() - } - appendLine($$"echo \"$(get_current_time): Post-Mount脚本执行完成\" >> \"$LOG_FILE\"") } } diff --git a/manager/app/src/main/jniLibs/arm64-v8a/libksu_susfs.so b/manager/app/src/main/jniLibs/arm64-v8a/libksu_susfs.so index 854b3a19f3f2e0611092100494234fd4e074ab0f..b020e7a6ad16ca2d3810fabb259c230e4f323099 100644 GIT binary patch delta 6305 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 NM83NzmaHw&{RfWC{U!ha delta 7102 zcmc&(eNDhoZ7!F?MUKpS+UuN>9IB~z_$ehE z_#WK%Eqv-eso$_%5yeldjE~5C75G<@VdF@+7g2+fG&PKI9n_L<_V*epI6Pj#+4#SaG+K!S z#Q?2_!xK3?iNhCgcshqCak$9gS`Ie?&c>$$Cv%2ku7i%lD>z)w;bsm`;qV3yPv!7U zv$z+fafYq429(a>?Hs<4!@D_r5r;cDd@+X)aCip8HImi$oAH(N&k2bZtF_JJ+TGUQ z>*(+Ekl!uMoG0Ge>#*9Y$EV|4)T>4Id$6FOT5R6fx~@ue_q)5?qC^)xmK`>?=ycgS zZB|=fr%iNpi96i=l6kx&DM!7v=zd$D)!{<-6#PJ3>J~dKeSHp(*kKc4WSdp=IKo^G+vA$Hj<+uiwM$+t~S&8=so8-8pi*mSF7jAZpZ(e_M%!- zaKi$VIf9Q9?&e&#FC$!=ptOjUhYv!ygM+!?6@hvB#+AA{j&F3_Ao^a3wNLMkXq6ofxqr z>-R>)OomaJO6^Nl{S|);OOm*bc zeO!SpZwuO^QAkf`fmJeJ!^Y30-DBl(TB{glpjd`HPP~L=#E{$-OH$jx)DEFe!(H7`gRDG6(yL0{{lGNyG*B|z^=~9n@Tl@&+coxktM`_ zVId?gf0-8szLMo@iM)ZrL3I?Y`e?Xf;F<@Q2Ci7R;^3P9d@@8ua|l8on#U*L-Q0xE zvC=$}fUm2O|4lk#l3WIpG+mQ`wJ(sdoCU00F9SB2h)iAA(GZ^+9V8M7~a?{Gu6&@u3uJfOvPGOHRpB}n?bpBJc|81yD3S8%}6?`oQ zq{2S~JXF`PEgak@OlSmiW%mYDR{FxBmgzq{(Nf!XvSl2NxTY5PT0VnpJFAg)QtN9u zb@^piZQEKWAYD=vp3p7-?f~SWPqC~u)6o6JJ7T1ZqlPS0y%jg7$fqvK=}iP zU>P1&p-MWf@6g_K3fbDx&rHE3z+no)wECe!R2Euq4%0OhT#v$`jj>@X$t=1>Ph+E& zKOZ+wxDTK^*1~Ay_QG!ABa&IX%J>L%eq73T`uDT>POEi!J7wEX{ssApMWXOa@>KEK zrT0mB5vrtYFM)j@g|7%zMD+lDW*~j9JPthZX^IJ2127G8ZwX$T3ILfw=>i zxpSHG88d}rPNf3V0nEI)%x}o+E7O+3qv%ZTAw4kNz$~20{E{*Msh(wObimvN%$0MQ zpD^ZU9Mh-;<{n^{&t<;Ln3p+b!vbJ-0<&r^bCNO>-{P3v3FOJrY~g>%E2Vpu5HJMQ zt!!Joer|ToEip(tB#@S(D(^#-0*5Hw(87xxrCQK-$hJc_BWd)mGqqsy5<6w!{ox445w(nWDilJr%6r*aW8+4dfi0T+~i#(H%zeP`M*k1Z@%y%xv;dS(cDXo+>Lf zrT`XvLQePD*>vf~`3k&JTQ+zlzH)o)X8_QH;&akl?iKXp%knzmCMj8U&~ltomBRjb zuA5=ls^3?wA3{I*te&aXe(LMQJ{dmM5xp)qzrm|8Nhl4 z_V%Y>*^lvWM`$`1jp<2zmPT=It;1W;ZZ{Gr>AC>rPWUJT}qI@;W>vD^Xi63fhCRE!YnpA#Yml-^rLCBBL8&5DIyjOs`($ z-3OL#sMwKB zGKcCTFi5w;`PFJn)2At}f%X_&H}|}H_WDNQ>`i!>`#n6ZxX%<|7;6{}R6`&?AYs zPLjuvCkLAqc~XUGg}m>>d>pNo9sny9qfd{^B{_iX>9`bRnpv5I4I^g>E>yUaTD(HR zhYGO~WV!=$6?-Tj-=fIJ=3!Bi0|=f(GX>;jjvuf-arkC=s{C3y^u{#tQpO~p4r zrrCa_U>BC+Yl?im5MPz#02)=}FJUT3E?I! z&Aka>tT-56gdd%emtlBWz!Lb8g6Wsz1B!e-8}F0kVKh>PeIV0{KMZgBqyVmG;ynua z#Bw|UGOfk~3N{&y-HQCuD(qC`4-;^&BKt})yxwK~u5YY4dvnjlQPA}WepmOrcD5Ly zVQq7LIH@BWi>j;-vf#x+7P+e?-rEA;UI}EREuf#~^t(a7$m!cazryJqpsQ|SPFeph z(6c%HKG179y$|$`S>3C30kC%#(B2RFX-lfS%3ihd{68 z^hZJOn9;q%+9Lq$odJfmkAr@i)1L(WBBwtM`V~$;4Z3RSYyf9K&*pSL=(U{w0_Yuz z-VF2dA^>|80QB>qpXT&mf_{(#TkY G=6?Ztw?k Pengaturan Dasar Jalur SUS - Coba Lepas Kait Pengaturan Jalur Status Fitur Diaktifkan Tambah Jalur SUS - Tambah Coba Lepas Kait Jalur SUS berhasil ditambahkan Kesalahan: Jalur tidak ditemukan Jalur misalnya: /system/addon.d Tidak ada jalur SUS yang dikonfigurasi - Tidak ada coba lepas kait yang dikonfigurasi - Mode Lepas Kait - Lepas Kait Normal (0) - Lepas Kait Terpisah (1) - Normal - Terpisah - Mode: %1$s (%2$s) - Jalur coba lepas kait berhasil ditambahkan: %s - Berhasil menyimpan jalur coba lepas kait: %s Atur Ulang Jalur SUS Ini akan menghapus semua konfigurasi jalur SUS. Apakah Anda yakin ingin melanjutkan? - Atur Ulang Coba Lepas Kait - Ini akan menghapus semua konfigurasi coba lepas kait. Apakah Anda yakin ingin melanjutkan? Atur Ulang Pengaturan Jalur Jalur Data Android @@ -422,7 +409,6 @@ Tanamkan: Secara permanen memasang ke sistem Dinonaktifkan Dukungan Jalur SUS - Dukungan Coba Lepas Kait Dukungan Spoof Uname Spoof Cmdline/Bootconfig Dukungan Open Redirect diff --git a/manager/app/src/main/res/values-in/strings.xml b/manager/app/src/main/res/values-in/strings.xml index 1c267f10..ef4b865a 100644 --- a/manager/app/src/main/res/values-in/strings.xml +++ b/manager/app/src/main/res/values-in/strings.xml @@ -389,33 +389,20 @@ Pengaturan Dasar Jalur SUS - Coba Umount Pengaturan Path Status Fitur yang Diaktifkan Tambahkan Jalur SUS - Tambahkan Coba Umount Jalur SUS berhasil ditambahkan Kesalahan jalur tidak ditemukan Jalur contoh: /system/addon.d Tidak ada jalur SUS yang dikonfigurasi - Tidak ada coba umount yang dikonfigurasi - Mode Umount - Umount Normal (0) - Umount Lepas (1) - Normal - Lepas - Mode: %1$s (%2$s) - Jalur coba umount berhasil ditambahkan: %s - Jalur coba umount berhasil disimpan: %s Setel Ulang Jalur SUS Ini akan menghapus semua konfigurasi jalur SUS. Apakah Anda yakin ingin melanjutkan? - Setel Ulang Coba Umount - Ini akan menghapus semua konfigurasi umount. Apakah Anda yakin ingin melanjutkan? Setel Ulang Pengaturan Jalur Jalur Data Android @@ -429,7 +416,6 @@ Dinonaktifkan Dukungan Jalur SUS - Dukungan Coba Umount Dukungan Spoof uname Spoof Cmdline/Bootconfig Dukungan Pengalihan Terbuka @@ -531,7 +517,6 @@ Bersihkan Residu Bersihkan file dan direktori sisa dari berbagai modul dan alat (mungkin terhapus secara tidak sengaja, mengakibatkan kehilangan dan gagal memulai, gunakan dengan hati-hati) Edit Jalur SUS - Edit Coba Umount Edit Konfigurasi Statis Kstat Edit Jalur Kstat Simpan diff --git a/manager/app/src/main/res/values-ja/strings.xml b/manager/app/src/main/res/values-ja/strings.xml index f0258a74..a49e129f 100644 --- a/manager/app/src/main/res/values-ja/strings.xml +++ b/manager/app/src/main/res/values-ja/strings.xml @@ -380,33 +380,20 @@ 基本設定 SUS のパス - アンマウントを試す パスの設定 有効な機能のステータス SUS パスを追加 - アンマウントを試すを追加 SUS パスが正常に追加されました パスが見つかりません パス 例: /system/addon.d SUS パスが未構成です - アンマウントを試すが未構成です - アンマウントモード - 通常のアンマウント (0) - アンマウントを分離 (1) - 通常 - 分離 - モード: %1$s (%2$s) - 追加されたパスのアンマウントに成功しました: %s - アンマウントのパスの保存に成功しました: %s SUS パスをリセット すべての SUS パスの構成が消去されます。続行してもよろしいですか? - リセットしてアンマウントを試す - すべてのアンマウント構成がリセットされます。続行してもよろしいですか? パスの設定をリセット Android データパス @@ -420,7 +407,6 @@ 無効 SUS パスの対応 - アンマウントを試すの対応 uname 偽装の対応 Cmdline/Bootconfig を偽装 オープンリダイレクトの対応 @@ -522,7 +508,6 @@ 残骸をクリーンアップ 様々なモジュールや残骸となったツールのファイルとディレクトリをクリーンアップします (誤って削除すると損失や起動の失敗に繋がる可能性があるため、注意して使用してください) SUS のパスを編集 - アンマウントを試すを編集 Kstat 静的構成を編集 Kstat のパスを編集 保存 diff --git a/manager/app/src/main/res/values-ru/strings.xml b/manager/app/src/main/res/values-ru/strings.xml index 1e49d082..bda0365b 100644 --- a/manager/app/src/main/res/values-ru/strings.xml +++ b/manager/app/src/main/res/values-ru/strings.xml @@ -390,33 +390,20 @@ Базовые настройки SUS пути - Попробовать размонтировать Настройки пути Статус включённых функций Добавить SUS путь - Добавить попробовать размонтировать Путь SUS успешно добавлен Ошибка пути Путь например: /system/addon.d SUS пути не настроены - Попытка размонтировать не настроена - Режим размонтирования - Обычное размонтирование (0) - Размонтирование отсоединением (1) - Нормальный - Отсоединить - Режим: %1$s (%2$s) - Попытка размонтировать путь успешно добавлена: %s - Попытка размонтировать путь успешно сохранена: %s Сбросить SUS пути Это очистит все конфигурации пути SUS. Вы уверены, что хотите продолжить? - Сбросить Umount - Это очистит все конфигурации размонтирования. Вы уверены, что хотите продолжить? Сбросить настройки пути Путь к данным Android @@ -430,7 +417,6 @@ Выключено Поддержка SUS пути - Поддержка размонтирования Поддержка подмены uname Подмена Cmdline/Bootconfig Поддержка Open Redirect @@ -532,7 +518,6 @@ Очистка Очистка остаточных файлов и каталогов различных модулей и инструментов (может быть удален по ошибке, в результате потери и неспособности начаться, используйте с осторожностью) Редактировать путь SUS - Изменить попробовать размонтировать Изменить статическую конфигурацию Kstat Редактировать путь Kstat Сохранить diff --git a/manager/app/src/main/res/values-tr/strings.xml b/manager/app/src/main/res/values-tr/strings.xml index 58b02427..47e588bc 100644 --- a/manager/app/src/main/res/values-tr/strings.xml +++ b/manager/app/src/main/res/values-tr/strings.xml @@ -387,33 +387,20 @@ Temel Ayarlar SUS Yolları - Bağlamayı Kaldırmayı Dene Yol Ayarları Etkinleştirilen Özellikler Durumu SUS Yolu Ekle - Bağlamayı Kaldırmayı Dene Ekle SUS yolu başarıyla eklendi Yol bulunamadı hatası Yol örn.: /system/addon.d Yapılandırılmış SUS yolu yok - Yapılandırılmış bağlamayı kaldırmayı dene yok - Bağlamayı Kaldır Modu - Normal Bağlamayı Kaldır (0) - Ayrı Bağlamayı Kaldır (1) - Normal - Ayrı - Mod: %1$s (%2$s) - Bağlamayı kaldırmayı dene yolu başarıyla eklendi: %s - Bağlamayı kaldırmayı dene yolu kaydetme başarılı: %s SUS Yollarını Sıfırla Bu, tüm SUS yol yapılandırmalarını temizleyecektir. Devam etmek istiyor musunuz? - Bağlamayı Kaldırmayı Dene Sıfırla - Bu, tüm bağlamayı kaldırmayı dene yapılandırmalarını temizleyecektir. Devam etmek istiyor musunuz? Yol Ayarlarını Sıfırla Android Veri Yolu @@ -427,7 +414,6 @@ Devre Dışı Bırakıldı SUS Yol Desteği - Bağlamayı Kaldırmayı Dene Desteği Uname Taklit Desteği Cmdline/Bootconfig Taklit Açık Yönlendirme Desteği @@ -529,7 +515,6 @@ Kalıntıları Temizle Çeşitli modüllerin ve araçların kalıntı dosyalarını ve dizinlerini temizleyin (yanlışlıkla silinerek kayba ve başlatılamamaya neden olabilir, dikkatli kullanın) SUS Yolunu Düzenle - Ayırmayı Deneme Yolunu Düzenle Kstat Statik Yapılandırmasını Düzenle Kstat Yolunu Düzenle Kaydet diff --git a/manager/app/src/main/res/values-uk/strings.xml b/manager/app/src/main/res/values-uk/strings.xml index f421781c..0a834b4a 100644 --- a/manager/app/src/main/res/values-uk/strings.xml +++ b/manager/app/src/main/res/values-uk/strings.xml @@ -377,33 +377,20 @@ Основні налаштування Шляхи SUS - Спроба відмонтування Налаштування шляхів Статус увімкнених функцій Додати шлях SUS - Додати спробу відмонтування Шлях SUS успішно додано Помилка: шлях не знайдено Шлях напр.: /system/addon.d Немає налаштованих шляхів SUS - Немає налаштованих спроб відмонтування - Режим відмонтування - Звичайне відмонтування (0) - Від\'єднане відмонтування (1) - Звичайний - Від\'єднаний - Режим: %1$s (%2$s) - Шлях для спроби відмонтування успішно додано: %s - Спроба збереження шляху відмонтування успішна: %s Скинути шляхи SUS Це видалить усі конфігурації шляхів SUS. Ви впевнені, що хочете продовжити? - Скинути спроби відмонтування - Це видалить усі конфігурації спроб відмонтування. Ви впевнені, що хочете продовжити? Скинути налаштування шляхів Шлях до Android Data @@ -417,7 +404,6 @@ Вимкнено Підтримка шляхів SUS - Підтримка спроб відмонтування Підтримка підміни uname Підміна Cmdline/Bootconfig Підтримка Open Redirect diff --git a/manager/app/src/main/res/values-vi/strings.xml b/manager/app/src/main/res/values-vi/strings.xml index 4e0562f7..2a0a1b3e 100644 --- a/manager/app/src/main/res/values-vi/strings.xml +++ b/manager/app/src/main/res/values-vi/strings.xml @@ -378,33 +378,20 @@ Cài đặt cơ bản Đường dẫn SuS - Try Umount Cài đặt Đường dẫn Trạng thái tính năng Thêm Đường dẫn SuS - Thêm Try Umount Đường dẫn SuS đã được thêm thành công Lỗi không tìm thấy đường dẫn Đường dẫn Ví dụ: /system/addon.d Không có Đường dẫn SuS nào được cấu hình - Không có Try Umount nào được cấu hình - Chế độ Umount - Normal Umount (0) - Detach Umount (1) - Normal - Detach - Chế độ: %1$s (%2$s) - Đường dẫn Try Umount đã thêm thành công: %s - Đường dẫn Try Umount đã lưu thành công: %s Đặt lại Đường dẫn SuS Thao tác này sẽ xóa tất cả các cấu hình Đường dẫn SuS. Bạn có chắc chắn muốn tiếp tục không? - Đặt lại Try Umount - Thao tác này sẽ xóa tất cả các cấu hình Try Umount. Bạn có chắc chắn muốn tiếp tục không? Reset Cài đặt Đường dẫn Đường dẫn Android Data @@ -418,7 +405,6 @@ Đã tắt Hỗ trợ Đường dẫn SuS - Hỗ trợ Try Umount Hỗ trợ giả mạo Uname Giả mạo Cmdline/Bootconfig Mở hỗ trợ chuyển hướng @@ -520,7 +506,6 @@ Dọn rác Dọn dẹp các file và folder còn sót lại của các module và công cụ (Có thể bị xóa nhầm, dẫn đến mất dữ liệu và không khởi động được) Chỉnh sửa Đường dẫn SuS - Chỉnh sửa Try Umount Chỉnh sửa cấu hình Kstat tĩnh Chỉnh sửa Đường dẫn Kstat Lưu 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 eeb0b206..69a66d46 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -396,33 +396,20 @@ 基本设置 SuS 路径 - 尝试卸载 路径设置 启用功能状态 添加 SuS 路径 - 添加尝试卸载 SuS 路径添加成功 路径未找到错误 路径 例如: /system/addon.d 暂无 SuS 路径配置 - 暂无尝试卸载配置 - 卸载模式 - 普通卸载(0) - 分离卸载(1) - 普通 - 分离 - 模式: %1$s (%2$s) - 尝试 umount 路径添加成功: %s - 尝试 umount 路径保存成功: %s 重置 SuS 路径 这将清除所有 SuS 路径配置,确定要继续吗? - 重置尝试卸载 - 这将清除所有尝试卸载配置,确定要继续吗? 重置路径设置 Android Data 路径 @@ -436,7 +423,6 @@ 已禁用 SuS 路径支持 - 尝试卸载支持 欺骗 uname 支持 欺骗 Cmdline/Bootconfig 开放重定向支持 @@ -538,7 +524,6 @@ 清理工具残留 清理各种模块以及工具的残留文件和目录(可能会误删导致丢失以及无法启动,谨慎使用) 编辑 SuS 路径 - 编辑尝试卸载 编辑 Kstat 静态配置 编辑 Kstat 路径 保存 diff --git a/manager/app/src/main/res/values-zh-rHK/strings.xml b/manager/app/src/main/res/values-zh-rHK/strings.xml index d755de66..5f1aad84 100644 --- a/manager/app/src/main/res/values-zh-rHK/strings.xml +++ b/manager/app/src/main/res/values-zh-rHK/strings.xml @@ -376,33 +376,20 @@ 基本配置 SuS 路徑 - 嘗試卸載 路徑配置 啟用功能狀態 添加 SuS 路徑 - 嘗試添加卸載 SuS 路徑添加成功 錯誤冇此找到路徑 路徑 例如: /system/addon.d 暫冇 SuS 路徑配置 - 暫冇嘗試卸載配置 - 卸載模式 - 普通卸載 (0) - 分離卸載 (1) - 普通 - 分離 - 模式: %1$s (%2$s) - 嘗試 umount 路徑添加成功: %s - 嘗試 umount 路徑存儲成功: %s 重置 SuS 路徑 這將清除所有 SuS 路徑配置,確定要繼續嗎? - 重置嘗試卸載 - 這將清除所有嘗試卸載配置,確定要繼續嗎? 重置路徑配置 Android Data 路徑 @@ -416,7 +403,6 @@ 已禁用 SuS 路徑支援 - 嘗試卸載支援 欺騙 uname 支援 欺騙 Cmdline/Bootconfig 開放重定向支援 @@ -518,7 +504,6 @@ 清理工具殘留 清理各種模組以及工具嘅殘留檔案同目錄(可能會誤刪導致丟失以及無法啟動,謹慎使用) 編輯 SuS 路徑 - 編輯嘗試解除安裝 編輯 Kstat 靜態配置 編輯 Kstat 路徑 儲存 diff --git a/manager/app/src/main/res/values-zh-rTW/strings.xml b/manager/app/src/main/res/values-zh-rTW/strings.xml index 351205f9..44288c6f 100644 --- a/manager/app/src/main/res/values-zh-rTW/strings.xml +++ b/manager/app/src/main/res/values-zh-rTW/strings.xml @@ -378,33 +378,20 @@ 基本設定 SuS 路徑 - 嘗試卸載 路徑設定 啟用功能狀態 新增 SuS 路徑 - 新增嘗試卸載 成功添加 SuS 路径 未找到路径 路徑 例如:/system/addon.d 暫無 SuS 路徑設定 - 暫無嘗試卸載設定 - 卸載模式 - 一般卸載 (0) - 分離卸載 (1) - 一般 - 分離 - 模式:%1$s (%2$s) - 嘗試 umount 路徑新增成功: %s - 嘗試 umount 路徑儲存成功: %s 重設 SuS 路徑 這將清除所有 SuS 路徑設定,確定要繼續嗎? - 重設嘗試卸載 - 這將清除所有嘗試卸載設定,確定要繼續嗎? 重置路徑設定 Android Data 路徑 @@ -418,7 +405,6 @@ 已停用 SuS 路徑支援 - 嘗試卸載支援 偽裝 uname 支援 偽裝 Cmdline/Bootconfig 開放重定向支援 @@ -520,7 +506,6 @@ 清理工具殘留 清理各種模組以及工具的殘留檔案和目錄(可能會誤刪導致丟失以及無法啟動,謹慎使用) 編輯 SuS 路徑 - 編輯嘗試解除安裝 編輯 Kstat 靜態配置 編輯 Kstat 路徑 儲存 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index e7b9c124..92032666 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -399,33 +399,20 @@ Basic Settings SUS Paths - Try Umount Path Settings Enabled Features Status Add SUS Path - Add Try Umount SUS path added successfully Path not found error Path e.g.: /system/addon.d No SUS paths configured - No try umount configured - Umount Mode - Normal Umount (0) - Detach Umount (1) - Normal - Detach - Mode: %1$s (%2$s) - Try to umount path added successfully: %s - Attempted umount path save succeeded: %s Reset SUS Paths This will clear all SUS path configurations. Are you sure you want to continue? - Reset Try Umount - This will clear all try umount configurations. Are you sure you want to continue? Reset Path Settings Android Data Path @@ -439,7 +426,6 @@ Disabled SUS Path Support - Try Umount Support Spoof uname Support Spoof Cmdline/Bootconfig Open Redirect Support @@ -541,7 +527,6 @@ Cleanup Residue Clean up the residual files and directories of various modules and tools (May be deleted by mistake, resulting in loss and failure to start, use with caution) Edit SUS Path - Edit Try Umount Edit Kstat Static Configuration Edit Kstat Path Save