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