manager: Move certain settings to the Advanced Settings section.
This commit is contained in:
@@ -330,25 +330,6 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// 强制签名验证开关
|
||||
var forceSignatureVerification by rememberSaveable {
|
||||
mutableStateOf(prefs.getBoolean("force_signature_verification", false))
|
||||
}
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Security,
|
||||
title = stringResource(R.string.module_signature_verification),
|
||||
summary = stringResource(R.string.module_signature_verification_summary),
|
||||
checked = forceSignatureVerification,
|
||||
onCheckedChange = { enabled ->
|
||||
prefs.edit { putBoolean("force_signature_verification", enabled) }
|
||||
forceSignatureVerification = enabled
|
||||
}
|
||||
)
|
||||
// UID 扫描开关
|
||||
if (Natives.version >= Natives.MINIMAL_SUPPORTED_UID_SCANNER && Natives.version >= Natives.MINIMAL_NEW_IOCTL_KERNEL) {
|
||||
UidScannerSection(prefs, snackBarHost, scope, context)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1004,124 +985,3 @@ private fun TopBar(
|
||||
scrollBehavior = scrollBehavior
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UidScannerSection(
|
||||
prefs: SharedPreferences,
|
||||
snackBarHost: SnackbarHostState,
|
||||
scope: CoroutineScope,
|
||||
context: Context
|
||||
) {
|
||||
if (Natives.version < Natives.MINIMAL_SUPPORTED_UID_SCANNER) return
|
||||
|
||||
val realAuto = Natives.isUidScannerEnabled()
|
||||
val realMulti = getUidMultiUserScan()
|
||||
|
||||
var autoOn by remember { mutableStateOf(realAuto) }
|
||||
var multiOn by remember { mutableStateOf(realMulti) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
autoOn = realAuto
|
||||
multiOn = realMulti
|
||||
prefs.edit {
|
||||
putBoolean("uid_auto_scan", autoOn)
|
||||
putBoolean("uid_multi_user_scan", multiOn)
|
||||
}
|
||||
}
|
||||
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Scanner,
|
||||
title = stringResource(R.string.uid_auto_scan_title),
|
||||
summary = stringResource(R.string.uid_auto_scan_summary),
|
||||
checked = autoOn,
|
||||
onCheckedChange = { target ->
|
||||
autoOn = target
|
||||
if (!target) multiOn = false
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
setUidAutoScan(target)
|
||||
val actual = Natives.isUidScannerEnabled() || readUidScannerFile()
|
||||
withContext(Dispatchers.Main) {
|
||||
autoOn = actual
|
||||
if (!actual) multiOn = false
|
||||
prefs.edit {
|
||||
putBoolean("uid_auto_scan", actual)
|
||||
putBoolean("uid_multi_user_scan", multiOn)
|
||||
}
|
||||
if (actual != target) {
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(R.string.uid_scanner_setting_failed)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = autoOn,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = fadeOut() + shrinkVertically()
|
||||
) {
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Groups,
|
||||
title = stringResource(R.string.uid_multi_user_scan_title),
|
||||
summary = stringResource(R.string.uid_multi_user_scan_summary),
|
||||
checked = multiOn,
|
||||
onCheckedChange = { target ->
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val ok = setUidMultiUserScan(target)
|
||||
withContext(Dispatchers.Main) {
|
||||
if (ok) {
|
||||
multiOn = target
|
||||
prefs.edit { putBoolean("uid_multi_user_scan", target) }
|
||||
} else {
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(R.string.uid_scanner_setting_failed)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = autoOn,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = fadeOut() + shrinkVertically()
|
||||
) {
|
||||
val confirmDialog = rememberConfirmDialog()
|
||||
SettingItem(
|
||||
icon = Icons.Filled.CleaningServices,
|
||||
title = stringResource(R.string.clean_runtime_environment),
|
||||
summary = stringResource(R.string.clean_runtime_environment_summary),
|
||||
onClick = {
|
||||
scope.launch {
|
||||
if (confirmDialog.awaitConfirm(
|
||||
title = context.getString(R.string.clean_runtime_environment),
|
||||
content = context.getString(R.string.clean_runtime_environment_confirm)
|
||||
) == ConfirmResult.Confirmed
|
||||
) {
|
||||
if (cleanRuntimeEnvironment()) {
|
||||
autoOn = false
|
||||
multiOn = false
|
||||
prefs.edit {
|
||||
putBoolean("uid_auto_scan", false)
|
||||
putBoolean("uid_multi_user_scan", false)
|
||||
}
|
||||
Natives.setUidScannerEnabled(false)
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(R.string.clean_runtime_environment_success)
|
||||
)
|
||||
} else {
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(R.string.clean_runtime_environment_failed)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
@@ -25,6 +28,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.edit
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.annotation.RootGraph
|
||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
@@ -33,8 +37,8 @@ import com.sukisu.ultra.Natives
|
||||
import com.sukisu.ultra.R
|
||||
import com.sukisu.ultra.ui.theme.component.ImageEditorDialog
|
||||
import com.sukisu.ultra.ui.component.KsuIsValid
|
||||
import com.sukisu.ultra.ui.screen.SwitchItem
|
||||
import com.sukisu.ultra.ui.theme.*
|
||||
import com.sukisu.ultra.ui.util.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -45,6 +49,7 @@ import zako.zako.zako.zakoui.screen.moreSettings.component.SettingItem
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.component.SettingsCard
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.component.SettingsDivider
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.component.SwitchSettingItem
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.component.UidScannerSection
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.state.MoreSettingsState
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@@ -341,6 +346,11 @@ private fun AdvancedSettings(
|
||||
state: MoreSettingsState,
|
||||
handlers: MoreSettingsHandlers
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val snackBarHost = remember { SnackbarHostState() }
|
||||
val prefs = remember { context.getSharedPreferences("settings", Context.MODE_PRIVATE) }
|
||||
|
||||
SettingsCard(title = stringResource(R.string.advanced_settings)) {
|
||||
// SELinux 开关
|
||||
SwitchSettingItem(
|
||||
@@ -353,6 +363,27 @@ private fun AdvancedSettings(
|
||||
onChange = handlers::handleSelinuxChange
|
||||
)
|
||||
|
||||
var forceSignatureVerification by rememberSaveable {
|
||||
mutableStateOf(prefs.getBoolean("force_signature_verification", false))
|
||||
}
|
||||
|
||||
// 强制签名验证开关
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Security,
|
||||
title = stringResource(R.string.module_signature_verification),
|
||||
summary = stringResource(R.string.module_signature_verification_summary),
|
||||
checked = forceSignatureVerification,
|
||||
onCheckedChange = { enabled ->
|
||||
prefs.edit { putBoolean("force_signature_verification", enabled) }
|
||||
forceSignatureVerification = enabled
|
||||
}
|
||||
)
|
||||
|
||||
// UID 扫描开关
|
||||
if (Natives.version >= Natives.MINIMAL_SUPPORTED_UID_SCANNER && Natives.version >= Natives.MINIMAL_NEW_IOCTL_KERNEL) {
|
||||
UidScannerSection(prefs, snackBarHost, scope, context)
|
||||
}
|
||||
|
||||
// 动态管理器设置
|
||||
if (Natives.version >= Natives.MINIMAL_SUPPORTED_DYNAMIC_MANAGER && Natives.version >= Natives.MINIMAL_NEW_IOCTL_KERNEL) {
|
||||
SettingItem(
|
||||
|
||||
@@ -6,15 +6,38 @@ import android.content.SharedPreferences
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.widget.Toast
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.expandVertically
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.CleaningServices
|
||||
import androidx.compose.material.icons.filled.Groups
|
||||
import androidx.compose.material.icons.filled.Scanner
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.edit
|
||||
import com.sukisu.ultra.Natives
|
||||
import com.sukisu.ultra.R
|
||||
import com.sukisu.ultra.ui.component.ConfirmResult
|
||||
import com.sukisu.ultra.ui.component.rememberConfirmDialog
|
||||
import com.sukisu.ultra.ui.screen.SettingItem
|
||||
import com.sukisu.ultra.ui.screen.SwitchItem
|
||||
import com.sukisu.ultra.ui.theme.*
|
||||
import com.sukisu.ultra.ui.util.*
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.state.MoreSettingsState
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.util.toggleLauncherIcon
|
||||
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
package zako.zako.zako.zakoui.screen.moreSettings.component
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.expandVertically
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.CleaningServices
|
||||
import androidx.compose.material.icons.filled.Groups
|
||||
import androidx.compose.material.icons.filled.Scanner
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@@ -20,9 +30,22 @@ import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
|
||||
import com.maxkeppeler.sheets.list.ListDialog
|
||||
import com.maxkeppeler.sheets.list.models.ListOption
|
||||
import com.maxkeppeler.sheets.list.models.ListSelection
|
||||
import com.sukisu.ultra.Natives
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.util.LocaleHelper
|
||||
import com.sukisu.ultra.R
|
||||
import com.sukisu.ultra.ui.component.ConfirmResult
|
||||
import com.sukisu.ultra.ui.component.rememberConfirmDialog
|
||||
import com.sukisu.ultra.ui.screen.SwitchItem
|
||||
import com.sukisu.ultra.ui.theme.*
|
||||
import com.sukisu.ultra.ui.util.cleanRuntimeEnvironment
|
||||
import com.sukisu.ultra.ui.util.getUidMultiUserScan
|
||||
import com.sukisu.ultra.ui.util.readUidScannerFile
|
||||
import com.sukisu.ultra.ui.util.setUidAutoScan
|
||||
import com.sukisu.ultra.ui.util.setUidMultiUserScan
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.MoreSettingsHandlers
|
||||
import zako.zako.zako.zakoui.screen.moreSettings.state.MoreSettingsState
|
||||
|
||||
@@ -474,3 +497,124 @@ fun DynamicManagerDialog(
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UidScannerSection(
|
||||
prefs: SharedPreferences,
|
||||
snackBarHost: SnackbarHostState,
|
||||
scope: CoroutineScope,
|
||||
context: Context
|
||||
) {
|
||||
if (Natives.version < Natives.MINIMAL_SUPPORTED_UID_SCANNER) return
|
||||
|
||||
val realAuto = Natives.isUidScannerEnabled()
|
||||
val realMulti = getUidMultiUserScan()
|
||||
|
||||
var autoOn by remember { mutableStateOf(realAuto) }
|
||||
var multiOn by remember { mutableStateOf(realMulti) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
autoOn = realAuto
|
||||
multiOn = realMulti
|
||||
prefs.edit {
|
||||
putBoolean("uid_auto_scan", autoOn)
|
||||
putBoolean("uid_multi_user_scan", multiOn)
|
||||
}
|
||||
}
|
||||
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Scanner,
|
||||
title = stringResource(R.string.uid_auto_scan_title),
|
||||
summary = stringResource(R.string.uid_auto_scan_summary),
|
||||
checked = autoOn,
|
||||
onCheckedChange = { target ->
|
||||
autoOn = target
|
||||
if (!target) multiOn = false
|
||||
|
||||
scope.launch(Dispatchers.IO) {
|
||||
setUidAutoScan(target)
|
||||
val actual = Natives.isUidScannerEnabled() || readUidScannerFile()
|
||||
withContext(Dispatchers.Main) {
|
||||
autoOn = actual
|
||||
if (!actual) multiOn = false
|
||||
prefs.edit {
|
||||
putBoolean("uid_auto_scan", actual)
|
||||
putBoolean("uid_multi_user_scan", multiOn)
|
||||
}
|
||||
if (actual != target) {
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(R.string.uid_scanner_setting_failed)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = autoOn,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = fadeOut() + shrinkVertically()
|
||||
) {
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Groups,
|
||||
title = stringResource(R.string.uid_multi_user_scan_title),
|
||||
summary = stringResource(R.string.uid_multi_user_scan_summary),
|
||||
checked = multiOn,
|
||||
onCheckedChange = { target ->
|
||||
scope.launch(Dispatchers.IO) {
|
||||
val ok = setUidMultiUserScan(target)
|
||||
withContext(Dispatchers.Main) {
|
||||
if (ok) {
|
||||
multiOn = target
|
||||
prefs.edit { putBoolean("uid_multi_user_scan", target) }
|
||||
} else {
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(R.string.uid_scanner_setting_failed)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = autoOn,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = fadeOut() + shrinkVertically()
|
||||
) {
|
||||
val confirmDialog = rememberConfirmDialog()
|
||||
com.sukisu.ultra.ui.screen.SettingItem(
|
||||
icon = Icons.Filled.CleaningServices,
|
||||
title = stringResource(R.string.clean_runtime_environment),
|
||||
summary = stringResource(R.string.clean_runtime_environment_summary),
|
||||
onClick = {
|
||||
scope.launch {
|
||||
if (confirmDialog.awaitConfirm(
|
||||
title = context.getString(R.string.clean_runtime_environment),
|
||||
content = context.getString(R.string.clean_runtime_environment_confirm)
|
||||
) == ConfirmResult.Confirmed
|
||||
) {
|
||||
if (cleanRuntimeEnvironment()) {
|
||||
autoOn = false
|
||||
multiOn = false
|
||||
prefs.edit {
|
||||
putBoolean("uid_auto_scan", false)
|
||||
putBoolean("uid_multi_user_scan", false)
|
||||
}
|
||||
Natives.setUidScannerEnabled(false)
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(R.string.clean_runtime_environment_success)
|
||||
)
|
||||
} else {
|
||||
snackBarHost.showSnackbar(
|
||||
context.getString(R.string.clean_runtime_environment_failed)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -70,9 +70,6 @@ class MoreSettingsState(
|
||||
// SELinux状态
|
||||
var selinuxEnabled by mutableStateOf(false)
|
||||
|
||||
// SuSFS 状态
|
||||
var isSusFSEnabled by mutableStateOf(true)
|
||||
|
||||
// 卡片配置状态
|
||||
var cardAlpha by mutableFloatStateOf(CardConfig.cardAlpha)
|
||||
var cardDim by mutableFloatStateOf(CardConfig.cardDim)
|
||||
|
||||
Reference in New Issue
Block a user