[skip ci]: Update kpm module display logic, fix installed and uninstalled name display

This commit is contained in:
ShirkNeko
2025-04-25 14:00:18 +08:00
parent 34f216181f
commit e07f20bf29
8 changed files with 45 additions and 19 deletions

View File

@@ -32,15 +32,16 @@ import com.sukisu.ultra.ui.util.*
import java.io.File import java.io.File
import androidx.core.content.edit import androidx.core.content.edit
import com.sukisu.ultra.R import com.sukisu.ultra.R
import java.io.BufferedReader
import java.io.FileInputStream import java.io.FileInputStream
import java.io.InputStreamReader
import java.net.* import java.net.*
/** /**
* KPM 管理界面 * KPM 管理界面
* 以下内核模块功能由KernelPatch开发经过修改后加入SukiSU Ultra的内核模块功能 * 以下内核模块功能由KernelPatch开发经过修改后加入SukiSU Ultra的内核模块功能
* 开发者:zako, Liaokong * 开发者:ShirkNeko, Liaokong
*/ */
var globalModuleFileName: String = ""
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Destination<RootGraph> @Destination<RootGraph>
@Composable @Composable
@@ -58,6 +59,11 @@ fun KpmScreen(
MaterialTheme.colorScheme.secondaryContainer MaterialTheme.colorScheme.secondaryContainer
} }
val moduleConfirmContentMap = viewModel.moduleList.associate { module ->
val moduleFileName = module.id
module.id to stringResource(R.string.confirm_uninstall_content, moduleFileName)
}
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
val kpmInstallSuccess = stringResource(R.string.kpm_install_success) val kpmInstallSuccess = stringResource(R.string.kpm_install_success)
@@ -70,13 +76,33 @@ fun KpmScreen(
val kpmInstallMode = stringResource(R.string.kpm_install_mode) val kpmInstallMode = stringResource(R.string.kpm_install_mode)
val kpmInstallModeLoad = stringResource(R.string.kpm_install_mode_load) val kpmInstallModeLoad = stringResource(R.string.kpm_install_mode_load)
val kpmInstallModeEmbed = stringResource(R.string.kpm_install_mode_embed) val kpmInstallModeEmbed = stringResource(R.string.kpm_install_mode_embed)
val kpmInstallModeDescription = stringResource(R.string.kpm_install_mode_description)
val invalidFileTypeMessage = stringResource(R.string.invalid_file_type) val invalidFileTypeMessage = stringResource(R.string.invalid_file_type)
val confirmTitle = stringResource(R.string.confirm_uninstall_title_with_filename) val confirmTitle = stringResource(R.string.confirm_uninstall_title_with_filename)
val confirmContent = stringResource(R.string.confirm_uninstall_content, globalModuleFileName)
var tempFileForInstall by remember { mutableStateOf<File?>(null) } var tempFileForInstall by remember { mutableStateOf<File?>(null) }
val installModeDialog = rememberCustomDialog { dismiss -> val installModeDialog = rememberCustomDialog { dismiss ->
var moduleName by remember { mutableStateOf<String?>(null) }
LaunchedEffect(tempFileForInstall) {
tempFileForInstall?.let { tempFile ->
try {
val command = arrayOf("su", "-c", "strings ${tempFile.absolutePath} | grep 'name='")
val process = Runtime.getRuntime().exec(command)
val inputStream = process.inputStream
val reader = BufferedReader(InputStreamReader(inputStream))
var line: String?
while (reader.readLine().also { line = it } != null) {
if (line!!.startsWith("name=")) {
moduleName = line.substringAfter("name=").trim()
break
}
}
process.waitFor()
} catch (e: Exception) {
Log.e("KsuCli", "Failed to get module name: ${e.message}", e)
}
}
}
AlertDialog( AlertDialog(
onDismissRequest = { onDismissRequest = {
dismiss() dismiss()
@@ -84,7 +110,7 @@ fun KpmScreen(
tempFileForInstall = null tempFileForInstall = null
}, },
title = { Text(kpmInstallMode) }, title = { Text(kpmInstallMode) },
text = { Text(kpmInstallModeDescription) }, text = { moduleName?.let { Text(stringResource(R.string.kpm_install_mode_description, it)) } },
confirmButton = { confirmButton = {
Column { Column {
Button( Button(
@@ -288,6 +314,7 @@ fun KpmScreen(
module = module, module = module,
onUninstall = { onUninstall = {
scope.launch { scope.launch {
val confirmContent = moduleConfirmContentMap[module.id] ?: ""
handleModuleUninstall( handleModuleUninstall(
module = module, module = module,
viewModel = viewModel, viewModel = viewModel,
@@ -327,7 +354,7 @@ private suspend fun handleModuleInstall(
val command = arrayOf("su", "-c", "strings ${tempFile.absolutePath} | grep 'name='") val command = arrayOf("su", "-c", "strings ${tempFile.absolutePath} | grep 'name='")
val process = Runtime.getRuntime().exec(command) val process = Runtime.getRuntime().exec(command)
val inputStream = process.inputStream val inputStream = process.inputStream
val reader = java.io.BufferedReader(java.io.InputStreamReader(inputStream)) val reader = BufferedReader(InputStreamReader(inputStream))
var line: String? var line: String?
while (reader.readLine().also { line = it } != null) { while (reader.readLine().also { line = it } != null) {
if (line!!.startsWith("name=")) { if (line!!.startsWith("name=")) {
@@ -396,7 +423,6 @@ private suspend fun handleModuleUninstall(
confirmDialog: ConfirmDialogHandle confirmDialog: ConfirmDialogHandle
) { ) {
val moduleFileName = "${module.id}.kpm" val moduleFileName = "${module.id}.kpm"
globalModuleFileName = moduleFileName
val moduleFilePath = "/data/adb/kpm/$moduleFileName" val moduleFilePath = "/data/adb/kpm/$moduleFileName"
val fileExists = try { val fileExists = try {
@@ -571,7 +597,7 @@ private fun checkStringsCommand(tempFile: File): Int {
val command = arrayOf("su", "-c", "strings ${tempFile.absolutePath} | grep -E 'name=|version=|license=|author='") val command = arrayOf("su", "-c", "strings ${tempFile.absolutePath} | grep -E 'name=|version=|license=|author='")
val process = Runtime.getRuntime().exec(command) val process = Runtime.getRuntime().exec(command)
val inputStream = process.inputStream val inputStream = process.inputStream
val reader = java.io.BufferedReader(java.io.InputStreamReader(inputStream)) val reader = BufferedReader(InputStreamReader(inputStream))
var line: String? var line: String?
var matchCount = 0 var matchCount = 0
val keywords = listOf("name=", "version=", "license=", "author=") val keywords = listOf("name=", "version=", "license=", "author=")

View File

@@ -13,6 +13,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.sukisu.ultra.ui.util.module.LatestVersionInfo import com.sukisu.ultra.ui.util.module.LatestVersionInfo
import androidx.core.net.toUri
/** /**
* @author weishu * @author weishu
@@ -42,14 +43,14 @@ fun download(
onDownloading() onDownloading()
return return
} else if (status == DownloadManager.STATUS_SUCCESSFUL) { } else if (status == DownloadManager.STATUS_SUCCESSFUL) {
onDownloaded(Uri.parse(localUri)) onDownloaded(localUri.toUri())
return return
} }
} }
} }
} }
val request = DownloadManager.Request(Uri.parse(url)) val request = DownloadManager.Request(url.toUri())
.setDestinationInExternalPublicDir( .setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS, Environment.DIRECTORY_DOWNLOADS,
fileName fileName
@@ -140,7 +141,7 @@ fun DownloadListener(context: Context, onDownloaded: (Uri) -> Unit) {
val uri = cursor.getString( val uri = cursor.getString(
cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI) cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)
) )
onDownloaded(Uri.parse(uri)) onDownloaded(uri.toUri())
} }
} }
} }

View File

@@ -19,7 +19,7 @@ public class UltraShellHelper {
} }
public static boolean isPathExists(String path) { public static boolean isPathExists(String path) {
return !runCmd("file " + path).contains("No such file or directory"); return runCmd("file " + path).contains("No such file or directory");
} }
public static void CopyFileTo(String path, String target) { public static void CopyFileTo(String path, String target) {

View File

@@ -8,12 +8,12 @@ public class UltraToolInstall {
private static final String OUTSIDE_SUSFSD_PATH = "/data/adb/ksu/bin/susfsd"; private static final String OUTSIDE_SUSFSD_PATH = "/data/adb/ksu/bin/susfsd";
public static void tryToInstall() { public static void tryToInstall() {
String kpmmgrPath = getKpmmgrPath(); String kpmmgrPath = getKpmmgrPath();
if (!UltraShellHelper.isPathExists(OUTSIDE_KPMMGR_PATH)) { if (UltraShellHelper.isPathExists(OUTSIDE_KPMMGR_PATH)) {
UltraShellHelper.CopyFileTo(kpmmgrPath, OUTSIDE_KPMMGR_PATH); UltraShellHelper.CopyFileTo(kpmmgrPath, OUTSIDE_KPMMGR_PATH);
UltraShellHelper.runCmd("chmod a+rx " + OUTSIDE_KPMMGR_PATH); UltraShellHelper.runCmd("chmod a+rx " + OUTSIDE_KPMMGR_PATH);
} }
String SuSFSDaemonPath = getSuSFSDaemonPath(); String SuSFSDaemonPath = getSuSFSDaemonPath();
if (!UltraShellHelper.isPathExists(OUTSIDE_SUSFSD_PATH)) { if (UltraShellHelper.isPathExists(OUTSIDE_SUSFSD_PATH)) {
UltraShellHelper.CopyFileTo(SuSFSDaemonPath, OUTSIDE_SUSFSD_PATH); UltraShellHelper.CopyFileTo(SuSFSDaemonPath, OUTSIDE_SUSFSD_PATH);
UltraShellHelper.runCmd("chmod a+rx " + OUTSIDE_SUSFSD_PATH); UltraShellHelper.runCmd("chmod a+rx " + OUTSIDE_SUSFSD_PATH);
} }

View File

@@ -257,7 +257,7 @@
<string name="kpm_install_mode">インストール</string> <string name="kpm_install_mode">インストール</string>
<string name="kpm_install_mode_load">読み込む</string> <string name="kpm_install_mode_load">読み込む</string>
<string name="kpm_install_mode_embed">埋め込む</string> <string name="kpm_install_mode_embed">埋め込む</string>
<string name="kpm_install_mode_description">モジュールのインストールモードを選択してください:\n\n読み込む: モジュールを一時的に読み込みます\n埋め込む: システムに恒久的にインストールします</string> <string name="kpm_install_mode_description">モジュール%1\$s のインストールモードを選択してください \n\n読み込む: モジュールを一時的に読み込みます\n埋め込む: システムに恒久的にインストールします</string>
<string name="log_failed_to_check_module_file">モジュールファイルの存在を確認できませんでした</string> <string name="log_failed_to_check_module_file">モジュールファイルの存在を確認できませんでした</string>
<string name="snackbar_failed_to_check_module_file">モジュールファイルが存在するか確認できません</string> <string name="snackbar_failed_to_check_module_file">モジュールファイルが存在するか確認できません</string>
<string name="confirm_uninstall_title">アンインストールを確認</string> <string name="confirm_uninstall_title">アンインストールを確認</string>

View File

@@ -253,7 +253,7 @@
<string name="kpm_install_mode">Cài đặt</string> <string name="kpm_install_mode">Cài đặt</string>
<string name="kpm_install_mode_load">Tải</string> <string name="kpm_install_mode_load">Tải</string>
<string name="kpm_install_mode_embed">Nhúng</string> <string name="kpm_install_mode_embed">Nhúng</string>
<string name="kpm_install_mode_description">Vui lòng chọn chế độ cài đặt mô-đun: \n\nTải: Tải tạm thời mô-đun \nNhúng: Cài đặt vĩnh viễn vào hệ thống</string> <string name="kpm_install_mode_description">Vui lòng%1\$s chọn chế độ cài đặt mô-đun \n\nTải: Tải tạm thời mô-đun \nNhúng: Cài đặt vĩnh viễn vào hệ thống</string>
<string name="log_failed_to_check_module_file">Không kiểm tra được sự tồn tại của tệp mô-đun</string> <string name="log_failed_to_check_module_file">Không kiểm tra được sự tồn tại của tệp mô-đun</string>
<string name="snackbar_failed_to_check_module_file">Không thể kiểm tra xem tệp mô-đun có tồn tại không</string> <string name="snackbar_failed_to_check_module_file">Không thể kiểm tra xem tệp mô-đun có tồn tại không</string>
<string name="confirm_uninstall_title">Xác nhận gỡ cài đặt</string> <string name="confirm_uninstall_title">Xác nhận gỡ cài đặt</string>

View File

@@ -253,7 +253,7 @@
<string name="kpm_install_mode">安装</string> <string name="kpm_install_mode">安装</string>
<string name="kpm_install_mode_load">加载</string> <string name="kpm_install_mode_load">加载</string>
<string name="kpm_install_mode_embed">嵌入</string> <string name="kpm_install_mode_embed">嵌入</string>
<string name="kpm_install_mode_description">请选择模块安装模式\n\n加载临时加载模块\n嵌入永久安装到系统</string> <string name="kpm_install_mode_description">请选择: %1\$s 模块安装模式 \n\n加载临时加载模块\n嵌入永久安装到系统</string>
<string name="snackbar_failed_to_check_module_file">无法检查模块文件是否存在</string> <string name="snackbar_failed_to_check_module_file">无法检查模块文件是否存在</string>
<string name="confirm_uninstall_title">确认卸载</string> <string name="confirm_uninstall_title">确认卸载</string>
<string name="confirm_uninstall_confirm">删除</string> <string name="confirm_uninstall_confirm">删除</string>
@@ -262,5 +262,4 @@
<string name="invalid_file_type">文件类型不正确,请选择 .kpm 文件</string> <string name="invalid_file_type">文件类型不正确,请选择 .kpm 文件</string>
<string name="confirm_uninstall_title_with_filename">卸载</string> <string name="confirm_uninstall_title_with_filename">卸载</string>
<string name="confirm_uninstall_content">将卸载以下 kpm 模块:\n%s</string> <string name="confirm_uninstall_content">将卸载以下 kpm 模块:\n%s</string>
</resources> </resources>

View File

@@ -255,7 +255,7 @@
<string name="kpm_install_mode">KPM Install</string> <string name="kpm_install_mode">KPM Install</string>
<string name="kpm_install_mode_load">Load</string> <string name="kpm_install_mode_load">Load</string>
<string name="kpm_install_mode_embed">Embed</string> <string name="kpm_install_mode_embed">Embed</string>
<string name="kpm_install_mode_description">Please select the module installation mode: \n\nLoad: Temporarily load the module \nEmbedded: Permanently install into the system</string> <string name="kpm_install_mode_description">Please select: %1\$s Module Installation Mode \n\nLoad: Temporarily load the module \nEmbedded: Permanently install into the system</string>
<string name="log_failed_to_check_module_file">Failed to check module file existence</string> <string name="log_failed_to_check_module_file">Failed to check module file existence</string>
<string name="snackbar_failed_to_check_module_file">Unable to check if module file exists</string> <string name="snackbar_failed_to_check_module_file">Unable to check if module file exists</string>
<string name="confirm_uninstall_title">Confirm uninstallation</string> <string name="confirm_uninstall_title">Confirm uninstallation</string>