mirror of
https://github.com/immich-app/immich.git
synced 2026-03-26 03:28:59 +03:00
fix(mobile): cronet image cache clearing on android (#27054)
This commit is contained in:
@@ -23,10 +23,18 @@ import okhttp3.HttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import okhttp3.OkHttpClient
|
||||
import org.chromium.net.CronetEngine
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.nio.file.FileVisitResult
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.SimpleFileVisitor
|
||||
import java.nio.file.attribute.BasicFileAttributes
|
||||
import java.net.Authenticator
|
||||
import java.net.CookieHandler
|
||||
import java.net.PasswordAuthentication
|
||||
@@ -277,10 +285,13 @@ object HttpClientManager {
|
||||
return result
|
||||
}
|
||||
|
||||
fun rebuildCronetEngine(): CronetEngine {
|
||||
val old = cronetEngine!!
|
||||
cronetEngine = buildCronetEngine()
|
||||
return old
|
||||
suspend fun rebuildCronetEngine(): Result<Long> {
|
||||
return runCatching {
|
||||
cronetEngine?.shutdown()
|
||||
val deletionResult = deleteFolderAndGetSize(cronetStoragePath.toPath())
|
||||
cronetEngine = buildCronetEngine()
|
||||
deletionResult
|
||||
}
|
||||
}
|
||||
|
||||
val cronetStoragePath: File get() = cronetStorageDir
|
||||
@@ -301,7 +312,7 @@ object HttpClientManager {
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildCronetEngine(): CronetEngine {
|
||||
fun buildCronetEngine(): CronetEngine {
|
||||
return CronetEngine.Builder(appContext)
|
||||
.enableHttp2(true)
|
||||
.enableQuic(true)
|
||||
@@ -312,6 +323,27 @@ object HttpClientManager {
|
||||
.build()
|
||||
}
|
||||
|
||||
private suspend fun deleteFolderAndGetSize(root: Path): Long = withContext(Dispatchers.IO) {
|
||||
var totalSize = 0L
|
||||
|
||||
Files.walkFileTree(root, object : SimpleFileVisitor<Path>() {
|
||||
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
|
||||
totalSize += attrs.size()
|
||||
Files.delete(file)
|
||||
return FileVisitResult.CONTINUE
|
||||
}
|
||||
|
||||
override fun postVisitDirectory(dir: Path, exc: IOException?): FileVisitResult {
|
||||
if (dir != root) {
|
||||
Files.delete(dir)
|
||||
}
|
||||
return FileVisitResult.CONTINUE
|
||||
}
|
||||
})
|
||||
|
||||
totalSize
|
||||
}
|
||||
|
||||
private fun build(cacheDir: File): OkHttpClient {
|
||||
val connectionPool = ConnectionPool(
|
||||
maxIdleConnections = KEEP_ALIVE_CONNECTIONS,
|
||||
|
||||
@@ -21,11 +21,6 @@ import java.io.EOFException
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.file.FileVisitResult
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.SimpleFileVisitor
|
||||
import java.nio.file.attribute.BasicFileAttributes
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
private class RemoteRequest(val cancellationSignal: CancellationSignal)
|
||||
@@ -205,18 +200,15 @@ private class CronetImageFetcher : ImageFetcher {
|
||||
|
||||
private fun onDrained() {
|
||||
val onCacheCleared = synchronized(stateLock) {
|
||||
val onCacheCleared = onCacheCleared
|
||||
val onCacheCleared = this.onCacheCleared
|
||||
this.onCacheCleared = null
|
||||
onCacheCleared
|
||||
}
|
||||
if (onCacheCleared != null) {
|
||||
val oldEngine = HttpClientManager.rebuildCronetEngine()
|
||||
oldEngine.shutdown()
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val result = runCatching { deleteFolderAndGetSize(HttpClientManager.cronetStoragePath.toPath()) }
|
||||
synchronized(stateLock) { draining = false }
|
||||
onCacheCleared(result)
|
||||
}
|
||||
} ?: return
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val result = HttpClientManager.rebuildCronetEngine()
|
||||
synchronized(stateLock) { draining = false }
|
||||
onCacheCleared(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,26 +298,6 @@ private class CronetImageFetcher : ImageFetcher {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deleteFolderAndGetSize(root: Path): Long = withContext(Dispatchers.IO) {
|
||||
var totalSize = 0L
|
||||
|
||||
Files.walkFileTree(root, object : SimpleFileVisitor<Path>() {
|
||||
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
|
||||
totalSize += attrs.size()
|
||||
Files.delete(file)
|
||||
return FileVisitResult.CONTINUE
|
||||
}
|
||||
|
||||
override fun postVisitDirectory(dir: Path, exc: IOException?): FileVisitResult {
|
||||
if (dir != root) {
|
||||
Files.delete(dir)
|
||||
}
|
||||
return FileVisitResult.CONTINUE
|
||||
}
|
||||
})
|
||||
|
||||
totalSize
|
||||
}
|
||||
}
|
||||
|
||||
private class OkHttpImageFetcher private constructor(
|
||||
|
||||
Reference in New Issue
Block a user