[skip ci]: Update kpm module display logic, fix installed and uninstalled name display
This commit is contained in:
@@ -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=")
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user