mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
@@ -49,6 +49,7 @@ android {
|
||||
|
||||
buildConfigField "String", "Cronet_Version", "\"$CronetVersion\""
|
||||
buildConfigField "String", "Cronet_Main_Version", "\"$CronetMainVersion\""
|
||||
buildConfigField "boolean", "isGoogle", "false"
|
||||
|
||||
javaCompileOptions {
|
||||
annotationProcessorOptions {
|
||||
@@ -104,6 +105,7 @@ android {
|
||||
dimension "mode"
|
||||
applicationId "io.legado.play"
|
||||
manifestPlaceholders.put("APP_CHANNEL_VALUE", "google")
|
||||
buildConfigField "boolean", "isGoogle", "true"
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
|
||||
@@ -13,9 +13,18 @@ class BodyUploadProvider(private val body: RequestBody) : UploadDataProvider(),
|
||||
|
||||
private val buffer = Buffer()
|
||||
|
||||
@Volatile
|
||||
private var filled: Boolean = false
|
||||
|
||||
init {
|
||||
fillBuffer()
|
||||
}
|
||||
|
||||
private fun fillBuffer() {
|
||||
try {
|
||||
buffer.clear()
|
||||
body.writeTo(buffer)
|
||||
buffer.flush()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
@@ -28,6 +37,9 @@ class BodyUploadProvider(private val body: RequestBody) : UploadDataProvider(),
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun read(uploadDataSink: UploadDataSink, byteBuffer: ByteBuffer) {
|
||||
if (!filled) {
|
||||
fillBuffer()
|
||||
}
|
||||
check(byteBuffer.hasRemaining()) { "Cronet passed a buffer with no bytes remaining" }
|
||||
var read: Int
|
||||
var bytesRead = 0
|
||||
@@ -40,8 +52,9 @@ class BodyUploadProvider(private val body: RequestBody) : UploadDataProvider(),
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun rewind(uploadDataSink: UploadDataSink) {
|
||||
buffer.clear()
|
||||
body.writeTo(buffer)
|
||||
check(body.isOneShot()) { "Okhttp RequestBody is oneShot" }
|
||||
filled = false
|
||||
fillBuffer()
|
||||
uploadDataSink.onRewindSucceeded()
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,10 @@ class CronetCoroutineInterceptor : Interceptor {
|
||||
|
||||
}
|
||||
|
||||
buildRequest(request, callBack)?.start()
|
||||
val req = buildRequest(request, callBack)?.also { it.start() }
|
||||
coroutine.invokeOnCancellation {
|
||||
req?.cancel()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -12,10 +12,13 @@ import okhttp3.MediaType
|
||||
import okhttp3.Request
|
||||
import org.chromium.net.CronetEngine.Builder.HTTP_CACHE_DISK
|
||||
import org.chromium.net.ExperimentalCronetEngine
|
||||
import org.chromium.net.UploadDataProvider
|
||||
import org.chromium.net.UrlRequest
|
||||
import org.json.JSONObject
|
||||
import splitties.init.appCtx
|
||||
|
||||
internal const val BUFFER_SIZE = 32 * 1024
|
||||
|
||||
val cronetEngine: ExperimentalCronetEngine? by lazy {
|
||||
if (!AppConfig.isGooglePlay) {
|
||||
CronetLoader.preDownload()
|
||||
@@ -85,10 +88,14 @@ fun buildRequest(request: Request, callback: UrlRequest.Callback): UrlRequest? {
|
||||
} else {
|
||||
addHeader("Content-Type", "text/plain")
|
||||
}
|
||||
setUploadDataProvider(
|
||||
BodyUploadProvider(requestBody),
|
||||
okHttpClient.dispatcher.executorService
|
||||
)
|
||||
val provider: UploadDataProvider = if (requestBody.contentLength() > BUFFER_SIZE) {
|
||||
LargeBodyUploadProvider(requestBody, okHttpClient.dispatcher.executorService)
|
||||
} else {
|
||||
BodyUploadProvider(requestBody)
|
||||
}
|
||||
provider.use {
|
||||
this.setUploadDataProvider(it, okHttpClient.dispatcher.executorService)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package io.legado.app.lib.cronet
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import okhttp3.RequestBody
|
||||
import okio.BufferedSource
|
||||
import okio.Pipe
|
||||
import okio.buffer
|
||||
import org.chromium.net.UploadDataProvider
|
||||
import org.chromium.net.UploadDataSink
|
||||
import java.io.IOException
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.concurrent.ExecutorService
|
||||
|
||||
/**
|
||||
* 用于上传大型文件
|
||||
*
|
||||
* @property body
|
||||
* @property executorService
|
||||
*/
|
||||
@Keep
|
||||
class LargeBodyUploadProvider(
|
||||
private val body: RequestBody,
|
||||
private val executorService: ExecutorService
|
||||
) : UploadDataProvider(), AutoCloseable {
|
||||
private val pipe = Pipe(BUFFER_SIZE.toLong())
|
||||
private var source: BufferedSource = pipe.source.buffer()
|
||||
|
||||
@Volatile
|
||||
private var filled: Boolean = false
|
||||
override fun getLength(): Long {
|
||||
return body.contentLength()
|
||||
}
|
||||
|
||||
override fun read(uploadDataSink: UploadDataSink, byteBuffer: ByteBuffer) {
|
||||
if (!filled) {
|
||||
fillBuffer()
|
||||
}
|
||||
check(byteBuffer.hasRemaining()) { "Cronet passed a buffer with no bytes remaining" }
|
||||
var read: Int
|
||||
var bytesRead = 0
|
||||
while (bytesRead <= 0) {
|
||||
read = source.read(byteBuffer)
|
||||
bytesRead += read
|
||||
}
|
||||
uploadDataSink.onReadSucceeded(false)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun fillBuffer() {
|
||||
executorService.submit {
|
||||
try {
|
||||
val writeSink = pipe.sink.buffer()
|
||||
filled = true
|
||||
body.writeTo(writeSink)
|
||||
writeSink.flush()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun rewind(p0: UploadDataSink?) {
|
||||
check(body.isOneShot()) { "Okhttp RequestBody is OneShot" }
|
||||
filled = false
|
||||
fillBuffer()
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
// pipe.cancel()
|
||||
// source.close()
|
||||
super.close()
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import splitties.init.appCtx
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
val isGooglePlay = appCtx.channel == "google"
|
||||
const val isGooglePlay = BuildConfig.isGoogle//appCtx.channel == "google"
|
||||
val isCronet = appCtx.getPrefBoolean(PreferKey.cronet)
|
||||
val useAntiAlias = appCtx.getPrefBoolean(PreferKey.antiAlias)
|
||||
var userAgent: String = getPrefUserAgent()
|
||||
|
||||
Reference in New Issue
Block a user