Step 5-2: Simplify and separate the main logic for flashing anykernel3
This commit is contained in:
@@ -0,0 +1,252 @@
|
|||||||
|
package com.sukisu.ultra.ui.kernelFlash
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Security
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.DpSize
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
import com.sukisu.ultra.R
|
||||||
|
import com.sukisu.ultra.ui.screen.InstallMethod
|
||||||
|
import top.yukonga.miuix.kmp.basic.Icon
|
||||||
|
import top.yukonga.miuix.kmp.basic.Text
|
||||||
|
import top.yukonga.miuix.kmp.basic.TextButton
|
||||||
|
import top.yukonga.miuix.kmp.extra.SuperArrow
|
||||||
|
import top.yukonga.miuix.kmp.extra.SuperDialog
|
||||||
|
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||||
|
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
||||||
|
|
||||||
|
enum class KpmPatchOption {
|
||||||
|
FOLLOW_KERNEL,
|
||||||
|
PATCH_KPM,
|
||||||
|
UNDO_PATCH_KPM
|
||||||
|
}
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
data class AnyKernel3State(
|
||||||
|
val kpmPatchOption: KpmPatchOption,
|
||||||
|
val showSlotSelectionDialog: Boolean,
|
||||||
|
val showKpmPatchDialog: Boolean,
|
||||||
|
val onHorizonKernelSelected: (InstallMethod.HorizonKernel) -> Unit,
|
||||||
|
val onSlotSelected: (String) -> Unit,
|
||||||
|
val onDismissSlotDialog: () -> Unit,
|
||||||
|
val onOptionSelected: (KpmPatchOption) -> Unit,
|
||||||
|
val onDismissPatchDialog: () -> Unit
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun rememberAnyKernel3State(
|
||||||
|
installMethodState: MutableState<InstallMethod?>,
|
||||||
|
preselectedKernelUri: String?,
|
||||||
|
horizonKernelSummary: String,
|
||||||
|
isAbDevice: Boolean
|
||||||
|
): AnyKernel3State {
|
||||||
|
var kpmPatchOption by remember { mutableStateOf(KpmPatchOption.FOLLOW_KERNEL) }
|
||||||
|
var showSlotSelectionDialog by remember { mutableStateOf(false) }
|
||||||
|
var showKpmPatchDialog by remember { mutableStateOf(false) }
|
||||||
|
var tempKernelUri by remember { mutableStateOf<Uri?>(null) }
|
||||||
|
|
||||||
|
val onHorizonKernelSelected: (InstallMethod.HorizonKernel) -> Unit = { method ->
|
||||||
|
val uri = method.uri
|
||||||
|
if (uri != null) {
|
||||||
|
if (isAbDevice) {
|
||||||
|
tempKernelUri = uri
|
||||||
|
showSlotSelectionDialog = true
|
||||||
|
} else {
|
||||||
|
installMethodState.value = method
|
||||||
|
showKpmPatchDialog = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val onSlotSelected: (String) -> Unit = { slot ->
|
||||||
|
val uri = tempKernelUri
|
||||||
|
if (uri != null) {
|
||||||
|
installMethodState.value = InstallMethod.HorizonKernel(
|
||||||
|
uri = uri,
|
||||||
|
slot = slot,
|
||||||
|
summary = horizonKernelSummary
|
||||||
|
)
|
||||||
|
tempKernelUri = null
|
||||||
|
showSlotSelectionDialog = false
|
||||||
|
showKpmPatchDialog = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val onDismissSlotDialog = {
|
||||||
|
showSlotSelectionDialog = false
|
||||||
|
tempKernelUri = null
|
||||||
|
}
|
||||||
|
|
||||||
|
val onOptionSelected: (KpmPatchOption) -> Unit = { option ->
|
||||||
|
kpmPatchOption = option
|
||||||
|
showKpmPatchDialog = false
|
||||||
|
}
|
||||||
|
|
||||||
|
val onDismissPatchDialog = {
|
||||||
|
showKpmPatchDialog = false
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(preselectedKernelUri, isAbDevice, horizonKernelSummary) {
|
||||||
|
preselectedKernelUri?.let { uriString ->
|
||||||
|
runCatching { uriString.toUri() }
|
||||||
|
.getOrNull()
|
||||||
|
?.let { preselectedUri ->
|
||||||
|
val method = InstallMethod.HorizonKernel(
|
||||||
|
uri = preselectedUri,
|
||||||
|
summary = horizonKernelSummary
|
||||||
|
)
|
||||||
|
if (isAbDevice) {
|
||||||
|
tempKernelUri = preselectedUri
|
||||||
|
showSlotSelectionDialog = true
|
||||||
|
} else {
|
||||||
|
installMethodState.value = method
|
||||||
|
showKpmPatchDialog = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return AnyKernel3State(
|
||||||
|
kpmPatchOption = kpmPatchOption,
|
||||||
|
showSlotSelectionDialog = showSlotSelectionDialog,
|
||||||
|
showKpmPatchDialog = showKpmPatchDialog,
|
||||||
|
onHorizonKernelSelected = onHorizonKernelSelected,
|
||||||
|
onSlotSelected = onSlotSelected,
|
||||||
|
onDismissSlotDialog = onDismissSlotDialog,
|
||||||
|
onOptionSelected = onOptionSelected,
|
||||||
|
onDismissPatchDialog = onDismissPatchDialog
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun KpmPatchSelectionDialog(
|
||||||
|
show: Boolean,
|
||||||
|
currentOption: KpmPatchOption,
|
||||||
|
onDismiss: () -> Unit,
|
||||||
|
onOptionSelected: (KpmPatchOption) -> Unit
|
||||||
|
) {
|
||||||
|
var selectedOption by remember { mutableStateOf(currentOption) }
|
||||||
|
val showDialog = remember { mutableStateOf(show) }
|
||||||
|
|
||||||
|
LaunchedEffect(show) {
|
||||||
|
showDialog.value = show
|
||||||
|
if (show) {
|
||||||
|
selectedOption = currentOption
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SuperDialog(
|
||||||
|
show = showDialog,
|
||||||
|
insideMargin = DpSize(0.dp, 0.dp),
|
||||||
|
onDismissRequest = {
|
||||||
|
showDialog.value = false
|
||||||
|
onDismiss()
|
||||||
|
},
|
||||||
|
content = {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 24.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 24.dp, vertical = 12.dp),
|
||||||
|
text = stringResource(id = R.string.kpm_patch_options),
|
||||||
|
fontSize = MiuixTheme.textStyles.title4.fontSize,
|
||||||
|
fontWeight = FontWeight.Medium,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = colorScheme.onSurface
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 24.dp, vertical = 8.dp),
|
||||||
|
text = stringResource(id = R.string.kpm_patch_description),
|
||||||
|
fontSize = MiuixTheme.textStyles.body2.fontSize,
|
||||||
|
color = colorScheme.onSurfaceVariantSummary,
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
|
val options = listOf(
|
||||||
|
KpmPatchOption.FOLLOW_KERNEL to stringResource(R.string.kpm_follow_kernel_file),
|
||||||
|
KpmPatchOption.PATCH_KPM to stringResource(R.string.enable_kpm_patch),
|
||||||
|
KpmPatchOption.UNDO_PATCH_KPM to stringResource(R.string.enable_kpm_undo_patch)
|
||||||
|
)
|
||||||
|
|
||||||
|
options.forEach { (option, title) ->
|
||||||
|
SuperArrow(
|
||||||
|
title = title,
|
||||||
|
onClick = {
|
||||||
|
selectedOption = option
|
||||||
|
},
|
||||||
|
leftAction = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.Security,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = if (selectedOption == option) {
|
||||||
|
colorScheme.primary
|
||||||
|
} else {
|
||||||
|
colorScheme.onSurfaceVariantSummary
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
insideMargin = PaddingValues(horizontal = 24.dp, vertical = 12.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(horizontal = 24.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
|
) {
|
||||||
|
TextButton(
|
||||||
|
text = stringResource(android.R.string.cancel),
|
||||||
|
onClick = {
|
||||||
|
showDialog.value = false
|
||||||
|
onDismiss()
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
TextButton(
|
||||||
|
text = stringResource(android.R.string.ok),
|
||||||
|
onClick = {
|
||||||
|
onOptionSelected(selectedOption)
|
||||||
|
showDialog.value = false
|
||||||
|
onDismiss()
|
||||||
|
},
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@ import androidx.compose.animation.expandVertically
|
|||||||
import androidx.compose.animation.shrinkVertically
|
import androidx.compose.animation.shrinkVertically
|
||||||
import androidx.compose.foundation.LocalIndication
|
import androidx.compose.foundation.LocalIndication
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -47,13 +46,10 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.semantics.Role
|
import androidx.compose.ui.semantics.Role
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.SdStorage
|
import androidx.compose.material.icons.filled.SdStorage
|
||||||
import androidx.compose.material.icons.filled.Security
|
import androidx.compose.material.icons.filled.Security
|
||||||
import androidx.core.net.toUri
|
|
||||||
import androidx.lifecycle.compose.dropUnlessResumed
|
import androidx.lifecycle.compose.dropUnlessResumed
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
import com.ramcosta.composedestinations.annotation.RootGraph
|
import com.ramcosta.composedestinations.annotation.RootGraph
|
||||||
@@ -69,7 +65,10 @@ import com.sukisu.ultra.R
|
|||||||
import com.sukisu.ultra.getKernelVersion
|
import com.sukisu.ultra.getKernelVersion
|
||||||
import com.sukisu.ultra.ui.component.ChooseKmiDialog
|
import com.sukisu.ultra.ui.component.ChooseKmiDialog
|
||||||
import com.sukisu.ultra.ui.component.rememberConfirmDialog
|
import com.sukisu.ultra.ui.component.rememberConfirmDialog
|
||||||
|
import com.sukisu.ultra.ui.kernelFlash.KpmPatchOption
|
||||||
|
import com.sukisu.ultra.ui.kernelFlash.KpmPatchSelectionDialog
|
||||||
import com.sukisu.ultra.ui.kernelFlash.component.SlotSelectionDialog
|
import com.sukisu.ultra.ui.kernelFlash.component.SlotSelectionDialog
|
||||||
|
import com.sukisu.ultra.ui.kernelFlash.rememberAnyKernel3State
|
||||||
import com.sukisu.ultra.ui.util.LkmSelection
|
import com.sukisu.ultra.ui.util.LkmSelection
|
||||||
import com.sukisu.ultra.ui.util.getAvailablePartitions
|
import com.sukisu.ultra.ui.util.getAvailablePartitions
|
||||||
import com.sukisu.ultra.ui.util.getCurrentKmi
|
import com.sukisu.ultra.ui.util.getCurrentKmi
|
||||||
@@ -94,11 +93,6 @@ import top.yukonga.miuix.kmp.icon.MiuixIcons
|
|||||||
import top.yukonga.miuix.kmp.icon.icons.useful.Back
|
import top.yukonga.miuix.kmp.icon.icons.useful.Back
|
||||||
import top.yukonga.miuix.kmp.icon.icons.useful.Edit
|
import top.yukonga.miuix.kmp.icon.icons.useful.Edit
|
||||||
import top.yukonga.miuix.kmp.icon.icons.useful.Move
|
import top.yukonga.miuix.kmp.icon.icons.useful.Move
|
||||||
import top.yukonga.miuix.kmp.extra.SuperDialog
|
|
||||||
import top.yukonga.miuix.kmp.basic.TextButton
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.ui.unit.DpSize
|
|
||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
|
||||||
import top.yukonga.miuix.kmp.utils.getWindowSize
|
import top.yukonga.miuix.kmp.utils.getWindowSize
|
||||||
@@ -109,12 +103,6 @@ import top.yukonga.miuix.kmp.utils.scrollEndHaptic
|
|||||||
* @author weishu
|
* @author weishu
|
||||||
* @date 2024/3/12.
|
* @date 2024/3/12.
|
||||||
*/
|
*/
|
||||||
enum class KpmPatchOption {
|
|
||||||
FOLLOW_KERNEL,
|
|
||||||
PATCH_KPM,
|
|
||||||
UNDO_PATCH_KPM
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@Destination<RootGraph>
|
@Destination<RootGraph>
|
||||||
fun InstallScreen(
|
fun InstallScreen(
|
||||||
@@ -122,19 +110,15 @@ fun InstallScreen(
|
|||||||
preselectedKernelUri: String? = null
|
preselectedKernelUri: String? = null
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
var installMethod by remember {
|
val installMethodState = remember {
|
||||||
mutableStateOf<InstallMethod?>(null)
|
mutableStateOf<InstallMethod?>(null)
|
||||||
}
|
}
|
||||||
|
var installMethod by installMethodState
|
||||||
|
|
||||||
var lkmSelection by remember {
|
var lkmSelection by remember {
|
||||||
mutableStateOf<LkmSelection>(LkmSelection.KmiNone)
|
mutableStateOf<LkmSelection>(LkmSelection.KmiNone)
|
||||||
}
|
}
|
||||||
|
|
||||||
var kpmPatchOption by remember { mutableStateOf(KpmPatchOption.FOLLOW_KERNEL) }
|
|
||||||
var showSlotSelectionDialog by remember { mutableStateOf(false) }
|
|
||||||
var showKpmPatchDialog by remember { mutableStateOf(false) }
|
|
||||||
var tempKernelUri by remember { mutableStateOf<Uri?>(null) }
|
|
||||||
|
|
||||||
val kernelVersion = getKernelVersion()
|
val kernelVersion = getKernelVersion()
|
||||||
val isGKI = kernelVersion.isGKI()
|
val isGKI = kernelVersion.isGKI()
|
||||||
val isAbDevice = produceState(initialValue = false) {
|
val isAbDevice = produceState(initialValue = false) {
|
||||||
@@ -145,28 +129,14 @@ fun InstallScreen(
|
|||||||
var partitionsState by remember { mutableStateOf<List<String>>(emptyList()) }
|
var partitionsState by remember { mutableStateOf<List<String>>(emptyList()) }
|
||||||
var hasCustomSelected by remember { mutableStateOf(false) }
|
var hasCustomSelected by remember { mutableStateOf(false) }
|
||||||
val horizonKernelSummary = stringResource(R.string.horizon_kernel_summary)
|
val horizonKernelSummary = stringResource(R.string.horizon_kernel_summary)
|
||||||
|
// AnyKernel3 刷写状态
|
||||||
// 处理预选的内核文件
|
val anyKernel3State = rememberAnyKernel3State(
|
||||||
LaunchedEffect(preselectedKernelUri) {
|
installMethodState = installMethodState,
|
||||||
preselectedKernelUri?.let { uriString ->
|
preselectedKernelUri = preselectedKernelUri,
|
||||||
try {
|
horizonKernelSummary = horizonKernelSummary,
|
||||||
val preselectedUri = uriString.toUri()
|
isAbDevice = isAbDevice
|
||||||
val horizonMethod = InstallMethod.HorizonKernel(
|
|
||||||
uri = preselectedUri,
|
|
||||||
summary = horizonKernelSummary
|
|
||||||
)
|
)
|
||||||
installMethod = horizonMethod
|
val kpmPatchOption = anyKernel3State.kpmPatchOption
|
||||||
tempKernelUri = preselectedUri
|
|
||||||
if (isAbDevice) {
|
|
||||||
showSlotSelectionDialog = true
|
|
||||||
} else {
|
|
||||||
showKpmPatchDialog = true
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val onInstall = {
|
val onInstall = {
|
||||||
installMethod?.let { method ->
|
installMethod?.let { method ->
|
||||||
@@ -203,33 +173,24 @@ fun InstallScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 槽位选择对话框
|
// 槽位选择对话框
|
||||||
if (showSlotSelectionDialog && isAbDevice) {
|
if (anyKernel3State.showSlotSelectionDialog && isAbDevice) {
|
||||||
SlotSelectionDialog(
|
SlotSelectionDialog(
|
||||||
show = true,
|
show = true,
|
||||||
onDismiss = { showSlotSelectionDialog = false },
|
onDismiss = { anyKernel3State.onDismissSlotDialog() },
|
||||||
onSlotSelected = { slot ->
|
onSlotSelected = { slot ->
|
||||||
showSlotSelectionDialog = false
|
anyKernel3State.onSlotSelected(slot)
|
||||||
val horizonMethod = InstallMethod.HorizonKernel(
|
|
||||||
uri = tempKernelUri,
|
|
||||||
slot = slot,
|
|
||||||
summary = horizonKernelSummary
|
|
||||||
)
|
|
||||||
installMethod = horizonMethod
|
|
||||||
// 槽位选择后,显示 KPM 补丁选择对话框
|
|
||||||
showKpmPatchDialog = true
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// KPM补丁选择对话框
|
// KPM补丁选择对话框
|
||||||
if (showKpmPatchDialog) {
|
if (anyKernel3State.showKpmPatchDialog) {
|
||||||
KpmPatchSelectionDialog(
|
KpmPatchSelectionDialog(
|
||||||
show = true,
|
show = true,
|
||||||
currentOption = kpmPatchOption,
|
currentOption = anyKernel3State.kpmPatchOption,
|
||||||
onDismiss = { showKpmPatchDialog = false },
|
onDismiss = { anyKernel3State.onDismissPatchDialog() },
|
||||||
onOptionSelected = { option ->
|
onOptionSelected = { option ->
|
||||||
kpmPatchOption = option
|
anyKernel3State.onOptionSelected(option)
|
||||||
showKpmPatchDialog = false
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -318,13 +279,7 @@ fun InstallScreen(
|
|||||||
SelectInstallMethod(
|
SelectInstallMethod(
|
||||||
onSelected = { method ->
|
onSelected = { method ->
|
||||||
if (method is InstallMethod.HorizonKernel && method.uri != null) {
|
if (method is InstallMethod.HorizonKernel && method.uri != null) {
|
||||||
if (isAbDevice) {
|
anyKernel3State.onHorizonKernelSelected(method)
|
||||||
tempKernelUri = method.uri
|
|
||||||
showSlotSelectionDialog = true
|
|
||||||
} else {
|
|
||||||
installMethod = method
|
|
||||||
showKpmPatchDialog = true
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
installMethod = method
|
installMethod = method
|
||||||
}
|
}
|
||||||
@@ -377,7 +332,7 @@ fun InstallScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// LKM 上传选项(仅 GKI)
|
// LKM 上传(仅 GKI)
|
||||||
if (isGKI) {
|
if (isGKI) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -405,7 +360,7 @@ fun InstallScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnyKernel3 相关信息显示
|
// AnyKernel3 刷写
|
||||||
(installMethod as? InstallMethod.HorizonKernel)?.let { method ->
|
(installMethod as? InstallMethod.HorizonKernel)?.let { method ->
|
||||||
if (method.slot != null) {
|
if (method.slot != null) {
|
||||||
Card(
|
Card(
|
||||||
@@ -649,121 +604,6 @@ private fun TopBar(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun KpmPatchSelectionDialog(
|
|
||||||
show: Boolean,
|
|
||||||
currentOption: KpmPatchOption,
|
|
||||||
onDismiss: () -> Unit,
|
|
||||||
onOptionSelected: (KpmPatchOption) -> Unit
|
|
||||||
) {
|
|
||||||
var selectedOption by remember { mutableStateOf(currentOption) }
|
|
||||||
val showDialog = remember { mutableStateOf(show) }
|
|
||||||
|
|
||||||
LaunchedEffect(show) {
|
|
||||||
showDialog.value = show
|
|
||||||
if (show) {
|
|
||||||
selectedOption = currentOption
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SuperDialog(
|
|
||||||
show = showDialog,
|
|
||||||
insideMargin = DpSize(0.dp, 0.dp),
|
|
||||||
onDismissRequest = {
|
|
||||||
showDialog.value = false
|
|
||||||
onDismiss()
|
|
||||||
},
|
|
||||||
content = {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(vertical = 24.dp)
|
|
||||||
) {
|
|
||||||
// 标题
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 24.dp, vertical = 12.dp),
|
|
||||||
text = stringResource(id = R.string.kpm_patch_options),
|
|
||||||
fontSize = MiuixTheme.textStyles.title4.fontSize,
|
|
||||||
fontWeight = FontWeight.Medium,
|
|
||||||
textAlign = TextAlign.Center,
|
|
||||||
color = colorScheme.onSurface
|
|
||||||
)
|
|
||||||
|
|
||||||
// 描述
|
|
||||||
Text(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 24.dp, vertical = 8.dp),
|
|
||||||
text = stringResource(id = R.string.kpm_patch_description),
|
|
||||||
fontSize = MiuixTheme.textStyles.body2.fontSize,
|
|
||||||
color = colorScheme.onSurfaceVariantSummary,
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
|
||||||
|
|
||||||
// 选项列表
|
|
||||||
val options = listOf(
|
|
||||||
KpmPatchOption.FOLLOW_KERNEL to stringResource(R.string.kpm_follow_kernel_file),
|
|
||||||
KpmPatchOption.PATCH_KPM to stringResource(R.string.enable_kpm_patch),
|
|
||||||
KpmPatchOption.UNDO_PATCH_KPM to stringResource(R.string.enable_kpm_undo_patch)
|
|
||||||
)
|
|
||||||
|
|
||||||
options.forEach { (option, title) ->
|
|
||||||
SuperArrow(
|
|
||||||
title = title,
|
|
||||||
onClick = {
|
|
||||||
selectedOption = option
|
|
||||||
},
|
|
||||||
leftAction = {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Filled.Security,
|
|
||||||
contentDescription = null,
|
|
||||||
tint = if (selectedOption == option) {
|
|
||||||
colorScheme.primary
|
|
||||||
} else {
|
|
||||||
colorScheme.onSurfaceVariantSummary
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
insideMargin = PaddingValues(horizontal = 24.dp, vertical = 12.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
|
||||||
|
|
||||||
// 按钮行
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 24.dp),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
|
||||||
) {
|
|
||||||
TextButton(
|
|
||||||
text = stringResource(android.R.string.cancel),
|
|
||||||
onClick = {
|
|
||||||
showDialog.value = false
|
|
||||||
onDismiss()
|
|
||||||
},
|
|
||||||
modifier = Modifier.weight(1f)
|
|
||||||
)
|
|
||||||
TextButton(
|
|
||||||
text = stringResource(android.R.string.ok),
|
|
||||||
onClick = {
|
|
||||||
onOptionSelected(selectedOption)
|
|
||||||
showDialog.value = false
|
|
||||||
onDismiss()
|
|
||||||
},
|
|
||||||
modifier = Modifier.weight(1f)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isKoFile(context: Context, uri: Uri): Boolean {
|
private fun isKoFile(context: Context, uri: Uri): Boolean {
|
||||||
val seg = uri.lastPathSegment ?: ""
|
val seg = uri.lastPathSegment ?: ""
|
||||||
if (seg.endsWith(".ko", ignoreCase = true)) return true
|
if (seg.endsWith(".ko", ignoreCase = true)) return true
|
||||||
|
|||||||
Reference in New Issue
Block a user