manager: Add support for automatic selection of corresponding SuSFS version and build time artifacts

This commit is contained in:
ShirkNeko
2025-06-14 22:04:40 +08:00
parent 97e367aa92
commit 85f5459c1d
6 changed files with 170 additions and 64 deletions

Binary file not shown.

View File

@@ -84,10 +84,12 @@ fun SuSFSConfigDialog(
var selectedTabIndex by remember { mutableIntStateOf(0) } var selectedTabIndex by remember { mutableIntStateOf(0) }
var unameValue by remember { mutableStateOf("") } var unameValue by remember { mutableStateOf("") }
var buildTimeValue by remember { mutableStateOf("") }
var isLoading by remember { mutableStateOf(false) } var isLoading by remember { mutableStateOf(false) }
var showConfirmReset by remember { mutableStateOf(false) } var showConfirmReset by remember { mutableStateOf(false) }
var autoStartEnabled by remember { mutableStateOf(false) } var autoStartEnabled by remember { mutableStateOf(false) }
var lastAppliedValue by remember { mutableStateOf("") } var lastAppliedValue by remember { mutableStateOf("") }
var lastAppliedBuildTime by remember { mutableStateOf("") }
// 路径管理相关状态 // 路径管理相关状态
var susPaths by remember { mutableStateOf(emptySet<String>()) } var susPaths by remember { mutableStateOf(emptySet<String>()) }
@@ -128,7 +130,8 @@ fun SuSFSConfigDialog(
// 实时判断是否可以启用开机自启动 // 实时判断是否可以启用开机自启动
val canEnableAutoStart by remember { val canEnableAutoStart by remember {
derivedStateOf { derivedStateOf {
unameValue.trim().isNotBlank() && unameValue.trim() != "default" || (unameValue.trim().isNotBlank() && unameValue.trim() != "default") ||
(buildTimeValue.trim().isNotBlank() && buildTimeValue.trim() != "default") ||
susPaths.isNotEmpty() || susMounts.isNotEmpty() || tryUmounts.isNotEmpty() susPaths.isNotEmpty() || susMounts.isNotEmpty() || tryUmounts.isNotEmpty()
} }
} }
@@ -145,8 +148,10 @@ fun SuSFSConfigDialog(
// 加载当前配置 // 加载当前配置
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
unameValue = SuSFSManager.getUnameValue(context) unameValue = SuSFSManager.getUnameValue(context)
buildTimeValue = SuSFSManager.getBuildTimeValue(context)
autoStartEnabled = SuSFSManager.isAutoStartEnabled(context) autoStartEnabled = SuSFSManager.isAutoStartEnabled(context)
lastAppliedValue = SuSFSManager.getLastAppliedValue(context) lastAppliedValue = SuSFSManager.getLastAppliedValue(context)
lastAppliedBuildTime = SuSFSManager.getLastAppliedBuildTime(context)
susPaths = SuSFSManager.getSusPaths(context) susPaths = SuSFSManager.getSusPaths(context)
susMounts = SuSFSManager.getSusMounts(context) susMounts = SuSFSManager.getSusMounts(context)
tryUmounts = SuSFSManager.getTryUmounts(context) tryUmounts = SuSFSManager.getTryUmounts(context)
@@ -585,7 +590,9 @@ fun SuSFSConfigDialog(
isLoading = true isLoading = true
if (SuSFSManager.resetToDefault(context)) { if (SuSFSManager.resetToDefault(context)) {
unameValue = "default" unameValue = "default"
buildTimeValue = "default"
lastAppliedValue = "default" lastAppliedValue = "default"
lastAppliedBuildTime = "default"
autoStartEnabled = false autoStartEnabled = false
} }
isLoading = false isLoading = false
@@ -615,6 +622,7 @@ fun SuSFSConfigDialog(
onDismissRequest = onDismiss, onDismissRequest = onDismiss,
title = { title = {
Row( Row(
modifier = Modifier.fillMaxWidth(0.8f),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Icon( Icon(
@@ -635,7 +643,7 @@ fun SuSFSConfigDialog(
Column( Column(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
// 优化后的标签页 - 使用ScrollableTabRow // 优化后的标签页
ScrollableTabRow( ScrollableTabRow(
selectedTabIndex = selectedTabIndex, selectedTabIndex = selectedTabIndex,
edgePadding = 16.dp, edgePadding = 16.dp,
@@ -667,7 +675,7 @@ fun SuSFSConfigDialog(
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.height(380.dp) .height(460.dp)
) { ) {
when (selectedTabIndex) { when (selectedTabIndex) {
0 -> { 0 -> {
@@ -705,7 +713,7 @@ fun SuSFSConfigDialog(
} }
} }
// 输入框 // Uname输入框
OutlinedTextField( OutlinedTextField(
value = unameValue, value = unameValue,
onValueChange = { unameValue = it }, onValueChange = { unameValue = it },
@@ -717,12 +725,33 @@ fun SuSFSConfigDialog(
shape = RoundedCornerShape(8.dp) shape = RoundedCornerShape(8.dp)
) )
// 构建时间伪装输入框
OutlinedTextField(
value = buildTimeValue,
onValueChange = { buildTimeValue = it },
label = { Text(stringResource(R.string.susfs_build_time_label)) },
placeholder = { Text(stringResource(R.string.susfs_build_time_placeholder)) },
modifier = Modifier.fillMaxWidth(),
enabled = !isLoading,
singleLine = true,
shape = RoundedCornerShape(8.dp)
)
// 当前值显示 // 当前值显示
Column(
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
Text( Text(
text = stringResource(R.string.susfs_current_value, SuSFSManager.getUnameValue(context)), text = stringResource(R.string.susfs_current_value, SuSFSManager.getUnameValue(context)),
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
Text(
text = stringResource(R.string.susfs_current_build_time, SuSFSManager.getBuildTimeValue(context)),
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
// 开机自启动开关 // 开机自启动开关
Card( Card(
@@ -1248,19 +1277,22 @@ fun SuSFSConfigDialog(
if (selectedTabIndex == 0) { if (selectedTabIndex == 0) {
Button( Button(
onClick = { onClick = {
if (unameValue.isNotBlank()) { if (unameValue.isNotBlank() || buildTimeValue.isNotBlank()) {
coroutineScope.launch { coroutineScope.launch {
isLoading = true isLoading = true
val success = SuSFSManager.setUname(context, unameValue.trim()) val finalUnameValue = unameValue.trim().ifBlank { "default" }
val finalBuildTimeValue = buildTimeValue.trim().ifBlank { "default" }
val success = SuSFSManager.setUname(context, finalUnameValue, finalBuildTimeValue)
if (success) { if (success) {
lastAppliedValue = unameValue.trim() lastAppliedValue = finalUnameValue
lastAppliedBuildTime = finalBuildTimeValue
onDismiss() onDismiss()
} }
isLoading = false isLoading = false
} }
} }
}, },
enabled = !isLoading && unameValue.isNotBlank(), enabled = !isLoading && (unameValue.isNotBlank() || buildTimeValue.isNotBlank()),
shape = RoundedCornerShape(8.dp) shape = RoundedCornerShape(8.dp)
) { ) {
Text(stringResource(R.string.susfs_apply)) Text(stringResource(R.string.susfs_apply))

View File

@@ -19,18 +19,40 @@ import java.io.File
object SuSFSManager { object SuSFSManager {
private const val PREFS_NAME = "susfs_config" private const val PREFS_NAME = "susfs_config"
private const val KEY_UNAME_VALUE = "uname_value" private const val KEY_UNAME_VALUE = "uname_value"
private const val KEY_BUILD_TIME_VALUE = "build_time_value"
private const val KEY_IS_ENABLED = "is_enabled" private const val KEY_IS_ENABLED = "is_enabled"
private const val KEY_AUTO_START_ENABLED = "auto_start_enabled" private const val KEY_AUTO_START_ENABLED = "auto_start_enabled"
private const val KEY_LAST_APPLIED_VALUE = "last_applied_value" private const val KEY_LAST_APPLIED_VALUE = "last_applied_value"
private const val KEY_LAST_APPLIED_BUILD_TIME = "last_applied_build_time"
private const val KEY_SUS_PATHS = "sus_paths" private const val KEY_SUS_PATHS = "sus_paths"
private const val KEY_SUS_MOUNTS = "sus_mounts" private const val KEY_SUS_MOUNTS = "sus_mounts"
private const val KEY_TRY_UMOUNTS = "try_umounts" private const val KEY_TRY_UMOUNTS = "try_umounts"
private const val KEY_ANDROID_DATA_PATH = "android_data_path" private const val KEY_ANDROID_DATA_PATH = "android_data_path"
private const val KEY_SDCARD_PATH = "sdcard_path" private const val KEY_SDCARD_PATH = "sdcard_path"
private const val SUSFS_BINARY_NAME = "ksu_susfs" private const val SUSFS_BINARY_BASE_NAME = "ksu_susfs"
private const val DEFAULT_UNAME = "default" private const val DEFAULT_UNAME = "default"
private const val DEFAULT_BUILD_TIME = "default"
private const val STARTUP_SCRIPT_PATH = "/data/adb/service.d/susfs_startup.sh" private const val STARTUP_SCRIPT_PATH = "/data/adb/service.d/susfs_startup.sh"
private const val SUSFS_TARGET_PATH = "/data/adb/ksu/bin/$SUSFS_BINARY_NAME"
private fun getSuSFS(): String {
return try {
getSuSFSVersion()
} catch (_: Exception) {
"1.5.8"
}
}
private fun getSuSFSBinaryName(): String {
val variant = getSuSFS().removePrefix("v")
return "${SUSFS_BINARY_BASE_NAME}_${variant}"
}
/**
* 获取SuSFS二进制文件的完整路径
*/
private fun getSuSFSTargetPath(): String {
return "/data/adb/ksu/bin/${getSuSFSBinaryName()}"
}
/** /**
* 启用功能状态数据类 * 启用功能状态数据类
@@ -90,6 +112,23 @@ object SuSFSManager {
return getPrefs(context).getString(KEY_UNAME_VALUE, DEFAULT_UNAME) ?: DEFAULT_UNAME return getPrefs(context).getString(KEY_UNAME_VALUE, DEFAULT_UNAME) ?: DEFAULT_UNAME
} }
/**
* 保存构建时间值
*/
fun saveBuildTimeValue(context: Context, value: String) {
getPrefs(context).edit().apply {
putString(KEY_BUILD_TIME_VALUE, value)
apply()
}
}
/**
* 获取保存的构建时间值
*/
fun getBuildTimeValue(context: Context): String {
return getPrefs(context).getString(KEY_BUILD_TIME_VALUE, DEFAULT_BUILD_TIME) ?: DEFAULT_BUILD_TIME
}
/** /**
* 保存最后应用的值 * 保存最后应用的值
*/ */
@@ -107,6 +146,23 @@ object SuSFSManager {
return getPrefs(context).getString(KEY_LAST_APPLIED_VALUE, DEFAULT_UNAME) ?: DEFAULT_UNAME return getPrefs(context).getString(KEY_LAST_APPLIED_VALUE, DEFAULT_UNAME) ?: DEFAULT_UNAME
} }
/**
* 保存最后应用的构建时间值
*/
private fun saveLastAppliedBuildTime(context: Context, value: String) {
getPrefs(context).edit().apply {
putString(KEY_LAST_APPLIED_BUILD_TIME, value)
apply()
}
}
/**
* 获取最后应用的构建时间值
*/
fun getLastAppliedBuildTime(context: Context): String {
return getPrefs(context).getString(KEY_LAST_APPLIED_BUILD_TIME, DEFAULT_BUILD_TIME) ?: DEFAULT_BUILD_TIME
}
/** /**
* 保存SuSFS启用状态 * 保存SuSFS启用状态
*/ */
@@ -226,8 +282,10 @@ object SuSFSManager {
*/ */
private suspend fun copyBinaryFromAssets(context: Context): String? = withContext(Dispatchers.IO) { private suspend fun copyBinaryFromAssets(context: Context): String? = withContext(Dispatchers.IO) {
try { try {
val inputStream = context.assets.open(SUSFS_BINARY_NAME) val binaryName = getSuSFSBinaryName()
val tempFile = File(context.cacheDir, SUSFS_BINARY_NAME) val targetPath = getSuSFSTargetPath()
val inputStream = context.assets.open(binaryName)
val tempFile = File(context.cacheDir, binaryName)
FileOutputStream(tempFile).use { outputStream -> FileOutputStream(tempFile).use { outputStream ->
inputStream.copyTo(outputStream) inputStream.copyTo(outputStream)
@@ -236,8 +294,8 @@ object SuSFSManager {
// 创建目标目录并复制文件到/data/adb/ksu/bin/ // 创建目标目录并复制文件到/data/adb/ksu/bin/
val shell = getRootShell() val shell = getRootShell()
val commands = arrayOf( val commands = arrayOf(
"cp '${tempFile.absolutePath}' '$SUSFS_TARGET_PATH'", "cp '${tempFile.absolutePath}' '$targetPath'",
"chmod 755 '$SUSFS_TARGET_PATH'", "chmod 755 '$targetPath'",
) )
var success = true var success = true
@@ -253,9 +311,9 @@ object SuSFSManager {
tempFile.delete() tempFile.delete()
if (success) { if (success) {
val verifyResult = shell.newJob().add("test -f '$SUSFS_TARGET_PATH'").exec() val verifyResult = shell.newJob().add("test -f '$targetPath'").exec()
if (verifyResult.isSuccess) { if (verifyResult.isSuccess) {
SUSFS_TARGET_PATH targetPath
} else { } else {
null null
} }
@@ -275,11 +333,13 @@ object SuSFSManager {
private suspend fun createStartupScript(context: Context): Boolean = withContext(Dispatchers.IO) { private suspend fun createStartupScript(context: Context): Boolean = withContext(Dispatchers.IO) {
try { try {
val unameValue = getUnameValue(context) val unameValue = getUnameValue(context)
val buildTimeValue = getBuildTimeValue(context)
val susPaths = getSusPaths(context) val susPaths = getSusPaths(context)
val susMounts = getSusMounts(context) val susMounts = getSusMounts(context)
val tryUmounts = getTryUmounts(context) val tryUmounts = getTryUmounts(context)
val androidDataPath = getAndroidDataPath(context) val androidDataPath = getAndroidDataPath(context)
val sdcardPath = getSdcardPath(context) val sdcardPath = getSdcardPath(context)
val targetPath = getSuSFSTargetPath()
val scriptContent = buildString { val scriptContent = buildString {
appendLine("#!/system/bin/sh") appendLine("#!/system/bin/sh")
@@ -290,7 +350,7 @@ object SuSFSManager {
appendLine("sleep 60") appendLine("sleep 60")
appendLine() appendLine()
appendLine("# 检查二进制文件是否存在") appendLine("# 检查二进制文件是否存在")
appendLine("if [ -f \"$SUSFS_TARGET_PATH\" ]; then") appendLine("if [ -f \"$targetPath\" ]; then")
appendLine(" # 创建日志目录") appendLine(" # 创建日志目录")
appendLine(" mkdir -p /data/adb/ksu/log") appendLine(" mkdir -p /data/adb/ksu/log")
appendLine() appendLine()
@@ -298,28 +358,28 @@ object SuSFSManager {
// 设置Android Data路径 // 设置Android Data路径
if (androidDataPath != "/sdcard/Android/data") { if (androidDataPath != "/sdcard/Android/data") {
appendLine(" # 设置Android Data路径") appendLine(" # 设置Android Data路径")
appendLine(" $SUSFS_TARGET_PATH set_android_data_root_path '$androidDataPath'") appendLine(" $targetPath set_android_data_root_path '$androidDataPath'")
appendLine(" echo \"\\$(date): Android Data路径设置为: $androidDataPath\" >> /data/adb/ksu/log/susfs_startup.log") appendLine(" echo \"\\$(date): Android Data路径设置为: $androidDataPath\" >> /data/adb/ksu/log/susfs_startup.log")
} }
// 设置SD卡路径 // 设置SD卡路径
if (sdcardPath != "/sdcard") { if (sdcardPath != "/sdcard") {
appendLine(" # 设置SD卡路径") appendLine(" # 设置SD卡路径")
appendLine(" $SUSFS_TARGET_PATH set_sdcard_root_path '$sdcardPath'") appendLine(" $targetPath set_sdcard_root_path '$sdcardPath'")
appendLine(" echo \"\\$(date): SD卡路径设置为: $sdcardPath\" >> /data/adb/ksu/log/susfs_startup.log") appendLine(" echo \"\\$(date): SD卡路径设置为: $sdcardPath\" >> /data/adb/ksu/log/susfs_startup.log")
} }
// 添加SUS路径 // 添加SUS路径
susPaths.forEach { path -> susPaths.forEach { path ->
appendLine(" # 添加SUS路径: $path") appendLine(" # 添加SUS路径: $path")
appendLine(" $SUSFS_TARGET_PATH add_sus_path '$path'") appendLine(" $targetPath add_sus_path '$path'")
appendLine(" echo \"\\$(date): 添加SUS路径: $path\" >> /data/adb/ksu/log/susfs_startup.log") appendLine(" echo \"\\$(date): 添加SUS路径: $path\" >> /data/adb/ksu/log/susfs_startup.log")
} }
// 添加SUS挂载 // 添加SUS挂载
susMounts.forEach { mount -> susMounts.forEach { mount ->
appendLine(" # 添加SUS挂载: $mount") appendLine(" # 添加SUS挂载: $mount")
appendLine(" $SUSFS_TARGET_PATH add_sus_mount '$mount'") appendLine(" $targetPath add_sus_mount '$mount'")
appendLine(" echo \"\\$(date): 添加SUS挂载: $mount\" >> /data/adb/ksu/log/susfs_startup.log") appendLine(" echo \"\\$(date): 添加SUS挂载: $mount\" >> /data/adb/ksu/log/susfs_startup.log")
} }
@@ -330,20 +390,20 @@ object SuSFSManager {
val path = parts[0] val path = parts[0]
val mode = parts[1] val mode = parts[1]
appendLine(" # 添加尝试卸载: $path (模式: $mode)") appendLine(" # 添加尝试卸载: $path (模式: $mode)")
appendLine(" $SUSFS_TARGET_PATH add_try_umount '$path' $mode") appendLine(" $targetPath add_try_umount '$path' $mode")
appendLine(" echo \"\\$(date): 添加尝试卸载: $path (模式: $mode)\" >> /data/adb/ksu/log/susfs_startup.log") appendLine(" echo \"\\$(date): 添加尝试卸载: $path (模式: $mode)\" >> /data/adb/ksu/log/susfs_startup.log")
} }
} }
// 设置uname // 设置uname和构建时间
if (unameValue != DEFAULT_UNAME) { if (unameValue != DEFAULT_UNAME || buildTimeValue != DEFAULT_BUILD_TIME) {
appendLine(" # 设置uname") appendLine(" # 设置uname和构建时间")
appendLine(" $SUSFS_TARGET_PATH set_uname '$unameValue' '$DEFAULT_UNAME'") appendLine(" $targetPath set_uname '$unameValue' '$buildTimeValue'")
appendLine(" echo \"\\$(date): 设置uname为: $unameValue\" >> /data/adb/ksu/log/susfs_startup.log") appendLine(" echo \"\\$(date): 设置uname为: $unameValue, 构建时间为: $buildTimeValue\" >> /data/adb/ksu/log/susfs_startup.log")
} }
appendLine("else") appendLine("else")
appendLine(" echo \"\\$(date): SuSFS二进制文件未找到: $SUSFS_TARGET_PATH\" >> /data/adb/ksu/log/susfs_startup.log") appendLine(" echo \"\\$(date): SuSFS二进制文件未找到: $targetPath\" >> /data/adb/ksu/log/susfs_startup.log")
appendLine("fi") appendLine("fi")
} }
@@ -460,13 +520,14 @@ object SuSFSManager {
try { try {
// 每次都重新执行命令获取最新状态 // 每次都重新执行命令获取最新状态
val shell = getRootShell() val shell = getRootShell()
val targetPath = getSuSFSTargetPath()
// 首先检查二进制文件是否存在于目标位置 // 首先检查二进制文件是否存在于目标位置
val checkResult = shell.newJob().add("test -f '$SUSFS_TARGET_PATH'").exec() val checkResult = shell.newJob().add("test -f '$targetPath'").exec()
val binaryPath = if (checkResult.isSuccess) { val binaryPath = if (checkResult.isSuccess) {
// 如果目标位置存在,直接使用 // 如果目标位置存在,直接使用
SUSFS_TARGET_PATH targetPath
} else { } else {
// 如果不存在尝试从assets复制 // 如果不存在尝试从assets复制
copyBinaryFromAssets(context) copyBinaryFromAssets(context)
@@ -685,9 +746,9 @@ object SuSFSManager {
} }
/** /**
* 执行SuSFS命令设置uname * 执行SuSFS命令设置uname和构建时间
*/ */
suspend fun setUname(context: Context, unameValue: String): Boolean = withContext(Dispatchers.IO) { suspend fun setUname(context: Context, unameValue: String, buildTimeValue: String): Boolean = withContext(Dispatchers.IO) {
try { try {
// 首先复制二进制文件到/data/adb/ksu/bin/ // 首先复制二进制文件到/data/adb/ksu/bin/
val binaryPath = copyBinaryFromAssets(context) val binaryPath = copyBinaryFromAssets(context)
@@ -703,7 +764,7 @@ object SuSFSManager {
} }
// 构建命令 // 构建命令
val command = "$binaryPath set_uname '$unameValue' '$DEFAULT_UNAME'" val command = "$binaryPath set_uname '$unameValue' '$buildTimeValue'"
// 执行命令 // 执行命令
val result = getRootShell().newJob().add(command).exec() val result = getRootShell().newJob().add(command).exec()
@@ -711,7 +772,9 @@ object SuSFSManager {
if (result.isSuccess) { if (result.isSuccess) {
// 保存配置 // 保存配置
saveUnameValue(context, unameValue) saveUnameValue(context, unameValue)
saveBuildTimeValue(context, buildTimeValue)
saveLastAppliedValue(context, unameValue) saveLastAppliedValue(context, unameValue)
saveLastAppliedBuildTime(context, buildTimeValue)
setEnabled(context, true) setEnabled(context, true)
// 如果开启了开机自启动,更新启动脚本 // 如果开启了开机自启动,更新启动脚本
@@ -722,7 +785,7 @@ object SuSFSManager {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
context, context,
context.getString(R.string.susfs_uname_set_success, unameValue), context.getString(R.string.susfs_uname_set_success, unameValue, buildTimeValue),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
@@ -759,8 +822,10 @@ object SuSFSManager {
if (enabled) { if (enabled) {
// 启用开机自启动 // 启用开机自启动
val lastValue = getLastAppliedValue(context) val lastValue = getLastAppliedValue(context)
if (lastValue == DEFAULT_UNAME && getSusPaths(context).isEmpty() && val lastBuildTime = getLastAppliedBuildTime(context)
getSusMounts(context).isEmpty() && getTryUmounts(context).isEmpty()) { if (lastValue == DEFAULT_UNAME && lastBuildTime == DEFAULT_BUILD_TIME &&
getSusPaths(context).isEmpty() && getSusMounts(context).isEmpty() &&
getTryUmounts(context).isEmpty()) {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
context, context,
@@ -773,7 +838,8 @@ object SuSFSManager {
// 确保二进制文件存在于目标位置 // 确保二进制文件存在于目标位置
val shell = getRootShell() val shell = getRootShell()
val checkResult = shell.newJob().add("test -f '$SUSFS_TARGET_PATH'").exec() val targetPath = getSuSFSTargetPath()
val checkResult = shell.newJob().add("test -f '$targetPath'").exec()
if (!checkResult.isSuccess) { if (!checkResult.isSuccess) {
// 如果不存在,尝试复制 // 如果不存在,尝试复制
@@ -850,10 +916,11 @@ object SuSFSManager {
* 重置为默认值 * 重置为默认值
*/ */
suspend fun resetToDefault(context: Context): Boolean { suspend fun resetToDefault(context: Context): Boolean {
val success = setUname(context, DEFAULT_UNAME) val success = setUname(context, DEFAULT_UNAME, DEFAULT_BUILD_TIME)
if (success) { if (success) {
// 重置时清除最后应用的值 // 重置时清除最后应用的值
saveLastAppliedValue(context, DEFAULT_UNAME) saveLastAppliedValue(context, DEFAULT_UNAME)
saveLastAppliedBuildTime(context, DEFAULT_BUILD_TIME)
// 如果开启了开机自启动,需要禁用它 // 如果开启了开机自启动,需要禁用它
if (isAutoStartEnabled(context)) { if (isAutoStartEnabled(context)) {
configureAutoStart(context, false) configureAutoStart(context, false)
@@ -867,7 +934,8 @@ object SuSFSManager {
*/ */
fun isBinaryAvailable(context: Context): Boolean { fun isBinaryAvailable(context: Context): Boolean {
return try { return try {
context.assets.open(SUSFS_BINARY_NAME).use { true } val binaryName = getSuSFSBinaryName()
context.assets.open(binaryName).use { true }
} catch (_: IOException) { } catch (_: IOException) {
false false
} }

View File

@@ -399,10 +399,13 @@
<!-- SuSFS Configuration --> <!-- SuSFS Configuration -->
<string name="susfs_config_title">SuSFS 配置</string> <string name="susfs_config_title">SuSFS 配置</string>
<string name="susfs_config_description">配置说明</string> <string name="susfs_config_description">配置说明</string>
<string name="susfs_config_description_text">此功能允许您自定义 SuSFS 的 uname 值。输入您想要设置的值,点击应用即可生效</string> <string name="susfs_config_description_text">此功能允许您自定义 SuSFS 的 uname 值和构建时间伪装。输入您想要设置的值,点击应用即可生效</string>
<string name="susfs_uname_label">Uname 值</string> <string name="susfs_uname_label">Uname 值</string>
<string name="susfs_uname_placeholder">请输入自定义 uname 值</string> <string name="susfs_uname_placeholder">请输入自定义 uname 值</string>
<string name="susfs_build_time_label">构建时间伪装</string>
<string name="susfs_build_time_placeholder">请输入构建时间伪装值</string>
<string name="susfs_current_value">当前值: %s</string> <string name="susfs_current_value">当前值: %s</string>
<string name="susfs_current_build_time">当前构建时间: %s</string>
<string name="susfs_reset_to_default">重置为默认值</string> <string name="susfs_reset_to_default">重置为默认值</string>
<string name="susfs_apply">应用</string> <string name="susfs_apply">应用</string>
<string name="susfs_done">完成</string> <string name="susfs_done">完成</string>
@@ -413,14 +416,14 @@
<string name="susfs_binary_not_found">无法找到 ksu_susfs 文件</string> <string name="susfs_binary_not_found">无法找到 ksu_susfs 文件</string>
<string name="susfs_command_failed">SuSFS 命令执行失败</string> <string name="susfs_command_failed">SuSFS 命令执行失败</string>
<string name="susfs_command_error">执行 SuSFS 命令时出错: %s</string> <string name="susfs_command_error">执行 SuSFS 命令时出错: %s</string>
<string name="susfs_uname_set_success">SuSFS uname 设置成功: %s</string> <string name="susfs_uname_set_success">SuSFS uname 和构建时间设置成功: %s, %s</string>
<!-- SuSFS Settings Item --> <!-- SuSFS Settings Item -->
<string name="susfs_config_setting_title">SuSFS 配置</string> <string name="susfs_config_setting_title">SuSFS 配置</string>
<string name="susfs_config_setting_summary">配置 SuSFS 的 uname 值 (当前: %s)</string> <string name="susfs_config_setting_summary">配置 SuSFS 的 uname 值和构建时间伪装 (当前: %s)</string>
<!-- 开机自启动相关 --> <!-- 开机自启动相关 -->
<string name="susfs_autostart_title">开机自启动</string> <string name="susfs_autostart_title">开机自启动</string>
<string name="susfs_autostart_description">系统启动时自动应用 uname 配置</string> <string name="susfs_autostart_description">系统启动时自动应用 uname 配置</string>
<string name="susfs_autostart_requirement">需要配置uname或添加路径后才能启用</string> <string name="susfs_autostart_requirement">需要配置 uname 或添加路径后才能启用</string>
<string name="susfs_autostart_enabled">开机自启动已启用</string> <string name="susfs_autostart_enabled">开机自启动已启用</string>
<string name="susfs_autostart_disabled">开机自启动已禁用</string> <string name="susfs_autostart_disabled">开机自启动已禁用</string>
<string name="susfs_autostart_enable_failed">启用开机自启动失败</string> <string name="susfs_autostart_enable_failed">启用开机自启动失败</string>
@@ -448,11 +451,11 @@
<string name="susfs_path_label">路径</string> <string name="susfs_path_label">路径</string>
<string name="susfs_mount_path_label">挂载路径</string> <string name="susfs_mount_path_label">挂载路径</string>
<string name="susfs_path_placeholder">例如: /system/addon.d</string> <string name="susfs_path_placeholder">例如: /system/addon.d</string>
<string name="susfs_sus_paths_management">SUS路径管理</string> <string name="susfs_sus_paths_management">SUS 路径管理</string>
<string name="susfs_sus_mounts_management">SUS挂载管理</string> <string name="susfs_sus_mounts_management">SUS 挂载管理</string>
<string name="susfs_try_umount_management">尝试卸载管理</string> <string name="susfs_try_umount_management">尝试卸载管理</string>
<string name="susfs_no_paths_configured">暂无SUS路径配置</string> <string name="susfs_no_paths_configured">暂无 SUS 路径配置</string>
<string name="susfs_no_mounts_configured">暂无SUS挂载配置</string> <string name="susfs_no_mounts_configured">暂无 SUS 挂载配置</string>
<string name="susfs_no_umounts_configured">暂无尝试卸载配置</string> <string name="susfs_no_umounts_configured">暂无尝试卸载配置</string>
<!-- SuSFS Umount Mode --> <!-- SuSFS Umount Mode -->
<string name="susfs_umount_mode_label">卸载模式</string> <string name="susfs_umount_mode_label">卸载模式</string>
@@ -465,21 +468,21 @@
<string name="susfs_run_umount_confirm_title">确认运行尝试卸载</string> <string name="susfs_run_umount_confirm_title">确认运行尝试卸载</string>
<string name="susfs_run_umount_confirm_message">这将立即执行所有已配置的尝试卸载操作,确定要继续吗?</string> <string name="susfs_run_umount_confirm_message">这将立即执行所有已配置的尝试卸载操作,确定要继续吗?</string>
<!-- SuSFS Reset Categories --> <!-- SuSFS Reset Categories -->
<string name="susfs_reset_paths_title">重置SUS路径</string> <string name="susfs_reset_paths_title">重置 SUS 路径</string>
<string name="susfs_reset_paths_message">这将清除所有SUS路径配置确定要继续吗</string> <string name="susfs_reset_paths_message">这将清除所有 SUS 路径配置,确定要继续吗?</string>
<string name="susfs_reset_mounts_title">重置SUS挂载</string> <string name="susfs_reset_mounts_title">重置 SUS 挂载</string>
<string name="susfs_reset_mounts_message">这将清除所有SUS挂载配置确定要继续吗</string> <string name="susfs_reset_mounts_message">这将清除所有 SUS 挂载配置,确定要继续吗?</string>
<string name="susfs_reset_umounts_title">重置尝试卸载</string> <string name="susfs_reset_umounts_title">重置尝试卸载</string>
<string name="susfs_reset_umounts_message">这将清除所有尝试卸载配置,确定要继续吗?</string> <string name="susfs_reset_umounts_message">这将清除所有尝试卸载配置,确定要继续吗?</string>
<!-- SuSFS Path Settings --> <!-- SuSFS Path Settings -->
<string name="susfs_path_settings">路径设置</string> <string name="susfs_path_settings">路径设置</string>
<string name="susfs_android_data_path_label">Android Data路径</string> <string name="susfs_android_data_path_label">Android Data 路径</string>
<string name="susfs_sdcard_path_label">SD卡路径</string> <string name="susfs_sdcard_path_label">SD 卡路径</string>
<string name="susfs_set_android_data_path">设置Android Data路径</string> <string name="susfs_set_android_data_path">设置 Android Data 路径</string>
<string name="susfs_set_sdcard_path">设置SD卡路径</string> <string name="susfs_set_sdcard_path">设置 SD 卡路径</string>
<!-- SuSFS Enabled Features --> <!-- SuSFS Enabled Features -->
<string name="susfs_enabled_features_title">启用功能状态</string> <string name="susfs_enabled_features_title">启用功能状态</string>
<string name="susfs_enabled_features_description">显示当前SuSFS启用的功能状态</string> <string name="susfs_enabled_features_description">显示当前 SuSFS 启用的功能状态</string>
<string name="susfs_no_features_found">未找到功能状态信息</string> <string name="susfs_no_features_found">未找到功能状态信息</string>
<string name="susfs_feature_enabled">已启用</string> <string name="susfs_feature_enabled">已启用</string>
<string name="susfs_feature_disabled">已禁用</string> <string name="susfs_feature_disabled">已禁用</string>

View File

@@ -401,10 +401,13 @@
<!-- SuSFS Configuration --> <!-- SuSFS Configuration -->
<string name="susfs_config_title">SuSFS Configuration</string> <string name="susfs_config_title">SuSFS Configuration</string>
<string name="susfs_config_description">Configuration Description</string> <string name="susfs_config_description">Configuration Description</string>
<string name="susfs_config_description_text">This feature allows you to customize the SuSFS uname value. Enter the value you want to set and click Apply to take effect.</string> <string name="susfs_config_description_text">This feature allows you to customize the SuSFS uname value and build time spoofing. Enter the values you want to set and click Apply to take effect.</string>
<string name="susfs_uname_label">Uname Value</string> <string name="susfs_uname_label">Uname Value</string>
<string name="susfs_uname_placeholder">Please enter custom uname value</string> <string name="susfs_uname_placeholder">Please enter custom uname value</string>
<string name="susfs_build_time_label">Build Time Spoofing</string>
<string name="susfs_build_time_placeholder">Please enter build time spoofing value</string>
<string name="susfs_current_value">Current value: %s</string> <string name="susfs_current_value">Current value: %s</string>
<string name="susfs_current_build_time">Current build time: %s</string>
<string name="susfs_reset_to_default">Reset to Default</string> <string name="susfs_reset_to_default">Reset to Default</string>
<string name="susfs_apply">Apply</string> <string name="susfs_apply">Apply</string>
<string name="susfs_done">Done</string> <string name="susfs_done">Done</string>
@@ -415,10 +418,10 @@
<string name="susfs_binary_not_found">Cannot find ksu_susfs file</string> <string name="susfs_binary_not_found">Cannot find ksu_susfs file</string>
<string name="susfs_command_failed">SuSFS command execution failed</string> <string name="susfs_command_failed">SuSFS command execution failed</string>
<string name="susfs_command_error">Error executing SuSFS command: %s</string> <string name="susfs_command_error">Error executing SuSFS command: %s</string>
<string name="susfs_uname_set_success">SuSFS uname set successfully: %s</string> <string name="susfs_uname_set_success">SuSFS uname and build time set successfully: %s, %s</string>
<!-- SuSFS Settings Item --> <!-- SuSFS Settings Item -->
<string name="susfs_config_setting_title">SuSFS Configuration</string> <string name="susfs_config_setting_title">SuSFS Configuration</string>
<string name="susfs_config_setting_summary">Configure SuSFS uname value (Current: %s)</string> <string name="susfs_config_setting_summary">Configure SuSFS uname value and build time spoofing (Current: %s)</string>
<!-- 开机自启动相关 --> <!-- 开机自启动相关 -->
<string name="susfs_autostart_title">Auto Start</string> <string name="susfs_autostart_title">Auto Start</string>
<string name="susfs_autostart_description">Automatically apply uname configuration at system startup</string> <string name="susfs_autostart_description">Automatically apply uname configuration at system startup</string>