diff --git a/.github/workflows/ksud.yml b/.github/workflows/ksud.yml index c6c22640..c4ab0c27 100644 --- a/.github/workflows/ksud.yml +++ b/.github/workflows/ksud.yml @@ -9,10 +9,10 @@ on: required: false type: string default: ubuntu-latest - # pack_lkm: - # required: false - # type: boolean - # default: true + pack_lkm: + required: false + type: boolean + default: true use_cache: required: false type: boolean @@ -29,11 +29,11 @@ jobs: - name: Download Artifacts uses: actions/download-artifact@v4 - # - name: Prepare LKM Files - # if: ${{ inputs.pack_lkm }} - # run: | - # cp android*-lkm/*_kernelsu.ko ./userspace/ksud_overlayfs/bin/aarch64/ - # cp android*-lkm/*_kernelsu.ko ./userspace/ksud_magic/bin/aarch64/ // DISBAND LKM MODE + - name: Prepare LKM Files + if: ${{ inputs.pack_lkm }} + run: | + cp android*-lkm/*_kernelsu.ko ./userspace/ksud_overlayfs/bin/aarch64/ + cp android*-lkm/*_kernelsu.ko ./userspace/ksud_magic/bin/aarch64/ - name: Import susfsd Libraries run: | diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Home.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Home.kt index 18f87384..c8eb5d8f 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Home.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Home.kt @@ -40,7 +40,7 @@ import com.dergoogler.mmrl.ui.component.LabelItemDefaults import com.dergoogler.mmrl.ui.component.text.TextRow import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootGraph -// import com.ramcosta.composedestinations.generated.destinations.InstallScreenDestination // DISBAND LKM MODE +import com.ramcosta.composedestinations.generated.destinations.InstallScreenDestination import com.ramcosta.composedestinations.navigation.DestinationsNavigator import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -66,9 +66,9 @@ fun HomeScreen(navigator: DestinationsNavigator) { TopBar( kernelVersion, ksuVersion, - // onInstallClick = { - // navigator.navigate(InstallScreenDestination) - // }, // DISBAND LKM MODE + onInstallClick = { + navigator.navigate(InstallScreenDestination) + }, scrollBehavior = scrollBehavior ) }, @@ -87,7 +87,7 @@ fun HomeScreen(navigator: DestinationsNavigator) { } StatusCard(kernelVersion, ksuVersion, lkmMode) { - // navigator.navigate(InstallScreenDestination) // DISBAND LKM MODE + navigator.navigate(InstallScreenDestination) } if (isManager && Natives.requireNewKernel()) { WarningCard( @@ -173,20 +173,22 @@ fun RebootDropdownItem(@StringRes id: Int, reason: String = "") { private fun TopBar( kernelVersion: KernelVersion, ksuVersion: Int?, - // onInstallClick: () -> Unit, // DISBAND LKM MODE + onInstallClick: () -> Unit, scrollBehavior: TopAppBarScrollBehavior? = null ) { TopAppBar( title = { Text(stringResource(R.string.app_name)) }, actions = { - // if (kernelVersion.isGKI()) { - // IconButton(onClick = onInstallClick) { - // Icon( - // imageVector = Icons.Filled.Archive, - // contentDescription = stringResource(id = R.string.install) - // ) - // } - // } // DISBAND LKM MODE + if (ksuVersion != null) { + if (kernelVersion.isGKI()) { + IconButton(onClick = onInstallClick) { + Icon( + imageVector = Icons.Filled.Archive, + contentDescription = stringResource(id = R.string.install) + ) + } + } + } if (ksuVersion != null) { var showDropdown by remember { mutableStateOf(false) } @@ -257,16 +259,17 @@ private fun StatusCard( tapCount++ if (tapCount == 10) { Toast.makeText(context, "Never gonna give you up! 💜", Toast.LENGTH_SHORT).show() - // tapCount = 0 val url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" val intent = android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(url)) intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(intent) + if (ksuVersion != null) { + context.startActivity(intent) + } else { + onClickInstall() + } + } else if (ksuVersion == null && kernelVersion.isGKI()) { + onClickInstall() } - - // if (kernelVersion.isGKI()) { - // onClickInstall() - // } } .padding(24.dp), verticalAlignment = Alignment.CenterVertically) { when { @@ -344,20 +347,20 @@ private fun StatusCard( } } - // kernelVersion.isGKI() -> { - // Icon(Icons.Filled.Report, stringResource(R.string.lkm_mode_deprecated)) - // Column(Modifier.padding(start = 20.dp)) { - // Text( - // text = stringResource(R.string.lkm_mode_deprecated), - // style = MaterialTheme.typography.titleMedium - // ) - // Spacer(Modifier.height(4.dp)) - // Text( - // text = stringResource(R.string.lkm_alternative_suggestion), - // style = MaterialTheme.typography.bodyMedium - // ) - // } - // } + kernelVersion.isGKI() -> { + Icon(Icons.Filled.Report, stringResource(R.string.home_not_installed)) + Column(Modifier.padding(start = 20.dp)) { + Text( + text = stringResource(R.string.home_not_installed), + style = MaterialTheme.typography.titleMedium + ) + Spacer(Modifier.height(4.dp)) + Text( + text = stringResource(R.string.home_click_to_install), + style = MaterialTheme.typography.bodyMedium + ) + } + } else -> { Icon(Icons.Filled.Dangerous, stringResource(R.string.home_failure)) diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Install.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Install.kt index 8a5e61c4..81546f4d 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Install.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Install.kt @@ -22,6 +22,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.FileUpload +import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -30,6 +31,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarScrollBehavior @@ -77,6 +79,32 @@ import com.rifsxd.ksunext.ui.util.rootAvailable @Destination @Composable fun InstallScreen(navigator: DestinationsNavigator) { + var showLkmWarning by remember { mutableStateOf(true) } + + if (showLkmWarning) { + AlertDialog( + onDismissRequest = { + showLkmWarning = false + navigator.popBackStack() + }, + title = { Text(stringResource(R.string.warning)) }, + text = { Text(stringResource(R.string.lkm_warning_message)) }, + confirmButton = { + TextButton(onClick = { showLkmWarning = false }) { + Text(stringResource(R.string.proceed)) + } + }, + dismissButton = { + TextButton(onClick = { + showLkmWarning = false + navigator.popBackStack() + }) { + Text(stringResource(R.string.cancel)) + } + } + ) + } + var installMethod by remember { mutableStateOf(null) } diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt index 0ee6089b..4646eaff 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt @@ -399,12 +399,12 @@ fun SettingScreen(navigator: DestinationsNavigator) { ) } - // val lkmMode = Natives.version >= Natives.MINIMAL_SUPPORTED_KERNEL_LKM && Natives.isLkmMode - // if (lkmMode) { - // UninstallItem(navigator) { - // loadingDialog.withLoading(it) - // } - // } // DISBAND LKM MODE + val lkmMode = Natives.version >= Natives.MINIMAL_SUPPORTED_KERNEL_LKM && Natives.isLkmMode + if (lkmMode) { + UninstallItem(navigator) { + loadingDialog.withLoading(it) + } + } var showBottomsheet by remember { mutableStateOf(false) } @@ -532,107 +532,107 @@ fun SettingScreen(navigator: DestinationsNavigator) { } } -// @Composable -// fun UninstallItem( -// navigator: DestinationsNavigator, -// withLoading: suspend (suspend () -> Unit) -> Unit, -// ) { -// val context = LocalContext.current -// val scope = rememberCoroutineScope() -// val uninstallConfirmDialog = rememberConfirmDialog() -// val showTodo = { -// Toast.makeText(context, "TODO", Toast.LENGTH_SHORT).show() -// } -// val uninstallDialog = rememberUninstallDialog { uninstallType -> -// scope.launch { -// val result = uninstallConfirmDialog.awaitConfirm( -// title = context.getString(uninstallType.title), -// content = context.getString(uninstallType.message) -// ) -// if (result == ConfirmResult.Confirmed) { -// withLoading { -// when (uninstallType) { -// UninstallType.TEMPORARY -> showTodo() -// UninstallType.PERMANENT -> navigator.navigate( -// FlashScreenDestination(FlashIt.FlashUninstall) -// ) -// UninstallType.RESTORE_STOCK_IMAGE -> navigator.navigate( -// FlashScreenDestination(FlashIt.FlashRestore) -// ) -// UninstallType.NONE -> Unit -// } -// } -// } -// } -// } -// val uninstall = stringResource(id = R.string.settings_uninstall) -// ListItem( -// leadingContent = { -// Icon( -// Icons.Filled.Delete, -// uninstall -// ) -// }, -// headlineContent = { Text(uninstall) }, -// modifier = Modifier.clickable { -// uninstallDialog.show() -// } -// ) -// } +@Composable +fun UninstallItem( + navigator: DestinationsNavigator, + withLoading: suspend (suspend () -> Unit) -> Unit, +) { + val context = LocalContext.current + val scope = rememberCoroutineScope() + val uninstallConfirmDialog = rememberConfirmDialog() + val showTodo = { + Toast.makeText(context, "TODO", Toast.LENGTH_SHORT).show() + } + val uninstallDialog = rememberUninstallDialog { uninstallType -> + scope.launch { + val result = uninstallConfirmDialog.awaitConfirm( + title = context.getString(uninstallType.title), + content = context.getString(uninstallType.message) + ) + if (result == ConfirmResult.Confirmed) { + withLoading { + when (uninstallType) { + UninstallType.TEMPORARY -> showTodo() + UninstallType.PERMANENT -> navigator.navigate( + FlashScreenDestination(FlashIt.FlashUninstall) + ) + UninstallType.RESTORE_STOCK_IMAGE -> navigator.navigate( + FlashScreenDestination(FlashIt.FlashRestore) + ) + UninstallType.NONE -> Unit + } + } + } + } + } + val uninstall = stringResource(id = R.string.settings_uninstall) + ListItem( + leadingContent = { + Icon( + Icons.Filled.Delete, + uninstall + ) + }, + headlineContent = { Text(uninstall) }, + modifier = Modifier.clickable { + uninstallDialog.show() + } + ) +} -// enum class UninstallType(val title: Int, val message: Int, val icon: ImageVector) { -// TEMPORARY( -// R.string.settings_uninstall_temporary, -// R.string.settings_uninstall_temporary_message, -// Icons.Filled.Delete -// ), -// PERMANENT( -// R.string.settings_uninstall_permanent, -// R.string.settings_uninstall_permanent_message, -// Icons.Filled.DeleteForever -// ), -// RESTORE_STOCK_IMAGE( -// R.string.settings_restore_stock_image, -// R.string.settings_restore_stock_image_message, -// Icons.AutoMirrored.Filled.Undo -// ), -// NONE(0, 0, Icons.Filled.Delete) -// } +enum class UninstallType(val title: Int, val message: Int, val icon: ImageVector) { + TEMPORARY( + R.string.settings_uninstall_temporary, + R.string.settings_uninstall_temporary_message, + Icons.Filled.Delete + ), + PERMANENT( + R.string.settings_uninstall_permanent, + R.string.settings_uninstall_permanent_message, + Icons.Filled.DeleteForever + ), + RESTORE_STOCK_IMAGE( + R.string.settings_restore_stock_image, + R.string.settings_restore_stock_image_message, + Icons.AutoMirrored.Filled.Undo + ), + NONE(0, 0, Icons.Filled.Delete) +} -// @OptIn(ExperimentalMaterial3Api::class) -// @Composable -// fun rememberUninstallDialog(onSelected: (UninstallType) -> Unit): DialogHandle { -// return rememberCustomDialog { dismiss -> -// val options = listOf( -// // UninstallType.TEMPORARY, -// UninstallType.PERMANENT, -// UninstallType.RESTORE_STOCK_IMAGE -// ) -// val listOptions = options.map { -// ListOption( -// titleText = stringResource(it.title), -// subtitleText = if (it.message != 0) stringResource(it.message) else null, -// icon = IconSource(it.icon) -// ) -// } +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun rememberUninstallDialog(onSelected: (UninstallType) -> Unit): DialogHandle { + return rememberCustomDialog { dismiss -> + val options = listOf( + // UninstallType.TEMPORARY, + UninstallType.PERMANENT, + UninstallType.RESTORE_STOCK_IMAGE + ) + val listOptions = options.map { + ListOption( + titleText = stringResource(it.title), + subtitleText = if (it.message != 0) stringResource(it.message) else null, + icon = IconSource(it.icon) + ) + } -// var selection = UninstallType.NONE -// ListDialog(state = rememberUseCaseState(visible = true, onFinishedRequest = { -// if (selection != UninstallType.NONE) { -// onSelected(selection) -// } -// }, onCloseRequest = { -// dismiss() -// }), header = Header.Default( -// title = stringResource(R.string.settings_uninstall), -// ), selection = ListSelection.Single( -// showRadioButtons = false, -// options = listOptions, -// ) { index, _ -> -// selection = options[index] -// }) -// } -// } // DISBAND LKM MODE + var selection = UninstallType.NONE + ListDialog(state = rememberUseCaseState(visible = true, onFinishedRequest = { + if (selection != UninstallType.NONE) { + onSelected(selection) + } + }, onCloseRequest = { + dismiss() + }), header = Header.Default( + title = stringResource(R.string.settings_uninstall), + ), selection = ListSelection.Single( + showRadioButtons = false, + options = listOptions, + ) { index, _ -> + selection = options[index] + }) + } +} @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/manager/app/src/main/jniLibs/arm64-v8a/libmagiskboot.so b/manager/app/src/main/jniLibs/arm64-v8a/libmagiskboot.so new file mode 100644 index 00000000..ce7478d6 Binary files /dev/null and b/manager/app/src/main/jniLibs/arm64-v8a/libmagiskboot.so differ diff --git a/manager/app/src/main/jniLibs/armeabi-v7a/libmagiskboot.so b/manager/app/src/main/jniLibs/armeabi-v7a/libmagiskboot.so new file mode 100644 index 00000000..157133c0 Binary files /dev/null and b/manager/app/src/main/jniLibs/armeabi-v7a/libmagiskboot.so differ diff --git a/manager/app/src/main/jniLibs/x86_64/libmagiskboot.so b/manager/app/src/main/jniLibs/x86_64/libmagiskboot.so new file mode 100644 index 00000000..095ffe57 Binary files /dev/null and b/manager/app/src/main/jniLibs/x86_64/libmagiskboot.so differ diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index f113692e..cc3de1e6 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -100,6 +100,7 @@ Proceed Cancel Later + The LKM patch relies on closed source components. Do you want to continue? 🔥 Next build https://github.com/KernelSU-Next/KernelSU-Next Next experimental branch. Check it out on GitHub! diff --git a/userspace/ksud_magic/bin/aarch64/bootctl b/userspace/ksud_magic/bin/aarch64/bootctl new file mode 100644 index 00000000..cf5c6136 Binary files /dev/null and b/userspace/ksud_magic/bin/aarch64/bootctl differ diff --git a/userspace/ksud_magic/bin/aarch64/ksuinit b/userspace/ksud_magic/bin/aarch64/ksuinit new file mode 100644 index 00000000..8d3ba057 Binary files /dev/null and b/userspace/ksud_magic/bin/aarch64/ksuinit differ diff --git a/userspace/ksud_magic/src/assets.rs b/userspace/ksud_magic/src/assets.rs index 723a87fe..bf8d5069 100644 --- a/userspace/ksud_magic/src/assets.rs +++ b/userspace/ksud_magic/src/assets.rs @@ -7,7 +7,7 @@ use crate::{defs::BINARY_DIR, utils}; pub const RESETPROP_PATH: &str = concatcp!(BINARY_DIR, "resetprop"); pub const BUSYBOX_PATH: &str = concatcp!(BINARY_DIR, "busybox"); -#[allow(dead_code)] + pub const BOOTCTL_PATH: &str = concatcp!(BINARY_DIR, "bootctl"); #[allow(dead_code)] diff --git a/userspace/ksud_magic/src/boot_patch.rs b/userspace/ksud_magic/src/boot_patch.rs index 82cf4e07..1737bc3e 100644 --- a/userspace/ksud_magic/src/boot_patch.rs +++ b/userspace/ksud_magic/src/boot_patch.rs @@ -19,7 +19,6 @@ use crate::defs::{KSU_BACKUP_DIR, KSU_BACKUP_FILE_PREFIX}; use crate::{assets, utils}; #[cfg(target_os = "android")] -#[allow(dead_code)] fn ensure_gki_kernel() -> Result<()> { let version = get_kernel_version()?; let is_gki = version.0 == 5 && version.1 >= 10 || version.2 > 5; @@ -28,7 +27,6 @@ fn ensure_gki_kernel() -> Result<()> { } #[cfg(target_os = "android")] -#[allow(dead_code)] pub fn get_kernel_version() -> Result<(i32, i32, i32)> { let uname = rustix::system::uname(); let version = uname.release().to_string_lossy(); @@ -53,7 +51,6 @@ pub fn get_kernel_version() -> Result<(i32, i32, i32)> { } #[cfg(target_os = "android")] -#[allow(dead_code)] fn parse_kmi(version: &str) -> Result { let re = Regex::new(r"(.* )?(\d+\.\d+)(\S+)?(android\d+)(.*)")?; let cap = re @@ -65,7 +62,6 @@ fn parse_kmi(version: &str) -> Result { } #[cfg(target_os = "android")] -#[allow(dead_code)] fn parse_kmi_from_uname() -> Result { let uname = rustix::system::uname(); let version = uname.release().to_string_lossy(); @@ -73,7 +69,6 @@ fn parse_kmi_from_uname() -> Result { } #[cfg(target_os = "android")] -#[allow(dead_code)] fn parse_kmi_from_modules() -> Result { use std::io::BufRead; // find a *.ko in /vendor/lib/modules @@ -92,18 +87,15 @@ fn parse_kmi_from_modules() -> Result { } #[cfg(target_os = "android")] -#[allow(dead_code)] pub fn get_current_kmi() -> Result { parse_kmi_from_uname().or_else(|_| parse_kmi_from_modules()) } #[cfg(not(target_os = "android"))] -#[allow(dead_code)] pub fn get_current_kmi() -> Result { bail!("Unsupported platform") } -#[allow(dead_code)] fn parse_kmi_from_kernel(kernel: &PathBuf, workdir: &Path) -> Result { use std::fs::{File, copy}; use std::io::{BufReader, Read}; @@ -137,7 +129,6 @@ fn parse_kmi_from_kernel(kernel: &PathBuf, workdir: &Path) -> Result { bail!("Try to choose LKM manually") } -#[allow(dead_code)] fn parse_kmi_from_boot(magiskboot: &Path, image: &PathBuf, workdir: &Path) -> Result { let image_path = workdir.join("image"); @@ -162,7 +153,6 @@ fn parse_kmi_from_boot(magiskboot: &Path, image: &PathBuf, workdir: &Path) -> Re parse_kmi_from_kernel(&image_path, workdir) } -#[allow(dead_code)] fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> { let status = Command::new(magiskboot) .current_dir(workdir) @@ -177,7 +167,6 @@ fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> { Ok(()) } -#[allow(dead_code)] fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) @@ -190,7 +179,6 @@ fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result { Ok(status.code() == Some(1)) } -#[allow(dead_code)] fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) @@ -202,7 +190,6 @@ fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result { Ok(status.success()) } -#[allow(dead_code)] fn dd, Q: AsRef>(ifile: P, ofile: Q) -> Result<()> { let status = Command::new("dd") .stdout(Stdio::null()) @@ -219,7 +206,6 @@ fn dd, Q: AsRef>(ifile: P, ofile: Q) -> Result<()> { Ok(()) } -#[allow(dead_code)] pub fn restore( image: Option, magiskboot_path: Option, @@ -337,7 +323,6 @@ pub fn restore( Ok(()) } -#[allow(dead_code)] #[allow(clippy::too_many_arguments)] pub fn patch( image: Option, @@ -357,7 +342,6 @@ pub fn patch( result } -#[allow(dead_code)] #[allow(clippy::too_many_arguments)] fn do_patch( image: Option, @@ -544,7 +528,6 @@ fn do_patch( Ok(()) } -#[allow(dead_code)] #[cfg(target_os = "android")] fn calculate_sha1(file_path: impl AsRef) -> Result { use sha1::Digest; @@ -565,7 +548,6 @@ fn calculate_sha1(file_path: impl AsRef) -> Result { Ok(format!("{:x}", result)) } -#[allow(dead_code)] #[cfg(target_os = "android")] fn do_backup(magiskboot: &Path, workdir: &Path, image: &str) -> Result<()> { let sha1 = calculate_sha1(image)?; @@ -586,7 +568,6 @@ fn do_backup(magiskboot: &Path, workdir: &Path, image: &str) -> Result<()> { Ok(()) } -#[allow(dead_code)] #[cfg(target_os = "android")] fn clean_backup(sha1: &str) -> Result<()> { println!("- Clean up backup"); @@ -610,7 +591,6 @@ fn clean_backup(sha1: &str) -> Result<()> { Ok(()) } -#[allow(dead_code)] fn flash_boot(bootdevice: &Option, new_boot: PathBuf) -> Result<()> { let Some(bootdevice) = bootdevice else { bail!("boot device not found") @@ -624,7 +604,6 @@ fn flash_boot(bootdevice: &Option, new_boot: PathBuf) -> Result<()> { Ok(()) } -#[allow(dead_code)] fn find_magiskboot(magiskboot_path: Option, workdir: &Path) -> Result { let magiskboot = { if which("magiskboot").is_ok() { @@ -649,7 +628,6 @@ fn find_magiskboot(magiskboot_path: Option, workdir: &Path) -> Result

