From 00b661be21becc0c9f3652618d0a2d45f5b4b662 Mon Sep 17 00:00:00 2001 From: zarzet <42882290+zarzet@users.noreply.github.com> Date: Mon, 19 Oct 2026 01:08:47 +0700 Subject: [PATCH] refactor(android): move the download service and worker backend calls into MainActivityServiceCalls.kt MainActivity.kt should be the dispatcher only. downloadByStrategy, the download foreground service, background work and native download worker cases keep their labels and order in the backend `when`; the multi-line ones now call MainActivity.handle functions in MainActivityServiceCalls.kt, and the one-line stop/pause/resume/cancel cases stay inline. Bodies move verbatim apart from the receiver label for this@MainActivity. --- .../kotlin/com/zarz/spotiflac/MainActivity.kt | 118 ++-------------- .../spotiflac/MainActivityServiceCalls.kt | 129 ++++++++++++++++++ 2 files changed, 139 insertions(+), 108 deletions(-) create mode 100644 android/app/src/main/kotlin/com/zarz/spotiflac/MainActivityServiceCalls.kt diff --git a/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt index 6f37d41c..83100e4d 100644 --- a/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt +++ b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivity.kt @@ -503,13 +503,7 @@ class MainActivity: FlutterFragmentActivity() { finishAndRemoveTask() result.success(null) } - "downloadByStrategy" -> { - val requestJson = call.arguments as String - val response = withContext(Dispatchers.IO) { - SafDownloadHandler.handle(this@MainActivity, requestJson, coreBackend) - } - result.success(response) - } + "downloadByStrategy" -> handleDownloadByStrategy(call, result) "getBackendImplementations" -> { result.success( mapOf( @@ -559,103 +553,25 @@ class MainActivity: FlutterFragmentActivity() { "downloadCoverToFile" -> handleDownloadCoverToFile(call, result) "extractCoverToFile" -> handleExtractCoverToFile(call, result) "reEnrichFile" -> handleReEnrichFile(call, result) - "startDownloadService" -> { - val trackName = call.argument("track_name") ?: "" - val artistName = call.argument("artist_name") ?: "" - val queueCount = call.argument("queue_count") ?: 0 - DownloadService.start(this@MainActivity, trackName, artistName, queueCount) - result.success(null) - } + "startDownloadService" -> handleStartDownloadService(call, result) "stopDownloadService" -> { DownloadService.stop(this@MainActivity) result.success(null) } - "updateDownloadServiceProgress" -> { - val trackName = call.argument("track_name") ?: "" - val artistName = call.argument("artist_name") ?: "" - val progress = (call.argument("progress") ?: 0).toLong() - val total = (call.argument("total") ?: 0).toLong() - val queueCount = (call.argument("queue_count") ?: 0).toInt() - val status = call.argument("status") ?: "downloading" - DownloadService.updateProgress(this@MainActivity, trackName, artistName, progress, total, queueCount, status) - result.success(null) - } + "updateDownloadServiceProgress" -> handleUpdateDownloadServiceProgress(call, result) "isDownloadServiceRunning" -> { result.success(DownloadService.isServiceRunning()) } - "startBackgroundWork" -> { - result.success( - BackgroundWorkService.start( - this@MainActivity, - call.argument("kind") ?: "", - call.argument("title") ?: "", - call.argument("text") ?: "", - ), - ) - } - "updateBackgroundWork" -> { - BackgroundWorkService.update( - call.argument("kind") ?: "", - call.argument("title") ?: "", - call.argument("text") ?: "", - call.argument("progress") ?: -1, - ) - result.success(null) - } + "startBackgroundWork" -> handleStartBackgroundWork(call, result) + "updateBackgroundWork" -> handleUpdateBackgroundWork(call, result) "stopBackgroundWork" -> { BackgroundWorkService.stop(call.argument("kind") ?: "") result.success(null) } - "startNativeDownloadWorker" -> { - val requestsJson = call.argument("requests_json") ?: "[]" - val settingsJson = call.argument("settings_json") ?: "{}" - val requestsPath = call.argument("requests_path") ?: "" - val settingsPath = call.argument("settings_path") ?: "" - if (requestsPath.isNotBlank()) { - DownloadService.startNativeQueueFromFiles( - this@MainActivity, - requestsPath, - settingsPath - ) - } else { - DownloadService.startNativeQueue(this@MainActivity, requestsJson, settingsJson) - } - result.success(null) - } - "appendNativeDownloadWorkerRequests" -> { - val requestsPath = call.argument("requests_path") ?: "" - val runId = call.argument("run_id") ?: "" - if (requestsPath.isNotBlank() && runId.isNotBlank()) { - DownloadService.appendNativeQueueFromFile( - this@MainActivity, - requestsPath, - runId, - ) - } - result.success(null) - } - "finishNativeDownloadWorkerPreparation" -> { - val runId = call.argument("run_id") ?: "" - if (runId.isNotBlank()) { - DownloadService.finishNativeQueuePreparation( - this@MainActivity, - runId, - ) - } - result.success(null) - } - "acknowledgeNativeDownloadWorkerItems" -> { - val runId = call.argument("run_id") ?: "" - val itemIdsJson = call.argument("item_ids_json") ?: "[]" - if (runId.isNotBlank()) { - DownloadService.acknowledgeNativeQueueItems( - this@MainActivity, - runId, - itemIdsJson, - ) - } - result.success(null) - } + "startNativeDownloadWorker" -> handleStartNativeDownloadWorker(call, result) + "appendNativeDownloadWorkerRequests" -> handleAppendNativeDownloadWorkerRequests(call, result) + "finishNativeDownloadWorkerPreparation" -> handleFinishNativeDownloadWorkerPreparation(call, result) + "acknowledgeNativeDownloadWorkerItems" -> handleAcknowledgeNativeDownloadWorkerItems(call, result) "pauseNativeDownloadWorker" -> { DownloadService.pauseNativeQueue(this@MainActivity) result.success(null) @@ -668,21 +584,7 @@ class MainActivity: FlutterFragmentActivity() { DownloadService.cancelNativeQueue(this@MainActivity) result.success(null) } - "getNativeDownloadWorkerSnapshot" -> { - val sinceStateSerial = - (call.argument("since_state_serial") ?: 0L).toLong() - // The snapshot can be megabytes late in a large - // batch; read and parse it off the main thread. - val payload = withContext(Dispatchers.IO) { - parseJsonPayload( - DownloadService.getNativeWorkerSnapshot( - this@MainActivity, - sinceStateSerial - ) - ) - } - result.success(payload) - } + "getNativeDownloadWorkerSnapshot" -> handleGetNativeDownloadWorkerSnapshot(call, result) "releaseMemory" -> { withContext(Dispatchers.IO) { coreBackend.releaseIdleResources() diff --git a/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivityServiceCalls.kt b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivityServiceCalls.kt new file mode 100644 index 00000000..92268ca6 --- /dev/null +++ b/android/app/src/main/kotlin/com/zarz/spotiflac/MainActivityServiceCalls.kt @@ -0,0 +1,129 @@ +package com.zarz.spotiflac + +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +// Download and background-work backend calls: the download strategy entry, +// the download foreground service, background work notifications, and the +// native download worker queue. One-line cases stay inline in MainActivity's +// backend `when`, which dispatches the rest here in the order it lists them. + +internal suspend fun MainActivity.handleDownloadByStrategy(call: MethodCall, result: MethodChannel.Result) { + val requestJson = call.arguments as String + val response = withContext(Dispatchers.IO) { + SafDownloadHandler.handle(this@handleDownloadByStrategy, requestJson, coreBackend) + } + result.success(response) +} + +internal fun MainActivity.handleStartDownloadService(call: MethodCall, result: MethodChannel.Result) { + val trackName = call.argument("track_name") ?: "" + val artistName = call.argument("artist_name") ?: "" + val queueCount = call.argument("queue_count") ?: 0 + DownloadService.start(this@handleStartDownloadService, trackName, artistName, queueCount) + result.success(null) +} + +internal fun MainActivity.handleUpdateDownloadServiceProgress(call: MethodCall, result: MethodChannel.Result) { + val trackName = call.argument("track_name") ?: "" + val artistName = call.argument("artist_name") ?: "" + val progress = (call.argument("progress") ?: 0).toLong() + val total = (call.argument("total") ?: 0).toLong() + val queueCount = (call.argument("queue_count") ?: 0).toInt() + val status = call.argument("status") ?: "downloading" + DownloadService.updateProgress(this@handleUpdateDownloadServiceProgress, trackName, artistName, progress, total, queueCount, status) + result.success(null) +} + +internal fun MainActivity.handleStartBackgroundWork(call: MethodCall, result: MethodChannel.Result) { + result.success( + BackgroundWorkService.start( + this@handleStartBackgroundWork, + call.argument("kind") ?: "", + call.argument("title") ?: "", + call.argument("text") ?: "", + ), + ) +} + +internal fun MainActivity.handleUpdateBackgroundWork(call: MethodCall, result: MethodChannel.Result) { + BackgroundWorkService.update( + call.argument("kind") ?: "", + call.argument("title") ?: "", + call.argument("text") ?: "", + call.argument("progress") ?: -1, + ) + result.success(null) +} + +internal fun MainActivity.handleStartNativeDownloadWorker(call: MethodCall, result: MethodChannel.Result) { + val requestsJson = call.argument("requests_json") ?: "[]" + val settingsJson = call.argument("settings_json") ?: "{}" + val requestsPath = call.argument("requests_path") ?: "" + val settingsPath = call.argument("settings_path") ?: "" + if (requestsPath.isNotBlank()) { + DownloadService.startNativeQueueFromFiles( + this@handleStartNativeDownloadWorker, + requestsPath, + settingsPath + ) + } else { + DownloadService.startNativeQueue(this@handleStartNativeDownloadWorker, requestsJson, settingsJson) + } + result.success(null) +} + +internal fun MainActivity.handleAppendNativeDownloadWorkerRequests(call: MethodCall, result: MethodChannel.Result) { + val requestsPath = call.argument("requests_path") ?: "" + val runId = call.argument("run_id") ?: "" + if (requestsPath.isNotBlank() && runId.isNotBlank()) { + DownloadService.appendNativeQueueFromFile( + this@handleAppendNativeDownloadWorkerRequests, + requestsPath, + runId, + ) + } + result.success(null) +} + +internal fun MainActivity.handleFinishNativeDownloadWorkerPreparation(call: MethodCall, result: MethodChannel.Result) { + val runId = call.argument("run_id") ?: "" + if (runId.isNotBlank()) { + DownloadService.finishNativeQueuePreparation( + this@handleFinishNativeDownloadWorkerPreparation, + runId, + ) + } + result.success(null) +} + +internal fun MainActivity.handleAcknowledgeNativeDownloadWorkerItems(call: MethodCall, result: MethodChannel.Result) { + val runId = call.argument("run_id") ?: "" + val itemIdsJson = call.argument("item_ids_json") ?: "[]" + if (runId.isNotBlank()) { + DownloadService.acknowledgeNativeQueueItems( + this@handleAcknowledgeNativeDownloadWorkerItems, + runId, + itemIdsJson, + ) + } + result.success(null) +} + +internal suspend fun MainActivity.handleGetNativeDownloadWorkerSnapshot(call: MethodCall, result: MethodChannel.Result) { + val sinceStateSerial = + (call.argument("since_state_serial") ?: 0L).toLong() + // The snapshot can be megabytes late in a large + // batch; read and parse it off the main thread. + val payload = withContext(Dispatchers.IO) { + parseJsonPayload( + DownloadService.getNativeWorkerSnapshot( + this@handleGetNativeDownloadWorkerSnapshot, + sinceStateSerial + ) + ) + } + result.success(payload) +}