manager: hide root-related features if kernelsu version null (#71)
Related PR: tiann#2483 Also attempting to address this: tiann#2483 (comment) Co-authored-by: rsuntk <rsuntk@yukiprjkt.my.id> Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
@@ -90,6 +90,14 @@ object Natives {
|
|||||||
fun requireNewKernel(): Boolean {
|
fun requireNewKernel(): Boolean {
|
||||||
return version < MINIMAL_SUPPORTED_KERNEL
|
return version < MINIMAL_SUPPORTED_KERNEL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isKsuValid(pkgName: String?): Boolean {
|
||||||
|
if (becomeManager(pkgName)) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@Parcelize
|
@Parcelize
|
||||||
|
|||||||
@@ -283,22 +283,27 @@ private fun TopBar(
|
|||||||
}
|
}
|
||||||
|
|
||||||
var showDropdown by remember { mutableStateOf(false) }
|
var showDropdown by remember { mutableStateOf(false) }
|
||||||
IconButton(onClick = { showDropdown = true }) {
|
if (Natives.isKsuValid(ksuApp.packageName)) {
|
||||||
Icon(Icons.Filled.Refresh, stringResource(R.string.reboot))
|
IconButton(onClick = { showDropdown = true }) {
|
||||||
DropdownMenu(expanded = showDropdown, onDismissRequest = { showDropdown = false }
|
Icon(Icons.Filled.Refresh, stringResource(R.string.reboot))
|
||||||
) {
|
DropdownMenu(
|
||||||
|
expanded = showDropdown,
|
||||||
|
onDismissRequest = { showDropdown = false }
|
||||||
|
) {
|
||||||
|
|
||||||
RebootDropdownItem(id = R.string.reboot)
|
RebootDropdownItem(id = R.string.reboot)
|
||||||
|
|
||||||
val pm = LocalContext.current.getSystemService(Context.POWER_SERVICE) as PowerManager?
|
val pm =
|
||||||
@Suppress("DEPRECATION")
|
LocalContext.current.getSystemService(Context.POWER_SERVICE) as PowerManager?
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && pm?.isRebootingUserspaceSupported == true) {
|
@Suppress("DEPRECATION")
|
||||||
RebootDropdownItem(id = R.string.reboot_userspace, reason = "userspace")
|
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")
|
||||||
}
|
}
|
||||||
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")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -307,6 +312,7 @@ private fun TopBar(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun StatusCard(
|
private fun StatusCard(
|
||||||
kernelVersion: KernelVersion,
|
kernelVersion: KernelVersion,
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import zako.zako.zako.ui.theme.*
|
|||||||
import zako.zako.zako.ui.util.*
|
import zako.zako.zako.ui.util.*
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import zako.zako.zako.R
|
import zako.zako.zako.R
|
||||||
|
import zako.zako.zako.*
|
||||||
|
|
||||||
|
|
||||||
fun saveCardConfig(context: Context) {
|
fun saveCardConfig(context: Context) {
|
||||||
@@ -175,6 +176,7 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
var showThemeColorDialog by remember { mutableStateOf(false) }
|
var showThemeColorDialog by remember { mutableStateOf(false) }
|
||||||
|
val ksuIsValid = Natives.isKsuValid(ksuApp.packageName)
|
||||||
|
|
||||||
// 图片选择器
|
// 图片选择器
|
||||||
val pickImageLauncher = rememberLauncherForActivityResult(
|
val pickImageLauncher = rememberLauncherForActivityResult(
|
||||||
@@ -208,17 +210,19 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
|||||||
.padding(top = 12.dp)
|
.padding(top = 12.dp)
|
||||||
) {
|
) {
|
||||||
// SELinux 开关
|
// SELinux 开关
|
||||||
SwitchItem(
|
if (ksuIsValid) {
|
||||||
icon = Icons.Filled.Security,
|
SwitchItem(
|
||||||
title = stringResource(R.string.selinux),
|
icon = Icons.Filled.Security,
|
||||||
summary = if (selinuxEnabled)
|
title = stringResource(R.string.selinux),
|
||||||
stringResource(R.string.selinux_enabled) else
|
summary = if (selinuxEnabled)
|
||||||
stringResource(R.string.selinux_disabled),
|
stringResource(R.string.selinux_enabled) else
|
||||||
checked = selinuxEnabled
|
stringResource(R.string.selinux_disabled),
|
||||||
) { enabled ->
|
checked = selinuxEnabled
|
||||||
val command = if (enabled) "setenforce 1" else "setenforce 0"
|
) { enabled ->
|
||||||
Shell.getShell().newJob().add(command).exec().let { result ->
|
val command = if (enabled) "setenforce 1" else "setenforce 0"
|
||||||
if (result.isSuccess) selinuxEnabled = enabled
|
Shell.getShell().newJob().add(command).exec().let { result ->
|
||||||
|
if (result.isSuccess) selinuxEnabled = enabled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import kotlinx.coroutines.withContext
|
|||||||
import zako.zako.zako.BuildConfig
|
import zako.zako.zako.BuildConfig
|
||||||
import zako.zako.zako.Natives
|
import zako.zako.zako.Natives
|
||||||
import zako.zako.zako.R
|
import zako.zako.zako.R
|
||||||
|
import zako.zako.zako.*
|
||||||
import zako.zako.zako.ui.component.*
|
import zako.zako.zako.ui.component.*
|
||||||
import zako.zako.zako.ui.theme.*
|
import zako.zako.zako.ui.theme.*
|
||||||
import zako.zako.zako.ui.util.LocalSnackbarHost
|
import zako.zako.zako.ui.util.LocalSnackbarHost
|
||||||
@@ -68,6 +69,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
// region 界面基础设置
|
// region 界面基础设置
|
||||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||||
val snackBarHost = LocalSnackbarHost.current
|
val snackBarHost = LocalSnackbarHost.current
|
||||||
|
val ksuIsValid = Natives.isKsuValid(ksuApp.packageName)
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
@@ -115,6 +117,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
// region 配置项列表
|
// region 配置项列表
|
||||||
// 配置文件模板入口
|
// 配置文件模板入口
|
||||||
val profileTemplate = stringResource(id = R.string.settings_profile_template)
|
val profileTemplate = stringResource(id = R.string.settings_profile_template)
|
||||||
|
if (ksuIsValid) {
|
||||||
ListItem(
|
ListItem(
|
||||||
leadingContent = { Icon(Icons.Filled.Fence, profileTemplate) },
|
leadingContent = { Icon(Icons.Filled.Fence, profileTemplate) },
|
||||||
headlineContent = { Text(profileTemplate) },
|
headlineContent = { Text(profileTemplate) },
|
||||||
@@ -123,34 +126,40 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
navigator.navigate(AppProfileTemplateScreenDestination)
|
navigator.navigate(AppProfileTemplateScreenDestination)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
}
|
||||||
// 卸载模块开关
|
// 卸载模块开关
|
||||||
var umountChecked by rememberSaveable {
|
var umountChecked by rememberSaveable {
|
||||||
mutableStateOf(Natives.isDefaultUmountModules())
|
mutableStateOf(Natives.isDefaultUmountModules())
|
||||||
}
|
}
|
||||||
SwitchItem(
|
|
||||||
icon = Icons.Filled.FolderDelete,
|
if (ksuIsValid) {
|
||||||
title = stringResource(id = R.string.settings_umount_modules_default),
|
SwitchItem(
|
||||||
summary = stringResource(id = R.string.settings_umount_modules_default_summary),
|
icon = Icons.Filled.FolderDelete,
|
||||||
checked = umountChecked
|
title = stringResource(id = R.string.settings_umount_modules_default),
|
||||||
) {
|
summary = stringResource(id = R.string.settings_umount_modules_default_summary),
|
||||||
if (Natives.setDefaultUmountModules(it)) {
|
checked = umountChecked
|
||||||
umountChecked = it
|
) {
|
||||||
}
|
if (Natives.setDefaultUmountModules(it)) {
|
||||||
|
umountChecked = it
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// SU 禁用开关(仅在兼容版本显示)
|
// SU 禁用开关(仅在兼容版本显示)
|
||||||
if (Natives.version >= Natives.MINIMAL_SUPPORTED_SU_COMPAT) {
|
if (ksuIsValid) {
|
||||||
var isSuDisabled by rememberSaveable {
|
if (Natives.version >= Natives.MINIMAL_SUPPORTED_SU_COMPAT) {
|
||||||
mutableStateOf(!Natives.isSuEnabled())
|
var isSuDisabled by rememberSaveable {
|
||||||
}
|
mutableStateOf(!Natives.isSuEnabled())
|
||||||
SwitchItem(
|
}
|
||||||
icon = Icons.Filled.RemoveModerator,
|
SwitchItem(
|
||||||
title = stringResource(id = R.string.settings_disable_su),
|
icon = Icons.Filled.RemoveModerator,
|
||||||
summary = stringResource(id = R.string.settings_disable_su_summary),
|
title = stringResource(id = R.string.settings_disable_su),
|
||||||
checked = isSuDisabled,
|
summary = stringResource(id = R.string.settings_disable_su_summary),
|
||||||
) { checked ->
|
checked = isSuDisabled,
|
||||||
val shouldEnable = !checked
|
) { checked ->
|
||||||
if (Natives.setSuEnabled(shouldEnable)) {
|
val shouldEnable = !checked
|
||||||
isSuDisabled = !shouldEnable
|
if (Natives.setSuEnabled(shouldEnable)) {
|
||||||
|
isSuDisabled = !shouldEnable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,14 +188,16 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
|||||||
prefs.getBoolean("enable_web_debugging", false)
|
prefs.getBoolean("enable_web_debugging", false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SwitchItem(
|
if (Natives.isKsuValid(ksuApp.packageName)) {
|
||||||
icon = Icons.Filled.DeveloperMode,
|
SwitchItem(
|
||||||
title = stringResource(id = R.string.enable_web_debugging),
|
icon = Icons.Filled.DeveloperMode,
|
||||||
summary = stringResource(id = R.string.enable_web_debugging_summary),
|
title = stringResource(id = R.string.enable_web_debugging),
|
||||||
checked = enableWebDebugging
|
summary = stringResource(id = R.string.enable_web_debugging_summary),
|
||||||
) {
|
checked = enableWebDebugging
|
||||||
prefs.edit { putBoolean("enable_web_debugging", it) }
|
) {
|
||||||
enableWebDebugging = it
|
prefs.edit { putBoolean("enable_web_debugging", it) }
|
||||||
|
enableWebDebugging = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 更多设置
|
// 更多设置
|
||||||
val newButtonTitle = stringResource(id = R.string.more_settings)
|
val newButtonTitle = stringResource(id = R.string.more_settings)
|
||||||
|
|||||||
Reference in New Issue
Block a user