From 6656604809aa0784c3796df3fc31f1e4acb8b7fc Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Sun, 27 Apr 2025 19:35:55 +0800 Subject: [PATCH] Add the function of obtaining and restoring the original slot, and display the current slot information in the slot selection dialog box -It should be possible to fix the issue of selecting slot positions Signed-off-by: ShirkNeko 109797057+ShirkNeko@users.noreply.github.com --- .../com/sukisu/ultra/flash/KernelFlash.kt | 53 ++++++++++++++++- .../ultra/ui/component/SlotSelectionDialog.kt | 58 +++++++++++++++++++ .../src/main/res/values-zh-rCN/strings.xml | 4 ++ manager/app/src/main/res/values/strings.xml | 4 ++ 4 files changed, 118 insertions(+), 1 deletion(-) diff --git a/manager/app/src/main/java/com/sukisu/ultra/flash/KernelFlash.kt b/manager/app/src/main/java/com/sukisu/ultra/flash/KernelFlash.kt index c26dca01..ba2849d3 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/flash/KernelFlash.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/flash/KernelFlash.kt @@ -90,6 +90,7 @@ class HorizonKernelWorker( private lateinit var binaryPath: String private var onFlashComplete: (() -> Unit)? = null + private var originalSlot: String? = null fun setOnFlashCompleteListener(listener: () -> Unit) { onFlashComplete = listener @@ -131,8 +132,30 @@ class HorizonKernelWorker( state.updateStep(context.getString(R.string.horizon_flashing)) state.updateProgress(0.7f) + + // 获取原始槽位信息 + if (slot != null) { + state.updateStep(context.getString(R.string.horizon_getting_original_slot)) + state.updateProgress(0.72f) + originalSlot = runCommandGetOutput(true, "getprop ro.boot.slot_suffix") + } + + // 设置目标槽位 + if (!slot.isNullOrEmpty()) { + state.updateStep(context.getString(R.string.horizon_setting_target_slot)) + state.updateProgress(0.74f) + runCommand(true, "resetprop -n ro.boot.slot_suffix _$slot") + } + flash() + // 恢复原始槽位 + if (!originalSlot.isNullOrEmpty()) { + state.updateStep(context.getString(R.string.horizon_restoring_original_slot)) + state.updateProgress(0.8f) + runCommand(true, "resetprop ro.boot.slot_suffix $originalSlot") + } + state.updateStep(context.getString(R.string.horizon_flash_complete_status)) state.completeFlashing() @@ -141,6 +164,13 @@ class HorizonKernelWorker( } } catch (e: Exception) { state.setError(e.message ?: context.getString(R.string.horizon_unknown_error)) + + // 恢复原始槽位 + if (!originalSlot.isNullOrEmpty()) { + state.updateStep(context.getString(R.string.horizon_restoring_original_slot)) + state.updateProgress(0.8f) + runCommand(true, "resetprop ro.boot.slot_suffix $originalSlot") + } } } @@ -245,12 +275,33 @@ class HorizonKernelWorker( } } + private fun runCommandGetOutput(su: Boolean, cmd: String): String { + val process = ProcessBuilder(if (su) "su" else "sh") + .redirectErrorStream(true) + .start() + + return try { + process.outputStream.bufferedWriter().use { writer -> + writer.write("$cmd\n") + writer.write("exit\n") + writer.flush() + } + process.inputStream.bufferedReader().use { reader -> + reader.readText().trim() + } + } catch (_: Exception) { + "" + } finally { + process.destroy() + } + } + private fun rootAvailable(): Boolean { return try { val process = Runtime.getRuntime().exec("su -c id") val exitValue = process.waitFor() exitValue == 0 - } catch (e: Exception) { + } catch (_: Exception) { false } } diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SlotSelectionDialog.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SlotSelectionDialog.kt index 50834f31..d3898d23 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SlotSelectionDialog.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SlotSelectionDialog.kt @@ -1,10 +1,12 @@ package com.sukisu.ultra.ui.component +import android.content.Context import androidx.compose.foundation.layout.* import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -24,6 +26,20 @@ fun SlotSelectionDialog( onDismiss: () -> Unit, onSlotSelected: (String) -> Unit ) { + val context = LocalContext.current + var currentSlot by remember { mutableStateOf(null) } + var errorMessage by remember { mutableStateOf(null) } + + LaunchedEffect(Unit) { + try { + currentSlot = getCurrentSlot(context) + errorMessage = null + } catch (e: Exception) { + errorMessage = e.message + currentSlot = null + } + } + if (show) { val cardColor = if (!ThemeConfig.useDynamicColor) { ThemeConfig.currentTheme.ButtonContrast @@ -44,6 +60,27 @@ fun SlotSelectionDialog( modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { + if (errorMessage != null) { + Text( + text = "Error: $errorMessage", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.error, + textAlign = TextAlign.Center + ) + } else { + Text( + text = stringResource( + id = R.string.current_slot, + currentSlot ?: "Unknown" + ), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + textAlign = TextAlign.Center + ) + } + + Spacer(modifier = Modifier.height(12.dp)) + Text( text = stringResource(id = R.string.select_slot_description), style = MaterialTheme.typography.bodyMedium, @@ -99,3 +136,24 @@ fun SlotSelectionDialog( ) } } + +// 获取当前槽位信息 +private fun getCurrentSlot(context: Context): String? { + return runCommandGetOutput(true, "getprop ro.boot.slot_suffix") +} + +private fun runCommandGetOutput(su: Boolean, cmd: String): String? { + return try { + val process = ProcessBuilder(if (su) "su" else "sh").start() + process.outputStream.bufferedWriter().use { writer -> + writer.write("$cmd\n") + writer.write("exit\n") + writer.flush() + } + process.inputStream.bufferedReader().use { reader -> + reader.readText().trim() + } + } catch (_: Exception) { + null + } +} \ No newline at end of file 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 7e161b32..7e2fa1cb 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -287,4 +287,8 @@ 复制失败 未知错误 + 获取原有槽位 + 设置指定槽位 + 恢复默认槽位 + 当前槽位:%1$s diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index e402b3a3..43652a9c 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -291,4 +291,8 @@ Copy failed Unknown error + Getting the original slot + Setting the specified slot + Restore Default Slot + Current Slot:%1$s