Skip to content

Commit d17a641

Browse files
committed
feat: unify download architecture with hub_uuid-based dispatch
- Add hub_uuid parameter throughout the Kotlin download pipeline (GetterService -> RustDownloader -> RustDownloaderAdapter -> DownloadTasker) so Rust can route downloads to the correct external downloader - Add registerDownloader/unregisterDownloader RPC methods to GetterService and GetterPort for external downloader registration - Create KotlinDownloaderRpcServer: JSON-RPC server exposing Kotlin-side downloader implementations to Rust's ExternalRpcDownloader - Create GooglePlayDownloaderImpl: bridges Google Play downloads through Rust's default HTTP downloader via the new dispatch system - Register Google Play downloader at startup in Init.kt - Pass CoolApk authentication headers in DownloadItem so the default HTTP downloader can use them for CDN requests that may require auth
1 parent 55b3a28 commit d17a641

File tree

13 files changed

+483
-11
lines changed

13 files changed

+483
-11
lines changed

app/src/main/java/net/xzos/upgradeall/wrapper/download/DownloadTasker.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class DownloadTasker(
124124
dir,
125125
CoroutineScope(SupervisorJob() + Dispatchers.IO)
126126
).apply {
127-
downloadList.forEach { addTask(it.toRustInputData(name)) }
127+
downloadList.forEach { addTask(it.toRustInputData(name, wrapper.hub.uuid)) }
128128
}.also { d ->
129129
d.observe { status ->
130130
val snap = getFileTaskerSnap(status.taskStatus())

core-getter/rpc/src/main/java/net/xzos/upgradeall/getter/rpc/DownloaderHelper.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,15 @@ object DownloaderHelper {
2525
/**
2626
* Convert DownloadItem to RustInputData
2727
*/
28-
fun net.xzos.upgradeall.websdk.data.json.DownloadItem.toRustInputData(filename: String): RustInputData {
28+
fun net.xzos.upgradeall.websdk.data.json.DownloadItem.toRustInputData(
29+
filename: String,
30+
hubUuid: String? = null
31+
): RustInputData {
2932
return RustInputData(
3033
name = filename,
3134
url = this.url,
3235
headers = this.headers ?: emptyMap(),
33-
cookies = this.cookies ?: emptyMap()
36+
cookies = this.cookies ?: emptyMap(),
37+
hubUuid = hubUuid
3438
)
3539
}

core-getter/rpc/src/main/java/net/xzos/upgradeall/getter/rpc/GetterService.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ interface GetterService {
7070
destPath: String,
7171
headers: Map<String, String>? = null,
7272
cookies: Map<String, String>? = null,
73+
hubUuid: String? = null,
7374
): TaskIdResponse
7475

7576
suspend fun downloadGetStatus(taskId: String): TaskInfo
@@ -84,6 +85,17 @@ interface GetterService {
8485
suspend fun downloadPause(taskId: String): Boolean
8586

8687
suspend fun downloadResume(taskId: String): Boolean
88+
89+
// ========================================================================
90+
// External Downloader Registration
91+
// ========================================================================
92+
93+
suspend fun registerDownloader(
94+
hubUuid: String,
95+
rpcUrl: String,
96+
): Boolean
97+
98+
suspend fun unregisterDownloader(hubUuid: String): Boolean
8799
}
88100

89101
/**

core-getter/rpc/src/main/java/net/xzos/upgradeall/getter/rpc/GetterServiceImpl.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class GetterServiceImpl(
125125
destPath: String,
126126
headers: Map<String, String>?,
127127
cookies: Map<String, String>?,
128+
hubUuid: String?,
128129
): TaskIdResponse {
129130
val params =
130131
mutableMapOf<String, Any?>(
@@ -133,6 +134,7 @@ class GetterServiceImpl(
133134
)
134135
if (headers != null) params["headers"] = headers
135136
if (cookies != null) params["cookies"] = cookies
137+
if (hubUuid != null) params["hub_uuid"] = hubUuid
136138

137139
return client.invoke("download_submit", params, typeOf<TaskIdResponse>())
138140
}
@@ -171,6 +173,27 @@ class GetterServiceImpl(
171173
return client.invoke("download_resume", params, typeOf<Boolean>())
172174
}
173175

176+
// ========================================================================
177+
// External Downloader Registration
178+
// ========================================================================
179+
180+
override suspend fun registerDownloader(
181+
hubUuid: String,
182+
rpcUrl: String,
183+
): Boolean {
184+
val params =
185+
mapOf(
186+
"hub_uuid" to hubUuid,
187+
"rpc_url" to rpcUrl,
188+
)
189+
return client.invoke("register_downloader", params, typeOf<Boolean>())
190+
}
191+
192+
override suspend fun unregisterDownloader(hubUuid: String): Boolean {
193+
val params = mapOf("hub_uuid" to hubUuid)
194+
return client.invoke("unregister_downloader", params, typeOf<Boolean>())
195+
}
196+
174197
/**
175198
* Close the underlying WebSocket connection
176199
*/

core-getter/rpc/src/main/java/net/xzos/upgradeall/getter/rpc/RustDownloader.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class RustDownloader(
1717
private val destPath: String,
1818
private val headers: Map<String, String>? = null,
1919
private val cookies: Map<String, String>? = null,
20+
private val hubUuid: String? = null,
2021
private val scope: CoroutineScope
2122
) {
2223
private var taskId: String? = null
@@ -41,7 +42,7 @@ class RustDownloader(
4142
_status.value = RustDownloadStatus.START
4243

4344
// Submit download task
44-
val response = getterService.downloadSubmit(url, destPath, headers, cookies)
45+
val response = getterService.downloadSubmit(url, destPath, headers, cookies, hubUuid)
4546
taskId = response.taskId
4647

4748
// Start polling for updates
@@ -238,12 +239,14 @@ class RustDownloaderBuilder(private val getterService: GetterService) {
238239
private var destPath: String = ""
239240
private var headers: Map<String, String>? = null
240241
private var cookies: Map<String, String>? = null
242+
private var hubUuid: String? = null
241243
private var scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
242244

243245
fun url(url: String) = apply { this.url = url }
244246
fun destPath(path: String) = apply { this.destPath = path }
245247
fun headers(headers: Map<String, String>) = apply { this.headers = headers }
246248
fun cookies(cookies: Map<String, String>) = apply { this.cookies = cookies }
249+
fun hubUuid(hubUuid: String?) = apply { this.hubUuid = hubUuid }
247250
fun scope(scope: CoroutineScope) = apply { this.scope = scope }
248251

249252
fun build(): RustDownloader {
@@ -253,6 +256,6 @@ class RustDownloaderBuilder(private val getterService: GetterService) {
253256
// Ensure parent directory exists
254257
File(destPath).parentFile?.mkdirs()
255258

256-
return RustDownloader(getterService, url, destPath, headers, cookies, scope)
259+
return RustDownloader(getterService, url, destPath, headers, cookies, hubUuid, scope)
257260
}
258261
}

core-getter/rpc/src/main/java/net/xzos/upgradeall/getter/rpc/RustDownloaderAdapter.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ class RustDownloaderAdapter(
2727
url = inputData.url,
2828
destPath = destFile.absolutePath,
2929
headers = inputData.headers,
30-
cookies = inputData.cookies
30+
cookies = inputData.cookies,
31+
hubUuid = inputData.hubUuid
3132
)
3233
)
3334
}
@@ -87,6 +88,8 @@ class RustDownloaderAdapter(
8788
taskData.headers?.let { builder.headers(it) }
8889
// Add cookies if present
8990
taskData.cookies?.let { builder.cookies(it) }
91+
// Add hubUuid if present
92+
taskData.hubUuid?.let { builder.hubUuid(it) }
9093

9194
val downloader = builder.build()
9295

@@ -180,12 +183,14 @@ data class RustTaskData(
180183
val url: String,
181184
val destPath: String,
182185
val headers: Map<String, String> = emptyMap(),
183-
val cookies: Map<String, String> = emptyMap()
186+
val cookies: Map<String, String> = emptyMap(),
187+
val hubUuid: String? = null
184188
)
185189

186190
data class RustInputData(
187191
val name: String,
188192
val url: String,
189193
val headers: Map<String, String> = emptyMap(),
190-
val cookies: Map<String, String> = emptyMap()
194+
val cookies: Map<String, String> = emptyMap(),
195+
val hubUuid: String? = null
191196
)

core-getter/src/main/java/net/xzos/upgradeall/getter/GetterPort.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,18 @@ class GetterPort(
158158
}
159159
}
160160

161+
fun registerDownloader(
162+
hubUuid: String,
163+
rpcUrl: String,
164+
): Boolean? {
165+
if (!init()) return null
166+
return runBlocking {
167+
service
168+
.registerDownloader(hubUuid, rpcUrl)
169+
.also { Log.d("GetterPort", "registerDownloader: uuid=$hubUuid url=$rpcUrl result=$it") }
170+
}
171+
}
172+
161173
fun getDownloadInfo(
162174
hubUuid: String,
163175
appData: Map<String, String>,

core-websdk/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,6 @@ dependencies {
6969
implementation libs.ktor.server.cio
7070

7171
api project(':core-getter')
72+
api project(':core-getter:rpc')
7273
api project(':core-websdk:data')
7374
}

core-websdk/src/main/java/net/xzos/upgradeall/core/websdk/Init.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import net.xzos.upgradeall.core.websdk.api.ServerApiProxy
88
import net.xzos.upgradeall.core.websdk.api.client_proxy.hubs.CoolApk
99
import net.xzos.upgradeall.core.websdk.api.client_proxy.hubs.GooglePlay
1010
import net.xzos.upgradeall.core.websdk.api.client_proxy.rpc.KotlinHubRpcServer
11+
import net.xzos.upgradeall.core.websdk.api.client_proxy.rpc.KotlinDownloaderRpcServer
12+
import net.xzos.upgradeall.core.websdk.api.client_proxy.rpc.GooglePlayDownloaderImpl
1113
import net.xzos.upgradeall.core.websdk.api.web.proxy.OkhttpProxy
1214
import net.xzos.upgradeall.getter.GetterPort
1315
import net.xzos.upgradeall.getter.RustConfig
@@ -25,6 +27,8 @@ val getterPort get() = data.getterPort!!
2527
lateinit var dataCacheManager: DataCacheManager
2628

2729
private var kotlinHubRpcServer: KotlinHubRpcServer? = null
30+
private var kotlinDownloaderRpcServer: KotlinDownloaderRpcServer? = null
31+
private var googlePlayDownloaderImpl: GooglePlayDownloaderImpl? = null
2832

2933
fun initSdkCache(config: CacheConfig) {
3034
dataCacheManager = DataCacheManager(config)
@@ -59,6 +63,17 @@ suspend fun runGetterService(context: Context) {
5963
server.getHubUuids().forEach { uuid ->
6064
getterPort.registerProvider(uuid, kotlinRpcUrl)
6165
}
66+
67+
// Start Google Play Downloader RPC Server and register it with Rust getter
68+
val googlePlayDownloader = GooglePlayDownloaderImpl(getterPort.getService())
69+
googlePlayDownloaderImpl = googlePlayDownloader
70+
val downloaderServer = KotlinDownloaderRpcServer(googlePlayDownloader)
71+
val downloaderRpcUrl = downloaderServer.start()
72+
kotlinDownloaderRpcServer = downloaderServer
73+
74+
// Register Google Play downloader with the Rust getter via JSON-RPC
75+
// UUID matches GooglePlay hub UUID
76+
getterPort.registerDownloader("65c2f60c-7d08-48b8-b4ba-ac6ee924f6fa", downloaderRpcUrl)
6277
}
6378

6479
fun renewSdkApi(host: String) {

0 commit comments

Comments
 (0)