manager: improve local LKM selection
Co-authored-by: YuKongA <70465933+YuKongA@users.noreply.github.com> Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
package com.sukisu.ultra.ui.screen
|
package com.sukisu.ultra.ui.screen
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.provider.OpenableColumns
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
@@ -211,7 +213,17 @@ fun InstallScreen(
|
|||||||
) {
|
) {
|
||||||
if (it.resultCode == Activity.RESULT_OK) {
|
if (it.resultCode == Activity.RESULT_OK) {
|
||||||
it.data?.data?.let { uri ->
|
it.data?.data?.let { uri ->
|
||||||
|
val isKo = isKoFile(context, uri)
|
||||||
|
if (isKo) {
|
||||||
lkmSelection = LkmSelection.LkmUri(uri)
|
lkmSelection = LkmSelection.LkmUri(uri)
|
||||||
|
} else {
|
||||||
|
lkmSelection = LkmSelection.KmiNone
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
context.getString(R.string.install_only_support_ko_file),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,7 +240,6 @@ fun InstallScreen(
|
|||||||
topBar = {
|
topBar = {
|
||||||
TopBar(
|
TopBar(
|
||||||
onBack = { navigator.popBackStack() },
|
onBack = { navigator.popBackStack() },
|
||||||
onLkmUpload = onLkmUpload,
|
|
||||||
scrollBehavior = scrollBehavior
|
scrollBehavior = scrollBehavior
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -268,31 +279,38 @@ fun InstallScreen(
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
) {
|
) {
|
||||||
(lkmSelection as? LkmSelection.LkmUri)?.let {
|
|
||||||
ElevatedCard(
|
ElevatedCard(
|
||||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant),
|
colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant),
|
||||||
elevation = getCardElevation(),
|
elevation = getCardElevation(),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(bottom = 12.dp)
|
.padding(bottom = 12.dp),
|
||||||
.clip(MaterialTheme.shapes.medium)
|
|
||||||
.shadow(
|
|
||||||
elevation = cardElevation,
|
|
||||||
shape = MaterialTheme.shapes.medium,
|
|
||||||
spotColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
|
ListItem(
|
||||||
|
headlineContent = {
|
||||||
|
Text(stringResource(id = R.string.install_upload_lkm_file))
|
||||||
|
},
|
||||||
|
supportingContent = {
|
||||||
|
(lkmSelection as? LkmSelection.LkmUri)?.let {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(
|
stringResource(
|
||||||
id = R.string.selected_lkm,
|
id = R.string.selected_lkm,
|
||||||
it.uri.lastPathSegment ?: "(file)"
|
it.uri.lastPathSegment ?: "(file)"
|
||||||
),
|
)
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
modifier = Modifier.padding(16.dp)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
leadingContent = {
|
||||||
|
Icon(
|
||||||
|
Icons.AutoMirrored.Filled.Input,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable { onLkmUpload() }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
(installMethod as? InstallMethod.HorizonKernel)?.let { method ->
|
(installMethod as? InstallMethod.HorizonKernel)?.let { method ->
|
||||||
if (method.slot != null) {
|
if (method.slot != null) {
|
||||||
ElevatedCard(
|
ElevatedCard(
|
||||||
@@ -952,7 +970,6 @@ fun rememberSelectKmiDialog(onSelected: (String?) -> Unit): DialogHandle {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun TopBar(
|
private fun TopBar(
|
||||||
onBack: () -> Unit = {},
|
onBack: () -> Unit = {},
|
||||||
onLkmUpload: () -> Unit = {},
|
|
||||||
scrollBehavior: TopAppBarScrollBehavior? = null
|
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||||
) {
|
) {
|
||||||
val colorScheme = MaterialTheme.colorScheme
|
val colorScheme = MaterialTheme.colorScheme
|
||||||
@@ -985,21 +1002,35 @@ private fun TopBar(
|
|||||||
windowInsets = WindowInsets.safeDrawing.only(
|
windowInsets = WindowInsets.safeDrawing.only(
|
||||||
WindowInsetsSides.Top + WindowInsetsSides.Horizontal
|
WindowInsetsSides.Top + WindowInsetsSides.Horizontal
|
||||||
),
|
),
|
||||||
actions = {
|
|
||||||
IconButton(
|
|
||||||
modifier = Modifier.padding(end = 16.dp),
|
|
||||||
onClick = onLkmUpload
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.AutoMirrored.Filled.Input,
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scrollBehavior = scrollBehavior
|
scrollBehavior = scrollBehavior
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isKoFile(context: Context, uri: Uri): Boolean {
|
||||||
|
val seg = uri.lastPathSegment ?: ""
|
||||||
|
if (seg.endsWith(".ko", ignoreCase = true)) return true
|
||||||
|
|
||||||
|
return try {
|
||||||
|
context.contentResolver.query(
|
||||||
|
uri,
|
||||||
|
arrayOf(OpenableColumns.DISPLAY_NAME),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)?.use { cursor ->
|
||||||
|
val idx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||||
|
if (idx != -1 && cursor.moveToFirst()) {
|
||||||
|
val name = cursor.getString(idx)
|
||||||
|
name?.endsWith(".ko", ignoreCase = true) == true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} ?: false
|
||||||
|
} catch (_: Throwable) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun SelectInstallPreview() {
|
fun SelectInstallPreview() {
|
||||||
|
|||||||
@@ -110,6 +110,8 @@
|
|||||||
<string name="install_inactive_slot">安装到未使用的槽位(OTA 后)</string>
|
<string name="install_inactive_slot">安装到未使用的槽位(OTA 后)</string>
|
||||||
<string name="install_inactive_slot_warning">将在重启后强制切换到另一个槽位!\n注意只能在 OTA 更新完成后的重启之前使用。\n确认?</string>
|
<string name="install_inactive_slot_warning">将在重启后强制切换到另一个槽位!\n注意只能在 OTA 更新完成后的重启之前使用。\n确认?</string>
|
||||||
<string name="install_next">下一步</string>
|
<string name="install_next">下一步</string>
|
||||||
|
<string name="install_upload_lkm_file">使用本地 LKM 文件</string>
|
||||||
|
<string name="install_only_support_ko_file">仅支持选择 .ko 文件</string>
|
||||||
<string name="select_file_tip">建议选择 %1$s 分区镜像</string>
|
<string name="select_file_tip">建议选择 %1$s 分区镜像</string>
|
||||||
<string name="select_file_tip_vendor">(实验性的)</string>
|
<string name="select_file_tip_vendor">(实验性的)</string>
|
||||||
<string name="select_kmi">选择 KMI</string>
|
<string name="select_kmi">选择 KMI</string>
|
||||||
@@ -123,7 +125,7 @@
|
|||||||
<string name="flashing">刷写中</string>
|
<string name="flashing">刷写中</string>
|
||||||
<string name="flash_success">刷写完成</string>
|
<string name="flash_success">刷写完成</string>
|
||||||
<string name="flash_failed">刷写失败</string>
|
<string name="flash_failed">刷写失败</string>
|
||||||
<string name="selected_lkm">选择的 LKM:%s</string>
|
<string name="selected_lkm">已选择的 LKM:%s</string>
|
||||||
<string name="save_log">保存日志</string>
|
<string name="save_log">保存日志</string>
|
||||||
<string name="log_saved">日志已保存</string>
|
<string name="log_saved">日志已保存</string>
|
||||||
<string name="sus_su_mode">SuS SU 模式:</string>
|
<string name="sus_su_mode">SuS SU 模式:</string>
|
||||||
|
|||||||
@@ -112,6 +112,8 @@
|
|||||||
<string name="install_inactive_slot">Install to inactive slot (After OTA)</string>
|
<string name="install_inactive_slot">Install to inactive slot (After OTA)</string>
|
||||||
<string name="install_inactive_slot_warning">Your device will be **FORCED** to boot to the current inactive slot after a reboot!\nOnly use this option after OTA is done.\nContinue?</string>
|
<string name="install_inactive_slot_warning">Your device will be **FORCED** to boot to the current inactive slot after a reboot!\nOnly use this option after OTA is done.\nContinue?</string>
|
||||||
<string name="install_next">Next</string>
|
<string name="install_next">Next</string>
|
||||||
|
<string name="install_upload_lkm_file">Use local LKM file</string>
|
||||||
|
<string name="install_only_support_ko_file">Only .ko files are supported</string>
|
||||||
<string name="select_file_tip">%1$s partition image is recommended</string>
|
<string name="select_file_tip">%1$s partition image is recommended</string>
|
||||||
<string name="select_file_tip_vendor">(Unstable)</string>
|
<string name="select_file_tip_vendor">(Unstable)</string>
|
||||||
<string name="select_kmi">Select KMI</string>
|
<string name="select_kmi">Select KMI</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user