diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigDialogs.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigDialogs.kt index 9dc0d300..8b3c4113 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigDialogs.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigDialogs.kt @@ -77,7 +77,7 @@ fun AddPathDialog( enabled = newPath.isNotBlank() && !isLoading, shape = RoundedCornerShape(8.dp) ) { - Text(stringResource(R.string.susfs_add)) + Text(stringResource(R.string.add)) } }, dismissButton = { @@ -186,7 +186,7 @@ fun AddTryUmountDialog( enabled = newUmountPath.isNotBlank() && !isLoading, shape = RoundedCornerShape(8.dp) ) { - Text(stringResource(R.string.susfs_add)) + Text(stringResource(R.string.add)) } }, dismissButton = { @@ -431,7 +431,7 @@ fun AddKstatStaticallyDialog( enabled = newKstatPath.isNotBlank() && !isLoading, shape = RoundedCornerShape(8.dp) ) { - Text("添加") + Text(stringResource(R.string.add)) } }, dismissButton = { diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigTabs.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigTabs.kt index 33982c24..ed21a8d8 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigTabs.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SuSFSConfigTabs.kt @@ -97,7 +97,7 @@ fun SusPathsContent( modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(8.dp)) - Text(text = stringResource(R.string.susfs_add)) + Text(text = stringResource(R.string.add)) } } } @@ -172,7 +172,7 @@ fun SusMountsContent( modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(8.dp)) - Text(text = stringResource(R.string.susfs_add)) + Text(text = stringResource(R.string.add)) } } } @@ -245,7 +245,7 @@ fun TryUmountContent( modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(8.dp)) - Text(text = stringResource(R.string.susfs_add)) + Text(text = stringResource(R.string.add)) } if (tryUmounts.isNotEmpty()) { @@ -403,7 +403,7 @@ fun KstatConfigContent( modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(8.dp)) - Text(text = stringResource(R.string.susfs_add)) + Text(text = stringResource(R.string.add)) } Button( @@ -419,7 +419,7 @@ fun KstatConfigContent( modifier = Modifier.size(24.dp) ) Spacer(modifier = Modifier.width(8.dp)) - Text(text = stringResource(R.string.susfs_add)) + Text(text = stringResource(R.string.add)) } } } diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt index 2927275b..8236505c 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSManager.kt @@ -36,13 +36,14 @@ object SuSFSManager { private const val KEY_KSTAT_CONFIGS = "kstat_configs" private const val KEY_ADD_KSTAT_PATHS = "add_kstat_paths" private const val KEY_HIDE_SUS_MOUNTS_FOR_ALL_PROCS = "hide_sus_mounts_for_all_procs" + // 常量 private const val SUSFS_BINARY_BASE_NAME = "ksu_susfs" private const val DEFAULT_UNAME = "default" private const val DEFAULT_BUILD_TIME = "default" private const val MODULE_ID = "susfs_manager" private const val MODULE_PATH = "/data/adb/modules/$MODULE_ID" - + private const val MIN_VERSION_FOR_HIDE_MOUNT = "1.5.8" data class SlotInfo(val slotName: String, val uname: String, val buildTime: String) data class CommandResult(val isSuccess: Boolean, val output: String, val errorOutput: String = "") @@ -53,13 +54,46 @@ object SuSFSManager { val canConfigure: Boolean = false ) - // 命令执行 + /** + * 模块配置数据类 + */ + data class ModuleConfig( + val targetPath: String, + val unameValue: String, + val buildTimeValue: String, + val executeInPostFsData: Boolean, + val susPaths: Set, + val susMounts: Set, + val tryUmounts: Set, + val androidDataPath: String, + val sdcardPath: String, + val enableLog: Boolean, + val kstatConfigs: Set, + val addKstatPaths: Set, + val hideSusMountsForAllProcs: Boolean, + val support158: Boolean + ) { + /** + * 检查是否有需要自启动的配置 + */ + fun hasAutoStartConfig(): Boolean { + return unameValue != DEFAULT_UNAME || + buildTimeValue != DEFAULT_BUILD_TIME || + susPaths.isNotEmpty() || + susMounts.isNotEmpty() || + tryUmounts.isNotEmpty() || + kstatConfigs.isNotEmpty() || + addKstatPaths.isNotEmpty() + } + } + + // 基础工具方法 private fun getPrefs(context: Context): SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) private fun getSuSFSVersionUse(): String = try { getSuSFSVersion() - } catch (_: Exception) { "1.5.8" } + } catch (_: Exception) { MIN_VERSION_FOR_HIDE_MOUNT } private fun getSuSFSBinaryName(): String = "${SUSFS_BINARY_BASE_NAME}_${getSuSFSVersionUse().removePrefix("v")}" @@ -78,7 +112,9 @@ object SuSFSManager { return CommandResult(result.isSuccess, result.out.joinToString("\n"), result.err.joinToString("\n")) } - // 版本比较 + /** + * 版本比较方法 + */ private fun compareVersions(version1: String, version2: String): Int { val v1Parts = version1.removePrefix("v").split(".").map { it.toIntOrNull() ?: 0 } val v2Parts = version2.removePrefix("v").split(".").map { it.toIntOrNull() ?: 0 } @@ -97,16 +133,39 @@ object SuSFSManager { return 0 } - // 检查当前SuSFS版本是否支持SUS挂载隐藏控制功能 + /** + * 版本检查方法 + */ fun isSusVersion_1_5_8(): Boolean { return try { val currentVersion = getSuSFSVersion() - compareVersions(currentVersion, "1.5.8") >= 0 + compareVersions(currentVersion, MIN_VERSION_FOR_HIDE_MOUNT) >= 0 } catch (_: Exception) { - true + true // 默认支持新功能 } } + /** + * 获取当前模块配置 + */ + private fun getCurrentModuleConfig(context: Context): ModuleConfig { + return ModuleConfig( + targetPath = getSuSFSTargetPath(), + unameValue = getUnameValue(context), + buildTimeValue = getBuildTimeValue(context), + executeInPostFsData = getExecuteInPostFsData(context), + susPaths = getSusPaths(context), + susMounts = getSusMounts(context), + tryUmounts = getTryUmounts(context), + androidDataPath = getAndroidDataPath(context), + sdcardPath = getSdcardPath(context), + enableLog = getEnableLogState(context), + kstatConfigs = getKstatConfigs(context), + addKstatPaths = getAddKstatPaths(context), + hideSusMountsForAllProcs = getHideSusMountsForAllProcs(context), + support158 = isSusVersion_1_5_8() + ) + } // 配置存取方法 fun saveUnameValue(context: Context, value: String) = @@ -143,8 +202,7 @@ object SuSFSManager { getPrefs(context).edit { putBoolean(KEY_EXECUTE_IN_POST_FS_DATA, executeInPostFsData) } if (isAutoStartEnabled(context)) { kotlinx.coroutines.CoroutineScope(Dispatchers.Default).launch { - removeMagiskModule() - createMagiskModule(context) + updateMagiskModule(context) } } } @@ -203,8 +261,6 @@ object SuSFSManager { fun getSdcardPath(context: Context): String = getPrefs(context).getString(KEY_SDCARD_PATH, "/sdcard") ?: "/sdcard" - - // 槽位信息获取 suspend fun getCurrentSlotInfo(): List = withContext(Dispatchers.IO) { try { @@ -310,17 +366,19 @@ object SuSFSManager { Toast.makeText(context, message, Toast.LENGTH_SHORT).show() } - private inline fun Map.getSetSafe(key: String): Set { - return when (val value = this[key]) { - is Set<*> -> value.filterIsInstance().toSet() - else -> emptySet() - } + /** + * 模块管理 + */ + private suspend fun updateMagiskModule(context: Context): Boolean { + return removeMagiskModule() && createMagiskModule(context) } - // 模块管理 + /** + * 模块创建方法 + */ private suspend fun createMagiskModule(context: Context): Boolean = withContext(Dispatchers.IO) { try { - val targetPath = getSuSFSTargetPath() + val config = getCurrentModuleConfig(context) // 创建模块目录 if (!runCmdWithResult("mkdir -p $MODULE_PATH").isSuccess) return@withContext false @@ -329,44 +387,9 @@ object SuSFSManager { val moduleProp = ScriptGenerator.generateModuleProp(MODULE_ID) if (!runCmdWithResult("cat > $MODULE_PATH/module.prop << 'EOF'\n$moduleProp\nEOF").isSuccess) return@withContext false - // 获取配置 - val config = mapOf( - "unameValue" to getUnameValue(context), - "buildTimeValue" to getBuildTimeValue(context), - "executeInPostFsData" to getExecuteInPostFsData(context), - "susPaths" to getSusPaths(context), - "susMounts" to getSusMounts(context), - "tryUmounts" to getTryUmounts(context), - "androidDataPath" to getAndroidDataPath(context), - "sdcardPath" to getSdcardPath(context), - "enableLog" to getEnableLogState(context), - "kstatConfigs" to getKstatConfigs(context), - "addKstatPaths" to getAddKstatPaths(context), - "hideSusMountsForAllProcs" to getHideSusMountsForAllProcs(context) - ) + // 生成并创建所有脚本文件 + val scripts = ScriptGenerator.generateAllScripts(config) - // 生成脚本 - val scripts = mapOf( - "service.sh" to ScriptGenerator.generateServiceScript( - targetPath, config["unameValue"] as String, config["buildTimeValue"] as String, - config.getSetSafe("susPaths"), config["enableLog"] as Boolean, - config["executeInPostFsData"] as Boolean, config.getSetSafe("kstatConfigs"), - config.getSetSafe("addKstatPaths") - ), - "post-fs-data.sh" to ScriptGenerator.generatePostFsDataScript( - targetPath, config["unameValue"] as String, config["buildTimeValue"] as String, - config["executeInPostFsData"] as Boolean, config["androidDataPath"] as String, - config["sdcardPath"] as String - ), - "post-mount.sh" to ScriptGenerator.generatePostMountScript( - targetPath, config.getSetSafe("susMounts"), config.getSetSafe("tryUmounts") - ), - "boot-completed.sh" to ScriptGenerator.generateBootCompletedScript( - targetPath, config["hideSusMountsForAllProcs"] as Boolean - ) - ) - - // 创建脚本文件 scripts.all { (filename, content) -> runCmdWithResult("cat > $MODULE_PATH/$filename << 'EOF'\n$content\nEOF").isSuccess && runCmdWithResult("chmod 755 $MODULE_PATH/$filename").isSuccess @@ -386,7 +409,6 @@ object SuSFSManager { } } - // 功能状态获取 suspend fun getEnabledFeatures(context: Context): List = withContext(Dispatchers.IO) { try { @@ -430,7 +452,6 @@ object SuSFSManager { }.sortedBy { it.name } } - private fun parseEnabledFeaturesFromStatus(context: Context, status: Natives.SusfsFeatureStatus): List { val featureList = listOf( Triple("status_sus_path", context.getString(R.string.sus_path_feature_label), status.statusSusPath), @@ -461,7 +482,7 @@ object SuSFSManager { val success = executeSusfsCommand(context, "enable_log ${if (enabled) 1 else 0}") if (success) { saveEnableLogState(context, enabled) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, if (enabled) context.getString(R.string.susfs_log_enabled) else context.getString(R.string.susfs_log_disabled)) } return success @@ -476,7 +497,7 @@ object SuSFSManager { val success = executeSusfsCommand(context, "hide_sus_mnts_for_all_procs ${if (hideForAll) 1 else 0}") if (success) { saveHideSusMountsForAllProcs(context, hideForAll) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, if (hideForAll) context.getString(R.string.susfs_hide_mounts_all_enabled) else @@ -493,7 +514,7 @@ object SuSFSManager { if (success) { saveUnameValue(context, unameValue) saveBuildTimeValue(context, buildTimeValue) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, context.getString(R.string.susfs_uname_set_success, unameValue, buildTimeValue)) } return success @@ -502,12 +523,37 @@ object SuSFSManager { // 添加SUS路径 @SuppressLint("StringFormatInvalid") suspend fun addSusPath(context: Context, path: String): Boolean { + // 如果是1.5.8版本,先设置路径配置 + if (isSusVersion_1_5_8()) { + // 获取当前配置的路径,如果没有配置则使用默认值 + val androidDataPath = getAndroidDataPath(context) + val sdcardPath = getSdcardPath(context) + + // 先设置Android Data路径 + val androidDataSuccess = executeSusfsCommand(context, "set_android_data_root_path '$androidDataPath'") + if (androidDataSuccess) { + showToast(context, context.getString(R.string.susfs_android_data_path_set, androidDataPath)) + } + + // 再设置SD卡路径 + val sdcardSuccess = executeSusfsCommand(context, "set_sdcard_root_path '$sdcardPath'") + if (sdcardSuccess) { + showToast(context, context.getString(R.string.susfs_sdcard_path_set, sdcardPath)) + } + + // 如果路径设置失败,记录但不阻止继续执行 + if (!androidDataSuccess || !sdcardSuccess) { + showToast(context, context.getString(R.string.susfs_path_setup_warning)) + } + } + + // 执行添加SUS路径命令 val result = executeSusfsCommandWithOutput(context, "add_sus_path '$path'") val isActuallySuccessful = result.isSuccess && !result.output.contains("not found, skip adding") if (isActuallySuccessful) { saveSusPaths(context, getSusPaths(context) + path) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, context.getString(R.string.susfs_sus_path_added_success, path)) } else { val errorMessage = if (result.output.contains("not found, skip adding")) { @@ -522,7 +568,7 @@ object SuSFSManager { suspend fun removeSusPath(context: Context, path: String): Boolean { saveSusPaths(context, getSusPaths(context) - path) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, "SUS path removed: $path") return true } @@ -532,14 +578,14 @@ object SuSFSManager { val success = executeSusfsCommand(context, "add_sus_mount '$mount'") if (success) { saveSusMounts(context, getSusMounts(context) + mount) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) } return success } suspend fun removeSusMount(context: Context, mount: String): Boolean { saveSusMounts(context, getSusMounts(context) - mount) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, "Removed SUS mount: $mount") return true } @@ -548,7 +594,7 @@ object SuSFSManager { suspend fun addTryUmount(context: Context, path: String, mode: Int): Boolean { val commandSuccess = executeSusfsCommand(context, "add_try_umount '$path' $mode") saveTryUmounts(context, getTryUmounts(context) + "$path|$mode") - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, if (commandSuccess) { context.getString(R.string.susfs_try_umount_added_success, path) @@ -560,7 +606,7 @@ object SuSFSManager { suspend fun removeTryUmount(context: Context, umountEntry: String): Boolean { saveTryUmounts(context, getTryUmounts(context) - umountEntry) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) val path = umountEntry.split("|").firstOrNull() ?: umountEntry showToast(context, "Removed Try to uninstall: $path") return true @@ -577,7 +623,7 @@ object SuSFSManager { if (success) { val configEntry = "$path|$ino|$dev|$nlink|$size|$atime|$atimeNsec|$mtime|$mtimeNsec|$ctime|$ctimeNsec|$blocks|$blksize" saveKstatConfigs(context, getKstatConfigs(context) + configEntry) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, context.getString(R.string.kstat_static_config_added, path)) } return success @@ -585,7 +631,7 @@ object SuSFSManager { suspend fun removeKstatConfig(context: Context, config: String): Boolean { saveKstatConfigs(context, getKstatConfigs(context) - config) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) val path = config.split("|").firstOrNull() ?: config showToast(context, context.getString(R.string.kstat_config_removed, path)) return true @@ -596,7 +642,7 @@ object SuSFSManager { val success = executeSusfsCommand(context, "add_sus_kstat '$path'") if (success) { saveAddKstatPaths(context, getAddKstatPaths(context) + path) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, context.getString(R.string.kstat_path_added, path)) } return success @@ -604,7 +650,7 @@ object SuSFSManager { suspend fun removeAddKstat(context: Context, path: String): Boolean { saveAddKstatPaths(context, getAddKstatPaths(context) - path) - if (isAutoStartEnabled(context)) createMagiskModule(context) + if (isAutoStartEnabled(context)) updateMagiskModule(context) showToast(context, context.getString(R.string.kstat_path_removed, path)) return true } @@ -623,16 +669,14 @@ object SuSFSManager { return success } - // 设置Android数据路径和SD卡路径 + // 设置Android数据路径 suspend fun setAndroidDataPath(context: Context, path: String): Boolean { val success = executeSusfsCommand(context, "set_android_data_root_path '$path'") if (success) { saveAndroidDataPath(context, path) - // 如果开机自启动已启用,立即更新模块脚本 if (isAutoStartEnabled(context)) { kotlinx.coroutines.CoroutineScope(Dispatchers.Default).launch { - removeMagiskModule() - createMagiskModule(context) + updateMagiskModule(context) } } } @@ -644,29 +688,28 @@ object SuSFSManager { val success = executeSusfsCommand(context, "set_sdcard_root_path '$path'") if (success) { saveSdcardPath(context, path) - // 如果开机自启动已启用,立即更新模块脚本 if (isAutoStartEnabled(context)) { kotlinx.coroutines.CoroutineScope(Dispatchers.Default).launch { - removeMagiskModule() - createMagiskModule(context) + updateMagiskModule(context) } } } return success } + /** + * 自启动配置检查 + */ fun hasConfigurationForAutoStart(context: Context): Boolean { - val enabledFeatures = runBlocking { getEnabledFeatures(context) } - return getUnameValue(context) != DEFAULT_UNAME || - getBuildTimeValue(context) != DEFAULT_BUILD_TIME || - getSusPaths(context).isNotEmpty() || - getSusMounts(context).isNotEmpty() || - getTryUmounts(context).isNotEmpty() || - getKstatConfigs(context).isNotEmpty() || - getAddKstatPaths(context).isNotEmpty() || - enabledFeatures.any { it.isEnabled } + val config = getCurrentModuleConfig(context) + return config.hasAutoStartConfig() || runBlocking { + getEnabledFeatures(context).any { it.isEnabled } + } } + /** + * 自启动配置方法 + */ suspend fun configureAutoStart(context: Context, enabled: Boolean): Boolean = withContext(Dispatchers.IO) { try { if (enabled) { diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt index b87a52d7..bccf377b 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/util/SuSFSModuleScripts.kt @@ -9,14 +9,22 @@ import android.annotation.SuppressLint object ScriptGenerator { // 常量定义 - @SuppressLint("SdCardPath") - private const val DEFAULT_ANDROID_DATA_PATH = "/sdcard/Android/data" - @SuppressLint("SdCardPath") - private const val DEFAULT_SDCARD_PATH = "/sdcard" private const val DEFAULT_UNAME = "default" private const val DEFAULT_BUILD_TIME = "default" private const val LOG_DIR = "/data/adb/ksu/log" + /** + * 生成所有脚本文件 + */ + fun generateAllScripts(config: SuSFSManager.ModuleConfig): Map { + return mapOf( + "service.sh" to generateServiceScript(config), + "post-fs-data.sh" to generatePostFsDataScript(config), + "post-mount.sh" to generatePostMountScript(config), + "boot-completed.sh" to generateBootCompletedScript(config) + ) + } + // 日志相关的通用脚本片段 private fun generateLogSetup(logFileName: String): String = """ # 日志目录 @@ -45,17 +53,7 @@ object ScriptGenerator { /** * 生成service.sh脚本内容 */ - @SuppressLint("SdCardPath") - fun generateServiceScript( - targetPath: String, - unameValue: String, - buildTimeValue: String, - susPaths: Set, - enableLog: Boolean, - executeInPostFsData: Boolean = false, - kstatConfigs: Set = emptySet(), - addKstatPaths: Set = emptySet() - ): String { + private fun generateServiceScript(config: SuSFSManager.ModuleConfig): String { return buildString { appendLine("#!/system/bin/sh") appendLine("# SuSFS Service Script") @@ -63,21 +61,25 @@ object ScriptGenerator { appendLine() appendLine(generateLogSetup("susfs_service.log")) appendLine() - appendLine(generateBinaryCheck(targetPath)) + appendLine(generateBinaryCheck(config.targetPath)) appendLine() - // 设置日志启用状态 - generateLogSettingSection(enableLog) + if (shouldConfigureInService(config)) { + // 添加SUS路径 (仅在不支持隐藏挂载时) + if (!config.support158 && config.susPaths.isNotEmpty()) { + generateSusPathsSection(config.susPaths) + } - // 添加SUS路径 - generateSusPathsSection(susPaths) + // 添加Kstat配置 + generateKstatSection(config.kstatConfigs, config.addKstatPaths) - // 添加Kstat配置 - generateKstatSection(kstatConfigs, addKstatPaths) + // 设置uname和构建时间 + generateUnameSection(config) - // 设置uname和构建时间 - generateUnameSection(unameValue, buildTimeValue, executeInPostFsData) + } + // 添加日志设置 + generateLogSettingSection(config.enableLog) // 隐藏BL相关配置 generateHideBlSection() @@ -85,6 +87,16 @@ object ScriptGenerator { } } + /** + * 判断是否需要在service中配置 + */ + private fun shouldConfigureInService(config: SuSFSManager.ModuleConfig): Boolean { + return config.susPaths.isNotEmpty() || + config.kstatConfigs.isNotEmpty() || + config.addKstatPaths.isNotEmpty() || + (!config.executeInPostFsData && (config.unameValue != DEFAULT_UNAME || config.buildTimeValue != DEFAULT_BUILD_TIME)) + } + private fun StringBuilder.generateLogSettingSection(enableLog: Boolean) { appendLine("# 设置日志启用状态") val logValue = if (enableLog) 1 else 0 @@ -137,15 +149,11 @@ object ScriptGenerator { } } - private fun StringBuilder.generateUnameSection( - unameValue: String, - buildTimeValue: String, - executeInPostFsData: Boolean - ) { - if (!executeInPostFsData && (unameValue != DEFAULT_UNAME || buildTimeValue != DEFAULT_BUILD_TIME)) { + private fun StringBuilder.generateUnameSection(config: SuSFSManager.ModuleConfig) { + if (!config.executeInPostFsData && (config.unameValue != DEFAULT_UNAME || config.buildTimeValue != DEFAULT_BUILD_TIME)) { appendLine("# 设置uname和构建时间") - appendLine("\"${'$'}SUSFS_BIN\" set_uname '$unameValue' '$buildTimeValue'") - appendLine("echo \"$(get_current_time): 设置uname为: $unameValue, 构建时间为: $buildTimeValue\" >> \"${'$'}LOG_FILE\"") + appendLine("\"${'$'}SUSFS_BIN\" set_uname '${config.unameValue}' '${config.buildTimeValue}'") + appendLine("echo \"$(get_current_time): 设置uname为: ${config.unameValue}, 构建时间为: ${config.buildTimeValue}\" >> \"${'$'}LOG_FILE\"") appendLine() } } @@ -246,44 +254,24 @@ object ScriptGenerator { /** * 生成post-fs-data.sh脚本内容 */ - fun generatePostFsDataScript( - targetPath: String, - unameValue: String, - buildTimeValue: String, - executeInPostFsData: Boolean = false, - androidDataPath: String = DEFAULT_ANDROID_DATA_PATH, - sdcardPath: String = DEFAULT_SDCARD_PATH - ): String { + private fun generatePostFsDataScript(config: SuSFSManager.ModuleConfig): String { return buildString { appendLine("#!/system/bin/sh") appendLine("# SuSFS Post-FS-Data Script") appendLine("# 在文件系统挂载后但在系统完全启动前执行") - appendLine("# 优先级最高的配置项") appendLine() appendLine(generateLogSetup("susfs_post_fs_data.log")) appendLine() - appendLine(generateBinaryCheck(targetPath)) + appendLine(generateBinaryCheck(config.targetPath)) appendLine() appendLine("echo \"$(get_current_time): Post-FS-Data脚本开始执行\" >> \"${'$'}LOG_FILE\"") appendLine() - // 路径设置 - appendLine("# 设置路径配置(优先级最高)") - appendLine("# 设置Android Data路径") - appendLine("\"${'$'}SUSFS_BIN\" set_android_data_root_path '$androidDataPath'") - appendLine("echo \"$(get_current_time): Android Data路径设置为: $androidDataPath\" >> \"${'$'}LOG_FILE\"") - appendLine() - - appendLine("# 设置SD卡路径") - appendLine("\"${'$'}SUSFS_BIN\" set_sdcard_root_path '$sdcardPath'") - appendLine("echo \"$(get_current_time): SD卡路径设置为: $sdcardPath\" >> \"${'$'}LOG_FILE\"") - appendLine() - // 设置uname和构建时间 - 只有在选择在post-fs-data中执行时才执行 - if (executeInPostFsData && (unameValue != DEFAULT_UNAME || buildTimeValue != DEFAULT_BUILD_TIME)) { + if (config.executeInPostFsData && (config.unameValue != DEFAULT_UNAME || config.buildTimeValue != DEFAULT_BUILD_TIME)) { appendLine("# 设置uname和构建时间") - appendLine("\"${'$'}SUSFS_BIN\" set_uname '$unameValue' '$buildTimeValue'") - appendLine("echo \"$(get_current_time): 设置uname为: $unameValue, 构建时间为: $buildTimeValue\" >> \"${'$'}LOG_FILE\"") + appendLine("\"${'$'}SUSFS_BIN\" set_uname '${config.unameValue}' '${config.buildTimeValue}'") + appendLine("echo \"$(get_current_time): 设置uname为: ${config.unameValue}, 构建时间为: ${config.buildTimeValue}\" >> \"${'$'}LOG_FILE\"") appendLine() } @@ -294,11 +282,7 @@ object ScriptGenerator { /** * 生成post-mount.sh脚本内容 */ - fun generatePostMountScript( - targetPath: String, - susMounts: Set, - tryUmounts: Set - ): String { + private fun generatePostMountScript(config: SuSFSManager.ModuleConfig): String { return buildString { appendLine("#!/system/bin/sh") appendLine("# SuSFS Post-Mount Script") @@ -308,13 +292,13 @@ object ScriptGenerator { appendLine() appendLine("echo \"$(get_current_time): Post-Mount脚本开始执行\" >> \"${'$'}LOG_FILE\"") appendLine() - appendLine(generateBinaryCheck(targetPath)) + appendLine(generateBinaryCheck(config.targetPath)) appendLine() // 添加SUS挂载 - if (susMounts.isNotEmpty()) { + if (config.susMounts.isNotEmpty()) { appendLine("# 添加SUS挂载") - susMounts.forEach { mount -> + config.susMounts.forEach { mount -> appendLine("\"${'$'}SUSFS_BIN\" add_sus_mount '$mount'") appendLine("echo \"$(get_current_time): 添加SUS挂载: $mount\" >> \"${'$'}LOG_FILE\"") } @@ -322,9 +306,9 @@ object ScriptGenerator { } // 添加尝试卸载 - if (tryUmounts.isNotEmpty()) { + if (config.tryUmounts.isNotEmpty()) { appendLine("# 添加尝试卸载") - tryUmounts.forEach { umount -> + config.tryUmounts.forEach { umount -> val parts = umount.split("|") if (parts.size == 2) { val path = parts[0] @@ -343,10 +327,7 @@ object ScriptGenerator { /** * 生成boot-completed.sh脚本内容 */ - fun generateBootCompletedScript( - targetPath: String, - hideSusMountsForAllProcs: Boolean = true - ): String { + private fun generateBootCompletedScript(config: SuSFSManager.ModuleConfig): String { return buildString { appendLine("#!/system/bin/sh") appendLine("# SuSFS Boot-Completed Script") @@ -356,36 +337,49 @@ object ScriptGenerator { appendLine() appendLine("echo \"$(get_current_time): Boot-Completed脚本开始执行\" >> \"${'$'}LOG_FILE\"") appendLine() - appendLine(generateBinaryCheck(targetPath)) + appendLine(generateBinaryCheck(config.targetPath)) appendLine() - // SUS挂载隐藏控制仅限1.5.8及以上版本 - appendLine("# 设置SUS挂载隐藏控制(仅限1.5.8及以上版本)") - appendLine("SUSFS_VERSION=$(${'$'}SUSFS_BIN show version 2>/dev/null | grep -o 'v[0-9]\\+\\.[0-9]\\+\\.[0-9]\\+' | head -1)") - appendLine("if [ -n \"${'$'}SUSFS_VERSION\" ]; then") - appendLine(" VERSION_NUM=$(echo \"${'$'}SUSFS_VERSION\" | sed 's/v//' | awk -F. '{printf \"%d%02d%02d\", $1, $2, $3}')") - appendLine(" if [ \"${'$'}VERSION_NUM\" -ge 10508 ]; then") - val hideValue = if (hideSusMountsForAllProcs) 1 else 0 - appendLine(" \"${'$'}SUSFS_BIN\" hide_sus_mnts_for_all_procs $hideValue") - appendLine(" echo \"$(get_current_time): SUS挂载隐藏控制设置为: ${if (hideSusMountsForAllProcs) "对所有进程隐藏" else "仅对非KSU进程隐藏"}\" >> \"${'$'}LOG_FILE\"") - appendLine(" else") - appendLine(" echo \"$(get_current_time): 当前版本 ${'$'}SUSFS_VERSION 不支持SUS挂载隐藏控制功能,需要1.5.8及以上版本\" >> \"${'$'}LOG_FILE\"") - appendLine(" fi") - appendLine("else") - appendLine(" echo \"$(get_current_time): 无法获取SuSFS版本信息,跳过SUS挂载隐藏控制设置\" >> \"${'$'}LOG_FILE\"") - appendLine("fi") - appendLine() + // 仅在支持隐藏挂载功能时执行相关配置 + if (config.support158) { + // SUS挂载隐藏控制 + val hideValue = if (config.hideSusMountsForAllProcs) 1 else 0 + appendLine("# 设置SUS挂载隐藏控制") + appendLine("\"${'$'}SUSFS_BIN\" hide_sus_mnts_for_all_procs $hideValue") + appendLine("echo \"$(get_current_time): SUS挂载隐藏控制设置为: ${if (config.hideSusMountsForAllProcs) "对所有进程隐藏" else "仅对非KSU进程隐藏"}\" >> \"${'$'}LOG_FILE\"") + appendLine() + + // 路径设置和SUS路径设置 + if (config.susPaths.isNotEmpty()) { + generatePathSettingSection(config.androidDataPath, config.sdcardPath) + generateSusPathsSection(config.susPaths) + } + } appendLine("echo \"$(get_current_time): Boot-Completed脚本执行完成\" >> \"${'$'}LOG_FILE\"") } } + @SuppressLint("SdCardPath") + private fun StringBuilder.generatePathSettingSection(androidDataPath: String, sdcardPath: String) { + appendLine("# 路径配置") + appendLine("# 设置Android Data路径") + appendLine("until [ -d \"/sdcard/Android\" ]; do sleep 1; done") + appendLine("\"${'$'}SUSFS_BIN\" set_android_data_root_path '$androidDataPath'") + appendLine("echo \"$(get_current_time): Android Data路径设置为: $androidDataPath\" >> \"${'$'}LOG_FILE\"") + appendLine() + appendLine("# 设置SD卡路径") + appendLine("\"${'$'}SUSFS_BIN\" set_sdcard_root_path '$sdcardPath'") + appendLine("echo \"$(get_current_time): SD卡路径设置为: $sdcardPath\" >> \"${'$'}LOG_FILE\"") + appendLine() + } + /** * 生成module.prop文件内容 */ fun generateModuleProp(moduleId: String): String { - val moduleVersion = "v1.0.0" - val moduleVersionCode = "1000" + val moduleVersion = "v1.0.1" + val moduleVersionCode = "1001" return """ id=$moduleId diff --git a/manager/app/src/main/res/values-ja/strings.xml b/manager/app/src/main/res/values-ja/strings.xml index 5fcb65a2..c8323ded 100644 --- a/manager/app/src/main/res/values-ja/strings.xml +++ b/manager/app/src/main/res/values-ja/strings.xml @@ -392,7 +392,6 @@ パスの設定 有効な機能のステータス - 追加 SUS パスを追加 SUS マウントを追加 diff --git a/manager/app/src/main/res/values-ru/strings.xml b/manager/app/src/main/res/values-ru/strings.xml index ae7cd276..1fc1b0cf 100644 --- a/manager/app/src/main/res/values-ru/strings.xml +++ b/manager/app/src/main/res/values-ru/strings.xml @@ -393,7 +393,6 @@ Настройки пути Статус включённых функций - Добавить Добавить SUS путь Добавить SUS монтирование diff --git a/manager/app/src/main/res/values-tr/strings.xml b/manager/app/src/main/res/values-tr/strings.xml index 3bb4103a..84ab78bf 100644 --- a/manager/app/src/main/res/values-tr/strings.xml +++ b/manager/app/src/main/res/values-tr/strings.xml @@ -391,7 +391,6 @@ Yol Ayarları Etkinleştirilen Özellikler Durumu - Ekle SUS Yolu Ekle SUS Bağlama Noktası Ekle diff --git a/manager/app/src/main/res/values-vi/strings.xml b/manager/app/src/main/res/values-vi/strings.xml index aef25efb..fbd82249 100644 --- a/manager/app/src/main/res/values-vi/strings.xml +++ b/manager/app/src/main/res/values-vi/strings.xml @@ -391,7 +391,6 @@ Cài đặt Đường dẫn Trạng thái tính năng - Thêm Thêm Đường dẫn SuS Thêm SuS Mount diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index 8b942eef..7f1610e8 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -391,7 +391,6 @@ 路径设置 启用功能状态 - 添加 添加SUS路径 添加SUS挂载 @@ -519,4 +518,7 @@ 运行 内核版本简洁模式 启用或禁用SukiSU内核版本显示的简洁模式 + Android Data路径已设置为: %s + SD卡路径已设置为: %s + 路径设置可能未完全成功,但将继续添加SUS路径 diff --git a/manager/app/src/main/res/values-zh-rHK/strings.xml b/manager/app/src/main/res/values-zh-rHK/strings.xml index b8a55430..8b38a6a3 100644 --- a/manager/app/src/main/res/values-zh-rHK/strings.xml +++ b/manager/app/src/main/res/values-zh-rHK/strings.xml @@ -390,7 +390,6 @@ 路徑設定 啟用功能狀態 - 添加 添加SUS路徑 添加SUS掛載 diff --git a/manager/app/src/main/res/values-zh-rTW/strings.xml b/manager/app/src/main/res/values-zh-rTW/strings.xml index 5d49f917..2d450006 100644 --- a/manager/app/src/main/res/values-zh-rTW/strings.xml +++ b/manager/app/src/main/res/values-zh-rTW/strings.xml @@ -391,7 +391,6 @@ 路徑設定 啟用功能狀態 - 新增 新增 SUS 路徑 新增 SUS 掛載 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index 884957bb..d417a824 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -392,8 +392,6 @@ Try Umount Path Settings Enabled Features Status - - Add Add SUS Path Add SUS Mount @@ -521,4 +519,7 @@ Run Kernel Version Concise Mode Enable or disable the clean mode displayed by the SukiSU kernel version + Android Data path has been set to: %s + SD card path has been set to: %s + Path setup may not be fully successful, but SUS paths will continue to be added