1
+ package org.session.libsession.avatars
2
+
3
+ import android.app.Application
4
+ import com.bumptech.glide.Glide
5
+ import kotlinx.coroutines.CoroutineScope
6
+ import kotlinx.coroutines.Dispatchers
7
+ import kotlinx.coroutines.launch
8
+ import kotlinx.coroutines.withContext
9
+ import org.session.libsession.utilities.recipients.RemoteFile
10
+ import org.session.libsignal.utilities.Log
11
+ import org.thoughtcrime.securesms.attachments.RemoteFileDownloadWorker
12
+ import org.thoughtcrime.securesms.dependencies.ManagerScope
13
+ import org.thoughtcrime.securesms.glide.RecipientAvatarDownloadManager
14
+ import java.io.File
15
+ import javax.inject.Inject
16
+ import javax.inject.Singleton
17
+
18
+ @Singleton
19
+ class AvatarCacheCleaner @Inject constructor(
20
+ private val application : Application ,
21
+ private val avatarDownloadManager : RecipientAvatarDownloadManager , // we can reuse some logic here
22
+ @param:ManagerScope private val coroutineScope : CoroutineScope
23
+ ) {
24
+
25
+ companion object {
26
+ const val TAG = " AvatarCacheCleaner"
27
+ }
28
+
29
+ /* *
30
+ * Deletes avatar files under cache/remote_files that are no longer referenced
31
+ * in the current config. Returns number of files deleted.
32
+ */
33
+ suspend fun cleanUpAvatars (): Int = withContext(Dispatchers .IO ) {
34
+ // 1) Build the set of still-wanted RemoteFiles (contacts + groups)
35
+ val wantedRemotes: Set <RemoteFile > = avatarDownloadManager.getAllAvatars()
36
+
37
+ // 2) Map to actual files (same hashing/location as downloader)
38
+ val wantedFiles: Set <File > = wantedRemotes
39
+ .map { RemoteFileDownloadWorker .computeFileName(application, it) }
40
+ .toSet()
41
+
42
+ // 3) Delete everything not wanted in cache/remote_files
43
+ val dir = File (application.cacheDir, " remote_files" )
44
+ val files = dir.listFiles().orEmpty()
45
+ var deleted = 0
46
+ for (f in files) {
47
+ if (f !in wantedFiles && f.delete()) deleted++
48
+ }
49
+
50
+ // 4) Clear Glide cache. Might need this now but we should remove after we fully migrate to Coil
51
+ // Note to keep this off the main thread
52
+ Glide .get(application).clearDiskCache()
53
+
54
+ deleted
55
+ }
56
+
57
+ fun launchAvatarCleanup (cancelInFlight : Boolean = false) {
58
+ coroutineScope.launch(Dispatchers .IO ) {
59
+ if (cancelInFlight) {
60
+ RemoteFileDownloadWorker .cancelAll(application)
61
+ }
62
+ val deleted = cleanUpAvatars()
63
+ Log .d(TAG , " Avatar cache removed: $deleted files" )
64
+ }
65
+ }
66
+ }
0 commit comments