From 5c8606e2fa5d9700fb24346520ef052d35954c0d Mon Sep 17 00:00:00 2001 From: tiann Date: Sun, 1 Jan 2023 19:08:37 +0800 Subject: [PATCH] manager: add menu bar for home screen --- .../java/me/weishu/kernelsu/ui/screen/Home.kt | 66 +++++++++++++++++-- .../me/weishu/kernelsu/ui/screen/Install.kt | 7 +- .../me/weishu/kernelsu/ui/screen/Settings.kt | 49 ++++++++++++++ .../java/me/weishu/kernelsu/ui/util/KsuCli.kt | 11 ++-- manager/app/src/main/res/values/strings.xml | 6 ++ 5 files changed, 121 insertions(+), 18 deletions(-) create mode 100644 manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Home.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Home.kt index 32237da7..068458d5 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Home.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Home.kt @@ -4,19 +4,21 @@ import android.content.ClipData import android.content.ClipboardManager import android.content.Context import android.os.Build +import android.os.PowerManager import android.system.Os +import androidx.annotation.StringRes import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.outlined.Block import androidx.compose.material.icons.outlined.CheckCircle import androidx.compose.material.icons.outlined.Warning import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -27,19 +29,26 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootNavGraph +import com.ramcosta.composedestinations.navigation.DestinationsNavigator import kotlinx.coroutines.launch import me.weishu.kernelsu.* import me.weishu.kernelsu.R +import me.weishu.kernelsu.ui.screen.destinations.SettingScreenDestination import me.weishu.kernelsu.ui.util.LinkifyText import me.weishu.kernelsu.ui.util.LocalSnackbarHost +import me.weishu.kernelsu.ui.util.reboot @OptIn(ExperimentalMaterial3Api::class) @RootNavGraph(start = true) @Destination @Composable -fun HomeScreen() { +fun HomeScreen(navigator: DestinationsNavigator) { Scaffold( - topBar = { TopBar() } + topBar = { + TopBar(onSettingsClick = { + navigator.navigate(SettingScreenDestination) + }) + } ) { innerPadding -> Column( modifier = Modifier @@ -60,11 +69,54 @@ fun HomeScreen() { } } +@Composable +fun RebootDropdownItem(@StringRes id: Int, reason: String = "") { + DropdownMenuItem(text = { + Text(stringResource(id)) + }, onClick = { + reboot(reason) + }) +} + @OptIn(ExperimentalMaterial3Api::class) @Composable -private fun TopBar() { +private fun TopBar(onSettingsClick: () -> Unit) { TopAppBar( - title = { Text(stringResource(R.string.app_name)) } + title = { Text(stringResource(R.string.app_name)) }, + actions = { + var showDropdown by remember { mutableStateOf(false) } + IconButton(onClick = { + showDropdown = true + }) { + Icon( + imageVector = Icons.Filled.Refresh, + contentDescription = stringResource(id = R.string.reboot) + ) + + DropdownMenu(expanded = showDropdown, onDismissRequest = { + showDropdown = false + }) { + + RebootDropdownItem(id = R.string.reboot) + + val pm = LocalContext.current.getSystemService(Context.POWER_SERVICE) as PowerManager? + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && pm?.isRebootingUserspaceSupported == true) { + RebootDropdownItem(id = R.string.reboot_userspace, reason = "userspace") + } + RebootDropdownItem(id = R.string.reboot_recovery, reason = "recovery") + RebootDropdownItem(id = R.string.reboot_bootloader, reason = "bootloader") + RebootDropdownItem(id = R.string.reboot_download, reason = "download") + RebootDropdownItem(id = R.string.reboot_edl, reason = "edl") + } + } + + IconButton(onClick = onSettingsClick) { + Icon( + imageVector = Icons.Filled.Settings, + contentDescription = stringResource(id = R.string.settings) + ) + } + } ) } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Install.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Install.kt index 839a167a..d5fb1452 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Install.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Install.kt @@ -1,16 +1,13 @@ package me.weishu.kernelsu.ui.screen -import android.content.Intent import android.net.Uri import android.os.Environment -import android.util.Log import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Save @@ -30,7 +27,7 @@ import me.weishu.kernelsu.R import me.weishu.kernelsu.ksuApp import me.weishu.kernelsu.ui.util.LocalSnackbarHost import me.weishu.kernelsu.ui.util.installModule -import me.weishu.kernelsu.ui.util.rebootUserSpace +import me.weishu.kernelsu.ui.util.reboot import java.io.File import java.text.SimpleDateFormat import java.util.* @@ -92,7 +89,7 @@ fun InstallScreen(navigator: DestinationsNavigator, uri: Uri) { onClick = { scope.launch { withContext(Dispatchers.IO) { - rebootUserSpace() + reboot() } } }, diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt new file mode 100644 index 00000000..fcad169c --- /dev/null +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Settings.kt @@ -0,0 +1,49 @@ +package me.weishu.kernelsu.ui.screen + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import com.ramcosta.composedestinations.annotation.Destination +import com.ramcosta.composedestinations.navigation.DestinationsNavigator +import me.weishu.kernelsu.R + +/** + * @author weishu + * @date 2023/1/1. + */ +@OptIn(ExperimentalMaterial3Api::class) +@Destination +@Composable +fun SettingScreen(navigator: DestinationsNavigator) { + + Scaffold ( + topBar = { + TopBar(onBack = { + navigator.popBackStack() + }) + } + ) { paddingValues -> + + Column(modifier = Modifier.padding(paddingValues)) { + Text(text = stringResource(id = R.string.settings)) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun TopBar(onBack: () -> Unit = {}) { + TopAppBar( + title = { Text(stringResource(R.string.settings)) }, + navigationIcon = { + IconButton( + onClick = onBack + ) { Icon(Icons.Filled.ArrowBack, contentDescription = null) } + }, + ) +} \ No newline at end of file diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt index 9c039216..9202a209 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt @@ -69,12 +69,11 @@ fun installModule(uri: Uri, onFinish: (Boolean)->Unit, onOutput: (String) -> Uni } } -fun rebootUserSpace() { - val pm = ksuApp.getSystemService(Context.POWER_SERVICE) as PowerManager +fun reboot(reason: String = "") { val shell = ksuApp.createRootShell() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && pm.isRebootingUserspaceSupported) { - ShellUtils.fastCmdResult(shell, "svc power reboot userspace") - } else { - ShellUtils.fastCmdResult(shell, "reboot") + if (reason == "recovery") { + // KEYCODE_POWER = 26, hide incorrect "Factory data reset" message + ShellUtils.fastCmd(shell, "/system/bin/input keyevent 26") } + ShellUtils.fastCmd(shell, "/system/bin/svc power reboot $reason || /system/bin/reboot $reason") } \ No newline at end of file diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index c6e7dfd2..bcf9a360 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -22,4 +22,10 @@ Install Install Reboot + Settings + Soft reboot + Reboot to recovery + Reboot to Bootloader + Reboot to Download + Reboot to EDL