From 1238a17a8a2c3c2652a8222bb6c89e152183d4b7 Mon Sep 17 00:00:00 2001
From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Date: Sat, 29 Mar 2025 21:09:27 +0800
Subject: [PATCH 1/9] Update setup.sh
---
kernel/setup.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/setup.sh b/kernel/setup.sh
index c4a3f597..3d042f9e 100755
--- a/kernel/setup.sh
+++ b/kernel/setup.sh
@@ -39,7 +39,7 @@ perform_cleanup() {
# Sets up or update KernelSU environment
setup_kernelsu() {
echo "[+] Setting up KernelSU..."
- test -d "$GKI_ROOT/KernelSU" || git clone https://github.com/ShirkNeko/KernelSU && echo "[+] Repository cloned."
+ test -d "$GKI_ROOT/KernelSU" || git clone https://github.com/ShirkNeko/SukiSU-Ultra && echo "[+] Repository cloned."
cd "$GKI_ROOT/KernelSU"
git stash && echo "[-] Stashed current changes."
if [ "$(git status | grep -Po 'v\d+(\.\d+)*' | head -n1)" ]; then
From 157e65418e7375cb40b230dfc3a7c7171b79cb2c Mon Sep 17 00:00:00 2001
From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Date: Sat, 29 Mar 2025 21:35:45 +0800
Subject: [PATCH 2/9] manager: update setup_kernelsu to clone and rename
repository to KernelSU
---
kernel/setup.sh | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/kernel/setup.sh b/kernel/setup.sh
index 3d042f9e..973b86be 100755
--- a/kernel/setup.sh
+++ b/kernel/setup.sh
@@ -39,7 +39,12 @@ perform_cleanup() {
# Sets up or update KernelSU environment
setup_kernelsu() {
echo "[+] Setting up KernelSU..."
- test -d "$GKI_ROOT/KernelSU" || git clone https://github.com/ShirkNeko/SukiSU-Ultra && echo "[+] Repository cloned."
+ # Clone the repository and rename it to KernelSU
+ if [ ! -d "$GKI_ROOT/KernelSU" ]; then
+ git clone https://github.com/ShirkNeko/SukiSU-Ultra SukiSU-Ultra
+ mv SukiSU-Ultra KernelSU
+ echo "[+] Repository cloned and renamed to KernelSU."
+ fi
cd "$GKI_ROOT/KernelSU"
git stash && echo "[-] Stashed current changes."
if [ "$(git status | grep -Po 'v\d+(\.\d+)*' | head -n1)" ]; then
@@ -72,4 +77,4 @@ elif [ "$1" = "--cleanup" ]; then
else
initialize_variables
setup_kernelsu "$@"
-fi
+fi
\ No newline at end of file
From 4eb3ec8197068c96e4e6d19f4fba0d751d75810e Mon Sep 17 00:00:00 2001
From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Date: Sat, 29 Mar 2025 21:40:49 +0800
Subject: [PATCH 3/9] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3?=
=?UTF-8?q?=E4=B8=AD=E7=9A=84setup.sh=E9=93=BE=E6=8E=A5=EF=BC=8C=E6=8C=87?=
=?UTF-8?q?=E5=90=91SukiSU-Ultra=E4=BB=93=E5=BA=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/README-en.md | 4 ++--
docs/README.md | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/README-en.md b/docs/README-en.md
index feafdd20..a9758616 100644
--- a/docs/README-en.md
+++ b/docs/README-en.md
@@ -17,12 +17,12 @@ Android device root solution based on [KernelSU](https://github.com/KernelSU/Ker
Using the susfs-dev branch (integrated susfs with support for non-GKI devices)
```
-curl -LSs "https://raw.githubusercontent.com/ShirkNeko/KernelSU/main/kernel/setup.sh" | bash -s susfs-dev
+curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-dev
```
Use main branching (no longer with support for non-GKI devices)
```
-curl -LSs "https://raw.githubusercontent.com/ShirkNeko/KernelSU/main/kernel/setup.sh" | bash -s main
+curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
## How to use integrated susfs
diff --git a/docs/README.md b/docs/README.md
index 90e7a0f6..0b3f1524 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -17,12 +17,12 @@
使用 susfs-dev 分支(已集成susfs,带非GKI设备的支持)
```
-curl -LSs "https://raw.githubusercontent.com/ShirkNeko/KernelSU/main/kernel/setup.sh" | bash -s susfs-dev
+curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/setup.sh" | bash -s susfs-dev
```
使用 main 分支(不再带非GKI设备的支持)
```
-curl -LSs "https://raw.githubusercontent.com/ShirkNeko/KernelSU/main/kernel/setup.sh" | bash -s main
+curl -LSs "https://raw.githubusercontent.com/ShirkNeko/SukiSU-Ultra/main/kernel/setup.sh" | bash -s main
```
## 如何集成 susfs
From a337472ac7410f4dc686ba3f28cba5dd845914df Mon Sep 17 00:00:00 2001
From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Date: Sun, 30 Mar 2025 02:06:13 +0800
Subject: [PATCH 4/9] Update Downloader.kt
---
.../src/main/java/shirkneko/zako/sukisu/ui/util/Downloader.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/util/Downloader.kt b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/util/Downloader.kt
index e3ff97b7..8791f492 100644
--- a/manager/app/src/main/java/shirkneko/zako/sukisu/ui/util/Downloader.kt
+++ b/manager/app/src/main/java/shirkneko/zako/sukisu/ui/util/Downloader.kt
@@ -64,7 +64,7 @@ fun download(
fun checkNewVersion(): LatestVersionInfo {
// 改为新的 release 接口
- val url = "https://api.github.com/repos/ShirkNeko/KernelSU/releases/latest"
+ val url = "https://api.github.com/repos/ShirkNeko/SukiSU-Ultra/releases/latest"
val defaultValue = LatestVersionInfo()
return runCatching {
okhttp3.OkHttpClient().newCall(okhttp3.Request.Builder().url(url).build()).execute()
From 321c9c20d56d530de974a829ce5a4ceb0b1b530e Mon Sep 17 00:00:00 2001
From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Date: Sun, 30 Mar 2025 18:24:20 +0800
Subject: [PATCH 5/9] Manager: simplify and fix SUSFS version display errors
Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
---
.../shirkneko/zako/sukisu/ui/screen/Home.kt | 64 ++++++++-----------
1 file changed, 27 insertions(+), 37 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 e2ca76d3..852f6079 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
@@ -478,7 +478,7 @@ private fun InfoCard() {
modifier = Modifier
.fillMaxWidth()
.padding(start = 24.dp, top = 24.dp, end = 24.dp, bottom = 16.dp)
- ) {
+ ) withContext@{
val contents = StringBuilder()
val uname = Os.uname()
@@ -492,7 +492,7 @@ private fun InfoCard() {
Text(text = content, style = MaterialTheme.typography.bodyMedium)
}
- InfoCardItem(stringResource(R.string.home_kernel), uname.release)
+ InfoCardItem(stringResource(R.string.home_kernel), uname.release)
if (!isSimpleMode) {
Spacer(Modifier.height(16.dp))
@@ -501,23 +501,23 @@ private fun InfoCard() {
}
- Spacer(Modifier.height(16.dp))
- val deviceModel = getDeviceModel(context)
- InfoCardItem(stringResource(R.string.home_device_model), deviceModel)
+ Spacer(Modifier.height(16.dp))
+ val deviceModel = getDeviceModel(context)
+ InfoCardItem(stringResource(R.string.home_device_model), deviceModel)
- Spacer(Modifier.height(16.dp))
- val managerVersion = getManagerVersion(context)
- InfoCardItem(
- stringResource(R.string.home_manager_version),
- "${managerVersion.first} (${managerVersion.second})"
- )
+ Spacer(Modifier.height(16.dp))
+ val managerVersion = getManagerVersion(context)
+ InfoCardItem(
+ stringResource(R.string.home_manager_version),
+ "${managerVersion.first} (${managerVersion.second})"
+ )
- Spacer(Modifier.height(16.dp))
- InfoCardItem(stringResource(R.string.home_selinux_status), getSELinuxStatus())
+ Spacer(Modifier.height(16.dp))
+ InfoCardItem(stringResource(R.string.home_selinux_status), getSELinuxStatus())
if (!isSimpleMode) {
@@ -525,33 +525,23 @@ private fun InfoCard() {
val suSFS = getSuSFS()
if (suSFS == "Supported") {
+ val suSFSVersion = getSuSFSVersion()
+ if (suSFSVersion.isEmpty()) return@withContext
+ val isSUS_SU = getSuSFSFeatures() == "CONFIG_KSU_SUSFS_SUS_SU"
+ val infoText = buildString {
+ append(suSFSVersion)
+ append(if (isSUS_SU) " (${getSuSFSVariant()})" else " (${stringResource(R.string.manual_hook)})")
+ if (isSUS_SU) {
+ val susSUMode = try { susfsSUS_SU_Mode().toString() } catch (_: Exception) { "" }
+ if (susSUMode.isNotEmpty()) {
+ append(" ${stringResource(R.string.sus_su_mode)} $susSUMode")
+ }
+ }
+ }
InfoCardItem(
stringResource(R.string.home_susfs_version),
- "${getSuSFSVersion()} (${stringResource(R.string.manual_hook)})"
+ infoText
)
- } else {
- val susSUMode = try {
- susfsSUS_SU_Mode()
- } catch (e: Exception) {
- 0
- }
-
- if (susSUMode == 2 || susSUMode == 0) {
- val isSUS_SU = getSuSFSFeatures() == "CONFIG_KSU_SUSFS_SUS_SU"
- val susSUModeLabel = stringResource(R.string.sus_su_mode)
- val susSUModeValue = susSUMode.toString()
- val susSUModeText = if (isSUS_SU) " $susSUModeLabel $susSUModeValue" else ""
-
- InfoCardItem(
- stringResource(R.string.home_susfs_version),
- "${getSuSFSVersion()} (${getSuSFSVariant()})$susSUModeText"
- )
- } else {
- InfoCardItem(
- stringResource(R.string.home_susfs_version),
- "${getSuSFSVersion()} (${stringResource(R.string.manual_hook)})"
- )
- }
}
}
}
From e4c70e2efbd3b720b30d94902a9ad8e5be3426b2 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 6/9] 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 d55af7626063ece666b52c251a8614a9d5b045b0 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 7/9] 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 46e4c85563a8e0e3da583087ce620bb97add0706 Mon Sep 17 00:00:00 2001
From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
Date: Wed, 2 Apr 2025 22:58:13 +0800
Subject: [PATCH 8/9] Add missing package names
---
.../app/src/main/java/shirkneko/zako/sukisu/ui/screen/kpm.kt | 2 ++
1 file changed, 2 insertions(+)
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 d3a59f39..5165332a 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
@@ -1,3 +1,5 @@
+package shirkneko.zako.sukisu.ui.screen
+
import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
From 13d22902057fa59b5c0c2ba4078717ac658d6044 Mon Sep 17 00:00:00 2001
From: WenHao2130 <98936399+WenHao2130@users.noreply.github.com>
Date: Thu, 3 Apr 2025 15:59:00 +0800
Subject: [PATCH 9/9] manager: optimize layout
Signed-off-by: WenHao2130
---
manager/app/src/main/res/values-zh-rCN/strings.xml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
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..8fdc291c 100644
--- a/manager/app/src/main/res/values-zh-rCN/strings.xml
+++ b/manager/app/src/main/res/values-zh-rCN/strings.xml
@@ -229,10 +229,10 @@
确定要卸载内核模块 %1$s 吗?
卸载成功
卸载失败
- 加载kpm模块
+ 加载 kpm 模块
确认加载吗?
- 加载kpm模块成功
- 加载kpm模块失败
+ 加载 kpm 模块成功
+ 加载 kpm 模块失败
KPM 版本
执行
关闭
@@ -244,7 +244,7 @@
KPM 文件无效
内核未进行补丁
内核未配置
- 以下内核模块功能由KernelPatch开发,经过修改后加入SukiSU Ultra的内核模块功能
- SukiSU Ultra展望
- SukiSU Ultra未来将会成为一个相对独立的KSU分支,但是依然感谢官方KernelSU和MKSU等做出的贡献
-
\ No newline at end of file
+ 以下内核模块功能由 KernelPatch 开发,经过修改后加入 SukiSU Ultra 的内核模块功能
+ SukiSU Ultra 展望
+ SukiSU Ultra 未来将会成为一个相对独立的 KernelSU 分支,但是依然感谢官方 KernelSU 和 MKSU 等做出的贡献
+