switch to okio official coroutines

This commit is contained in:
Chloe committed 2026-02-01 01:28:07 -07:00
1 parent d0715c1bd8
commit 1f1e0de523
3 files changed
+61 -45

No files matched your search

+3
View File
@@ -100,8 +100,11 @@ dependencies {
implementation ("androidx.activity:activity-ktx:1.12.3") implementation ("androidx.activity:activity-ktx:1.12.3")
implementation ("androidx.appcompat:appcompat:1.7.1") implementation ("androidx.appcompat:appcompat:1.7.1")
implementation ("androidx.documentfile:documentfile:1.1.0") implementation ("androidx.documentfile:documentfile:1.1.0")
implementation ("com.squareup.okio:okio:3.16.4") implementation ("com.squareup.okio:okio:3.16.4")
implementation ("com.squareup.okhttp3:okhttp:5.3.2") implementation ("com.squareup.okhttp3:okhttp:5.3.2")
implementation ("com.squareup.okhttp3:okhttp-coroutines:5.3.2")
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0") implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0")
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:1.10.0") implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:1.10.0")
implementation ("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1") implementation ("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1")
@@ -1,6 +1,5 @@
package com.geode.launcher.updater package com.geode.launcher.updater
import com.geode.launcher.utils.DownloadUtils.executeCoroutine
import kotlin.time.Clock import kotlin.time.Clock
import kotlinx.datetime.DateTimeUnit import kotlinx.datetime.DateTimeUnit
import kotlin.time.Instant import kotlin.time.Instant
@@ -12,6 +11,7 @@ import kotlinx.serialization.json.okio.decodeFromBufferedSource
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.coroutines.executeAsync
import java.io.IOException import java.io.IOException
import java.net.URL import java.net.URL
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime
@@ -62,9 +62,9 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
.build() .build()
val call = httpClient.newCall(request) val call = httpClient.newCall(request)
val response = call.executeCoroutine()
return when (response.code) { return call.executeAsync().use { response ->
when (response.code) {
200 -> { 200 -> {
val format = Json { val format = Json {
namingStrategy = JsonNamingStrategy.SnakeCase namingStrategy = JsonNamingStrategy.SnakeCase
@@ -72,7 +72,7 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
} }
val release = format.decodeFromBufferedSource<List<Release>>( val release = format.decodeFromBufferedSource<List<Release>>(
response.body!!.source() response.body.source()
) )
(release.find { it.tagName != "nightly" }) (release.find { it.tagName != "nightly" })
@@ -94,7 +94,7 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
throw IOException(msg) throw IOException(msg)
} }
throw IOException("response 403: ${response.body!!.string()}") throw IOException("response 403: ${response.body.string()}")
} }
404 -> { 404 -> {
null null
@@ -104,6 +104,7 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
} }
} }
} }
}
@OptIn(ExperimentalTime::class) @OptIn(ExperimentalTime::class)
private fun generateRateLimitMessage(resetTime: Instant): String { private fun generateRateLimitMessage(resetTime: Instant): String {
@@ -124,9 +125,8 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
.build() .build()
val call = httpClient.newCall(request) val call = httpClient.newCall(request)
val response = call.executeCoroutine() return call.executeAsync().use { response ->
when (response.code) {
return when (response.code) {
200 -> { 200 -> {
val format = Json { val format = Json {
namingStrategy = JsonNamingStrategy.SnakeCase namingStrategy = JsonNamingStrategy.SnakeCase
@@ -134,7 +134,7 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
} }
val release = format.decodeFromBufferedSource<Release>( val release = format.decodeFromBufferedSource<Release>(
response.body!!.source() response.body.source()
) )
release release
@@ -155,7 +155,7 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
throw IOException(msg) throw IOException(msg)
} }
throw IOException("response 403: ${response.body!!.string()}") throw IOException("response 403: ${response.body.string()}")
} }
404 -> { 404 -> {
null null
@@ -165,6 +165,7 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
} }
} }
} }
}
@OptIn(ExperimentalSerializationApi::class) @OptIn(ExperimentalSerializationApi::class)
suspend fun getLatestIndexRelease(gd: Long, prerelease: Boolean = false): DownloadableLoaderRelease? { suspend fun getLatestIndexRelease(gd: Long, prerelease: Boolean = false): DownloadableLoaderRelease? {
@@ -181,9 +182,8 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
.build() .build()
val call = httpClient.newCall(request) val call = httpClient.newCall(request)
val response = call.executeCoroutine() return call.executeAsync().use { response ->
when (response.code) {
return when (response.code) {
200 -> { 200 -> {
val format = Json { val format = Json {
namingStrategy = JsonNamingStrategy.SnakeCase namingStrategy = JsonNamingStrategy.SnakeCase
@@ -191,7 +191,7 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
} }
val body = format.decodeFromBufferedSource<LoaderPayload<LoaderVersion>>( val body = format.decodeFromBufferedSource<LoaderPayload<LoaderVersion>>(
response.body!!.source() response.body.source()
) )
val release = body.payload ?: throw IOException("index error: ${body.error}") val release = body.payload ?: throw IOException("index error: ${body.error}")
@@ -206,4 +206,5 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
} }
} }
} }
}
} }
@@ -3,17 +3,18 @@ package com.geode.launcher.utils
import android.os.Build import android.os.Build
import android.os.FileUtils import android.os.FileUtils
import kotlinx.coroutines.runInterruptible import kotlinx.coroutines.runInterruptible
import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.Call
import okhttp3.Callback
import okhttp3.MediaType import okhttp3.MediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.RequestBody
import okhttp3.ResponseBody import okhttp3.ResponseBody
import okhttp3.coroutines.executeAsync
import okio.Buffer import okio.Buffer
import okio.BufferedSink
import okio.BufferedSource import okio.BufferedSource
import okio.ForwardingSink
import okio.ForwardingSource import okio.ForwardingSource
import okio.Sink
import okio.Source import okio.Source
import okio.buffer import okio.buffer
import java.io.IOException import java.io.IOException
@@ -21,8 +22,6 @@ import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.zip.ZipInputStream import java.util.zip.ZipInputStream
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
typealias ProgressCallback = (progress: Long, outOf: Long) -> Unit typealias ProgressCallback = (progress: Long, outOf: Long) -> Unit
@@ -50,7 +49,7 @@ object DownloadUtils {
val originalResponse = chain.proceed(chain.request()) val originalResponse = chain.proceed(chain.request())
originalResponse.newBuilder() originalResponse.newBuilder()
.body(ProgressResponseBody( .body(ProgressResponseBody(
originalResponse.body!!, onProgress originalResponse.body, onProgress
)) ))
.build() .build()
} }
@@ -59,30 +58,8 @@ object DownloadUtils {
val progressClient = progressClientBuilder.build() val progressClient = progressClientBuilder.build()
val call = progressClient.newCall(request) val call = progressClient.newCall(request)
val response = call.executeCoroutine() return call.executeAsync().use { response ->
response.body.byteStream()
return response.body!!.byteStream()
}
suspend fun Call.executeCoroutine(): Response {
return suspendCancellableCoroutine { continuation ->
this.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
if (continuation.isCancelled) {
return
}
continuation.resumeWithException(e)
}
override fun onResponse(call: Call, response: Response) {
continuation.resume(response)
}
})
continuation.invokeOnCancellation {
this.cancel()
}
} }
} }
@@ -167,3 +144,38 @@ private class ProgressResponseBody (
} }
} }
} }
// now based on <https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/UploadProgress.java#L84>
class ProgressRequestBody(
private val requestBody: RequestBody,
private val progressCallback: ProgressCallback
) : RequestBody() {
override fun contentType(): MediaType? {
return requestBody.contentType()
}
override fun contentLength(): Long {
return requestBody.contentLength()
}
override fun writeTo(sink: BufferedSink) {
val bufferedSink = this.sink(sink).buffer()
requestBody.writeTo(bufferedSink)
bufferedSink.flush()
}
private fun sink(sink: Sink): Sink {
return object : ForwardingSink(sink) {
var totalBytesWritten = 0L
override fun write(source: Buffer, byteCount: Long) {
super.write(source, byteCount)
totalBytesWritten += byteCount
progressCallback(
totalBytesWritten,
contentLength()
)
}
}
}
}