From 625fbb0247470b909708d258c72271129046bf6c Mon Sep 17 00:00:00 2001 From: vfsfitvnm Date: Sun, 12 Jun 2022 14:40:41 +0200 Subject: [PATCH] Add song cache settings --- .../it/vfsfitvnm/vimusic/MainActivity.kt | 1 + .../it/vfsfitvnm/vimusic/MainApplication.kt | 23 +++---- .../vimusic/services/PlayerService.kt | 17 +++-- .../ui/screens/settings/OtherScreen.kt | 69 +++++++++++++++++-- .../it/vfsfitvnm/vimusic/utils/Preferences.kt | 1 + 5 files changed, 87 insertions(+), 24 deletions(-) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt index 24d63de..3d2e5e5 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt @@ -42,6 +42,7 @@ import it.vfsfitvnm.vimusic.ui.components.rememberBottomSheetState import it.vfsfitvnm.vimusic.ui.components.rememberMenuState import it.vfsfitvnm.vimusic.ui.screens.HomeScreen import it.vfsfitvnm.vimusic.ui.screens.IntentUriScreen +import it.vfsfitvnm.vimusic.ui.screens.settings.OtherScreen import it.vfsfitvnm.vimusic.ui.styling.* import it.vfsfitvnm.vimusic.ui.views.PlayerView import it.vfsfitvnm.vimusic.utils.* diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainApplication.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainApplication.kt index f83a998..84efd6d 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainApplication.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainApplication.kt @@ -1,7 +1,6 @@ package it.vfsfitvnm.vimusic import android.app.Application -import android.content.Context import coil.ImageLoader import coil.ImageLoaderFactory import coil.disk.DiskCache @@ -15,18 +14,14 @@ class MainApplication : Application(), ImageLoaderFactory { } override fun newImageLoader(): ImageLoader { - return defaultCoilImageLoader(preferences.coilDiskCacheMaxSizeBytes) + return ImageLoader.Builder(this) + .crossfade(true) + .diskCache( + DiskCache.Builder() + .directory(filesDir.resolve("coil")) + .maxSizeBytes(preferences.coilDiskCacheMaxSizeBytes) + .build() + ) + .build() } } - -fun Context.defaultCoilImageLoader(diskCacheMaxSize: Long): ImageLoader { - return ImageLoader.Builder(this) - .crossfade(true) - .diskCache( - DiskCache.Builder() - .directory(filesDir.resolve("coil")) - .maxSizeBytes(diskCacheMaxSize) - .build() - ) - .build() -} \ No newline at end of file diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/services/PlayerService.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/services/PlayerService.kt index 37991bb..8c53a32 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/services/PlayerService.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/services/PlayerService.kt @@ -18,6 +18,7 @@ import androidx.core.app.NotificationCompat import androidx.core.graphics.drawable.IconCompat import androidx.core.graphics.drawable.toBitmap import androidx.core.net.toUri +import androidx.core.os.bundleOf import androidx.media3.common.* import androidx.media3.common.util.Util import androidx.media3.database.StandaloneDatabaseProvider @@ -25,7 +26,7 @@ import androidx.media3.datasource.DataSource import androidx.media3.datasource.DefaultHttpDataSource import androidx.media3.datasource.ResolvingDataSource import androidx.media3.datasource.cache.CacheDataSource -import androidx.media3.datasource.cache.NoOpCacheEvictor +import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor import androidx.media3.datasource.cache.SimpleCache import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.analytics.AnalyticsListener @@ -36,11 +37,10 @@ import androidx.media3.session.* import androidx.media3.session.MediaNotification.ActionFactory import coil.ImageLoader import coil.request.ImageRequest +import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.ListenableFuture -import it.vfsfitvnm.vimusic.Database -import it.vfsfitvnm.vimusic.MainActivity +import it.vfsfitvnm.vimusic.* import it.vfsfitvnm.vimusic.R -import it.vfsfitvnm.vimusic.internal import it.vfsfitvnm.vimusic.models.QueuedMediaItem import it.vfsfitvnm.vimusic.utils.* import it.vfsfitvnm.youtubemusic.Outcome @@ -52,6 +52,8 @@ val StartRadioCommand = SessionCommand("StartRadioCommand", Bundle.EMPTY) val StartArtistRadioCommand = SessionCommand("StartArtistRadioCommand", Bundle.EMPTY) val StopRadioCommand = SessionCommand("StopRadioCommand", Bundle.EMPTY) +val GetCacheSizeCommand = SessionCommand("GetCacheSizeCommand", Bundle.EMPTY) + @ExperimentalAnimationApi @ExperimentalFoundationApi class PlayerService : MediaSessionService(), MediaSession.MediaItemFiller, @@ -83,7 +85,8 @@ class PlayerService : MediaSessionService(), MediaSession.MediaItemFiller, createNotificationChannel() setMediaNotificationProvider(this) - cache = SimpleCache(cacheDir, NoOpCacheEvictor(), StandaloneDatabaseProvider(this)) + val cacheEvictor = LeastRecentlyUsedCacheEvictor(preferences.exoPlayerDiskCacheMaxSizeBytes) + cache = SimpleCache(cacheDir, cacheEvictor, StandaloneDatabaseProvider(this)) val player = ExoPlayer.Builder(this) .setHandleAudioBecomingNoisy(true) @@ -176,6 +179,7 @@ class PlayerService : MediaSessionService(), MediaSession.MediaItemFiller, .add(StartRadioCommand) .add(StartArtistRadioCommand) .add(StopRadioCommand) + .add(GetCacheSizeCommand) .build() val playerCommands = Player.Commands.Builder().addAllCommands().build() return MediaSession.ConnectionResult.accept(sessionCommands, playerCommands) @@ -206,6 +210,9 @@ class PlayerService : MediaSessionService(), MediaSession.MediaItemFiller, } } StopRadioCommand -> radio = null + GetCacheSizeCommand -> { + return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS, bundleOf("cacheSize" to cache.cacheSpace))) + } } return super.onCustomCommand(session, controller, customCommand, args) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/OtherScreen.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/OtherScreen.kt index 5c50488..1571722 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/OtherScreen.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/screens/settings/OtherScreen.kt @@ -1,5 +1,6 @@ package it.vfsfitvnm.vimusic.ui.screens.settings +import android.os.Bundle import android.text.format.Formatter import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.* @@ -16,15 +17,18 @@ import coil.Coil import coil.annotation.ExperimentalCoilApi import it.vfsfitvnm.route.RouteHandler import it.vfsfitvnm.vimusic.R +import it.vfsfitvnm.vimusic.services.GetCacheSizeCommand import it.vfsfitvnm.vimusic.ui.components.SeekBar import it.vfsfitvnm.vimusic.ui.components.TopAppBar import it.vfsfitvnm.vimusic.ui.screens.* import it.vfsfitvnm.vimusic.ui.styling.LocalColorPalette import it.vfsfitvnm.vimusic.ui.styling.LocalTypography import it.vfsfitvnm.vimusic.utils.LocalPreferences +import it.vfsfitvnm.vimusic.utils.LocalYoutubePlayer import it.vfsfitvnm.vimusic.utils.secondary import it.vfsfitvnm.vimusic.utils.semiBold import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.guava.await import kotlinx.coroutines.launch @OptIn(ExperimentalCoilApi::class) @@ -54,10 +58,9 @@ fun OtherScreen() { val colorPalette = LocalColorPalette.current val typography = LocalTypography.current val preferences = LocalPreferences.current + val mediaController = LocalYoutubePlayer.current?.mediaController - var coilDiskCache by remember { - mutableStateOf(Coil.imageLoader(context).diskCache) - } + val coilDiskCache = Coil.imageLoader(context).diskCache val coroutineScope = rememberCoroutineScope() @@ -94,7 +97,6 @@ fun OtherScreen() { ) } - coilDiskCache?.let { diskCache -> var diskCacheSize by remember(diskCache) { mutableStateOf(diskCache.size) @@ -133,7 +135,6 @@ fun OtherScreen() { }, onDrag = { delta -> scrubbingDiskCacheMaxSize = scrubbingDiskCacheMaxSize?.plus(delta)?.coerceIn(250L * 1024 * 1024, 2048L * 1024 * 1024) - println("new = $scrubbingDiskCacheMaxSize") }, onDragEnd = { preferences.coilDiskCacheMaxSizeBytes = scrubbingDiskCacheMaxSize ?: preferences.coilDiskCacheMaxSizeBytes @@ -164,6 +165,64 @@ fun OtherScreen() { } ) } + + mediaController?.let { mediaController -> + val diskCacheSize by produceState(initialValue = 0L) { + value = mediaController.sendCustomCommand(GetCacheSizeCommand, Bundle.EMPTY).await().extras.getLong("cacheSize") + } + + var scrubbingDiskCacheMaxSize by remember { + mutableStateOf(null) + } + + SettingsEntryGroupText( + title = "SONG CACHE", + ) + + Column( + modifier = Modifier + .padding(start = 24.dp) + .padding(horizontal = 32.dp, vertical = 16.dp) + .fillMaxWidth() + ) { + BasicText( + text = "Max size", + style = typography.xs.semiBold, + ) + + BasicText( + text = Formatter.formatShortFileSize(context, scrubbingDiskCacheMaxSize ?: preferences.exoPlayerDiskCacheMaxSizeBytes), + style = typography.xs.semiBold.secondary + ) + + SeekBar( + value = (scrubbingDiskCacheMaxSize ?: preferences.exoPlayerDiskCacheMaxSizeBytes).coerceIn(250L * 1024 * 1024, 4096L * 1024 * 1024), + minimumValue = 250L * 1024 * 1024, + maximumValue = 4096L * 1024 * 1024, + onDragStart = { + scrubbingDiskCacheMaxSize = it + }, + onDrag = { delta -> + scrubbingDiskCacheMaxSize = scrubbingDiskCacheMaxSize?.plus(delta)?.coerceIn(250L * 1024 * 1024, 4096L * 1024 * 1024) + }, + onDragEnd = { + preferences.exoPlayerDiskCacheMaxSizeBytes = scrubbingDiskCacheMaxSize ?: preferences.exoPlayerDiskCacheMaxSizeBytes + scrubbingDiskCacheMaxSize = null + }, + color = colorPalette.text, + backgroundColor = colorPalette.textDisabled, + shape = RoundedCornerShape(8.dp), + modifier = Modifier + .padding(top = 8.dp) + .fillMaxWidth() + ) + } + + DisabledSettingsEntry( + title = "Space used", + text = "${Formatter.formatShortFileSize(context, diskCacheSize)} (${diskCacheSize * 100 / preferences.exoPlayerDiskCacheMaxSizeBytes.coerceAtLeast(1)}%)", + ) + } } } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt index 6a22a6e..4acc123 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/utils/Preferences.kt @@ -23,6 +23,7 @@ class Preferences(holder: SharedPreferences) : SharedPreferences by holder { var homePageSongCollection by preference("homePageSongCollection", SongCollection.MostPlayed) var thumbnailRoundness by preference("thumbnailRoundness", ThumbnailRoundness.Light) var coilDiskCacheMaxSizeBytes by preference("coilDiskCacheMaxSizeBytes", 512L * 1024 * 1024) + var exoPlayerDiskCacheMaxSizeBytes by preference("exoPlayerDiskCacheMaxSizeBytes", 512L * 1024 * 1024) var displayLikeButtonInNotification by preference("displayLikeButtonInNotification", false) var persistentQueue by preference("persistentQueue", false) }