Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb2d8fd7e0 | ||
|
|
2b6d418fe6 | ||
|
|
d8b1126b96 | ||
|
|
2eeddcfa80 |
@@ -91,14 +91,6 @@ object Natives {
|
||||
return version < MINIMAL_SUPPORTED_KERNEL
|
||||
}
|
||||
|
||||
fun isKsuValid(pkgName: String?): Boolean {
|
||||
if (becomeManager(pkgName)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
@Parcelize
|
||||
@Keep
|
||||
|
||||
@@ -48,7 +48,6 @@ fun ImageEditorDialog(
|
||||
var offsetY by remember { mutableFloatStateOf(0f) }
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val density = LocalDensity.current
|
||||
var lastScale by remember { mutableFloatStateOf(1f) }
|
||||
var lastOffsetX by remember { mutableFloatStateOf(0f) }
|
||||
var lastOffsetY by remember { mutableFloatStateOf(0f) }
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.sukisu.ultra.ui.component
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.sukisu.ultra.Natives
|
||||
import com.sukisu.ultra.ksuApp
|
||||
|
||||
@Composable
|
||||
fun KsuIsValid(
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val isManager = Natives.becomeManager(ksuApp.packageName)
|
||||
val ksuVersion = if (isManager) Natives.version else null
|
||||
|
||||
if (ksuVersion != null) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||
|
||||
/**
|
||||
* 槽位选择对话框组件
|
||||
* 用于HorizonKernel刷写时选择目标槽位
|
||||
* 用于Kernel刷写时选择目标槽位
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
||||
@@ -70,7 +70,7 @@ fun SwitchItem(
|
||||
text = it,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 3,
|
||||
maxLines = Int.MAX_VALUE,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ import com.sukisu.ultra.Natives
|
||||
import com.sukisu.ultra.R
|
||||
import com.sukisu.ultra.getKernelVersion
|
||||
import com.sukisu.ultra.ksuApp
|
||||
import com.sukisu.ultra.ui.component.KsuIsValid
|
||||
import com.sukisu.ultra.ui.component.rememberConfirmDialog
|
||||
import com.sukisu.ultra.ui.theme.CardConfig
|
||||
import com.sukisu.ultra.ui.theme.CardConfig.cardElevation
|
||||
@@ -400,17 +401,18 @@ private fun TopBar(
|
||||
}
|
||||
|
||||
var showDropdown by remember { mutableStateOf(false) }
|
||||
if (Natives.isKsuValid(ksuApp.packageName)) {
|
||||
IconButton(onClick = { showDropdown = true }) {
|
||||
KsuIsValid {
|
||||
IconButton(onClick = {
|
||||
showDropdown = true
|
||||
}) {
|
||||
Icon(
|
||||
Icons.Filled.Refresh,
|
||||
contentDescription = stringResource(R.string.reboot),
|
||||
imageVector = Icons.Filled.Refresh,
|
||||
contentDescription = stringResource(id = R.string.reboot)
|
||||
)
|
||||
|
||||
DropdownMenu(
|
||||
expanded = showDropdown,
|
||||
onDismissRequest = { showDropdown = false }
|
||||
) {
|
||||
DropdownMenu(expanded = showDropdown, onDismissRequest = {
|
||||
showDropdown = false
|
||||
}) {
|
||||
RebootDropdownItem(id = R.string.reboot)
|
||||
|
||||
val pm = LocalContext.current.getSystemService(Context.POWER_SERVICE) as PowerManager?
|
||||
@@ -652,7 +654,7 @@ fun WarningCard(
|
||||
@Composable
|
||||
fun ContributionCard() {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val links = listOf("https://github.com/zako", "https://github.com/udochina")
|
||||
val links = listOf("https://github.com/ShirkNeko", "https://github.com/udochina")
|
||||
|
||||
ElevatedCard(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
|
||||
@@ -69,7 +69,6 @@ import java.io.InputStreamReader
|
||||
import java.util.zip.ZipInputStream
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.net.toUri
|
||||
import com.sukisu.ultra.ui.theme.ThemeConfig
|
||||
import com.sukisu.ultra.R
|
||||
import com.sukisu.ultra.ui.theme.CardConfig.cardElevation
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ import com.sukisu.ultra.Natives
|
||||
import com.sukisu.ultra.R
|
||||
import com.sukisu.ultra.ksuApp
|
||||
import com.sukisu.ultra.ui.component.ImageEditorDialog
|
||||
import com.sukisu.ultra.ui.component.KsuIsValid
|
||||
import com.sukisu.ultra.ui.component.SwitchItem
|
||||
import com.sukisu.ultra.ui.theme.CardConfig
|
||||
import com.sukisu.ultra.ui.theme.ThemeColors
|
||||
@@ -267,7 +268,6 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
)
|
||||
|
||||
var showThemeColorDialog by remember { mutableStateOf(false) }
|
||||
val ksuIsValid = Natives.isKsuValid(ksuApp.packageName)
|
||||
|
||||
// 图片选择器
|
||||
val pickImageLauncher = rememberLauncherForActivityResult(
|
||||
@@ -674,7 +674,7 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
) {
|
||||
Column {
|
||||
// SELinux 开关
|
||||
if (ksuIsValid) {
|
||||
KsuIsValid {
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Security,
|
||||
title = stringResource(R.string.selinux),
|
||||
|
||||
@@ -57,6 +57,7 @@ import com.sukisu.ultra.ui.util.LocalSnackbarHost
|
||||
import com.sukisu.ultra.ui.util.getBugreportFile
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import com.sukisu.ultra.ui.component.KsuIsValid
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@@ -65,7 +66,6 @@ import java.time.format.DateTimeFormatter
|
||||
fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
val snackBarHost = LocalSnackbarHost.current
|
||||
val ksuIsValid = Natives.isKsuValid(ksuApp.packageName)
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
@@ -110,7 +110,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
}
|
||||
}
|
||||
|
||||
// 设置分组卡片 - 配置
|
||||
// 配置
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -130,7 +130,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
|
||||
// 配置文件模板入口
|
||||
val profileTemplate = stringResource(id = R.string.settings_profile_template)
|
||||
if (ksuIsValid) {
|
||||
KsuIsValid {
|
||||
SettingItem(
|
||||
icon = Icons.Filled.Fence,
|
||||
title = profileTemplate,
|
||||
@@ -146,7 +146,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
mutableStateOf(Natives.isDefaultUmountModules())
|
||||
}
|
||||
|
||||
if (ksuIsValid) {
|
||||
KsuIsValid {
|
||||
SwitchSettingItem(
|
||||
icon = Icons.Filled.FolderDelete,
|
||||
title = stringResource(id = R.string.settings_umount_modules_default),
|
||||
@@ -161,7 +161,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
}
|
||||
|
||||
// SU 禁用开关(仅在兼容版本显示)
|
||||
if (ksuIsValid) {
|
||||
KsuIsValid {
|
||||
if (Natives.version >= Natives.MINIMAL_SUPPORTED_SU_COMPAT) {
|
||||
var isSuDisabled by rememberSaveable {
|
||||
mutableStateOf(!Natives.isSuEnabled())
|
||||
@@ -226,7 +226,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
prefs.getBoolean("enable_web_debugging", false)
|
||||
)
|
||||
}
|
||||
if (Natives.isKsuValid(ksuApp.packageName)) {
|
||||
KsuIsValid {
|
||||
SwitchSettingItem(
|
||||
icon = Icons.Filled.DeveloperMode,
|
||||
title = stringResource(id = R.string.enable_web_debugging),
|
||||
|
||||
@@ -166,7 +166,6 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
|
||||
snackbarHost = { SnackbarHost(snackBarHostState) },
|
||||
contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal),
|
||||
bottomBar = {
|
||||
// 批量操作按钮,直接放在底部栏
|
||||
AnimatedVisibility(
|
||||
visible = viewModel.showBatchActions && viewModel.selectedApps.isNotEmpty(),
|
||||
enter = slideInVertically(initialOffsetY = { it }),
|
||||
@@ -181,15 +180,13 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||
horizontalArrangement = Arrangement.SpaceEvenly
|
||||
) {
|
||||
OutlinedButton(
|
||||
onClick = {
|
||||
// 修改为重新赋值为空集合
|
||||
viewModel.selectedApps = emptySet()
|
||||
viewModel.showBatchActions = false
|
||||
},
|
||||
modifier = Modifier.weight(1f),
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
@@ -197,9 +194,9 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Close,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp)
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
Text(stringResource(android.R.string.cancel))
|
||||
}
|
||||
|
||||
@@ -209,7 +206,6 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
|
||||
viewModel.updateBatchPermissions(true)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.weight(1f),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
@@ -217,9 +213,9 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Check,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp)
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
Text(stringResource(R.string.batch_authorization))
|
||||
}
|
||||
|
||||
@@ -229,7 +225,6 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
|
||||
viewModel.updateBatchPermissions(false)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.weight(1f),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = MaterialTheme.colorScheme.error
|
||||
)
|
||||
@@ -237,9 +232,9 @@ fun SuperUserScreen(navigator: DestinationsNavigator) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Block,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp)
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Spacer(modifier = Modifier.width(6.dp))
|
||||
Text(stringResource(R.string.batch_cancel_authorization))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,6 @@
|
||||
<string name="batch_authorization">授权</string>
|
||||
<string name="batch_cancel_authorization">撤销</string>
|
||||
<string name="color_yellow">黄色</string>
|
||||
<string name="kpm">内核模块</string>
|
||||
<string name="kpm_title">内核模块</string>
|
||||
<string name="kpm_empty">暂无已安装的内核模块</string>
|
||||
<string name="kpm_version">版本</string>
|
||||
|
||||
@@ -222,12 +222,11 @@
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
<string name="failed_reboot">Reboot Failed</string>
|
||||
<string name="batch_authorization">authorizations</string>
|
||||
<string name="batch_authorization">empower</string>
|
||||
<string name="batch_cancel_authorization">withdraw</string>
|
||||
<string name="backup">Backup</string>
|
||||
<string name="color_yellow">Yellow</string>
|
||||
<string name="kpm">KPM</string>
|
||||
<string name="kpm_title">Kernel Module</string>
|
||||
<string name="kpm_title">KPM</string>
|
||||
<string name="kpm_empty">No installed kernel modules at this time</string>
|
||||
<string name="kpm_version">Version</string>
|
||||
<string name="kpm_author">Author</string>
|
||||
|
||||
Reference in New Issue
Block a user