manager: add menu bar for home screen

This commit is contained in:
tiann
2023-01-01 19:08:37 +08:00
parent e63da60173
commit 5c8606e2fa
5 changed files with 121 additions and 18 deletions

View File

@@ -4,19 +4,21 @@ import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import android.os.PowerManager
import android.system.Os import android.system.Os
import androidx.annotation.StringRes
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons 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.Block
import androidx.compose.material.icons.outlined.CheckCircle import androidx.compose.material.icons.outlined.CheckCircle
import androidx.compose.material.icons.outlined.Warning import androidx.compose.material.icons.outlined.Warning
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@@ -27,19 +29,26 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph import com.ramcosta.composedestinations.annotation.RootNavGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.weishu.kernelsu.* import me.weishu.kernelsu.*
import me.weishu.kernelsu.R 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.LinkifyText
import me.weishu.kernelsu.ui.util.LocalSnackbarHost import me.weishu.kernelsu.ui.util.LocalSnackbarHost
import me.weishu.kernelsu.ui.util.reboot
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@RootNavGraph(start = true) @RootNavGraph(start = true)
@Destination @Destination
@Composable @Composable
fun HomeScreen() { fun HomeScreen(navigator: DestinationsNavigator) {
Scaffold( Scaffold(
topBar = { TopBar() } topBar = {
TopBar(onSettingsClick = {
navigator.navigate(SettingScreenDestination)
})
}
) { innerPadding -> ) { innerPadding ->
Column( Column(
modifier = Modifier 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) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun TopBar() { private fun TopBar(onSettingsClick: () -> Unit) {
TopAppBar( 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)
)
}
}
) )
} }

View File

@@ -1,16 +1,13 @@
package me.weishu.kernelsu.ui.screen package me.weishu.kernelsu.ui.screen
import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Environment import android.os.Environment
import android.util.Log
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons 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.ArrowBack
import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Save 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.ksuApp
import me.weishu.kernelsu.ui.util.LocalSnackbarHost import me.weishu.kernelsu.ui.util.LocalSnackbarHost
import me.weishu.kernelsu.ui.util.installModule 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.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@@ -92,7 +89,7 @@ fun InstallScreen(navigator: DestinationsNavigator, uri: Uri) {
onClick = { onClick = {
scope.launch { scope.launch {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
rebootUserSpace() reboot()
} }
} }
}, },

View File

@@ -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) }
},
)
}

View File

@@ -69,12 +69,11 @@ fun installModule(uri: Uri, onFinish: (Boolean)->Unit, onOutput: (String) -> Uni
} }
} }
fun rebootUserSpace() { fun reboot(reason: String = "") {
val pm = ksuApp.getSystemService(Context.POWER_SERVICE) as PowerManager
val shell = ksuApp.createRootShell() val shell = ksuApp.createRootShell()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && pm.isRebootingUserspaceSupported) { if (reason == "recovery") {
ShellUtils.fastCmdResult(shell, "svc power reboot userspace") // KEYCODE_POWER = 26, hide incorrect "Factory data reset" message
} else { ShellUtils.fastCmd(shell, "/system/bin/input keyevent 26")
ShellUtils.fastCmdResult(shell, "reboot")
} }
ShellUtils.fastCmd(shell, "/system/bin/svc power reboot $reason || /system/bin/reboot $reason")
} }

View File

@@ -22,4 +22,10 @@
<string name="module_install">Install</string> <string name="module_install">Install</string>
<string name="install">Install</string> <string name="install">Install</string>
<string name="reboot">Reboot</string> <string name="reboot">Reboot</string>
<string name="settings">Settings</string>
<string name="reboot_userspace">Soft reboot</string>
<string name="reboot_recovery">Reboot to recovery</string>
<string name="reboot_bootloader">Reboot to Bootloader</string>
<string name="reboot_download">Reboot to Download</string>
<string name="reboot_edl">Reboot to EDL</string>
</resources> </resources>