manager: Add support for automatic selection of corresponding SuSFS version and build time artifacts
This commit is contained in:
BIN
manager/app/src/main/assets/ksu_susfs_1.5.7
Normal file
BIN
manager/app/src/main/assets/ksu_susfs_1.5.7
Normal file
Binary file not shown.
@@ -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))
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user