Skip to content

Commit

Permalink
add user custom select lkm file button on install screen top bar (#1491)
Browse files Browse the repository at this point in the history
  • Loading branch information
Houvven authored Mar 20, 2024
1 parent 65a0f00 commit 39b025b
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {

@Parcelize
sealed class FlashIt : Parcelable {
data class FlashBoot(val bootUri: Uri? = null, val ota: Boolean) : FlashIt()
data class FlashBoot(val bootUri: Uri? = null, val lkmUri: Uri? = null, val ota: Boolean) : FlashIt()

data class FlashModule(val uri: Uri) : FlashIt()
}
Expand All @@ -153,6 +153,7 @@ fun flashIt(
when (flashIt) {
is FlashIt.FlashBoot -> installBoot(
flashIt.bootUri,
flashIt.lkmUri,
flashIt.ota,
onFinish,
onStdout,
Expand Down
44 changes: 38 additions & 6 deletions manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Install.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package me.weishu.kernelsu.ui.screen
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.util.Log
import android.webkit.DownloadListener
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
Expand All @@ -14,6 +16,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.FileUpload
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
Expand All @@ -35,8 +38,11 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.net.toFile
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import me.weishu.kernelsu.R
Expand All @@ -61,20 +67,41 @@ fun InstallScreen(navigator: DestinationsNavigator) {
mutableStateOf<InstallMethod?>(null)
}

var lkmFileUri = null as Uri?

val onClickInstall = {
installMethod?.let { method ->
val flashIt = FlashIt.FlashBoot(
if (method is InstallMethod.SelectFile) method.uri else null,
method is InstallMethod.DirectInstallToInactiveSlot
bootUri = if (method is InstallMethod.SelectFile) method.uri else null,
lkmUri = lkmFileUri,
ota = method is InstallMethod.DirectInstallToInactiveSlot
)
navigator.navigate(FlashScreenDestination(flashIt))
}
}

Scaffold(topBar = {
TopBar {
navigator.popBackStack()
val selectLkmLauncher =
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
it.data?.data?.let { uri ->
lkmFileUri = uri
}
}
}

val onLkmUpload = {
selectLkmLauncher.launch(
Intent(Intent.ACTION_GET_CONTENT).apply {
type = "application/octet-stream"
}
)
}

Scaffold(topBar = {
TopBar(
onBack = { navigator.popBackStack() },
onLkmUpload = onLkmUpload
)
}) {
Column(modifier = Modifier.padding(it)) {
SelectInstallMethod { method ->
Expand Down Expand Up @@ -217,14 +244,19 @@ private fun SelectInstallMethod(onSelected: (InstallMethod) -> Unit = {}) {

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TopBar(onBack: () -> Unit = {}) {
private fun TopBar(onBack: () -> Unit = {}, onLkmUpload: () -> Unit = {}) {
TopAppBar(
title = { Text(stringResource(R.string.install)) },
navigationIcon = {
IconButton(
onClick = onBack
) { Icon(Icons.Filled.ArrowBack, contentDescription = null) }
},
actions = {
IconButton(onClick = onLkmUpload) {
Icon(Icons.Filled.FileUpload, contentDescription = null)
}
}
)
}

Expand Down
19 changes: 18 additions & 1 deletion manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,11 @@ fun installModule(

fun installBoot(
bootUri: Uri?,
lkmUri: Uri?,
ota: Boolean,
onFinish: (Boolean) -> Unit,
onStdout: (String) -> Unit,
onStderr: (String) -> Unit
onStderr: (String) -> Unit,
): Boolean {
val resolver = ksuApp.contentResolver

Expand All @@ -161,6 +162,17 @@ fun installBoot(
}
}

val lkmFile = lkmUri?.let { uri ->
with(resolver.openInputStream(uri)) {
val lkmFile = File(ksuApp.cacheDir, "kernelsu-tmp-lkm.ko")
lkmFile.outputStream().use { output ->
this?.copyTo(output)
}

lkmFile
}
}

val magiskboot = File(ksuApp.applicationInfo.nativeLibraryDir, "libmagiskboot.so")
var cmd = "boot-patch --magiskboot ${magiskboot.absolutePath}"

Expand All @@ -175,6 +187,10 @@ fun installBoot(
cmd += " -u"
}

lkmFile?.let {
cmd += " -m ${it.absolutePath}"
}

// output dir
val downloadsDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
Expand All @@ -200,6 +216,7 @@ fun installBoot(
Log.i("KernelSU", "install boot result: ${result.isSuccess}")

bootFile?.delete()
lkmFile?.delete()

// if boot uri is empty, it is direct install, when success, we should show reboot button
onFinish(bootUri == null && result.isSuccess)
Expand Down

0 comments on commit 39b025b

Please sign in to comment.