diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3ff765d..c3fee67 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -138,5 +138,7 @@ dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.4") // Networking - implementation("com.github.niusounds:cronet-engine:0.1.0") + implementation("com.vk.knet:core:1.0") + implementation("com.vk.knet:cronet:1.0") + implementation("com.vk.knet:okcronet:1.0") } diff --git a/app/src/main/java/app/revanced/manager/api/API.kt b/app/src/main/java/app/revanced/manager/api/API.kt index 9e3581a..55d0fbe 100644 --- a/app/src/main/java/app/revanced/manager/api/API.kt +++ b/app/src/main/java/app/revanced/manager/api/API.kt @@ -4,14 +4,15 @@ import android.util.Log import app.revanced.manager.dto.github.Assets import app.revanced.manager.preferences.PreferencesManager import app.revanced.manager.repository.GitHubRepository -import io.ktor.client.* -import io.ktor.client.request.* -import io.ktor.client.statement.* -import io.ktor.util.cio.* -import io.ktor.utils.io.* +import com.vk.knet.core.Knet +import com.vk.knet.core.http.HttpMethod +import com.vk.knet.core.http.HttpRequest +import com.vk.knet.cornet.CronetKnetEngine import java.io.File -class API(private val repository: GitHubRepository, private val prefs: PreferencesManager, val client: HttpClient) { +class API(private val repository: GitHubRepository, private val prefs: PreferencesManager, cronet: CronetKnetEngine) { + + val client = Knet.Build(cronet) suspend fun findAsset(repo: String, file: String): PatchesAsset { val asset = repository.fetchAssets().tools.findAsset(repo, file) ?: throw MissingAssetException() @@ -42,7 +43,7 @@ class API(private val repository: GitHubRepository, private val prefs: Preferenc } } - suspend fun downloadAsset( + fun downloadAsset( workdir: File, assets: PatchesAsset ): Pair { @@ -55,9 +56,9 @@ class API(private val repository: GitHubRepository, private val prefs: Preferenc return assets to out } Log.d("ReVanced Manager", "Downloading asset ${assets.asset.name}") - client.get(assets.asset.downloadUrl) - .bodyAsChannel() - .copyAndClose(out.writeChannel()) + val file = client.execute(HttpRequest(HttpMethod.GET, assets.asset.downloadUrl)).body?.asBytes() + file?.let { out.writeBytes(it) } + return assets to out } diff --git a/app/src/main/java/app/revanced/manager/di/HttpModule.kt b/app/src/main/java/app/revanced/manager/di/HttpModule.kt index 99f1910..c02c1dc 100644 --- a/app/src/main/java/app/revanced/manager/di/HttpModule.kt +++ b/app/src/main/java/app/revanced/manager/di/HttpModule.kt @@ -1,41 +1,42 @@ package app.revanced.manager.di import android.content.Context -import com.niusounds.ktor.client.engine.cronet.Cronet -import io.ktor.client.* -import io.ktor.client.plugins.* -import io.ktor.client.plugins.cache.* -import io.ktor.client.plugins.contentnegotiation.* -import io.ktor.serialization.kotlinx.json.* -import kotlinx.serialization.json.Json +import com.vk.knet.core.utils.ByteArrayPool +import com.vk.knet.cornet.CronetKnetEngine +import com.vk.knet.cornet.config.CronetCache +import com.vk.knet.cornet.config.CronetQuic +import com.vk.knet.cornet.pool.buffer.CronetNativeByteBufferPool import org.koin.android.ext.koin.androidContext import org.koin.dsl.module +import java.util.concurrent.TimeUnit val httpModule = module { - fun provideHttpClient(appContext: Context) = HttpClient( - engine = Cronet.create { - context = appContext - config = { - enableBrotli(true) - enableQuic(true) - } + fun client(appContext: Context) = CronetKnetEngine.Build(appContext) { + client { + setCache(CronetCache.Disk(appContext.filesDir, 1024 * 1024 * 10)) + + enableHttp2(true) + enableQuic( + CronetQuic() + ) + + useBrotli(true) + connectTimeout(15, TimeUnit.SECONDS) + writeTimeout(15, TimeUnit.SECONDS) + readTimeout(15, TimeUnit.SECONDS) + + nativePool(CronetNativeByteBufferPool.DEFAULT) + arrayPool(ByteArrayPool.DEFAULT) + + maxConcurrentRequests(50) + maxConcurrentRequestsPerHost(10) + + followRedirects(true) + followSslRedirects(true) } - ) { - BrowserUserAgent() - install(ContentNegotiation) { - json(Json { - encodeDefaults = true - isLenient = true - ignoreUnknownKeys = true - }) - } - install(HttpRequestRetry) { - retryOnServerErrors(maxRetries = 5) - } - install(HttpCache) } single { - provideHttpClient(androidContext()) + client(androidContext()) } } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/manager/repository/GitHubRepository.kt b/app/src/main/java/app/revanced/manager/repository/GitHubRepository.kt index 0a15dea..330f559 100644 --- a/app/src/main/java/app/revanced/manager/repository/GitHubRepository.kt +++ b/app/src/main/java/app/revanced/manager/repository/GitHubRepository.kt @@ -1,24 +1,28 @@ package app.revanced.manager.repository -import app.revanced.manager.dto.github.Tools import app.revanced.manager.dto.github.Repositories -import io.ktor.client.* -import io.ktor.client.call.* -import io.ktor.client.request.* +import app.revanced.manager.dto.github.Tools +import com.vk.knet.core.Knet +import com.vk.knet.core.http.HttpMethod +import com.vk.knet.core.http.HttpRequest +import com.vk.knet.cornet.CronetKnetEngine import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json -class GitHubRepository(val client: HttpClient) { +class GitHubRepository(cronet: CronetKnetEngine) { + val client = Knet.Build(cronet) suspend fun fetchAssets() = withContext(Dispatchers.IO) { - client.get("$apiUrl/tools") { - parameter("per_page", 1) - }.body() as Tools + val stream = client.execute(HttpRequest(HttpMethod.GET, "$apiUrl/tools")).body!!.asString() + Json.decodeFromString(stream) as Tools } suspend fun fetchContributors() = withContext(Dispatchers.IO) { - client.get("$apiUrl/contributors").body() as Repositories + val stream = client.execute(HttpRequest(HttpMethod.GET,"$apiUrl/contributors")).body!!.asString() + Json.decodeFromString(stream) as Repositories } private companion object {