, skip_init: bool, diff --git a/userspace/ksud_magic/src/cli.rs b/userspace/ksud_magic/src/cli.rs index 453db04d..505b5f0c 100644 --- a/userspace/ksud_magic/src/cli.rs +++ b/userspace/ksud_magic/src/cli.rs @@ -62,65 +62,67 @@ enum Commands { #[command(subcommand)] command: Profile, }, - // - // /// Patch boot or init_boot images to apply KernelSU Next - // BootPatch { - // /// boot image path, if not specified, will try to find the boot image automatically - // #[arg(short, long)] - // boot: Option, - // - // /// kernel image path to replace - // #[arg(short, long)] - // kernel: Option, - // - // /// LKM module path to replace, if not specified, will use the builtin one - // #[arg(short, long)] - // module: Option, - // - // /// init to be replaced - // #[arg(short, long, requires("module"))] - // init: Option, - // - // /// will use another slot when boot image is not specified - // #[arg(short = 'u', long, default_value = "false")] - // ota: bool, - // - // /// Flash it to boot partition after patch - // #[arg(short, long, default_value = "false")] - // flash: bool, - // - // /// output path, if not specified, will use current directory - // #[arg(short, long, default_value = None)] - // out: Option, - // - // /// magiskboot path, if not specified, will search from $PATH - // #[arg(long, default_value = None)] - // magiskboot: Option, - // - // /// KMI version, if specified, will use the specified KMI - // #[arg(long, default_value = None)] - // kmi: Option, - // }, - // - // /// Restore boot or init_boot images patched by KernelSU Next - // BootRestore { - // /// boot image path, if not specified, will try to find the boot image automatically - // #[arg(short, long)] - // boot: Option, - // - // /// Flash it to boot partition after patch - // #[arg(short, long, default_value = "false")] - // flash: bool, - // - // /// magiskboot path, if not specified, will search from $PATH - // #[arg(long, default_value = None)] - // magiskboot: Option, - // }, + + /// Patch boot or init_boot images to apply KernelSU Next + BootPatch { + /// boot image path, if not specified, will try to find the boot image automatically + #[arg(short, long)] + boot: Option, + + /// kernel image path to replace + #[arg(short, long)] + kernel: Option, + + /// LKM module path to replace, if not specified, will use the builtin one + #[arg(short, long)] + module: Option, + + /// init to be replaced + #[arg(short, long, requires("module"))] + init: Option, + + /// will use another slot when boot image is not specified + #[arg(short = 'u', long, default_value = "false")] + ota: bool, + + /// Flash it to boot partition after patch + #[arg(short, long, default_value = "false")] + flash: bool, + + /// output path, if not specified, will use current directory + #[arg(short, long, default_value = None)] + out: Option, + + /// magiskboot path, if not specified, will search from $PATH + #[arg(long, default_value = None)] + magiskboot: Option, + + /// KMI version, if specified, will use the specified KMI + #[arg(long, default_value = None)] + kmi: Option, + }, + + /// Restore boot or init_boot images patched by KernelSU Next + BootRestore { + /// boot image path, if not specified, will try to find the boot image automatically + #[arg(short, long)] + boot: Option, + + /// Flash it to boot partition after patch + #[arg(short, long, default_value = "false")] + flash: bool, + + /// magiskboot path, if not specified, will search from $PATH + #[arg(long, default_value = None)] + magiskboot: Option, + }, + /// Show boot information BootInfo { #[command(subcommand)] command: BootInfo, }, + /// For developers Debug { #[command(subcommand)] @@ -354,17 +356,17 @@ pub fn run() -> Result<()> { Debug::Test => assets::ensure_binaries(false), }, - // Commands::BootPatch { - // boot, - // init, - // kernel, - // module, - // ota, - // flash, - // out, - // magiskboot, - // kmi, - // } => crate::boot_patch::patch(boot, kernel, module, init, ota, flash, out, magiskboot, kmi), // DISBAND LKM MODE + Commands::BootPatch { + boot, + init, + kernel, + module, + ota, + flash, + out, + magiskboot, + kmi, + } => crate::boot_patch::patch(boot, kernel, module, init, ota, flash, out, magiskboot, kmi), Commands::BootInfo { command } => match command { BootInfo::CurrentKmi => { let kmi = crate::boot_patch::get_current_kmi()?; @@ -378,11 +380,11 @@ pub fn run() -> Result<()> { return Ok(()); } }, - // Commands::BootRestore { - // boot, - // magiskboot, - // flash, - // } => crate::boot_patch::restore(boot, magiskboot, flash), + Commands::BootRestore { + boot, + magiskboot, + flash, + } => crate::boot_patch::restore(boot, magiskboot, flash), }; if let Err(e) = &result { diff --git a/userspace/ksud_overlayfs/bin/aarch64/bootctl b/userspace/ksud_overlayfs/bin/aarch64/bootctl new file mode 100644 index 00000000..cf5c6136 Binary files /dev/null and b/userspace/ksud_overlayfs/bin/aarch64/bootctl differ diff --git a/userspace/ksud_overlayfs/bin/aarch64/ksuinit b/userspace/ksud_overlayfs/bin/aarch64/ksuinit new file mode 100644 index 00000000..8d3ba057 Binary files /dev/null and b/userspace/ksud_overlayfs/bin/aarch64/ksuinit differ diff --git a/userspace/ksud_overlayfs/src/assets.rs b/userspace/ksud_overlayfs/src/assets.rs index 0e6c859c..bf8d5069 100644 --- a/userspace/ksud_overlayfs/src/assets.rs +++ b/userspace/ksud_overlayfs/src/assets.rs @@ -8,7 +8,6 @@ use crate::{defs::BINARY_DIR, utils}; pub const RESETPROP_PATH: &str = concatcp!(BINARY_DIR, "resetprop"); pub const BUSYBOX_PATH: &str = concatcp!(BINARY_DIR, "busybox"); -#[allow(dead_code)] pub const BOOTCTL_PATH: &str = concatcp!(BINARY_DIR, "bootctl"); #[allow(dead_code)] diff --git a/userspace/ksud_overlayfs/src/boot_patch.rs b/userspace/ksud_overlayfs/src/boot_patch.rs index 6b239932..2d2a0eb2 100644 --- a/userspace/ksud_overlayfs/src/boot_patch.rs +++ b/userspace/ksud_overlayfs/src/boot_patch.rs @@ -19,7 +19,6 @@ use crate::defs::{KSU_BACKUP_DIR, KSU_BACKUP_FILE_PREFIX}; use crate::{assets, utils}; #[cfg(target_os = "android")] -#[allow(dead_code)] fn ensure_gki_kernel() -> Result<()> { let version = get_kernel_version()?; let is_gki = version.0 == 5 && version.1 >= 10 || version.2 > 5; @@ -28,7 +27,6 @@ fn ensure_gki_kernel() -> Result<()> { } #[cfg(target_os = "android")] -#[allow(dead_code)] pub fn get_kernel_version() -> Result<(i32, i32, i32)> { let uname = rustix::system::uname(); let version = uname.release().to_string_lossy(); @@ -94,12 +92,10 @@ pub fn get_current_kmi() -> Result { } #[cfg(not(target_os = "android"))] -#[allow(dead_code)] pub fn get_current_kmi() -> Result { bail!("Unsupported platform") } -#[allow(dead_code)] fn parse_kmi_from_kernel(kernel: &PathBuf, workdir: &Path) -> Result { use std::fs::{File, copy}; use std::io::{BufReader, Read}; @@ -133,7 +129,6 @@ fn parse_kmi_from_kernel(kernel: &PathBuf, workdir: &Path) -> Result { bail!("Try to choose LKM manually") } -#[allow(dead_code)] fn parse_kmi_from_boot(magiskboot: &Path, image: &PathBuf, workdir: &Path) -> Result { let image_path = workdir.join("image"); @@ -158,7 +153,6 @@ fn parse_kmi_from_boot(magiskboot: &Path, image: &PathBuf, workdir: &Path) -> Re parse_kmi_from_kernel(&image_path, workdir) } -#[allow(dead_code)] fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> { let status = Command::new(magiskboot) .current_dir(workdir) @@ -173,7 +167,6 @@ fn do_cpio_cmd(magiskboot: &Path, workdir: &Path, cmd: &str) -> Result<()> { Ok(()) } -#[allow(dead_code)] fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) @@ -186,7 +179,6 @@ fn is_magisk_patched(magiskboot: &Path, workdir: &Path) -> Result { Ok(status.code() == Some(1)) } -#[allow(dead_code)] fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result { let status = Command::new(magiskboot) .current_dir(workdir) @@ -198,7 +190,6 @@ fn is_kernelsu_patched(magiskboot: &Path, workdir: &Path) -> Result { Ok(status.success()) } -#[allow(dead_code)] fn dd, Q: AsRef>(ifile: P, ofile: Q) -> Result<()> { let status = Command::new("dd") .stdout(Stdio::null()) @@ -332,7 +323,6 @@ pub fn restore( Ok(()) } -#[allow(dead_code)] #[allow(clippy::too_many_arguments)] pub fn patch( image: Option, @@ -352,7 +342,6 @@ pub fn patch( result } -#[allow(dead_code)] #[allow(clippy::too_many_arguments)] fn do_patch( image: Option, @@ -540,7 +529,6 @@ fn do_patch( } #[cfg(target_os = "android")] -#[allow(dead_code)] fn calculate_sha1(file_path: impl AsRef) -> Result { use sha1::Digest; use std::io::Read; @@ -561,7 +549,6 @@ fn calculate_sha1(file_path: impl AsRef) -> Result { } #[cfg(target_os = "android")] -#[allow(dead_code)] fn do_backup(magiskboot: &Path, workdir: &Path, image: &str) -> Result<()> { let sha1 = calculate_sha1(image)?; let filename = format!("{KSU_BACKUP_FILE_PREFIX}{sha1}"); @@ -582,7 +569,6 @@ fn do_backup(magiskboot: &Path, workdir: &Path, image: &str) -> Result<()> { } #[cfg(target_os = "android")] -#[allow(dead_code)] fn clean_backup(sha1: &str) -> Result<()> { println!("- Clean up backup"); let backup_name = format!("{}{}", KSU_BACKUP_FILE_PREFIX, sha1); @@ -605,7 +591,6 @@ fn clean_backup(sha1: &str) -> Result<()> { Ok(()) } -#[allow(dead_code)] fn flash_boot(bootdevice: &Option, new_boot: PathBuf) -> Result<()> { let Some(bootdevice) = bootdevice else { bail!("boot device not found") @@ -619,7 +604,6 @@ fn flash_boot(bootdevice: &Option, new_boot: PathBuf) -> Result<()> { Ok(()) } -#[allow(dead_code)] fn find_magiskboot(magiskboot_path: Option, workdir: &Path) -> Result { let magiskboot = { if which("magiskboot").is_ok() { @@ -644,7 +628,6 @@ fn find_magiskboot(magiskboot_path: Option, workdir: &Path) -> Result

, skip_init: bool, @@ -694,7 +677,6 @@ fn find_boot_image( Ok((bootimage, bootdevice)) } -#[allow(dead_code)] fn post_ota() -> Result<()> { use crate::defs::ADB_DIR; use assets::BOOTCTL_PATH; diff --git a/userspace/ksud_overlayfs/src/cli.rs b/userspace/ksud_overlayfs/src/cli.rs index 94dc9bad..41eace42 100644 --- a/userspace/ksud_overlayfs/src/cli.rs +++ b/userspace/ksud_overlayfs/src/cli.rs @@ -58,65 +58,67 @@ enum Commands { #[command(subcommand)] command: Profile, }, - // - // /// Patch boot or init_boot images to apply KernelSU Next - // BootPatch { - // /// boot image path, if not specified, will try to find the boot image automatically - // #[arg(short, long)] - // boot: Option, - // - // /// kernel image path to replace - // #[arg(short, long)] - // kernel: Option, - // - // /// LKM module path to replace, if not specified, will use the builtin one - // #[arg(short, long)] - // module: Option, - // - // /// init to be replaced - // #[arg(short, long, requires("module"))] - // init: Option, - // - // /// will use another slot when boot image is not specified - // #[arg(short = 'u', long, default_value = "false")] - // ota: bool, - // - // /// Flash it to boot partition after patch - // #[arg(short, long, default_value = "false")] - // flash: bool, - // - // /// output path, if not specified, will use current directory - // #[arg(short, long, default_value = None)] - // out: Option, - // - // /// magiskboot path, if not specified, will search from $PATH - // #[arg(long, default_value = None)] - // magiskboot: Option, - // - // /// KMI version, if specified, will use the specified KMI - // #[arg(long, default_value = None)] - // kmi: Option, - // }, // DISBAND LKM MODE - // - // /// Restore boot or init_boot images patched by KernelSU Next - // BootRestore { - // /// boot image path, if not specified, will try to find the boot image automatically - // #[arg(short, long)] - // boot: Option, - // - // /// Flash it to boot partition after patch - // #[arg(short, long, default_value = "false")] - // flash: bool, - // - // /// magiskboot path, if not specified, will search from $PATH - // #[arg(long, default_value = None)] - // magiskboot: Option, - // }, + + /// Patch boot or init_boot images to apply KernelSU Next + BootPatch { + /// boot image path, if not specified, will try to find the boot image automatically + #[arg(short, long)] + boot: Option, + + /// kernel image path to replace + #[arg(short, long)] + kernel: Option, + + /// LKM module path to replace, if not specified, will use the builtin one + #[arg(short, long)] + module: Option, + + /// init to be replaced + #[arg(short, long, requires("module"))] + init: Option, + + /// will use another slot when boot image is not specified + #[arg(short = 'u', long, default_value = "false")] + ota: bool, + + /// Flash it to boot partition after patch + #[arg(short, long, default_value = "false")] + flash: bool, + + /// output path, if not specified, will use current directory + #[arg(short, long, default_value = None)] + out: Option, + + /// magiskboot path, if not specified, will search from $PATH + #[arg(long, default_value = None)] + magiskboot: Option, + + /// KMI version, if specified, will use the specified KMI + #[arg(long, default_value = None)] + kmi: Option, + }, + + /// Restore boot or init_boot images patched by KernelSU Next + BootRestore { + /// boot image path, if not specified, will try to find the boot image automatically + #[arg(short, long)] + boot: Option, + + /// Flash it to boot partition after patch + #[arg(short, long, default_value = "false")] + flash: bool, + + /// magiskboot path, if not specified, will search from $PATH + #[arg(long, default_value = None)] + magiskboot: Option, + }, + /// Show boot information BootInfo { #[command(subcommand)] command: BootInfo, }, + /// For developers Debug { #[command(subcommand)] @@ -326,7 +328,7 @@ pub fn run() -> Result<()> { Module::Shrink => module::shrink_ksu_images(), } } - Commands::Install { magiskboot } => utils::install(magiskboot), // DISBAND LKM MODE + Commands::Install { magiskboot } => utils::install(magiskboot), Commands::Uninstall { magiskboot } => utils::uninstall(magiskboot), Commands::Sepolicy { command } => match command { Sepolicy::Patch { sepolicy } => crate::sepolicy::live_patch(&sepolicy), @@ -369,17 +371,17 @@ pub fn run() -> Result<()> { Debug::Test => assets::ensure_binaries(false), }, - // Commands::BootPatch { - // boot, - // init, - // kernel, - // module, - // ota, - // flash, - // out, - // magiskboot, - // kmi, - // } => crate::boot_patch::patch(boot, kernel, module, init, ota, flash, out, magiskboot, kmi), // DISBAND LKM MODE + Commands::BootPatch { + boot, + init, + kernel, + module, + ota, + flash, + out, + magiskboot, + kmi, + } => crate::boot_patch::patch(boot, kernel, module, init, ota, flash, out, magiskboot, kmi), Commands::BootInfo { command } => match command { BootInfo::CurrentKmi => { let kmi = crate::boot_patch::get_current_kmi()?; @@ -393,11 +395,11 @@ pub fn run() -> Result<()> { return Ok(()); } }, - // Commands::BootRestore { - // boot, - // magiskboot, - // flash, - // } => crate::boot_patch::restore(boot, magiskboot, flash), + Commands::BootRestore { + boot, + magiskboot, + flash, + } => crate::boot_patch::restore(boot, magiskboot, flash), }; if let Err(e) = &result {