refactor(native): share errorJson and retire Go-era names in native comments

MainActivitySafIo and SafDownloadHandler each defined an identical
errorJson. Keep one internal top-level function in MainActivitySafIo
and drop the private copy. errorJson, isMediaStoreUri, extFromFileName
and extFromMimeType never used their MainActivity receiver, so they
become plain top-level functions; call sites are unchanged.

Rust is the only backend. Rename the iOS invokeGoMethod, which
dispatches the OS-owned channel methods, to invokeOsMethod, and reword
the comments that still described Go calls, the Go progress stream, the
Go metadata reader or a "native migration boundary" so they describe
the current backend. Channel method names and reply keys are unchanged.
This commit is contained in:
zarzet committed 2026-10-18 23:01:04 +07:00
1 parent fcec0942b9
commit 92adce43ef
9 files changed
+13 -21

No files matched your search

@@ -160,7 +160,7 @@ internal fun withCoreFFmpegExecution(
}
}
/** Native migration boundary; each process selects one stateful backend. */
/** Native boundary to the Rust backend; each process holds one stateful instance. */
internal interface CoreBackend {
val implementation: String
fun invokeApplication(method: String, arguments: Any?): Any?
@@ -362,7 +362,7 @@ class DownloadService : Service() {
internal val nativeWorkerTerminalStatuses = mutableMapOf<String, String>()
internal val nativeReplayGainEntries = mutableListOf<JSONObject>()
internal val nativeReplayGainRequestAlbumKeys = mutableMapOf<String, String>()
// One coordinator polls Go's delta progress stream for all native workers.
// One coordinator polls the backend's delta progress stream for all native workers.
// Individual workers consume this cache instead of parsing the complete
// multi-progress JSON independently.
internal val nativeWorkerProgressLock = Any()
@@ -14,7 +14,7 @@ import java.util.concurrent.atomic.AtomicReference
// Native-worker item state snapshots for the Flutter side.
/**
* The compact subset of Go progress needed by the Android worker UI. Keeping
* The compact subset of backend progress needed by the Android worker UI. Keeping
* this as a Kotlin value avoids sharing mutable JSONObject instances between
* the polling coroutine and worker coroutines.
*/
@@ -17,7 +17,7 @@ import java.util.Locale
// SAF/MediaStore URI IO helpers: temp copies, writes, sidecars, and the
// SAF post-processing pipeline.
internal fun MainActivity.errorJson(message: String): String {
internal fun errorJson(message: String): String {
val obj = JSONObject()
obj.put("success", false)
obj.put("error", message)
@@ -31,7 +31,7 @@ internal fun MainActivity.errorJson(message: String): String {
* which require READ_MEDIA_AUDIO / READ_EXTERNAL_STORAGE permission
* instead of SAF tree permission.
*/
internal fun MainActivity.isMediaStoreUri(uri: Uri): Boolean {
internal fun isMediaStoreUri(uri: Uri): Boolean {
val authority = uri.authority ?: return false
return authority == "media" ||
authority.startsWith("media.") ||
@@ -61,7 +61,7 @@ internal fun MainActivity.resolveMediaStoreExt(uri: Uri, fallbackExt: String?):
return fallbackExt ?: ""
}
internal fun MainActivity.extFromFileName(name: String): String {
internal fun extFromFileName(name: String): String {
return when {
name.endsWith(".m4a") -> ".m4a"
name.endsWith(".mp4") -> ".mp4"
@@ -81,7 +81,7 @@ internal fun MainActivity.extFromFileName(name: String): String {
}
}
internal fun MainActivity.extFromMimeType(mime: String?): String {
internal fun extFromMimeType(mime: String?): String {
return when (mime) {
"audio/mp4" -> ".m4a"
"audio/aac" -> ".aac"
@@ -869,7 +869,7 @@ object NativeDownloadFinalizer {
check(!metadata.has("error")) { "ReplayGain verification failed: $metadata" }
val isOpus = metadata.optString("audio_codec", "") == "opus"
for (key in fields.keys()) {
// Opus stores only R128 gain, exposed by the Go reader as dB.
// Opus stores only R128 gain, exposed by the Rust reader as dB.
if (isOpus && key.endsWith("_peak")) continue
val expected = fields.optString(key, "").trim().removeSuffix("dB").trim().toDoubleOrNull()
val actual = metadata.optString(key, "").trim().removeSuffix("dB").trim().toDoubleOrNull()
@@ -870,12 +870,4 @@ object SafDownloadHandler {
val baseName = if (artistName.isNotBlank()) "$artistName - $trackName" else trackName
return forceFilenameExt(baseName, outputExt)
}
private fun errorJson(message: String): String {
val obj = JSONObject()
obj.put("success", false)
obj.put("error", message)
obj.put("message", message)
return obj.toString()
}
}
+3 -3
View File
@@ -308,7 +308,7 @@ import UniformTypeIdentifiers
switch call.method {
case "beginBackgroundDownloadTask":
downloadsActive = true
// Request the assertion before the long-running Go call starts.
// Request the assertion before the long-running backend call starts.
// Waiting for applicationDidEnterBackground is too late: iOS may
// suspend the process before the assertion is granted.
beginBackgroundDownloadTask()
@@ -351,7 +351,7 @@ import UniformTypeIdentifiers
DispatchQueue.global(qos: .userInitiated).async {
do {
let response = try self.invokeGoMethod(call: call)
let response = try self.invokeOsMethod(call: call)
DispatchQueue.main.async {
result(response)
}
@@ -477,7 +477,7 @@ import UniformTypeIdentifiers
}
}
private func invokeGoMethod(call: FlutterMethodCall) throws -> Any? {
private func invokeOsMethod(call: FlutterMethodCall) throws -> Any? {
switch call.method {
case "getBackendImplementations":
+1 -1
View File
@@ -151,7 +151,7 @@ final class CoreDirectoryScope {
deinit { close() }
}
/// Native migration boundary; each process selects one stateful backend.
/// Native boundary to the Rust backend; each process holds one stateful instance.
protocol CoreBackend {
var implementation: String { get }
func prepareApplicationArguments(method: String, arguments: Any?) throws -> Any?
@@ -129,7 +129,7 @@ final class DownloadProgressSubscription {
}
}
// Schedule from main so subscription identity is never accessed
// concurrently, and stop/relisten does not wait for an old Go call.
// concurrently, and stop/relisten does not wait for an old backend call.
DispatchQueue.main.async { [weak self] in
guard let self, self.current === session, !session.isCancelled else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + self.interval) { [weak self] in