Step 7-2: Removed redundant pop-ups from the susfs interface and fixed path issues (on Android 16).
This commit is contained in:
@@ -261,10 +261,11 @@ fun SuSFSConfigScreen(
|
||||
editingPath = null
|
||||
},
|
||||
onConfirm = { path ->
|
||||
val oldPath = editingPath
|
||||
coroutineScope.launch {
|
||||
isLoading = true
|
||||
val success = if (editingPath != null) {
|
||||
SuSFSManager.editSusPath(context, editingPath!!, path)
|
||||
val success = if (oldPath != null) {
|
||||
SuSFSManager.editSusPath(context, oldPath, path)
|
||||
} else {
|
||||
SuSFSManager.addSusPath(context, path)
|
||||
}
|
||||
@@ -289,10 +290,11 @@ fun SuSFSConfigScreen(
|
||||
editingLoopPath = null
|
||||
},
|
||||
onConfirm = { path ->
|
||||
val oldPath = editingLoopPath
|
||||
coroutineScope.launch {
|
||||
isLoading = true
|
||||
val success = if (editingLoopPath != null) {
|
||||
SuSFSManager.editSusLoopPath(context, editingLoopPath!!, path)
|
||||
val success = if (oldPath != null) {
|
||||
SuSFSManager.editSusLoopPath(context, oldPath, path)
|
||||
} else {
|
||||
SuSFSManager.addSusLoopPath(context, path)
|
||||
}
|
||||
@@ -317,10 +319,11 @@ fun SuSFSConfigScreen(
|
||||
editingSusMap = null
|
||||
},
|
||||
onConfirm = { path ->
|
||||
val oldPath = editingSusMap
|
||||
coroutineScope.launch {
|
||||
isLoading = true
|
||||
val success = if (editingSusMap != null) {
|
||||
SuSFSManager.editSusMap(context, editingSusMap!!, path)
|
||||
val success = if (oldPath != null) {
|
||||
SuSFSManager.editSusMap(context, oldPath, path)
|
||||
} else {
|
||||
SuSFSManager.addSusMap(context, path)
|
||||
}
|
||||
@@ -370,10 +373,11 @@ fun SuSFSConfigScreen(
|
||||
editingUmount = null
|
||||
},
|
||||
onConfirm = { path, mode ->
|
||||
val oldUmount = editingUmount
|
||||
coroutineScope.launch {
|
||||
isLoading = true
|
||||
val success = if (editingUmount != null) {
|
||||
SuSFSManager.editTryUmount(context, editingUmount!!, path, mode)
|
||||
val success = if (oldUmount != null) {
|
||||
SuSFSManager.editTryUmount(context, oldUmount, path, mode)
|
||||
} else {
|
||||
SuSFSManager.addTryUmount(context, path, mode)
|
||||
}
|
||||
@@ -397,12 +401,13 @@ fun SuSFSConfigScreen(
|
||||
editingKstatConfig = null
|
||||
},
|
||||
onConfirm = { path, ino, dev, nlink, size, atime, atimeNsec, mtime, mtimeNsec, ctime, ctimeNsec, blocks, blksize ->
|
||||
val oldConfig = editingKstatConfig
|
||||
coroutineScope.launch {
|
||||
isLoading = true
|
||||
val success = if (editingKstatConfig != null) {
|
||||
val success = if (oldConfig != null) {
|
||||
SuSFSManager.editKstatConfig(
|
||||
context,
|
||||
editingKstatConfig!!,
|
||||
oldConfig,
|
||||
path,
|
||||
ino,
|
||||
dev,
|
||||
@@ -442,10 +447,11 @@ fun SuSFSConfigScreen(
|
||||
editingKstatPath = null
|
||||
},
|
||||
onConfirm = { path ->
|
||||
val oldPath = editingKstatPath
|
||||
coroutineScope.launch {
|
||||
isLoading = true
|
||||
val success = if (editingKstatPath != null) {
|
||||
SuSFSManager.editAddKstat(context, editingKstatPath!!, path)
|
||||
val success = if (oldPath != null) {
|
||||
SuSFSManager.editAddKstat(context, oldPath, path)
|
||||
} else {
|
||||
SuSFSManager.addKstat(context, path)
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ fun SusPathsContent(
|
||||
|
||||
val (appPathGroups, otherPaths) = remember(susPaths, superUserApps) {
|
||||
val appPathRegex = Regex(".*/Android/data/([^/]+)/?.*")
|
||||
val uidPathRegex = Regex("/sys/fs/cgroup/uid_([0-9]+)")
|
||||
val uidPathRegex = Regex("/sys/fs/cgroup(?:/[^/]+)*/uid_([0-9]+)")
|
||||
val appPathMap = mutableMapOf<String, MutableList<String>>()
|
||||
val uidToPackageMap = mutableMapOf<String, String>()
|
||||
val others = mutableListOf<String>()
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.util.Log
|
||||
import android.widget.Toast
|
||||
import com.sukisu.ultra.R
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import com.topjohnwu.superuser.io.SuFile
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@@ -58,7 +59,7 @@ object SuSFSManager {
|
||||
const val MAX_SUSFS_VERSION = "2.0.0"
|
||||
private const val BACKUP_FILE_EXTENSION = ".susfs_backup"
|
||||
private const val MEDIA_DATA_PATH = "/data/media/0/Android/data"
|
||||
private const val CGROUP_UID_PATH_PREFIX = "/sys/fs/cgroup/uid_"
|
||||
private const val CGROUP_BASE_PATH = "/sys/fs/cgroup"
|
||||
private const val SUSFS_BINARY_TARGET_NAME = "ksu_susfs"
|
||||
|
||||
data class SlotInfo(val slotName: String, val uname: String, val buildTime: String)
|
||||
@@ -241,13 +242,17 @@ object SuSFSManager {
|
||||
)
|
||||
val shell = Shell.getShell()
|
||||
val result = shell.newJob().add("$binaryPath $command").exec()
|
||||
SuSFSModuleManager.CommandResult(
|
||||
val commandResult = SuSFSModuleManager.CommandResult(
|
||||
isSuccess = result.isSuccess,
|
||||
output = result.out.joinToString("\n"),
|
||||
errorOutput = result.err.joinToString("\n")
|
||||
)
|
||||
if (!commandResult.isSuccess) {
|
||||
Log.e("SuSFSManager", "Command failed: $command, error: ${commandResult.errorOutput}")
|
||||
}
|
||||
commandResult
|
||||
} catch (e: Exception) {
|
||||
Log.e("SuSFSManager", "Command execution failed", e)
|
||||
Log.e("SuSFSManager", "Exception executing command: $command", e)
|
||||
SuSFSModuleManager.CommandResult(false, "", e.message ?: "Unknown error")
|
||||
}
|
||||
}
|
||||
@@ -436,8 +441,7 @@ object SuSFSManager {
|
||||
.exec()
|
||||
|
||||
result.isSuccess && outputList.isNotEmpty() && outputList[0].trim() == "exists"
|
||||
} catch (e: Exception) {
|
||||
Log.w("SuSFSManager", "Failed to check directory for ${appInfo.packageName}: ${e.message}")
|
||||
} catch (_: Exception) {
|
||||
false
|
||||
}
|
||||
if (exists) appInfo else null
|
||||
@@ -445,8 +449,7 @@ object SuSFSManager {
|
||||
}.awaitAll().filterNotNull()
|
||||
|
||||
filteredApps.sortedBy { it.appName }
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} catch (_: Exception) {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
@@ -463,16 +466,52 @@ object SuSFSManager {
|
||||
val packageManager = context.packageManager
|
||||
val packageInfo = packageManager.getPackageInfo(packageName, 0)
|
||||
packageInfo.applicationInfo?.uid
|
||||
} catch (e: Exception) {
|
||||
Log.w("SuSFSManager", "Failed to get UID for package $packageName: ${e.message}")
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildUidPath(uid: Int): String = "$CGROUP_UID_PATH_PREFIX$uid"
|
||||
|
||||
private fun checkPathExists(path: String): Boolean {
|
||||
return try {
|
||||
val shell = try {
|
||||
getRootShell()
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
val file = if (shell != null) {
|
||||
SuFile(path).apply { setShell(shell) }
|
||||
} else {
|
||||
File(path)
|
||||
}
|
||||
|
||||
file.exists() && file.isDirectory
|
||||
} catch (_: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildUidPath(uid: Int): String {
|
||||
val possiblePaths = listOf(
|
||||
"$CGROUP_BASE_PATH/uid_$uid",
|
||||
"$CGROUP_BASE_PATH/apps/uid_$uid",
|
||||
"$CGROUP_BASE_PATH/system/uid_$uid",
|
||||
"$CGROUP_BASE_PATH/freezer/uid_$uid",
|
||||
"$CGROUP_BASE_PATH/memory/uid_$uid",
|
||||
"$CGROUP_BASE_PATH/cpuset/uid_$uid",
|
||||
"$CGROUP_BASE_PATH/cpu/uid_$uid"
|
||||
)
|
||||
|
||||
for (path in possiblePaths) {
|
||||
if (checkPathExists(path)) {
|
||||
return path
|
||||
}
|
||||
}
|
||||
return possiblePaths[0]
|
||||
}
|
||||
|
||||
// 快捷添加应用路径
|
||||
@SuppressLint("StringFormatMatches")
|
||||
suspend fun addAppPaths(context: Context, packageName: String): Boolean {
|
||||
val androidDataPath = getAndroidDataPath(context)
|
||||
getSdcardPath(context)
|
||||
@@ -480,37 +519,28 @@ object SuSFSManager {
|
||||
val path1 = "$androidDataPath/$packageName"
|
||||
val path2 = "$MEDIA_DATA_PATH/$packageName"
|
||||
|
||||
val uid = getAppUid(context, packageName)
|
||||
if (uid == null) {
|
||||
Log.w("SuSFSManager", "Failed to get UID for package: $packageName")
|
||||
return false
|
||||
}
|
||||
val uid = getAppUid(context, packageName) ?: return false
|
||||
|
||||
val path3 = buildUidPath(uid)
|
||||
|
||||
var successCount = 0
|
||||
val totalCount = 3
|
||||
|
||||
// 添加第一个路径(Android/data路径)
|
||||
if (addSusPath(context, path1)) {
|
||||
if (addSusPathInternal(context, path1, showToast = false)) {
|
||||
successCount++
|
||||
}
|
||||
|
||||
// 添加第二个路径(媒体数据路径)
|
||||
if (addSusPath(context, path2)) {
|
||||
if (addSusPathInternal(context, path2, showToast = false)) {
|
||||
successCount++
|
||||
}
|
||||
|
||||
// 添加第三个路径(UID路径)
|
||||
if (addSusPath(context, path3)) {
|
||||
if (addSusPathInternal(context, path3, showToast = false)) {
|
||||
successCount++
|
||||
}
|
||||
|
||||
val success = successCount > 0
|
||||
|
||||
Log.d("SuSFSManager", "Added $successCount/$totalCount paths for $packageName (UID: $uid)")
|
||||
|
||||
return success
|
||||
return successCount > 0
|
||||
}
|
||||
|
||||
// 获取所有配置的Map
|
||||
@@ -808,7 +838,6 @@ object SuSFSManager {
|
||||
if (success) {
|
||||
saveEnableLogState(context, enabled)
|
||||
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
|
||||
}
|
||||
@@ -819,11 +848,6 @@ object SuSFSManager {
|
||||
if (success) {
|
||||
saveEnableAvcLogSpoofing(context, enabled)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, if (enabled)
|
||||
context.getString(R.string.avc_log_spoofing_enabled)
|
||||
else
|
||||
context.getString(R.string.avc_log_spoofing_disabled)
|
||||
)
|
||||
}
|
||||
return success
|
||||
}
|
||||
@@ -834,11 +858,6 @@ object SuSFSManager {
|
||||
if (success) {
|
||||
saveHideSusMountsForAllProcs(context, hideForAll)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, if (hideForAll)
|
||||
context.getString(R.string.susfs_hide_mounts_all_enabled)
|
||||
else
|
||||
context.getString(R.string.susfs_hide_mounts_all_disabled)
|
||||
)
|
||||
}
|
||||
return success
|
||||
}
|
||||
@@ -851,34 +870,22 @@ object SuSFSManager {
|
||||
saveUnameValue(context, unameValue)
|
||||
saveBuildTimeValue(context, buildTimeValue)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, context.getString(R.string.susfs_uname_set_success, unameValue, buildTimeValue))
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
// 添加SUS路径
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
suspend fun addSusPath(context: Context, path: String): Boolean {
|
||||
private suspend fun addSusPathInternal(context: Context, path: String, showToast: Boolean = true): Boolean {
|
||||
// 先设置路径配置
|
||||
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))
|
||||
}
|
||||
executeSusfsCommand(context, "set_android_data_root_path '$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))
|
||||
}
|
||||
executeSusfsCommand(context, "set_sdcard_root_path '$sdcardPath'")
|
||||
|
||||
// 执行添加SUS路径命令
|
||||
val result = executeSusfsCommandWithOutput(context, "add_sus_path '$path'")
|
||||
@@ -887,22 +894,21 @@ object SuSFSManager {
|
||||
if (isActuallySuccessful) {
|
||||
saveSusPaths(context, getSusPaths(context) + path)
|
||||
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")) {
|
||||
context.getString(R.string.susfs_path_not_found_error, path)
|
||||
} else {
|
||||
"${context.getString(R.string.susfs_command_failed)}\n${result.output}\n${result.errorOutput}"
|
||||
}
|
||||
showToast(context, errorMessage)
|
||||
} else if (showToast) {
|
||||
val errorMsg = result.errorOutput.ifEmpty { context.getString(R.string.susfs_command_failed) }
|
||||
showToast(context, errorMsg)
|
||||
}
|
||||
return isActuallySuccessful
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
suspend fun addSusPath(context: Context, path: String): Boolean {
|
||||
return addSusPathInternal(context, path, showToast = true)
|
||||
}
|
||||
|
||||
suspend fun removeSusPath(context: Context, path: String): Boolean {
|
||||
saveSusPaths(context, getSusPaths(context) - path)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, "SUS path removed: $path")
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -911,28 +917,25 @@ object SuSFSManager {
|
||||
return try {
|
||||
val currentPaths = getSusPaths(context).toMutableSet()
|
||||
if (!currentPaths.remove(oldPath)) {
|
||||
showToast(context, "Original path not found: $oldPath")
|
||||
showToast(context, context.getString(R.string.susfs_command_failed))
|
||||
return false
|
||||
}
|
||||
|
||||
saveSusPaths(context, currentPaths)
|
||||
|
||||
val success = addSusPath(context, newPath)
|
||||
val success = addSusPathInternal(context, newPath, showToast = false)
|
||||
|
||||
if (success) {
|
||||
showToast(context, "SUS path updated: $oldPath -> $newPath")
|
||||
return true
|
||||
} else {
|
||||
if (!success) {
|
||||
// 如果添加新路径失败,恢复旧路径
|
||||
currentPaths.add(oldPath)
|
||||
saveSusPaths(context, currentPaths)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, "Failed to update path, reverted to original")
|
||||
return false
|
||||
showToast(context, context.getString(R.string.susfs_command_failed))
|
||||
}
|
||||
return success
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
showToast(context, "Error updating SUS path: ${e.message}")
|
||||
Log.e("SuSFSManager", "Exception editing SUS path", e)
|
||||
showToast(context, context.getString(R.string.susfs_command_failed))
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -944,10 +947,12 @@ object SuSFSManager {
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
suspend fun addSusLoopPath(context: Context, path: String): Boolean {
|
||||
private suspend fun addSusLoopPathInternal(context: Context, path: String, showToast: Boolean = true): Boolean {
|
||||
// 检查路径是否有效
|
||||
if (!isValidLoopPath(path)) {
|
||||
showToast(context, context.getString(R.string.susfs_loop_path_invalid_location))
|
||||
if (showToast) {
|
||||
showToast(context, context.getString(R.string.susfs_invalid_loop_path))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -958,22 +963,21 @@ object SuSFSManager {
|
||||
if (isActuallySuccessful) {
|
||||
saveSusLoopPaths(context, getSusLoopPaths(context) + path)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, context.getString(R.string.susfs_loop_path_added_success, path))
|
||||
} else {
|
||||
val errorMessage = if (result.output.contains("not found, skip adding")) {
|
||||
context.getString(R.string.susfs_path_not_found_error, path)
|
||||
} else {
|
||||
"${context.getString(R.string.susfs_command_failed)}\n${result.output}\n${result.errorOutput}"
|
||||
}
|
||||
showToast(context, errorMessage)
|
||||
} else if (showToast) {
|
||||
val errorMsg = result.errorOutput.ifEmpty { context.getString(R.string.susfs_add_loop_path_failed) }
|
||||
showToast(context, errorMsg)
|
||||
}
|
||||
return isActuallySuccessful
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
suspend fun addSusLoopPath(context: Context, path: String): Boolean {
|
||||
return addSusLoopPathInternal(context, path, showToast = true)
|
||||
}
|
||||
|
||||
suspend fun removeSusLoopPath(context: Context, path: String): Boolean {
|
||||
saveSusLoopPaths(context, getSusLoopPaths(context) - path)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, context.getString(R.string.susfs_loop_path_removed, path))
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -981,54 +985,57 @@ object SuSFSManager {
|
||||
suspend fun editSusLoopPath(context: Context, oldPath: String, newPath: String): Boolean {
|
||||
// 检查新路径是否有效
|
||||
if (!isValidLoopPath(newPath)) {
|
||||
showToast(context, context.getString(R.string.susfs_loop_path_invalid_location))
|
||||
showToast(context, context.getString(R.string.susfs_invalid_loop_path))
|
||||
return false
|
||||
}
|
||||
|
||||
return try {
|
||||
val currentPaths = getSusLoopPaths(context).toMutableSet()
|
||||
if (!currentPaths.remove(oldPath)) {
|
||||
showToast(context, "Original loop path not found: $oldPath")
|
||||
showToast(context, context.getString(R.string.susfs_edit_loop_path_failed))
|
||||
return false
|
||||
}
|
||||
|
||||
saveSusLoopPaths(context, currentPaths)
|
||||
|
||||
val success = addSusLoopPath(context, newPath)
|
||||
val success = addSusLoopPathInternal(context, newPath, showToast = false)
|
||||
|
||||
if (success) {
|
||||
showToast(context, context.getString(R.string.susfs_loop_path_updated, oldPath, newPath))
|
||||
return true
|
||||
} else {
|
||||
if (!success) {
|
||||
// 如果添加新路径失败,恢复旧路径
|
||||
currentPaths.add(oldPath)
|
||||
saveSusLoopPaths(context, currentPaths)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, "Failed to update loop path, reverted to original")
|
||||
return false
|
||||
showToast(context, context.getString(R.string.susfs_edit_loop_path_failed))
|
||||
}
|
||||
return success
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
showToast(context, "Error updating SUS loop path: ${e.message}")
|
||||
Log.e("SuSFSManager", "Exception editing SUS loop path", e)
|
||||
showToast(context, context.getString(R.string.susfs_edit_loop_path_failed))
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// 添加 SUS Maps
|
||||
suspend fun addSusMap(context: Context, map: String): Boolean {
|
||||
val success = executeSusfsCommand(context, "add_sus_map '$map'")
|
||||
private suspend fun addSusMapInternal(context: Context, map: String, showToast: Boolean = true): Boolean {
|
||||
val result = executeSusfsCommandWithOutput(context, "add_sus_map '$map'")
|
||||
val success = result.isSuccess
|
||||
if (success) {
|
||||
saveSusMaps(context, getSusMaps(context) + map)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, context.getString(R.string.susfs_sus_map_added_success, map))
|
||||
} else if (showToast) {
|
||||
val errorMsg = result.errorOutput.ifEmpty { context.getString(R.string.susfs_add_map_failed) }
|
||||
showToast(context, errorMsg)
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
suspend fun addSusMap(context: Context, map: String): Boolean {
|
||||
return addSusMapInternal(context, map, showToast = true)
|
||||
}
|
||||
|
||||
suspend fun removeSusMap(context: Context, map: String): Boolean {
|
||||
saveSusMaps(context, getSusMaps(context) - map)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, context.getString(R.string.susfs_sus_map_removed, map))
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1036,51 +1043,44 @@ object SuSFSManager {
|
||||
return try {
|
||||
val currentMaps = getSusMaps(context).toMutableSet()
|
||||
if (!currentMaps.remove(oldMap)) {
|
||||
showToast(context, "Original SUS map not found: $oldMap")
|
||||
showToast(context, context.getString(R.string.susfs_edit_map_failed))
|
||||
return false
|
||||
}
|
||||
|
||||
saveSusMaps(context, currentMaps)
|
||||
|
||||
val success = addSusMap(context, newMap)
|
||||
val success = addSusMapInternal(context, newMap, showToast = false)
|
||||
|
||||
if (success) {
|
||||
showToast(context, context.getString(R.string.susfs_sus_map_updated, oldMap, newMap))
|
||||
return true
|
||||
} else {
|
||||
if (!success) {
|
||||
// 如果添加新映射失败,恢复旧映射
|
||||
currentMaps.add(oldMap)
|
||||
saveSusMaps(context, currentMaps)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, "Failed to update SUS map, reverted to original")
|
||||
return false
|
||||
showToast(context, context.getString(R.string.susfs_edit_map_failed))
|
||||
}
|
||||
return success
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
showToast(context, "Error updating SUS map: ${e.message}")
|
||||
Log.e("SuSFSManager", "Exception editing SUS map", e)
|
||||
showToast(context, context.getString(R.string.susfs_edit_map_failed))
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// 添加尝试卸载
|
||||
suspend fun addTryUmount(context: Context, path: String, mode: Int): Boolean {
|
||||
val commandSuccess = executeSusfsCommand(context, "add_try_umount '$path' $mode")
|
||||
private suspend fun addTryUmountInternal(context: Context, path: String, mode: Int): Boolean {
|
||||
executeSusfsCommand(context, "add_try_umount '$path' $mode")
|
||||
saveTryUmounts(context, getTryUmounts(context) + "$path|$mode")
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
|
||||
showToast(context, if (commandSuccess) {
|
||||
context.getString(R.string.susfs_try_umount_added_success, path)
|
||||
} else {
|
||||
context.getString(R.string.susfs_try_umount_added_saved, path)
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
suspend fun addTryUmount(context: Context, path: String, mode: Int): Boolean {
|
||||
return addTryUmountInternal(context, path, mode)
|
||||
}
|
||||
|
||||
suspend fun removeTryUmount(context: Context, umountEntry: String): Boolean {
|
||||
saveTryUmounts(context, getTryUmounts(context) - umountEntry)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
val path = umountEntry.split("|").firstOrNull() ?: umountEntry
|
||||
showToast(context, "Removed Try to uninstall: $path")
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1089,28 +1089,21 @@ object SuSFSManager {
|
||||
return try {
|
||||
val currentUmounts = getTryUmounts(context).toMutableSet()
|
||||
if (!currentUmounts.remove(oldEntry)) {
|
||||
showToast(context, "Original umount entry not found: $oldEntry")
|
||||
return false
|
||||
}
|
||||
|
||||
saveTryUmounts(context, currentUmounts)
|
||||
|
||||
val success = addTryUmount(context, newPath, newMode)
|
||||
val success = addTryUmountInternal(context, newPath, newMode)
|
||||
|
||||
if (success) {
|
||||
showToast(context, "Try umount updated: $oldEntry -> $newPath|$newMode")
|
||||
return true
|
||||
} else {
|
||||
if (!success) {
|
||||
// 如果添加新条目失败,恢复旧条目
|
||||
currentUmounts.add(oldEntry)
|
||||
saveTryUmounts(context, currentUmounts)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, "Failed to update umount entry, reverted to original")
|
||||
return false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
showToast(context, "Error updating try umount: ${e.message}")
|
||||
return success
|
||||
} catch (_: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -1123,37 +1116,34 @@ object SuSFSManager {
|
||||
if (success) {
|
||||
saveUmountForZygoteIsoService(context, enabled)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, if (enabled)
|
||||
context.getString(R.string.umount_zygote_iso_service_enabled)
|
||||
else
|
||||
context.getString(R.string.umount_zygote_iso_service_disabled)
|
||||
)
|
||||
} else {
|
||||
showToast(context, context.getString(R.string.susfs_command_failed))
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
// 添加kstat配置
|
||||
suspend fun addKstatStatically(context: Context, path: String, ino: String, dev: String, nlink: String,
|
||||
private suspend fun addKstatStaticallyInternal(context: Context, path: String, ino: String, dev: String, nlink: String,
|
||||
size: String, atime: String, atimeNsec: String, mtime: String, mtimeNsec: String,
|
||||
ctime: String, ctimeNsec: String, blocks: String, blksize: String): Boolean {
|
||||
ctime: String, ctimeNsec: String, blocks: String, blksize: String
|
||||
): Boolean {
|
||||
val command = "add_sus_kstat_statically '$path' '$ino' '$dev' '$nlink' '$size' '$atime' '$atimeNsec' '$mtime' '$mtimeNsec' '$ctime' '$ctimeNsec' '$blocks' '$blksize'"
|
||||
val success = executeSusfsCommand(context, command)
|
||||
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)) updateMagiskModule(context)
|
||||
showToast(context, context.getString(R.string.kstat_static_config_added, path))
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
suspend fun addKstatStatically(context: Context, path: String, ino: String, dev: String, nlink: String,
|
||||
size: String, atime: String, atimeNsec: String, mtime: String, mtimeNsec: String,
|
||||
ctime: String, ctimeNsec: String, blocks: String, blksize: String): Boolean {
|
||||
return addKstatStaticallyInternal(context, path, ino, dev, nlink, size, atime, atimeNsec, mtime, mtimeNsec, ctime, ctimeNsec, blocks, blksize)
|
||||
}
|
||||
|
||||
suspend fun removeKstatConfig(context: Context, config: String): Boolean {
|
||||
saveKstatConfigs(context, getKstatConfigs(context) - config)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
val path = config.split("|").firstOrNull() ?: config
|
||||
showToast(context, context.getString(R.string.kstat_config_removed, path))
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1165,48 +1155,45 @@ object SuSFSManager {
|
||||
return try {
|
||||
val currentConfigs = getKstatConfigs(context).toMutableSet()
|
||||
if (!currentConfigs.remove(oldConfig)) {
|
||||
showToast(context, "Original kstat config not found")
|
||||
return false
|
||||
}
|
||||
|
||||
saveKstatConfigs(context, currentConfigs)
|
||||
|
||||
val success = addKstatStatically(context, path, ino, dev, nlink, size, atime, atimeNsec,
|
||||
mtime, mtimeNsec, ctime, ctimeNsec, blocks, blksize)
|
||||
val success = addKstatStaticallyInternal(context, path, ino, dev, nlink, size, atime, atimeNsec,
|
||||
mtime, mtimeNsec, ctime, ctimeNsec, blocks, blksize
|
||||
)
|
||||
|
||||
if (success) {
|
||||
showToast(context, context.getString(R.string.kstat_config_updated, path))
|
||||
return true
|
||||
} else {
|
||||
if (!success) {
|
||||
// 如果添加新配置失败,恢复旧配置
|
||||
currentConfigs.add(oldConfig)
|
||||
saveKstatConfigs(context, currentConfigs)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, "Failed to update kstat config, reverted to original")
|
||||
return false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
showToast(context, "Error updating kstat config: ${e.message}")
|
||||
return success
|
||||
} catch (
|
||||
_: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// 添加kstat路径
|
||||
suspend fun addKstat(context: Context, path: String): Boolean {
|
||||
private suspend fun addKstatInternal(context: Context, path: String): Boolean {
|
||||
val success = executeSusfsCommand(context, "add_sus_kstat '$path'")
|
||||
if (success) {
|
||||
saveAddKstatPaths(context, getAddKstatPaths(context) + path)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, context.getString(R.string.kstat_path_added, path))
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
suspend fun addKstat(context: Context, path: String): Boolean {
|
||||
return addKstatInternal(context, path)
|
||||
}
|
||||
|
||||
suspend fun removeAddKstat(context: Context, path: String): Boolean {
|
||||
saveAddKstatPaths(context, getAddKstatPaths(context) - path)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, context.getString(R.string.kstat_path_removed, path))
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1216,44 +1203,33 @@ object SuSFSManager {
|
||||
return try {
|
||||
val currentPaths = getAddKstatPaths(context).toMutableSet()
|
||||
if (!currentPaths.remove(oldPath)) {
|
||||
showToast(context, "Original kstat path not found: $oldPath")
|
||||
return false
|
||||
}
|
||||
|
||||
saveAddKstatPaths(context, currentPaths)
|
||||
|
||||
val success = addKstat(context, newPath)
|
||||
val success = addKstatInternal(context, newPath)
|
||||
|
||||
if (success) {
|
||||
showToast(context, context.getString(R.string.kstat_path_updated, oldPath, newPath))
|
||||
return true
|
||||
} else {
|
||||
if (!success) {
|
||||
// 如果添加新路径失败,恢复旧路径
|
||||
currentPaths.add(oldPath)
|
||||
saveAddKstatPaths(context, currentPaths)
|
||||
if (isAutoStartEnabled(context)) updateMagiskModule(context)
|
||||
showToast(context, "Failed to update kstat path, reverted to original")
|
||||
return false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
showToast(context, "Error updating kstat path: ${e.message}")
|
||||
return success
|
||||
} catch (_: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// 更新kstat
|
||||
suspend fun updateKstat(context: Context, path: String): Boolean {
|
||||
val success = executeSusfsCommand(context, "update_sus_kstat '$path'")
|
||||
if (success) showToast(context, context.getString(R.string.kstat_updated, path))
|
||||
return success
|
||||
return executeSusfsCommand(context, "update_sus_kstat '$path'")
|
||||
}
|
||||
|
||||
// 更新kstat全克隆
|
||||
suspend fun updateKstatFullClone(context: Context, path: String): Boolean {
|
||||
val success = executeSusfsCommand(context, "update_sus_kstat_full_clone '$path'")
|
||||
if (success) showToast(context, context.getString(R.string.kstat_full_clone_updated, path))
|
||||
return success
|
||||
return executeSusfsCommand(context, "update_sus_kstat_full_clone '$path'")
|
||||
}
|
||||
|
||||
// 设置Android数据路径
|
||||
@@ -1295,14 +1271,14 @@ object SuSFSManager {
|
||||
try {
|
||||
if (enabled) {
|
||||
if (!hasConfigurationForAutoStart(context)) {
|
||||
showToast(context, context.getString(R.string.susfs_no_config_to_autostart))
|
||||
Log.e("SuSFSManager", "No configuration available for auto start")
|
||||
return@withContext false
|
||||
}
|
||||
|
||||
val targetPath = getSuSFSTargetPath()
|
||||
if (!runCmdWithResult("test -f '$targetPath'").isSuccess) {
|
||||
copyBinaryFromAssets(context) ?: run {
|
||||
showToast(context, context.getString(R.string.susfs_binary_not_found))
|
||||
Log.e("SuSFSManager", "Failed to copy binary from assets for auto start")
|
||||
return@withContext false
|
||||
}
|
||||
}
|
||||
@@ -1310,24 +1286,21 @@ object SuSFSManager {
|
||||
val success = SuSFSModuleManager.createMagiskModule(context)
|
||||
if (success) {
|
||||
setAutoStartEnabled(context, true)
|
||||
showToast(context, context.getString(R.string.susfs_autostart_enabled_success, SuSFSModuleManager.getModulePath()))
|
||||
} else {
|
||||
showToast(context, context.getString(R.string.susfs_autostart_enable_failed))
|
||||
Log.e("SuSFSManager", "Failed to create Magisk module for auto start")
|
||||
}
|
||||
success
|
||||
} else {
|
||||
val success = SuSFSModuleManager.removeMagiskModule()
|
||||
if (success) {
|
||||
setAutoStartEnabled(context, false)
|
||||
showToast(context, context.getString(R.string.susfs_autostart_disabled_success))
|
||||
} else {
|
||||
showToast(context, context.getString(R.string.susfs_autostart_disable_failed))
|
||||
Log.e("SuSFSManager", "Failed to remove Magisk module")
|
||||
}
|
||||
success
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
showToast(context, context.getString(R.string.susfs_autostart_error, e.message ?: "Unknown error"))
|
||||
Log.e("SuSFSManager", "Exception configuring auto start: enabled=$enabled", e)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,16 +361,11 @@
|
||||
<!-- SuSFS Toast Messages -->
|
||||
<string name="susfs_binary_not_found">无法找到 ksu_susfs 文件</string>
|
||||
<string name="susfs_command_failed">SuSFS 命令执行失败</string>
|
||||
<string name="susfs_uname_set_success" formatted="false">SuSFS 内核名称和构建时间设置成功: %s, %s</string>
|
||||
<!-- SuSFS Settings Item -->
|
||||
<!-- 开机自启动相关 -->
|
||||
<string name="susfs_autostart_title">开机自启动</string>
|
||||
<string name="susfs_autostart_description">重启时自动应用所有非默认配置</string>
|
||||
<string name="susfs_autostart_requirement">需要添加配置后才能启用</string>
|
||||
<string name="susfs_autostart_enable_failed">启用开机自启动失败</string>
|
||||
<string name="susfs_autostart_disable_failed">禁用开机自启动失败</string>
|
||||
<string name="susfs_autostart_error">开机自启动配置错误: %s</string>
|
||||
<string name="susfs_no_config_to_autostart">没有可用的配置进行开机自启动</string>
|
||||
<!-- SuSFS Tab Titles -->
|
||||
<string name="susfs_tab_basic_settings">基本设置</string>
|
||||
<string name="susfs_tab_sus_paths">SuS 路径</string>
|
||||
@@ -380,8 +375,6 @@
|
||||
<!-- SuSFS Path Management -->
|
||||
<string name="susfs_add_sus_path">添加 SuS 路径</string>
|
||||
<string name="susfs_add_try_umount">添加尝试卸载</string>
|
||||
<string name="susfs_sus_path_added_success">SuS 路径添加成功</string>
|
||||
<string name="susfs_path_not_found_error">路径未找到错误</string>
|
||||
<string name="susfs_path_label">路径</string>
|
||||
<string name="susfs_no_paths_configured">暂无 SuS 路径配置</string>
|
||||
<string name="susfs_no_umounts_configured">暂无尝试卸载配置</string>
|
||||
@@ -392,8 +385,6 @@
|
||||
<string name="susfs_umount_mode_normal_short">普通</string>
|
||||
<string name="susfs_umount_mode_detach_short">分离</string>
|
||||
<string name="susfs_umount_mode_display">模式: %1$s (%2$s)</string>
|
||||
<string name="susfs_try_umount_added_success">尝试 umount 路径添加成功: %s</string>
|
||||
<string name="susfs_try_umount_added_saved">尝试 umount 路径保存成功: %s</string>
|
||||
<!-- SuSFS Run Umount -->
|
||||
<!-- SuSFS Reset Categories -->
|
||||
<string name="susfs_reset_paths_title">重置 SuS 路径</string>
|
||||
@@ -424,8 +415,6 @@
|
||||
<string name="susfs_enable_log_label">SuSFS 启用日志</string>
|
||||
<string name="susfs_log_config_description">启用或者关闭 SuSFS 的日志</string>
|
||||
<string name="susfs_log_config_title">SuSFS 日志配置</string>
|
||||
<string name="susfs_log_enabled">启用 SuSFS 日志</string>
|
||||
<string name="susfs_log_disabled">关闭 SuSFS 日志</string>
|
||||
<string name="susfs_execution_location_label">执行位置</string>
|
||||
<string name="susfs_current_execution_location">当前执行位置:%s</string>
|
||||
<string name="susfs_execution_location_service">Service</string>
|
||||
@@ -440,16 +429,8 @@
|
||||
<string name="susfs_slot_use_build_time">使用构建时间</string>
|
||||
<string name="susfs_slot_info_unavailable">无法获取槽位信息</string>
|
||||
<!-- SuSFS 自启动相关字符串 -->
|
||||
<string name="susfs_autostart_enabled_success">SuSFS 自启动模块已启用,模块路径:%s</string>
|
||||
<string name="susfs_autostart_disabled_success">SuSFS 自启动模块已禁用</string>
|
||||
<!-- SuSFS Kstat相关字符串 -->
|
||||
<string name="susfs_tab_kstat_config">Kstat 配置</string>
|
||||
<string name="kstat_static_config_added">Kstat 静态配置已添加:%1$s</string>
|
||||
<string name="kstat_config_removed">已移除 Kstat 配置:%1$s</string>
|
||||
<string name="kstat_path_added">Kstat 路径已添加:%1$s</string>
|
||||
<string name="kstat_path_removed">已移除 Kstat 路径:%1$s</string>
|
||||
<string name="kstat_updated">Kstat 已更新:%1$s</string>
|
||||
<string name="kstat_full_clone_updated">Kstat 完整克隆已更新:%1$s</string>
|
||||
<string name="add_kstat_statically_title">添加 Kstat 静态配置</string>
|
||||
<string name="file_or_directory_path_label">文件/目录路径</string>
|
||||
<string name="hint_use_default_value">提示:可以使用 "default" 来使用原始值</string>
|
||||
@@ -469,11 +450,6 @@
|
||||
<string name="susfs_hide_mounts_for_all_procs_label">对所有进程隐藏 SuS 挂载</string>
|
||||
<string name="susfs_hide_mounts_for_all_procs_enabled_description">启用后,SuS 挂载将对所有进程隐藏,包括 KSU 进程</string>
|
||||
<string name="susfs_hide_mounts_for_all_procs_disabled_description">禁用后,SuS 挂载仅对非 KSU 进程隐藏,KSU 进程可以看到挂载</string>
|
||||
<string name="susfs_hide_mounts_all_enabled">已启用对所有进程隐藏 SuS 挂载</string>
|
||||
<string name="susfs_hide_mounts_all_disabled">已禁用对所有进程隐藏 SuS 挂载</string>
|
||||
<string name="susfs_android_data_path_set">Android Data 路径已设置为: %s</string>
|
||||
<string name="susfs_sdcard_path_set">SDCard 路径已设置为: %s</string>
|
||||
<string name="susfs_path_setup_warning">路径设置可能未完全成功,但将继续添加 SuS 路径</string>
|
||||
<!-- 备份和还原相关字符串 -->
|
||||
<string name="susfs_backup_title">备份</string>
|
||||
<string name="susfs_backup_description">创建所有 SuSFS 配置的备份。备份文件将包含所有设置、路径和配置信息。</string>
|
||||
@@ -506,13 +482,9 @@
|
||||
<string name="edit">编辑</string>
|
||||
<string name="delete">删除</string>
|
||||
<string name="update">更新</string>
|
||||
<string name="kstat_config_updated">Kstat 配置更新</string>
|
||||
<string name="kstat_path_updated">Kstat 路径更新</string>
|
||||
<string name="susfs_update_full_clone">Susfs 完整克隆更新</string>
|
||||
<string name="umount_zygote_iso_service">卸载 Zygote 隔离服务</string>
|
||||
<string name="umount_zygote_iso_service_description">启用此选项将在系统启动时卸载 Zygote 隔离服务挂载点</string>
|
||||
<string name="umount_zygote_iso_service_enabled">Zygote 隔离服务卸载已启用</string>
|
||||
<string name="umount_zygote_iso_service_disabled">Zygote 隔离服务卸载已禁用</string>
|
||||
<string name="app_paths_section">应用路径</string>
|
||||
<string name="other_paths_section">其他路径</string>
|
||||
<string name="add_custom_path">其他</string>
|
||||
@@ -526,33 +498,29 @@
|
||||
<string name="susfs_tab_sus_loop_paths">SuS 循环路径</string>
|
||||
<string name="susfs_add_sus_loop_path">添加 SuS 循环路径</string>
|
||||
<string name="susfs_edit_sus_loop_path">编辑 SuS 循环路径</string>
|
||||
<string name="susfs_loop_path_added_success">SuS 循环路径添加成功: %1$s</string>
|
||||
<string name="susfs_loop_path_removed">SuS 循环路径已移除: %1$s</string>
|
||||
<string name="susfs_loop_path_updated">SuS 循环路径已更新: %1$s -> %2$s</string>
|
||||
<string name="susfs_no_loop_paths_configured">未配置 SuS 循环路径</string>
|
||||
<string name="susfs_reset_loop_paths_title">重置循环路径</string>
|
||||
<string name="susfs_reset_loop_paths_message">确定要清空所有 SuS 循环路径吗?此操作无法撤销。</string>
|
||||
<string name="susfs_loop_path_label">循环路径</string>
|
||||
<string name="susfs_loop_path_restriction_warning">注意:只有不在 /storage/ 和 /sdcard/ 内的路径才能通过循环路径添加。</string>
|
||||
<string name="susfs_loop_path_invalid_location">错误:循环路径不能位于 /storage/ 或 /sdcard/ 目录内</string>
|
||||
<string name="susfs_invalid_loop_path">无效的循环路径</string>
|
||||
<string name="susfs_add_loop_path_failed">添加循环路径失败</string>
|
||||
<string name="susfs_edit_loop_path_failed">编辑循环路径失败</string>
|
||||
<string name="loop_paths_section">循环路径</string>
|
||||
<string name="add_loop_path">添加循环路径</string>
|
||||
<!-- 循环路径功能描述 -->
|
||||
<string name="sus_loop_paths_description_title">循环路径配置</string>
|
||||
<string name="sus_loop_paths_description_text">循环路径会在每次非 root 用户应用或隔离服务启动时重新标记为 SUS_PATH。这有助于解决添加的路径可能因 inode 状态重置或内核中 inode 重新创建而失效的问题</string>
|
||||
<string name="avc_log_spoofing">AVC 日志欺骗</string>
|
||||
<string name="avc_log_spoofing_enabled">AVC 日志欺骗已启用</string>
|
||||
<string name="avc_log_spoofing_disabled">AVC 日志欺骗已禁用</string>
|
||||
<string name="avc_log_spoofing_description">禁用: 禁用在内核 AVC 日志中欺骗 \'su\' 的 sus tcontext。\n启用: 启用在内核 AVC 日志中将 \'su\' 的 sus tcontext 欺骗为 \'kernel\'</string>
|
||||
<!-- SUS Map related strings -->
|
||||
<string name="susfs_tab_sus_maps">SUS映射</string>
|
||||
<string name="susfs_sus_map_label">库文件路径</string>
|
||||
<string name="susfs_add_sus_map">添加SUS映射</string>
|
||||
<string name="susfs_edit_sus_map">编辑SUS映射</string>
|
||||
<string name="susfs_sus_map_added_success">SUS映射添加成功: %1$s</string>
|
||||
<string name="susfs_sus_map_removed">SUS映射已移除: %1$s</string>
|
||||
<string name="susfs_sus_map_updated">SUS映射已更新: %1$s -> %2$s</string>
|
||||
<string name="susfs_no_sus_maps_configured">未配置SUS映射</string>
|
||||
<string name="susfs_add_map_failed">添加SUS映射失败</string>
|
||||
<string name="susfs_edit_map_failed">编辑SUS映射失败</string>
|
||||
<string name="susfs_reset_sus_maps_title">重置SUS映射</string>
|
||||
<string name="susfs_reset_sus_maps_message">这将移除所有已配置的SUS映射。此操作无法撤销。</string>
|
||||
<string name="sus_maps_section">内存映射隐藏</string>
|
||||
|
||||
@@ -369,16 +369,11 @@
|
||||
<!-- SuSFS Toast Messages -->
|
||||
<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_uname_set_success" formatted="false">SuSFS uname and build time set successfully: %s, %s</string>
|
||||
<!-- SuSFS Settings Item -->
|
||||
<!-- 开机自启动相关 -->
|
||||
<string name="susfs_autostart_title">Auto Start</string>
|
||||
<string name="susfs_autostart_description">Automatically apply all non-default configurations on reboot</string>
|
||||
<string name="susfs_autostart_requirement">Configuration needs to be added to enable</string>
|
||||
<string name="susfs_autostart_enable_failed">Failed to enable auto start</string>
|
||||
<string name="susfs_autostart_disable_failed">Failed to disable auto start</string>
|
||||
<string name="susfs_autostart_error">Auto start configuration error: %s</string>
|
||||
<string name="susfs_no_config_to_autostart">No available configuration for auto start</string>
|
||||
<!-- SuSFS Tab Titles -->
|
||||
<string name="susfs_tab_basic_settings">Basic Settings</string>
|
||||
<string name="susfs_tab_sus_paths">SUS Paths</string>
|
||||
@@ -388,8 +383,6 @@
|
||||
<!-- SuSFS Path Management -->
|
||||
<string name="susfs_add_sus_path">Add SUS Path</string>
|
||||
<string name="susfs_add_try_umount">Add Try Umount</string>
|
||||
<string name="susfs_sus_path_added_success">SUS path added successfully</string>
|
||||
<string name="susfs_path_not_found_error">Path not found error</string>
|
||||
<string name="susfs_path_label">Path</string>
|
||||
<string name="susfs_no_paths_configured">No SUS paths configured</string>
|
||||
<string name="susfs_no_umounts_configured">No try umount configured</string>
|
||||
@@ -400,8 +393,6 @@
|
||||
<string name="susfs_umount_mode_normal_short">Normal</string>
|
||||
<string name="susfs_umount_mode_detach_short">Detach</string>
|
||||
<string name="susfs_umount_mode_display">Mode: %1$s (%2$s)</string>
|
||||
<string name="susfs_try_umount_added_success">Try to umount path added successfully: %s</string>
|
||||
<string name="susfs_try_umount_added_saved">Attempted umount path save succeeded: %s</string>
|
||||
<!-- SuSFS Reset Categories -->
|
||||
<string name="susfs_reset_paths_title">Reset SUS Paths</string>
|
||||
<string name="susfs_reset_paths_message">This will clear all SUS path configurations. Are you sure you want to continue?</string>
|
||||
@@ -431,8 +422,6 @@
|
||||
<string name="susfs_enable_log_label">SuSFS Enable Log</string>
|
||||
<string name="susfs_log_config_description">Enable or disable logging for SuSFS</string>
|
||||
<string name="susfs_log_config_title">SuSFS Logging Configuration</string>
|
||||
<string name="susfs_log_enabled">Enabling SuSFS Logging</string>
|
||||
<string name="susfs_log_disabled">Turn off SuSFS logging</string>
|
||||
<string name="susfs_execution_location_label">Execution Location</string>
|
||||
<string name="susfs_current_execution_location">Current execution location: %s</string>
|
||||
<string name="susfs_execution_location_service">Service</string>
|
||||
@@ -447,16 +436,8 @@
|
||||
<string name="susfs_slot_use_build_time">Use Build Time</string>
|
||||
<string name="susfs_slot_info_unavailable">Unable to retrieve slot information</string>
|
||||
<!-- SuSFS 自启动相关字符串 -->
|
||||
<string name="susfs_autostart_enabled_success">SuSFS auto-start module enabled, module path: %s</string>
|
||||
<string name="susfs_autostart_disabled_success">SuSFS auto-start module disabled</string>
|
||||
<!-- SuSFS Kstat相关字符串 -->
|
||||
<string name="susfs_tab_kstat_config">Kstat Configuration</string>
|
||||
<string name="kstat_static_config_added">Kstat static configuration added: %1$s</string>
|
||||
<string name="kstat_config_removed">Kstat configuration removed: %1$s</string>
|
||||
<string name="kstat_path_added">Kstat path added: %1$s</string>
|
||||
<string name="kstat_path_removed">Kstat path removed: %1$s</string>
|
||||
<string name="kstat_updated">Kstat updated: %1$s</string>
|
||||
<string name="kstat_full_clone_updated">Kstat full clone updated: %1$s</string>
|
||||
<string name="add_kstat_statically_title">Add Kstat Static Configuration</string>
|
||||
<string name="file_or_directory_path_label">File/Directory Path</string>
|
||||
<string name="hint_use_default_value">Hint: You can use "default" to use the original value</string>
|
||||
@@ -476,11 +457,6 @@
|
||||
<string name="susfs_hide_mounts_for_all_procs_label">Hide SUS mounts for all processes</string>
|
||||
<string name="susfs_hide_mounts_for_all_procs_enabled_description">When enabled, SUS mounts will be hidden from all processes, including KSU processes</string>
|
||||
<string name="susfs_hide_mounts_for_all_procs_disabled_description">When disabled, SUS mounts will only be hidden from non-KSU processes, KSU processes can see the mounts</string>
|
||||
<string name="susfs_hide_mounts_all_enabled">Enabled hiding SUS mounts for all processes</string>
|
||||
<string name="susfs_hide_mounts_all_disabled">Disabled hiding SUS mounts for all processes</string>
|
||||
<string name="susfs_android_data_path_set">Android Data path has been set to: %s</string>
|
||||
<string name="susfs_sdcard_path_set">SD card path has been set to: %s</string>
|
||||
<string name="susfs_path_setup_warning">Path setup may not be fully successful, but SUS paths will continue to be added</string>
|
||||
<!-- 备份和还原相关字符串 -->
|
||||
<string name="susfs_backup_title">Backup</string>
|
||||
<string name="susfs_backup_description">Create a backup of all SuSFS configurations. The backup file will include all settings, paths, and configurations</string>
|
||||
@@ -513,13 +489,9 @@
|
||||
<string name="edit">Edit</string>
|
||||
<string name="delete">Delete</string>
|
||||
<string name="update">Update</string>
|
||||
<string name="kstat_config_updated">Kstat config update</string>
|
||||
<string name="kstat_path_updated">Kstat path update</string>
|
||||
<string name="susfs_update_full_clone">Susfs update full clone</string>
|
||||
<string name="umount_zygote_iso_service">Unmount Zygote Isolation Service</string>
|
||||
<string name="umount_zygote_iso_service_description">Enable this option to unmount Zygote isolation service mount points at system startup</string>
|
||||
<string name="umount_zygote_iso_service_enabled">Zygote isolation service unmount enabled</string>
|
||||
<string name="umount_zygote_iso_service_disabled">Zygote isolation service unmount disabled</string>
|
||||
<string name="app_paths_section">Application Path</string>
|
||||
<string name="other_paths_section">Other paths</string>
|
||||
<string name="add_custom_path">Other</string>
|
||||
@@ -533,33 +505,29 @@
|
||||
<string name="susfs_tab_sus_loop_paths">SUS Loop Paths</string>
|
||||
<string name="susfs_add_sus_loop_path">Add SUS Loop Path</string>
|
||||
<string name="susfs_edit_sus_loop_path">Edit SUS Loop Path</string>
|
||||
<string name="susfs_loop_path_added_success">SUS loop path added successfully: %1$s</string>
|
||||
<string name="susfs_loop_path_removed">SUS loop path removed: %1$s</string>
|
||||
<string name="susfs_loop_path_updated">SUS loop path updated: %1$s -> %2$s</string>
|
||||
<string name="susfs_no_loop_paths_configured">No SUS loop paths configured</string>
|
||||
<string name="susfs_reset_loop_paths_title">Reset Loop Paths</string>
|
||||
<string name="susfs_reset_loop_paths_message">Are you sure you want to clear all SUS loop paths? This action cannot be undone</string>
|
||||
<string name="susfs_loop_path_label">Loop Path</string>
|
||||
<string name="susfs_loop_path_restriction_warning">Note: Only paths NOT inside /storage/ and /sdcard/ can be added via loop paths</string>
|
||||
<string name="susfs_loop_path_invalid_location">Error: Loop paths cannot be inside /storage/ or /sdcard/ directories</string>
|
||||
<string name="susfs_invalid_loop_path">Invalid loop path</string>
|
||||
<string name="susfs_add_loop_path_failed">Failed to add loop path</string>
|
||||
<string name="susfs_edit_loop_path_failed">Failed to edit loop path</string>
|
||||
<string name="loop_paths_section">Loop Paths</string>
|
||||
<string name="add_loop_path">Add Loop Path</string>
|
||||
<!-- 循环路径功能描述 -->
|
||||
<string name="sus_loop_paths_description_title">Loop Path Configuration</string>
|
||||
<string name="sus_loop_paths_description_text">Loop paths are re-flagged as SUS_PATH on each non-root user app or isolated service startup. This helps address issues where added paths may have their inode status reset or inode re-created in the kernel</string>
|
||||
<string name="avc_log_spoofing">AVC Log Spoofing</string>
|
||||
<string name="avc_log_spoofing_enabled">AVC log spoofing has been enabled</string>
|
||||
<string name="avc_log_spoofing_disabled">AVC log spoofing has been disabled</string>
|
||||
<string name="avc_log_spoofing_description">Disabled: Disable spoofing the sus tcontext of \'su\' shown in avc log in kernel\nEnabled: Enable spoofing the sus tcontext of \'su\' with \'kernel\' shown in avc log in kernel</string>
|
||||
<!-- SUS Map related strings -->
|
||||
<string name="susfs_tab_sus_maps">SUS Maps</string>
|
||||
<string name="susfs_sus_map_label">Library Path</string>
|
||||
<string name="susfs_add_sus_map">Add SUS Map</string>
|
||||
<string name="susfs_edit_sus_map">Edit SUS Map</string>
|
||||
<string name="susfs_sus_map_added_success">SUS map added successfully: %1$s</string>
|
||||
<string name="susfs_sus_map_removed">SUS map removed: %1$s</string>
|
||||
<string name="susfs_sus_map_updated">SUS map updated: %1$s -> %2$s</string>
|
||||
<string name="susfs_no_sus_maps_configured">No SUS maps configured</string>
|
||||
<string name="susfs_add_map_failed">Failed to add SUS map</string>
|
||||
<string name="susfs_edit_map_failed">Failed to edit SUS map</string>
|
||||
<string name="susfs_reset_sus_maps_title">Reset SUS Maps</string>
|
||||
<string name="susfs_reset_sus_maps_message">This will remove all configured SUS maps. This action cannot be undone.</string>
|
||||
<string name="sus_maps_section">Memory Map Hiding</string>
|
||||
|
||||
Reference in New Issue
Block a user