From a45e0f78efdbe968c1502bfb456e4661bb42e5d1 Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Tue, 1 Apr 2025 17:24:13 +0800 Subject: [PATCH 1/6] Add KPM module count display to the main page and update related string resources --- .../src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt | 7 ++++++- manager/app/src/main/res/values-zh-rCN/strings.xml | 1 + manager/app/src/main/res/values/strings.xml | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt index 51fc6f33..0d86bd77 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt @@ -333,6 +333,12 @@ private fun StatusCard( text = stringResource(R.string.home_module_count, getModuleCount()), style = MaterialTheme.typography.bodyMedium ) + Spacer(modifier = Modifier.height(4.dp)) + Text( + text = stringResource(R.string.home_kpm_module_count, getKpmModuleCount()), + style = MaterialTheme.typography.bodyMedium + ) + Spacer(modifier = Modifier.height(4.dp)) val suSFS = getSuSFS() @@ -556,7 +562,6 @@ private fun InfoCard() { if (!isSimpleMode){ - Spacer(Modifier.height(16.dp)) val kpmVersion = getKpmVersion() val displayVersion = if (kpmVersion.isEmpty() || kpmVersion.startsWith("Error")) { stringResource(R.string.not_supported) 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 cf8d3779..f91406a6 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -239,6 +239,7 @@ 成功 错误 不支持 + kpm模块数: 以下内核模块功能由KernelPatch开发,经过修改后加入SukiSU Ultra的内核模块功能 SukiSU Ultra展望 SukiSU Ultra未来将会成为一个相对独立的KSU分支,但是依然感谢官方KernelSU和MKSU等做出的贡献 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index a38c2904..696ba35f 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -245,4 +245,5 @@ failed SukiSU Ultra will be a relatively independent branch of KSU in the future, but thanks to the official KernelSU and MKSU etc. for their contributions! unsupported + Number of kpm modules: From a971fee132a882bac167d0059a6c8efad3a5c40b Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Tue, 1 Apr 2025 17:27:51 +0800 Subject: [PATCH 2/6] Revert "Add KPM module count display to the main page and update related string resources" This reverts commit a45e0f78efdbe968c1502bfb456e4661bb42e5d1. --- .../src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt | 7 +------ manager/app/src/main/res/values-zh-rCN/strings.xml | 1 - manager/app/src/main/res/values/strings.xml | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt index 0d86bd77..51fc6f33 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt @@ -333,12 +333,6 @@ private fun StatusCard( text = stringResource(R.string.home_module_count, getModuleCount()), style = MaterialTheme.typography.bodyMedium ) - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = stringResource(R.string.home_kpm_module_count, getKpmModuleCount()), - style = MaterialTheme.typography.bodyMedium - ) - Spacer(modifier = Modifier.height(4.dp)) val suSFS = getSuSFS() @@ -562,6 +556,7 @@ private fun InfoCard() { if (!isSimpleMode){ + Spacer(Modifier.height(16.dp)) val kpmVersion = getKpmVersion() val displayVersion = if (kpmVersion.isEmpty() || kpmVersion.startsWith("Error")) { stringResource(R.string.not_supported) 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 f91406a6..cf8d3779 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -239,7 +239,6 @@ 成功 错误 不支持 - kpm模块数: 以下内核模块功能由KernelPatch开发,经过修改后加入SukiSU Ultra的内核模块功能 SukiSU Ultra展望 SukiSU Ultra未来将会成为一个相对独立的KSU分支,但是依然感谢官方KernelSU和MKSU等做出的贡献 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index 696ba35f..a38c2904 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -245,5 +245,4 @@ failed SukiSU Ultra will be a relatively independent branch of KSU in the future, but thanks to the official KernelSU and MKSU etc. for their contributions! unsupported - Number of kpm modules: From 12c7558b915595652f9419ab3ebddd666b8a2e88 Mon Sep 17 00:00:00 2001 From: liankong Date: Wed, 2 Apr 2025 14:03:50 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E7=BB=99WebUI=E6=B7=BB=E5=8A=A0=E5=AF=B9KP?= =?UTF-8?q?M=E7=9A=84=E6=93=8D=E6=8E=A7=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zako/sukisu/ui/webui/WebViewInterface.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/webui/WebViewInterface.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/webui/WebViewInterface.kt index fedae073..e4576429 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/webui/WebViewInterface.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/webui/WebViewInterface.kt @@ -19,6 +19,9 @@ import shirkneko.zako.sukisu.ui.util.listModules import shirkneko.zako.sukisu.ui.util.withNewRootShell import org.json.JSONArray import org.json.JSONObject +import shirkneko.zako.sukisu.ui.util.KsuCli +import shirkneko.zako.sukisu.ui.util.controlKpmModule +import shirkneko.zako.sukisu.ui.util.listKpmModules import java.io.File import java.util.concurrent.CompletableFuture @@ -197,6 +200,18 @@ class WebViewInterface( } return currentModuleInfo.toString() } + + // =================== KPM支持 ============================= + + @JavascriptInterface + fun listAllKpm() : String { + return listKpmModules() + } + + @JavascriptInterface + fun controlKpm(name: String, args: String) : Int { + return controlKpmModule(name, args) + } } fun hideSystemUI(window: Window) = From fbf2799674b933234a84933b01e0815d3ca69545 Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Wed, 2 Apr 2025 00:35:55 +0800 Subject: [PATCH 4/6] Opt the error handling logic for loading and unloading modules, this will fix the file type error, and more detail handling --- .../main/java/shirkneko/zako/sukisu/ui/component/AboutCard.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/component/AboutCard.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/component/AboutCard.kt index b3b1db7c..2a9d7a7a 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/component/AboutCard.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/component/AboutCard.kt @@ -98,7 +98,7 @@ private fun AboutCardContent() { val annotatedString = AnnotatedString.Companion.fromHtml( htmlString = stringResource( id = R.string.about_source_code, - "GitHub", + "GitHub", "Telegram" ), linkStyles = TextLinkStyles( From d925036bd6af74ed9e111581928b20642d14bc57 Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Wed, 2 Apr 2025 00:36:08 +0800 Subject: [PATCH 5/6] Optimize the error handling logic for loading and unloading modules, this will fix the file type error, and more detail handling-2 --- .../shirkneko/zako/sukisu/ui/MainActivity.kt | 90 +++++++++++++------ .../sukisu/ui/screen/BottomBarDestination.kt | 2 +- .../shirkneko/zako/sukisu/ui/screen/Home.kt | 52 +++++++++-- .../shirkneko/zako/sukisu/ui/screen/kpm.kt | 34 +++++-- .../shirkneko/zako/sukisu/ui/util/KsuCli.kt | 10 +-- .../src/main/res/values-zh-rCN/strings.xml | 5 ++ manager/app/src/main/res/values/strings.xml | 5 ++ 7 files changed, 151 insertions(+), 47 deletions(-) diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/MainActivity.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/MainActivity.kt index 15099c52..f2153d20 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/MainActivity.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/MainActivity.kt @@ -49,6 +49,7 @@ import shirkneko.zako.sukisu.ui.theme.KernelSUTheme import shirkneko.zako.sukisu.ui.theme.loadCustomBackground import shirkneko.zako.sukisu.ui.theme.loadThemeMode import shirkneko.zako.sukisu.ui.util.LocalSnackbarHost +import shirkneko.zako.sukisu.ui.util.getKpmVersion import shirkneko.zako.sukisu.ui.util.rootAvailable import shirkneko.zako.sukisu.ui.util.install @@ -107,6 +108,7 @@ private fun BottomBar(navController: NavHostController) { val navigator = navController.rememberDestinationsNavigator() val isManager = Natives.becomeManager(ksuApp.packageName) val fullFeatured = isManager && !Natives.requireNewKernel() && rootAvailable() + val kpmVersion = getKpmVersion() // 获取卡片颜色和透明度 val cardColor = MaterialTheme.colorScheme.secondaryContainer @@ -122,35 +124,69 @@ private fun BottomBar(navController: NavHostController) { ) ) { BottomBarDestination.entries.forEach { destination -> - if (!fullFeatured && destination.rootRequired) return@forEach - val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction) - NavigationBarItem( - selected = isCurrentDestOnBackStack, - onClick = { - if (isCurrentDestOnBackStack) { - navigator.popBackStack(destination.direction, false) - } - navigator.navigate(destination.direction) { - popUpTo(NavGraphs.root) { - saveState = true + if (destination == BottomBarDestination.Kpm) { + if (kpmVersion.isNotEmpty() && !kpmVersion.startsWith("Error")) { + if (!fullFeatured && destination.rootRequired) return@forEach + val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction) + NavigationBarItem( + selected = isCurrentDestOnBackStack, + onClick = { + if (isCurrentDestOnBackStack) { + navigator.popBackStack(destination.direction, false) + } + navigator.navigate(destination.direction) { + popUpTo(NavGraphs.root) { + saveState = true + } + launchSingleTop = true + restoreState = true + } + }, + icon = { + if (isCurrentDestOnBackStack) { + Icon(destination.iconSelected, stringResource(destination.label)) + } else { + Icon(destination.iconNotSelected, stringResource(destination.label)) + } + }, + label = { Text(stringResource(destination.label)) }, + alwaysShowLabel = false, + colors = androidx.compose.material3.NavigationBarItemDefaults.colors( + unselectedTextColor = MaterialTheme.colorScheme.onSurfaceVariant + ) + ) + } + } else { + if (!fullFeatured && destination.rootRequired) return@forEach + val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction) + NavigationBarItem( + selected = isCurrentDestOnBackStack, + onClick = { + if (isCurrentDestOnBackStack) { + navigator.popBackStack(destination.direction, false) } - launchSingleTop = true - restoreState = true - } - }, - icon = { - if (isCurrentDestOnBackStack) { - Icon(destination.iconSelected, stringResource(destination.label)) - } else { - Icon(destination.iconNotSelected, stringResource(destination.label)) - } - }, - label = { Text(stringResource(destination.label)) }, - alwaysShowLabel = false, - colors = androidx.compose.material3.NavigationBarItemDefaults.colors( - unselectedTextColor = MaterialTheme.colorScheme.onSurfaceVariant + navigator.navigate(destination.direction) { + popUpTo(NavGraphs.root) { + saveState = true + } + launchSingleTop = true + restoreState = true + } + }, + icon = { + if (isCurrentDestOnBackStack) { + Icon(destination.iconSelected, stringResource(destination.label)) + } else { + Icon(destination.iconNotSelected, stringResource(destination.label)) + } + }, + label = { Text(stringResource(destination.label)) }, + alwaysShowLabel = false, + colors = androidx.compose.material3.NavigationBarItemDefaults.colors( + unselectedTextColor = MaterialTheme.colorScheme.onSurfaceVariant + ) ) - ) + } } } } \ No newline at end of file diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/BottomBarDestination.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/BottomBarDestination.kt index 285acbd9..0812085b 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/BottomBarDestination.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/BottomBarDestination.kt @@ -21,8 +21,8 @@ enum class BottomBarDestination( val rootRequired: Boolean, ) { Home(HomeScreenDestination, R.string.home, Icons.Filled.Home, Icons.Outlined.Home, false), + Kpm(KpmScreenDestination, R.string.kpm_title, Icons.Filled.Build, Icons.Outlined.Build, true), SuperUser(SuperUserScreenDestination, R.string.superuser, Icons.Filled.Security, Icons.Outlined.Security, true), Module(ModuleScreenDestination, R.string.module, Icons.Filled.Apps, Icons.Outlined.Apps, true), - Kpm(KpmScreenDestination, R.string.kpm_title, Icons.Filled.Build, Icons.Outlined.Build, true), Settings(SettingScreenDestination, R.string.settings, Icons.Filled.Settings, Icons.Outlined.Settings, false), } diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt index 51fc6f33..0e407dd8 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/Home.kt @@ -51,6 +51,10 @@ import androidx.compose.animation.shrinkVertically import androidx.compose.runtime.saveable.rememberSaveable import shirkneko.zako.sukisu.ui.theme.CardConfig import androidx.core.content.edit +import java.io.BufferedReader +import java.io.InputStreamReader +import java.util.Scanner +import java.util.zip.GZIPInputStream import kotlin.random.Random @OptIn(ExperimentalMaterial3Api::class) @@ -333,6 +337,14 @@ private fun StatusCard( text = stringResource(R.string.home_module_count, getModuleCount()), style = MaterialTheme.typography.bodyMedium ) + val kpmVersion = getKpmVersion() + if (kpmVersion.isNotEmpty() && !kpmVersion.startsWith("Error")) { + Spacer(Modifier.height(4.dp)) + Text( + text = stringResource(R.string.home_kpm_module, getKpmModuleCount()), + style = MaterialTheme.typography.bodyMedium + ) + } Spacer(modifier = Modifier.height(4.dp)) val suSFS = getSuSFS() @@ -555,18 +567,28 @@ private fun InfoCard() { InfoCardItem(stringResource(R.string.home_selinux_status), getSELinuxStatus()) - if (!isSimpleMode){ - Spacer(Modifier.height(16.dp)) + + if (!isSimpleMode) { val kpmVersion = getKpmVersion() - val displayVersion = if (kpmVersion.isEmpty() || kpmVersion.startsWith("Error")) { - stringResource(R.string.not_supported) + var displayVersion: String + val isKpmConfigured = checkKpmConfigured() + + if (kpmVersion.isEmpty() || kpmVersion.startsWith("Error")) { + val statusText = if (isKpmConfigured) { + stringResource(R.string.kernel_patched) + } else { + stringResource(R.string.kernel_not_enabled) + } + displayVersion = "${stringResource(R.string.not_supported)} ($statusText)" } else { - kpmVersion + displayVersion = "${stringResource(R.string.supported)} ($kpmVersion)" } + Spacer(Modifier.height(16.dp)) InfoCardItem(stringResource(R.string.home_kpm_version), displayVersion) } + if (!isSimpleMode) { Spacer(modifier = Modifier.height(16.dp)) @@ -645,4 +667,24 @@ private fun getDeviceModel(context: Context): String { } catch (e: Exception) { Build.DEVICE } +} + +private fun checkKpmConfigured(): Boolean { + try { + val process = Runtime.getRuntime().exec("su -c cat /proc/config.gz") + val inputStream = process.inputStream + val gzipInputStream = GZIPInputStream(inputStream) + val reader = BufferedReader(InputStreamReader(gzipInputStream)) + + var line: String? + while (reader.readLine().also { line = it } != null) { + if (line?.contains("CONFIG_KPM=y") == true) { + return true + } + } + reader.close() + } catch (e: Exception) { + e.printStackTrace() + } + return false } \ No newline at end of file diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/kpm.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/kpm.kt index 3ab01997..d3a59f39 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/kpm.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/kpm.kt @@ -4,8 +4,6 @@ import android.content.Intent import android.util.Log import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.SpringSpec import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items @@ -92,6 +90,15 @@ fun KpmScreen( } } + if (!tempFile.name.endsWith(".kpm")) { + snackBarHost.showSnackbar( + message = "文件类型不正确,请选择 .kpm 文件", + duration = SnackbarDuration.Short + ) + tempFile.delete() + return@launch + } + val confirmResult = confirmDialog.awaitConfirm( title = kpmInstall, content = kpmInstallConfirm, @@ -102,10 +109,15 @@ fun KpmScreen( if (confirmResult == ConfirmResult.Confirmed) { val success = loadingDialog.withLoading { try { - loadKpmModule(tempFile.absolutePath) - true + val loadResult = loadKpmModule(tempFile.absolutePath) + if (true && loadResult.startsWith("Error")) { + Log.e("KsuCli", "Failed to load KPM module: $loadResult") + false + } else { + true + } } catch (e: Exception) { - Log.e("KsuCli", "Failed to load KPM module: ${e.message}") + Log.e("KsuCli", "Failed to load KPM module: ${e.message}", e) false } } @@ -234,13 +246,19 @@ fun KpmScreen( if (confirmResult == ConfirmResult.Confirmed) { val success = loadingDialog.withLoading { try { - unloadKpmModule(module.id) - true + val unloadResult = unloadKpmModule(module.id) + if (true && unloadResult.startsWith("Error")) { + Log.e("KsuCli", "Failed to unload KPM module: $unloadResult") + false + } else { + true + } } catch (e: Exception) { - Log.e("KsuCli", "Failed to unload KPM module: ${e.message}") + Log.e("KsuCli", "Failed to unload KPM module: ${e.message}", e) false } } + if (success) { viewModel.fetchModuleList() snackBarHost.showSnackbar( diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/util/KsuCli.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/util/KsuCli.kt index 9cd8bd29..178531d6 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/util/KsuCli.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/util/KsuCli.kt @@ -486,18 +486,16 @@ private fun getKpmmgrPath(): String { } -fun loadKpmModule(path: String, args: String? = null): Boolean { +fun loadKpmModule(path: String, args: String? = null): String { val shell = getRootShell() val cmd = "${getKpmmgrPath()} load $path ${args ?: ""}" - val result = ShellUtils.fastCmd(shell, cmd) - return result.contains("Success", ignoreCase = true) + return ShellUtils.fastCmd(shell, cmd) } -fun unloadKpmModule(name: String): Boolean { +fun unloadKpmModule(name: String): String { val shell = getRootShell() val cmd = "${getKpmmgrPath()} unload $name" - val result = ShellUtils.fastCmd(shell, cmd) - return result.trim().isEmpty() || result.trim() == "0" + return ShellUtils.fastCmd(shell, cmd) } fun getKpmModuleCount(): Int { 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 cf8d3779..c9dc4555 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -239,6 +239,11 @@ 成功 错误 不支持 + 支持 + KPM 模块数:%d + KPM 文件无效 + 内核未进行补丁 + 内核未配置 以下内核模块功能由KernelPatch开发,经过修改后加入SukiSU Ultra的内核模块功能 SukiSU Ultra展望 SukiSU Ultra未来将会成为一个相对独立的KSU分支,但是依然感谢官方KernelSU和MKSU等做出的贡献 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index a38c2904..98ba0564 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -245,4 +245,9 @@ failed SukiSU Ultra will be a relatively independent branch of KSU in the future, but thanks to the official KernelSU and MKSU etc. for their contributions! unsupported + supported + Number of KPM modules:%d + Invalid KPM file + Kernel not patched + Kernel not configured From 8a6507e83406f4b9c07889538274678ac03c716c Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Thu, 3 Apr 2025 23:19:50 +0800 Subject: [PATCH 6/6] Manager: Add clean mode switch and option to hide kernel version number --- .../zako/sukisu/ui/screen/MoreSettings.kt | 46 ++++++++++++------- .../src/main/res/values-zh-rCN/strings.xml | 1 + manager/app/src/main/res/values/strings.xml | 1 + 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/MoreSettings.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/MoreSettings.kt index 3e1409c5..741d24cf 100644 --- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/MoreSettings.kt +++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/screen/MoreSettings.kt @@ -210,24 +210,36 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { } } - // 添加简洁模块开关 - SwitchItem( - icon = Icons.Filled.FormatPaint, - title = stringResource(R.string.simple_mode), - summary = stringResource(R.string.simple_mode_summary), - checked = isSimpleMode - ) { - onSimpleModeChange(it) - } + var isExpanded by remember { mutableStateOf(false) } - // 隐藏内核部分版本号 - SwitchItem( - icon = Icons.Filled.FormatPaint, - title = stringResource(R.string.hide_kernel_kernelsu_version), - summary = stringResource(R.string.hide_kernel_kernelsu_version_summary), - checked = isHideVersion - ) { - onHideVersionChange(it) + ListItem( + leadingContent = { Icon(Icons.Filled.FormatPaint, null) }, + headlineContent = { Text(stringResource(R.string.more_settings_simplicity_mode)) }, + modifier = Modifier.clickable { + isExpanded = !isExpanded + } + ) + + if (isExpanded) { + // 添加简洁模块开关 + SwitchItem( + icon = Icons.Filled.Brush, + title = stringResource(R.string.simple_mode), + summary = stringResource(R.string.simple_mode_summary), + checked = isSimpleMode + ) { + onSimpleModeChange(it) + } + + // 隐藏内核部分版本号 + SwitchItem( + icon = Icons.Filled.VisibilityOff, + title = stringResource(R.string.hide_kernel_kernelsu_version), + summary = stringResource(R.string.hide_kernel_kernelsu_version_summary), + checked = isHideVersion + ) { + onHideVersionChange(it) + } } // region SUSFS 配置(仅在支持时显示) 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 c9dc4555..cf2ccf64 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -247,4 +247,5 @@ 以下内核模块功能由KernelPatch开发,经过修改后加入SukiSU Ultra的内核模块功能 SukiSU Ultra展望 SukiSU Ultra未来将会成为一个相对独立的KSU分支,但是依然感谢官方KernelSU和MKSU等做出的贡献 + 简洁模式 \ No newline at end of file diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index 98ba0564..d118cbfd 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -250,4 +250,5 @@ Invalid KPM file Kernel not patched Kernel not configured + simplicity mode