@@ -20,19 +20,14 @@ package org.akanework.gramophone.logic
2020import android.annotation.SuppressLint
2121import android.app.Application
2222import android.app.NotificationManager
23- import android.content.ContentUris
2423import android.content.Intent
2524import android.content.SharedPreferences
26- import android.graphics.Bitmap
2725import android.os.Build
2826import android.os.Debug
2927import android.os.Environment
3028import android.os.StrictMode
3129import android.os.StrictMode.ThreadPolicy
3230import android.os.StrictMode.VmPolicy
33- import android.provider.MediaStore
34- import android.util.Size
35- import android.webkit.MimeTypeMap
3631import androidx.appcompat.app.AppCompatDelegate
3732import androidx.compose.runtime.Composer
3833import androidx.compose.runtime.ExperimentalComposeRuntimeApi
@@ -44,19 +39,8 @@ import androidx.preference.PreferenceManager
4439import coil3.ImageLoader
4540import coil3.PlatformContext
4641import coil3.SingletonImageLoader
47- import coil3.Uri
48- import coil3.asImage
49- import coil3.decode.ContentMetadata
50- import coil3.decode.DataSource
51- import coil3.decode.ImageSource
52- import coil3.fetch.Fetcher
53- import coil3.fetch.ImageFetchResult
54- import coil3.fetch.SourceFetchResult
42+ import coil3.disk.DiskCache
5543import coil3.request.NullRequestDataException
56- import coil3.request.allowHardware
57- import coil3.size.pxOrElse
58- import coil3.toBitmap
59- import coil3.toCoilUri
6044import coil3.util.Logger
6145import kotlinx.coroutines.CoroutineScope
6246import kotlinx.coroutines.Dispatchers
@@ -65,22 +49,15 @@ import kotlinx.coroutines.flow.MutableStateFlow
6549import kotlinx.coroutines.launch
6650import kotlinx.coroutines.runBlocking
6751import okio.Path.Companion.toOkioPath
68- import okio.buffer
69- import okio.source
7052import org.akanework.gramophone.BuildConfig
7153import org.akanework.gramophone.R
7254import org.akanework.gramophone.logic.ui.BugHandlerActivity
73- import org.akanework.gramophone.logic.utils.Flags
55+ import org.akanework.gramophone.logic.utils.CoilArtPipeline
7456import org.akanework.gramophone.ui.LyricWidgetProvider
7557import org.lsposed.hiddenapibypass.HiddenApiBypass
7658import org.lsposed.hiddenapibypass.LSPass
7759import org.nift4.gramophone.hificore.UacManager
78- import org.nift4.mediastorecompat.MediaStoreCompat
79- import org.nift4.mediastorecompat.ThumbnailUtilsCompat
80- import uk.akane.libphonograph.Constants
8160import uk.akane.libphonograph.reader.FlowReader
82- import uk.akane.libphonograph.utils.MiscUtils
83- import java.io.File
8461import java.io.IOException
8562import kotlin.system.exitProcess
8663
@@ -263,8 +240,7 @@ class GramophoneApplication : Application(), SingletonImageLoader.Factory,
263240 whiteListSetFlow,
264241 if (hasScopedStorageWithMediaTypes()) MutableStateFlow (null ) else
265242 shouldUseEnhancedCoverReadingFlow!! ,
266- recentlyAddedFilterSecondFlow,
267- " gramophoneAlbumCover"
243+ recentlyAddedFilterSecondFlow
268244 )
269245 // Set application theme when launching.
270246 when (prefs.getString(" theme_mode" , " 0" )) {
@@ -336,88 +312,16 @@ class GramophoneApplication : Application(), SingletonImageLoader.Factory,
336312
337313 override fun newImageLoader (context : PlatformContext ): ImageLoader {
338314 return ImageLoader .Builder (context)
339- .diskCache(null )
315+ .diskCache {
316+ DiskCache .Builder ()
317+ .directory(context.cacheDir.resolve(" image_cache" ).toOkioPath())
318+ .maxSizeBytes(50L * 1024 * 1024 ) // 50MB
319+ .build()
320+ }
340321 .components {
341- add(Fetcher .Factory { data, options, _ ->
342- if (data !is Uri ) return @Factory null
343- if (data.scheme != " gramophoneSongCover" ) return @Factory null
344- return @Factory Fetcher {
345- val file = File (data.path!! )
346- val uri = ContentUris .appendId(
347- MediaStore .Audio .Media .EXTERNAL_CONTENT_URI .buildUpon(),
348- data.authority!! .toLong()
349- ).appendPath(MEDIA_ALBUM_ART ).build()
350- val bmp = if (options.size.width.pxOrElse { 0 } > 300
351- && options.size.height.pxOrElse { 0 } > 300 ) try {
352- ThumbnailUtilsCompat .createAudioThumbnail(file, options.size.let {
353- Size (
354- it.width.pxOrElse { throw IllegalArgumentException (" missing required size" ) },
355- it.height.pxOrElse { throw IllegalArgumentException (" missing required size" ) })
356- }, null )
357- } catch (e: IOException ) {
358- if (e.message != " No embedded album art found" &&
359- e.message != " No thumbnails in Downloads directories" &&
360- e.message != " No thumbnails in top-level directories" &&
361- e.message != " No album art found"
362- )
363- throw e
364- null
365- } else null
366- if (bmp != null ) {
367- // This would crash while drawing if we don't catch it here
368- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O &&
369- bmp.config == Bitmap .Config .HARDWARE && ! options.allowHardware)
370- throw IllegalStateException (" Got hardware bitmap unexpectedly" )
371- ImageFetchResult (
372- bmp.asImage(), true , DataSource .DISK
373- )
374- } else {
375- if (uri == null ) return @Fetcher null
376- val stream = contentResolver.openAssetFileDescriptor(uri, " r" )
377- checkNotNull(stream) { " Unable to open '$uri '." }
378- SourceFetchResult (
379- source = ImageSource (
380- source = stream.createInputStream().source().buffer(),
381- fileSystem = options.fileSystem,
382- metadata = ContentMetadata (uri.toCoilUri(), stream),
383- ),
384- mimeType = contentResolver.getType(uri),
385- dataSource = DataSource .DISK ,
386- )
387- }
388- }
389- })
390- add(Fetcher .Factory { data, options, _ ->
391- if (data !is Uri ) return @Factory null
392- if (data.scheme != " gramophoneAlbumCover" ) return @Factory null
393- return @Factory Fetcher {
394- val cover = MiscUtils .findBestCover(File (data.path!! ))
395- if (cover == null ) {
396- val uri =
397- ContentUris .withAppendedId(
398- Constants .baseAlbumCoverUri,
399- data.authority!! .toLong()
400- )
401- val contentResolver = options.context.contentResolver
402- val afd = contentResolver.openAssetFileDescriptor(uri, " r" )
403- checkNotNull(afd) { " Unable to open '$uri '." }
404- return @Fetcher SourceFetchResult (
405- source = ImageSource (
406- source = afd.createInputStream().source().buffer(),
407- fileSystem = options.fileSystem,
408- metadata = ContentMetadata (data, afd),
409- ),
410- mimeType = contentResolver.getType(uri),
411- dataSource = DataSource .DISK ,
412- )
413- }
414- return @Fetcher SourceFetchResult (
415- ImageSource (cover.toOkioPath(), options.fileSystem, null , null , null ),
416- MimeTypeMap .getSingleton().getMimeTypeFromExtension(cover.extension),
417- DataSource .DISK
418- )
419- }
420- })
322+ add(CoilArtPipeline .ResolutionInterceptor ())
323+ add(CoilArtPipeline .ArtResourceKeyer ())
324+ add(CoilArtPipeline .ArtResourceFetcher .Factory ())
421325 }
422326 .run {
423327 if (! BuildConfig .DEBUG ) this else
0 commit comments