[skip ci]:

Fixing tools used by kernels under 5.10
-Add Slot selection is not displayed for non-ab partitions
This commit is contained in:
ShirkNeko
2025-05-05 22:09:01 +08:00
parent 349ca36d4e
commit caee2417d6
3 changed files with 46 additions and 59 deletions

View File

@@ -3,8 +3,10 @@
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<application

View File

@@ -133,15 +133,13 @@ class HorizonKernelWorker(
state.updateStep(context.getString(R.string.horizon_flashing))
state.updateProgress(0.7f)
// 获取原始槽位信息
if (slot != null) {
val isAbDevice = isAbDevice()
if (isAbDevice && 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")
@@ -149,8 +147,7 @@ class HorizonKernelWorker(
flash()
// 恢复原始槽位
if (!originalSlot.isNullOrEmpty()) {
if (isAbDevice && !originalSlot.isNullOrEmpty()) {
state.updateStep(context.getString(R.string.horizon_restoring_original_slot))
state.updateProgress(0.8f)
runCommand(true, "resetprop ro.boot.slot_suffix $originalSlot")
@@ -165,8 +162,7 @@ class HorizonKernelWorker(
} catch (e: Exception) {
state.setError(e.message ?: context.getString(R.string.horizon_unknown_error))
// 恢复原始槽位
if (!originalSlot.isNullOrEmpty()) {
if (isAbDevice() && !originalSlot.isNullOrEmpty()) {
state.updateStep(context.getString(R.string.horizon_restoring_original_slot))
state.updateProgress(0.8f)
runCommand(true, "resetprop ro.boot.slot_suffix $originalSlot")
@@ -174,6 +170,17 @@ class HorizonKernelWorker(
}
}
// 检查设备是否为AB分区设备
private fun isAbDevice(): Boolean {
val abUpdate = runCommandGetOutput(true, "getprop ro.build.ab_update")?.trim() ?: ""
if (abUpdate.equals("false", ignoreCase = true) || abUpdate.isEmpty()) {
return false
}
val slotSuffix = runCommandGetOutput(true, "getprop ro.boot.slot_suffix")
return !slotSuffix.isNullOrEmpty()
}
private fun cleanup() {
runCommand(false, "find ${context.filesDir.absolutePath} -type f ! -name '*.jpg' ! -name '*.png' -delete")
}
@@ -198,10 +205,18 @@ class HorizonKernelWorker(
private fun patch() {
val kernelVersion = runCommandGetOutput(true, "cat /proc/version")
val versionRegex = """\d+\.\d+\.\d+""".toRegex()
val version = versionRegex.find(kernelVersion)?.value ?: ""
val toolName = when {
version.startsWith("5.10.") -> "5_10"
else -> "5_15+"
val version = kernelVersion?.let { versionRegex.find(it) }?.value ?: ""
val toolName = if (version.isNotEmpty()) {
val parts = version.split('.')
if (parts.size >= 2) {
val major = parts[0].toIntOrNull() ?: 0
val minor = parts[1].toIntOrNull() ?: 0
if (major < 5 || (major == 5 && minor <= 10)) "5_10" else "5_15+"
} else {
"5_15+"
}
} else {
"5_15+"
}
val toolPath = "${context.filesDir.absolutePath}/mkbootfs"
AssetsUtil.exportFiles(context, "$toolName-mkbootfs", toolPath)
@@ -283,7 +298,7 @@ class HorizonKernelWorker(
}
}
private fun runCommandGetOutput(su: Boolean, cmd: String): String {
private fun runCommandGetOutput(su: Boolean, cmd: String): String? {
val process = ProcessBuilder(if (su) "su" else "sh")
.redirectErrorStream(true)
.start()

View File

@@ -115,6 +115,7 @@ fun InstallScreen(navigator: DestinationsNavigator) {
val summary = stringResource(R.string.horizon_kernel_summary)
val kernelVersion = getKernelVersion()
val isGKI = kernelVersion.isGKI()
val isAbDevice = isAbDevice()
val onFlashComplete = {
showRebootDialog = true
@@ -169,7 +170,7 @@ fun InstallScreen(navigator: DestinationsNavigator) {
// 槽位选择
SlotSelectionDialog(
show = showSlotSelectionDialog,
show = showSlotSelectionDialog && isAbDevice,
onDismiss = { showSlotSelectionDialog = false },
onSlotSelected = { slot ->
showSlotSelectionDialog = false
@@ -240,10 +241,15 @@ fun InstallScreen(navigator: DestinationsNavigator) {
) {
SelectInstallMethod(
isGKI = isGKI,
isAbDevice = isAbDevice,
onSelected = { method ->
if (method is InstallMethod.HorizonKernel && method.uri != null && method.slot == null) {
tempKernelUri = method.uri
showSlotSelectionDialog = true
if (method is InstallMethod.HorizonKernel && method.uri != null) {
if (isAbDevice) {
tempKernelUri = method.uri
showSlotSelectionDialog = true
} else {
installMethod = method
}
} else {
installMethod = method
}
@@ -395,6 +401,7 @@ sealed class InstallMethod {
@Composable
private fun SelectInstallMethod(
isGKI: Boolean = false,
isAbDevice: Boolean = false,
onSelected: (InstallMethod) -> Unit = {}
) {
val rootAvailable = rootAvailable()
@@ -488,7 +495,7 @@ private fun SelectInstallMethod(
modifier = Modifier.padding(horizontal = 16.dp)
) {
// LKM 安装/修补
if (isGKI && rootAvailable) {
if (isGKI) {
ElevatedCard(
colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant),
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
@@ -698,43 +705,6 @@ private fun SelectInstallMethod(
}
}
}
// 没有root
if (!rootAvailable) {
ElevatedCard(
colors = getCardColors(MaterialTheme.colorScheme.errorContainer),
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 12.dp)
.clip(MaterialTheme.shapes.large)
.shadow(
elevation = cardElevation,
shape = MaterialTheme.shapes.large,
spotColor = MaterialTheme.colorScheme.error.copy(alpha = 0.1f)
)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(24.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
imageVector = Icons.Filled.AutoFixHigh,
contentDescription = null,
tint = MaterialTheme.colorScheme.onErrorContainer,
modifier = Modifier
.padding(end = 16.dp)
)
Text(
text = stringResource(R.string.root_require_for_install),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onErrorContainer
)
}
}
}
}
}