Initial Jvmheapless IO for Coil

This commit is contained in:
tarsin committed 2023-07-26 17:01:15 +08:00
1 parent 01353e05cc
commit 9818f227d7
3 files changed
+70 -1

No files matched your search

@@ -18,6 +18,7 @@ package com.hippo.ehviewer
import android.app.Application
import android.content.ComponentCallbacks2
import android.net.Uri
import androidx.appcompat.app.AppCompatDelegate
import androidx.collection.LruCache
import androidx.lifecycle.ProcessLifecycleOwner
@@ -29,6 +30,7 @@ import com.google.net.cronet.okhttptransport.RedirectStrategy.withoutRedirects
import com.hippo.ehviewer.client.EhCookieStore
import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.client.data.GalleryDetail
import com.hippo.ehviewer.coil.CronetHttpUriFetcher
import com.hippo.ehviewer.coil.MergeInterceptor
import com.hippo.ehviewer.dailycheck.checkDawn
import com.hippo.ehviewer.download.DownloadManager
@@ -54,6 +56,7 @@ import eu.kanade.tachiyomi.network.interceptor.CloudflareInterceptor
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.withUIContext
import kotlinx.coroutines.launch
import moe.tarsin.kt.unreachable
import okhttp3.AsyncDns
import okhttp3.android.AndroidAsyncDns
import okio.Path.Companion.toOkioPath
@@ -142,8 +145,16 @@ class EhApplication : Application(), ImageLoaderFactory {
}
override fun newImageLoader() = imageLoader {
okHttpClient(nonCacheOkHttpClient)
components {
if (isCronetSupported) {
callFactory { unreachable() }
add { data: Uri, options, loader ->
if (data.scheme != "http" && data.scheme != "https") return@add null
CronetHttpUriFetcher(data.toString(), options, loader)
}
} else {
okHttpClient(nonCacheOkHttpClient)
}
add { result, options, _ -> ImageDecoderDecoder(result.source, options, false) }
add(MergeInterceptor)
}
@@ -0,0 +1,55 @@
package com.hippo.ehviewer.coil
import android.webkit.MimeTypeMap
import coil.ImageLoader
import coil.decode.DataSource
import coil.decode.ImageSource
import coil.fetch.FetchResult
import coil.fetch.Fetcher
import coil.fetch.SourceResult
import coil.request.Options
import com.hippo.ehviewer.spider.awaitBodyFully
import com.hippo.ehviewer.spider.cronetRequest
import com.hippo.ehviewer.spider.execute
import java.io.RandomAccessFile
class CronetHttpUriFetcher(val data: String, val options: Options, val imageLoader: ImageLoader) : Fetcher {
override suspend fun fetch(): FetchResult {
val diskCacheKey = options.diskCacheKey ?: data
val diskCache = requireNotNull(imageLoader.diskCache)
val snapshot = diskCache.openSnapshot(diskCacheKey) ?: kotlin.run {
cronetRequest(data) {
disableCache()
}.execute {
val success = diskCache.suspendEdit(diskCacheKey) {
RandomAccessFile(data.toFile(), "rw").use { f ->
val chan = f.channel
awaitBodyFully { buffer ->
chan.write(buffer)
}
}
}
check(success)
}
requireNotNull(diskCache.openSnapshot(diskCacheKey))
}
val src = ImageSource(snapshot.data, diskCache.fileSystem, diskCacheKey, snapshot)
return SourceResult(
source = src,
mimeType = getMimeType(data),
dataSource = DataSource.DISK,
)
}
}
private fun getMimeType(url: String) = MimeTypeMap.getSingleton().getMimeTypeFromUrl(url)
private fun MimeTypeMap.getMimeTypeFromUrl(url: String?): String? {
if (url.isNullOrBlank()) return null
val extension = url
.substringBeforeLast('#') // Strip the fragment.
.substringBeforeLast('?') // Strip the query.
.substringAfterLast('/') // Get the last path segment.
.substringAfterLast('.', missingDelimiterValue = "") // Get the file extension.
return getMimeTypeFromExtension(extension)
}
@@ -0,0 +1,3 @@
package moe.tarsin.kt
fun unreachable(): Nothing = error("Unreachable!!!")