diff --git a/app/src/main/java/com/cappielloantonio/tempo/model/SessionMediaItem.kt b/app/src/main/java/com/cappielloantonio/tempo/model/SessionMediaItem.kt index 90d01f90..60d641ce 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/model/SessionMediaItem.kt +++ b/app/src/main/java/com/cappielloantonio/tempo/model/SessionMediaItem.kt @@ -3,6 +3,7 @@ package com.cappielloantonio.tempo.model import android.net.Uri import android.os.Bundle import androidx.annotation.Keep +import androidx.media3.common.HeartRating import androidx.media3.common.MediaItem import androidx.media3.common.MediaItem.RequestMetadata import androidx.media3.common.MediaMetadata @@ -243,6 +244,13 @@ class SessionMediaItem() { .setAlbumTitle(album) .setArtist(artist) .setArtworkUri(artworkUri) + .setUserRating(HeartRating(starred != null)) + .setSupportedCommands( + listOf( + Constants.CUSTOM_COMMAND_TOGGLE_HEART_ON, + Constants.CUSTOM_COMMAND_TOGGLE_HEART_OFF + ) + ) .setExtras(bundle) .setIsBrowsable(false) .setIsPlayable(true) diff --git a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/SettingsFragment.java b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/SettingsFragment.java index ef4f2134..0ee8d86f 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/SettingsFragment.java +++ b/app/src/main/java/com/cappielloantonio/tempo/ui/fragment/SettingsFragment.java @@ -117,6 +117,7 @@ public class SettingsFragment extends PreferenceFragmentCompat { actionDeleteDownloadStorage(); actionKeepScreenOn(); actionAutoDownloadLyrics(); + actionMiniPlayerHeart(); bindMediaService(); actionAppEqualizer(); @@ -358,6 +359,21 @@ public class SettingsFragment extends PreferenceFragmentCompat { }); } + private void actionMiniPlayerHeart() { + SwitchPreference preference = findPreference("mini_shuffle_button_visibility"); + if (preference == null) { + return; + } + + preference.setChecked(Preferences.showShuffleInsteadOfHeart()); + preference.setOnPreferenceChangeListener((pref, newValue) -> { + if (newValue instanceof Boolean) { + Preferences.setShuffleInsteadOfHeart((Boolean) newValue); + } + return true; + }); + } + private void actionAutoDownloadLyrics() { SwitchPreference preference = findPreference("auto_download_lyrics"); if (preference == null) { diff --git a/app/src/main/java/com/cappielloantonio/tempo/util/Constants.kt b/app/src/main/java/com/cappielloantonio/tempo/util/Constants.kt index da8862df..bd0cc26d 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/util/Constants.kt +++ b/app/src/main/java/com/cappielloantonio/tempo/util/Constants.kt @@ -116,4 +116,13 @@ object Constants { const val HOME_SECTOR_RECENTLY_ADDED = "HOME_SECTOR_RECENTLY_ADDED" const val HOME_SECTOR_PINNED_PLAYLISTS = "HOME_SECTOR_PINNED_PLAYLISTS" const val HOME_SECTOR_SHARED = "HOME_SECTOR_SHARED" + + const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON = "android.media3.session.demo.SHUFFLE_ON" + const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF = "android.media3.session.demo.SHUFFLE_OFF" + const val CUSTOM_COMMAND_TOGGLE_HEART_ON = "android.media3.session.demo.HEART_ON" + const val CUSTOM_COMMAND_TOGGLE_HEART_OFF = "android.media3.session.demo.HEART_OFF" + const val CUSTOM_COMMAND_TOGGLE_HEART_LOADING = "android.media3.session.demo.HEART_LOADING" + const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF = "android.media3.session.demo.REPEAT_OFF" + const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE = "android.media3.session.demo.REPEAT_ONE" + const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL = "android.media3.session.demo.REPEAT_ALL" } \ No newline at end of file diff --git a/app/src/main/java/com/cappielloantonio/tempo/util/MappingUtil.java b/app/src/main/java/com/cappielloantonio/tempo/util/MappingUtil.java index f8f15f07..e254d3c7 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/util/MappingUtil.java +++ b/app/src/main/java/com/cappielloantonio/tempo/util/MappingUtil.java @@ -8,6 +8,7 @@ import androidx.media3.common.MediaItem; import androidx.media3.common.MediaMetadata; import androidx.media3.common.MimeTypes; import androidx.media3.common.util.UnstableApi; +import androidx.media3.common.HeartRating; import com.cappielloantonio.tempo.App; import com.cappielloantonio.tempo.glide.CustomGlideRequest; @@ -16,6 +17,7 @@ import com.cappielloantonio.tempo.repository.DownloadRepository; import com.cappielloantonio.tempo.subsonic.models.Child; import com.cappielloantonio.tempo.subsonic.models.InternetRadioStation; import com.cappielloantonio.tempo.subsonic.models.PodcastEpisode; +import com.google.common.collect.ImmutableList; import java.util.ArrayList; import java.util.List; @@ -83,6 +85,13 @@ public class MappingUtil { .setAlbumTitle(media.getAlbum()) .setArtist(media.getArtist()) .setArtworkUri(artworkUri) + .setUserRating(new HeartRating(media.getStarred() != null)) + .setSupportedCommands( + ImmutableList.of( + Constants.CUSTOM_COMMAND_TOGGLE_HEART_ON, + Constants.CUSTOM_COMMAND_TOGGLE_HEART_OFF + ) + ) .setExtras(bundle) .setIsBrowsable(false) .setIsPlayable(true) diff --git a/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt b/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt index 80276319..d3d81ee2 100644 --- a/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt +++ b/app/src/main/java/com/cappielloantonio/tempo/util/Preferences.kt @@ -73,6 +73,7 @@ object Preferences { private const val LAST_INSTANT_MIX = "last_instant_mix" private const val EQUALIZER_ENABLED = "equalizer_enabled" private const val EQUALIZER_BAND_LEVELS = "equalizer_band_levels" + private const val MINI_SHUFFLE_BUTTON_VISIBILITY = "mini_shuffle_button_visibility" @JvmStatic fun getServer(): String? { @@ -359,6 +360,16 @@ object Preferences { ).apply() } + @JvmStatic + fun showShuffleInsteadOfHeart(): Boolean { + return App.getInstance().preferences.getBoolean(MINI_SHUFFLE_BUTTON_VISIBILITY, false) + } + + @JvmStatic + fun setShuffleInsteadOfHeart(enabled: Boolean) { + App.getInstance().preferences.edit().putBoolean(MINI_SHUFFLE_BUTTON_VISIBILITY, enabled).apply() + } + @JvmStatic fun showServerUnreachableDialog(): Boolean { return App.getInstance().preferences.getLong( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7b461a67..2b7a4148 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -88,6 +88,9 @@ Required http or https prefix required Downloads + Toggle Heart off + Toggle Heart on + Loading… Select two or more filters Filter Filter artists @@ -332,6 +335,8 @@ Sync timer If enabled, the user will have the ability to save their play queue and will have the ability to load state when opening the application. Sync play queue for this user [Not Fully Baked] + Show Shuffle button + If enabled, show the shuffle button, remove the heart in the mini player Show radio If enabled, show the radio section. Restart the app for it to take full effect. Auto download lyrics diff --git a/app/src/main/res/xml/global_preferences.xml b/app/src/main/res/xml/global_preferences.xml index f240a304..e8b5faeb 100644 --- a/app/src/main/res/xml/global_preferences.xml +++ b/app/src/main/res/xml/global_preferences.xml @@ -97,6 +97,13 @@ android:defaultValue="true" android:summary="@string/settings_music_directory_summary" android:key="music_directory_section_visibility" /> + + + diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaLibraryServiceCallback.kt b/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaLibraryServiceCallback.kt index 099ae672..1815a815 100644 --- a/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaLibraryServiceCallback.kt +++ b/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaLibraryServiceCallback.kt @@ -2,21 +2,42 @@ package com.cappielloantonio.tempo.service import android.content.Context import android.os.Bundle +import android.util.Log import androidx.annotation.OptIn +import androidx.concurrent.futures.CallbackToFutureAdapter +import androidx.media3.common.HeartRating import androidx.media3.common.MediaItem +import androidx.media3.common.MediaMetadata import androidx.media3.common.Player +import androidx.media3.common.Rating import androidx.media3.common.util.UnstableApi import androidx.media3.session.CommandButton import androidx.media3.session.LibraryResult +import androidx.media3.session.MediaConstants import androidx.media3.session.MediaLibraryService import androidx.media3.session.MediaSession import androidx.media3.session.SessionCommand +import androidx.media3.session.SessionError import androidx.media3.session.SessionResult +import com.cappielloantonio.tempo.App import com.cappielloantonio.tempo.R import com.cappielloantonio.tempo.repository.AutomotiveRepository +import com.cappielloantonio.tempo.subsonic.base.ApiResponse +import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_HEART_LOADING +import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_HEART_OFF +import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_HEART_ON +import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL +import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF +import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE +import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF +import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON import com.google.common.collect.ImmutableList +import com.cappielloantonio.tempo.util.Preferences import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.ListenableFuture +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response open class MediaLibrarySessionCallback( context: Context, @@ -28,82 +49,245 @@ open class MediaLibrarySessionCallback( MediaBrowserTree.initialize(automotiveRepository) } - private val shuffleCommandButtons: List = listOf( - CommandButton.Builder() - .setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description)) - .setSessionCommand( - SessionCommand( - CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON, Bundle.EMPTY - ) - ).setIconResId(R.drawable.exo_icon_shuffle_off).build(), + private val customCommandToggleShuffleModeOn = CommandButton.Builder() + .setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description)) + .setSessionCommand( + SessionCommand( + CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON, Bundle.EMPTY + ) + ).setIconResId(R.drawable.exo_icon_shuffle_off).build() - CommandButton.Builder() - .setDisplayName(context.getString(R.string.exo_controls_shuffle_off_description)) - .setSessionCommand( - SessionCommand( - CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF, Bundle.EMPTY - ) - ).setIconResId(R.drawable.exo_icon_shuffle_on).build() + private val customCommandToggleShuffleModeOff = CommandButton.Builder() + .setDisplayName(context.getString(R.string.exo_controls_shuffle_off_description)) + .setSessionCommand( + SessionCommand( + CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF, Bundle.EMPTY + ) + ).setIconResId(R.drawable.exo_icon_shuffle_on).build() + + private val customCommandToggleRepeatModeOff = CommandButton.Builder() + .setDisplayName(context.getString(R.string.exo_controls_repeat_off_description)) + .setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, Bundle.EMPTY)) + .setIconResId(R.drawable.exo_icon_repeat_off) + .build() + + private val customCommandToggleRepeatModeOne = CommandButton.Builder() + .setDisplayName(context.getString(R.string.exo_controls_repeat_one_description)) + .setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE, Bundle.EMPTY)) + .setIconResId(R.drawable.exo_icon_repeat_one) + .build() + + private val customCommandToggleRepeatModeAll = CommandButton.Builder() + .setDisplayName(context.getString(R.string.exo_controls_repeat_all_description)) + .setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, Bundle.EMPTY)) + .setIconResId(R.drawable.exo_icon_repeat_all) + .build() + + private val customCommandToggleHeartOn = CommandButton.Builder() + .setDisplayName(context.getString(R.string.exo_controls_heart_on_description)) + .setSessionCommand( + SessionCommand( + CUSTOM_COMMAND_TOGGLE_HEART_ON, Bundle.EMPTY + ) + ) + .setIconResId(R.drawable.ic_favorite) + .build() + + private val customCommandToggleHeartOff = CommandButton.Builder() + .setDisplayName(context.getString(R.string.exo_controls_heart_off_description)) + .setSessionCommand( + SessionCommand(CUSTOM_COMMAND_TOGGLE_HEART_OFF, Bundle.EMPTY) + ) + .setIconResId(R.drawable.ic_favorites_outlined) + .build() + + // Fake Command while waiting for like update command + private val customCommandToggleHeartLoading = CommandButton.Builder() + .setDisplayName(context.getString(R.string.cast_expanded_controller_loading)) + .setSessionCommand( + SessionCommand(CUSTOM_COMMAND_TOGGLE_HEART_LOADING, Bundle.EMPTY) + ) + .setIconResId(R.drawable.ic_bookmark_sync) + .build() + + private val customLayoutCommandButtons = listOf( + customCommandToggleShuffleModeOn, + customCommandToggleShuffleModeOff, + customCommandToggleRepeatModeOff, + customCommandToggleRepeatModeOne, + customCommandToggleRepeatModeAll, + customCommandToggleHeartOn, + customCommandToggleHeartOff, + customCommandToggleHeartLoading, ) - private val repeatCommandButtons: List = listOf( - CommandButton.Builder() - .setDisplayName(context.getString(R.string.exo_controls_repeat_off_description)) - .setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, Bundle.EMPTY)) - .setIconResId(R.drawable.exo_icon_repeat_off) - .build(), - CommandButton.Builder() - .setDisplayName(context.getString(R.string.exo_controls_repeat_one_description)) - .setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE, Bundle.EMPTY)) - .setIconResId(R.drawable.exo_icon_repeat_one) - .build(), - CommandButton.Builder() - .setDisplayName(context.getString(R.string.exo_controls_repeat_all_description)) - .setSessionCommand(SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, Bundle.EMPTY)) - .setIconResId(R.drawable.exo_icon_repeat_all) - .build() - ) - - private val customLayoutCommandButtons: List = - shuffleCommandButtons + repeatCommandButtons - @OptIn(UnstableApi::class) val mediaNotificationSessionCommands = MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon() .also { builder -> - (shuffleCommandButtons + repeatCommandButtons).forEach { commandButton -> + customLayoutCommandButtons.forEach { commandButton -> commandButton.sessionCommand?.let { builder.add(it) } } }.build() - fun buildCustomLayout(player: Player): ImmutableList { - val shuffle = shuffleCommandButtons[if (player.shuffleModeEnabled) 1 else 0] - val repeat = when (player.repeatMode) { - Player.REPEAT_MODE_ONE -> repeatCommandButtons[1] - Player.REPEAT_MODE_ALL -> repeatCommandButtons[2] - else -> repeatCommandButtons[0] - } - return ImmutableList.of(shuffle, repeat) - } - @OptIn(UnstableApi::class) override fun onConnect( session: MediaSession, controller: MediaSession.ControllerInfo ): MediaSession.ConnectionResult { + session.player.addListener(object : Player.Listener { + override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) { + updateMediaNotificationCustomLayout(session) + } + + override fun onRepeatModeChanged(repeatMode: Int) { + updateMediaNotificationCustomLayout(session) + } + + override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) { + updateMediaNotificationCustomLayout(session) + } + + override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { + updateMediaNotificationCustomLayout(session) + } + }) + + // FIXME: I'm not sure this if is required anymore if (session.isMediaNotificationController(controller) || session.isAutomotiveController( controller ) || session.isAutoCompanionController(controller) ) { - val customLayout = buildCustomLayout(session.player) - return MediaSession.ConnectionResult.AcceptedResultBuilder(session) .setAvailableSessionCommands(mediaNotificationSessionCommands) - .setCustomLayout(customLayout).build() + .setCustomLayout(buildCustomLayout(session.player)) + .build() } return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build() } + // Update the mediaNotification after some changes + @OptIn(UnstableApi::class) + private fun updateMediaNotificationCustomLayout( + session: MediaSession, + isRatingPending: Boolean = false + ) { + session.setCustomLayout( + session.mediaNotificationControllerInfo!!, + buildCustomLayout(session.player, isRatingPending) + ) + } + + private fun buildCustomLayout(player: Player, isRatingPending: Boolean = false): ImmutableList { + val customLayout = mutableListOf() + + val showShuffle = Preferences.showShuffleInsteadOfHeart() + + if (!showShuffle) { + if (player.currentMediaItem != null && !isRatingPending) { + // Heart button + if ((player.mediaMetadata.userRating as HeartRating?)?.isHeart == true) { + customLayout.add(customCommandToggleHeartOff) + } else { + customLayout.add(customCommandToggleHeartOn) + } + } + } else { + customLayout.add( + if (player.shuffleModeEnabled) customCommandToggleShuffleModeOff else customCommandToggleShuffleModeOn + ) + } + + // Add repeat button + val repeatButton = when (player.repeatMode) { + Player.REPEAT_MODE_ONE -> customCommandToggleRepeatModeOne + Player.REPEAT_MODE_ALL -> customCommandToggleRepeatModeAll + else -> customCommandToggleRepeatModeOff + } + + customLayout.add(repeatButton) + return ImmutableList.copyOf(customLayout) + } + + // Setting rating without a mediaId will set the currently listened mediaId + override fun onSetRating( + session: MediaSession, + controller: MediaSession.ControllerInfo, + rating: Rating + ): ListenableFuture { + return onSetRating(session, controller, session.player.currentMediaItem!!.mediaId, rating) + } + + override fun onSetRating( + session: MediaSession, + controller: MediaSession.ControllerInfo, + mediaId: String, + rating: Rating + ): ListenableFuture { + val isStaring = (rating as HeartRating).isHeart + + val networkCall = if (isStaring) + App.getSubsonicClientInstance(false) + .mediaAnnotationClient + .star(mediaId, null, null) + else + App.getSubsonicClientInstance(false) + .mediaAnnotationClient + .unstar(mediaId, null, null) + + return CallbackToFutureAdapter.getFuture { completer -> + networkCall.enqueue(object : Callback { + @OptIn(UnstableApi::class) + override fun onResponse( + call: Call, + response: Response + ) { + if (response.isSuccessful) { + + // Search if the media item in the player should be updated + for (i in 0 until session.player.mediaItemCount) { + val mediaItem = session.player.getMediaItemAt(i) + if (mediaItem.mediaId == mediaId) { + val newMetadata = mediaItem.mediaMetadata.buildUpon() + .setUserRating(HeartRating(isStaring)).build() + session.player.replaceMediaItem( + i, + mediaItem.buildUpon().setMediaMetadata(newMetadata).build() + ) + } + } + + updateMediaNotificationCustomLayout(session) + completer.set(SessionResult(SessionResult.RESULT_SUCCESS)) + } else { + updateMediaNotificationCustomLayout(session) + completer.set( + SessionResult( + SessionError( + response.code(), + response.message() + ) + ) + ) + } + } + + @OptIn(UnstableApi::class) + override fun onFailure(call: Call, t: Throwable) { + updateMediaNotificationCustomLayout(session) + completer.set( + SessionResult( + SessionError( + SessionError.ERROR_UNKNOWN, + "An error as occurred" + ) + ) + ) + } + }) + } + } + @OptIn(UnstableApi::class) override fun onCustomCommand( session: MediaSession, @@ -111,9 +295,23 @@ open class MediaLibrarySessionCallback( customCommand: SessionCommand, args: Bundle ): ListenableFuture { + + val mediaItemId = args.getString( + MediaConstants.EXTRA_KEY_MEDIA_ID, + session.player.currentMediaItem?.mediaId + ) + when (customCommand.customAction) { - CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> session.player.shuffleModeEnabled = true - CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> session.player.shuffleModeEnabled = false + CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> { + session.player.shuffleModeEnabled = true + updateMediaNotificationCustomLayout(session) + return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) + } + CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> { + session.player.shuffleModeEnabled = false + updateMediaNotificationCustomLayout(session) + return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) + } CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> { @@ -123,16 +321,31 @@ open class MediaLibrarySessionCallback( else -> Player.REPEAT_MODE_OFF } session.player.repeatMode = nextMode + updateMediaNotificationCustomLayout(session) + return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) } - else -> return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED)) + CUSTOM_COMMAND_TOGGLE_HEART_ON, + CUSTOM_COMMAND_TOGGLE_HEART_OFF -> { + val currentRating = session.player.mediaMetadata.userRating as? HeartRating + val isCurrentlyLiked = currentRating?.isHeart ?: false + + val newLikedState = !isCurrentlyLiked + + updateMediaNotificationCustomLayout( + session, + isRatingPending = true // Show loading state + ) + return onSetRating(session, controller, HeartRating(newLikedState)) + } + else -> return Futures.immediateFuture( + SessionResult( + SessionError( + SessionError.ERROR_NOT_SUPPORTED, + customCommand.customAction + ) + ) + ) } - - session.setCustomLayout( - session.mediaNotificationControllerInfo!!, - buildCustomLayout(session.player) - ) - - return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS)) } override fun onGetLibraryRoot( @@ -186,17 +399,4 @@ open class MediaLibrarySessionCallback( ): ListenableFuture>> { return MediaBrowserTree.search(query) } - - companion object { - private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON = - "android.media3.session.demo.SHUFFLE_ON" - private const val CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF = - "android.media3.session.demo.SHUFFLE_OFF" - private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF = - "android.media3.session.demo.REPEAT_OFF" - private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE = - "android.media3.session.demo.REPEAT_ONE" - private const val CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL = - "android.media3.session.demo.REPEAT_ALL" - } } \ No newline at end of file diff --git a/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaService.kt b/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaService.kt index a8b17ef6..963daa32 100644 --- a/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaService.kt +++ b/app/src/tempo/java/com/cappielloantonio/tempo/service/MediaService.kt @@ -219,16 +219,10 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener { override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) { Preferences.setShuffleModeEnabled(shuffleModeEnabled) - mediaLibrarySession.setCustomLayout( - librarySessionCallback.buildCustomLayout(player) - ) } override fun onRepeatModeChanged(repeatMode: Int) { Preferences.setRepeatMode(repeatMode) - mediaLibrarySession.setCustomLayout( - librarySessionCallback.buildCustomLayout(player) - ) } }) }