Merge pull request #8 from le-firehawk/feature-media-window

feat: enhance Android media player notification window
This commit is contained in:
eddyizm 2025-08-02 19:24:57 -07:00 committed by GitHub
commit 5144947f77
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 255 additions and 67 deletions

View file

@ -32,7 +32,8 @@ class MediaService : MediaLibraryService() {
private lateinit var player: ExoPlayer
private lateinit var mediaLibrarySession: MediaLibrarySession
private lateinit var customCommands: List<CommandButton>
private lateinit var shuffleCommands: List<CommandButton>
private lateinit var repeatCommands: List<CommandButton>
private var customLayout = ImmutableList.of<CommandButton>()
@ -41,6 +42,12 @@ class MediaService : MediaLibraryService() {
"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"
}
override fun onCreate() {
@ -72,7 +79,7 @@ class MediaService : MediaLibraryService() {
val connectionResult = super.onConnect(session, controller)
val availableSessionCommands = connectionResult.availableSessionCommands.buildUpon()
customCommands.forEach { commandButton ->
shuffleCommands.forEach { commandButton ->
// TODO: Aggiungere i comandi personalizzati
// commandButton.sessionCommand?.let { availableSessionCommands.add(it) }
}
@ -89,22 +96,40 @@ class MediaService : MediaLibraryService() {
}
}
fun buildCustomLayout(player: Player): ImmutableList<CommandButton> {
val shuffle = shuffleCommands[if (player.shuffleModeEnabled) 1 else 0]
val repeat = when (player.repeatMode) {
Player.REPEAT_MODE_ONE -> repeatCommands[1]
Player.REPEAT_MODE_ALL -> repeatCommands[2]
else -> repeatCommands[0]
}
return ImmutableList.of(shuffle, repeat)
}
override fun onCustomCommand(
session: MediaSession,
controller: ControllerInfo,
customCommand: SessionCommand,
args: Bundle
): ListenableFuture<SessionResult> {
if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) {
player.shuffleModeEnabled = true
customLayout = ImmutableList.of(customCommands[1])
session.setCustomLayout(customLayout)
} else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) {
player.shuffleModeEnabled = false
customLayout = ImmutableList.of(customCommands[0])
session.setCustomLayout(customLayout)
when (customCommand.customAction) {
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON -> player.shuffleModeEnabled = true
CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF -> player.shuffleModeEnabled = false
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF,
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL,
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> {
val nextMode = when (player.repeatMode) {
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ONE
else -> Player.REPEAT_MODE_OFF
}
player.repeatMode = nextMode
}
}
customLayout = librarySessionCallback.buildCustomLayout(player)
session.setCustomLayout(customLayout)
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
}
@ -125,17 +150,28 @@ class MediaService : MediaLibraryService() {
}
private fun initializeCustomCommands() {
customCommands =
listOf(
getShuffleCommandButton(
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON, Bundle.EMPTY)
),
getShuffleCommandButton(
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF, Bundle.EMPTY)
)
shuffleCommands = listOf(
getShuffleCommandButton(
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON, Bundle.EMPTY)
),
getShuffleCommandButton(
SessionCommand(CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF, Bundle.EMPTY)
)
)
customLayout = ImmutableList.of(customCommands[0])
repeatCommands = listOf(
getRepeatCommandButton(
SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_OFF, Bundle.EMPTY)
),
getRepeatCommandButton(
SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE, Bundle.EMPTY)
),
getRepeatCommandButton(
SessionCommand(CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL, Bundle.EMPTY)
)
)
customLayout = ImmutableList.of(shuffleCommands[0], repeatCommands[0])
}
private fun initializePlayer() {
@ -147,6 +183,9 @@ class MediaService : MediaLibraryService() {
.setWakeMode(C.WAKE_MODE_NETWORK)
.setLoadControl(initializeLoadControl())
.build()
player.shuffleModeEnabled = Preferences.isShuffleModeEnabled()
player.repeatMode = Preferences.getRepeatMode()
}
private fun initializeMediaLibrarySession() {
@ -224,6 +263,18 @@ class MediaService : MediaLibraryService() {
}
}
}
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
Preferences.setShuffleModeEnabled(shuffleModeEnabled)
customLayout = librarySessionCallback.buildCustomLayout(player)
mediaLibrarySession.setCustomLayout(customLayout)
}
override fun onRepeatModeChanged(repeatMode: Int) {
Preferences.setRepeatMode(repeatMode)
customLayout = librarySessionCallback.buildCustomLayout(player)
mediaLibrarySession.setCustomLayout(customLayout)
}
})
}
@ -251,6 +302,25 @@ class MediaService : MediaLibraryService() {
.build()
}
@SuppressLint("PrivateResource")
private fun getRepeatCommandButton(sessionCommand: SessionCommand): CommandButton {
val icon = when (sessionCommand.customAction) {
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> R.drawable.exo_icon_repeat_one
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL -> R.drawable.exo_icon_repeat_all
else -> R.drawable.exo_icon_repeat_off
}
val description = when (sessionCommand.customAction) {
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> R.string.exo_controls_repeat_one_description
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL -> R.string.exo_controls_repeat_all_description
else -> R.string.exo_controls_repeat_off_description
}
return CommandButton.Builder()
.setDisplayName(getString(description))
.setSessionCommand(sessionCommand)
.setIconResId(icon)
.build()
}
private fun ignoreFuture(customLayout: ListenableFuture<SessionResult>) {
/* Do nothing. */
}

View file

@ -4,6 +4,7 @@ import android.content.Context
import android.os.Bundle
import androidx.annotation.OptIn
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.session.CommandButton
import androidx.media3.session.LibraryResult
@ -27,7 +28,7 @@ open class MediaLibrarySessionCallback(
MediaBrowserTree.initialize(automotiveRepository)
}
private val customLayoutCommandButtons: List<CommandButton> = listOf(
private val shuffleCommandButtons: List<CommandButton> = listOf(
CommandButton.Builder()
.setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description))
.setSessionCommand(
@ -45,15 +46,46 @@ open class MediaLibrarySessionCallback(
).setIconResId(R.drawable.exo_icon_shuffle_on).build()
)
private val repeatCommandButtons: List<CommandButton> = 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<CommandButton> =
shuffleCommandButtons + repeatCommandButtons
@OptIn(UnstableApi::class)
val mediaNotificationSessionCommands =
MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
.also { builder ->
customLayoutCommandButtons.forEach { commandButton ->
(shuffleCommandButtons + repeatCommandButtons).forEach { commandButton ->
commandButton.sessionCommand?.let { builder.add(it) }
}
}.build()
fun buildCustomLayout(player: Player): ImmutableList<CommandButton> {
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
@ -62,12 +94,11 @@ open class MediaLibrarySessionCallback(
controller
) || session.isAutoCompanionController(controller)
) {
val customLayout =
customLayoutCommandButtons[if (session.player.shuffleModeEnabled) 1 else 0]
val customLayout = buildCustomLayout(session.player)
return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
.setAvailableSessionCommands(mediaNotificationSessionCommands)
.setCustomLayout(ImmutableList.of(customLayout)).build()
.setCustomLayout(customLayout).build()
}
return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build()
@ -80,25 +111,28 @@ open class MediaLibrarySessionCallback(
customCommand: SessionCommand,
args: Bundle
): ListenableFuture<SessionResult> {
if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) {
session.player.shuffleModeEnabled = true
session.setCustomLayout(
session.mediaNotificationControllerInfo!!,
ImmutableList.of(customLayoutCommandButtons[1])
)
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
} else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) {
session.player.shuffleModeEnabled = false
session.setCustomLayout(
session.mediaNotificationControllerInfo!!,
ImmutableList.of(customLayoutCommandButtons[0])
)
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
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_REPEAT_MODE_OFF,
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL,
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> {
val nextMode = when (session.player.repeatMode) {
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ONE
else -> Player.REPEAT_MODE_OFF
}
session.player.repeatMode = nextMode
}
else -> return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
}
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
session.setCustomLayout(
session.mediaNotificationControllerInfo!!,
buildCustomLayout(session.player)
)
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
}
override fun onGetLibraryRoot(
@ -158,5 +192,11 @@ open class MediaLibrarySessionCallback(
"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"
}
}

View file

@ -33,6 +33,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
private lateinit var player: ExoPlayer
private lateinit var castPlayer: CastPlayer
private lateinit var mediaLibrarySession: MediaLibrarySession
private lateinit var librarySessionCallback: MediaLibrarySessionCallback
override fun onCreate() {
super.onCreate()
@ -79,6 +80,9 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
.setWakeMode(C.WAKE_MODE_NETWORK)
.setLoadControl(initializeLoadControl())
.build()
player.shuffleModeEnabled = Preferences.isShuffleModeEnabled()
player.repeatMode = Preferences.getRepeatMode()
}
private fun initializeCastPlayer() {
@ -97,13 +101,14 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)
}
librarySessionCallback = createLibrarySessionCallback()
mediaLibrarySession =
MediaLibrarySession.Builder(this, player, createLibrarySessionCallback())
MediaLibrarySession.Builder(this, player, librarySessionCallback)
.setSessionActivity(sessionActivityPendingIntent)
.build()
}
private fun createLibrarySessionCallback(): MediaLibrarySession.Callback {
private fun createLibrarySessionCallback(): MediaLibrarySessionCallback {
return MediaLibrarySessionCallback(this, automotiveRepository)
}
@ -166,6 +171,20 @@ 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)
)
}
})
}

View file

@ -4,6 +4,7 @@ import android.content.Context
import android.os.Bundle
import androidx.annotation.OptIn
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.session.CommandButton
import androidx.media3.session.LibraryResult
@ -27,7 +28,7 @@ open class MediaLibrarySessionCallback(
MediaBrowserTree.initialize(automotiveRepository)
}
private val customLayoutCommandButtons: List<CommandButton> = listOf(
private val shuffleCommandButtons: List<CommandButton> = listOf(
CommandButton.Builder()
.setDisplayName(context.getString(R.string.exo_controls_shuffle_on_description))
.setSessionCommand(
@ -45,15 +46,46 @@ open class MediaLibrarySessionCallback(
).setIconResId(R.drawable.exo_icon_shuffle_on).build()
)
private val repeatCommandButtons: List<CommandButton> = 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<CommandButton> =
shuffleCommandButtons + repeatCommandButtons
@OptIn(UnstableApi::class)
val mediaNotificationSessionCommands =
MediaSession.ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon()
.also { builder ->
customLayoutCommandButtons.forEach { commandButton ->
(shuffleCommandButtons + repeatCommandButtons).forEach { commandButton ->
commandButton.sessionCommand?.let { builder.add(it) }
}
}.build()
fun buildCustomLayout(player: Player): ImmutableList<CommandButton> {
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
@ -62,12 +94,11 @@ open class MediaLibrarySessionCallback(
controller
) || session.isAutoCompanionController(controller)
) {
val customLayout =
customLayoutCommandButtons[if (session.player.shuffleModeEnabled) 1 else 0]
val customLayout = buildCustomLayout(session.player)
return MediaSession.ConnectionResult.AcceptedResultBuilder(session)
.setAvailableSessionCommands(mediaNotificationSessionCommands)
.setCustomLayout(ImmutableList.of(customLayout)).build()
.setCustomLayout(customLayout).build()
}
return MediaSession.ConnectionResult.AcceptedResultBuilder(session).build()
@ -80,25 +111,28 @@ open class MediaLibrarySessionCallback(
customCommand: SessionCommand,
args: Bundle
): ListenableFuture<SessionResult> {
if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON == customCommand.customAction) {
session.player.shuffleModeEnabled = true
session.setCustomLayout(
session.mediaNotificationControllerInfo!!,
ImmutableList.of(customLayoutCommandButtons[1])
)
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
} else if (CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF == customCommand.customAction) {
session.player.shuffleModeEnabled = false
session.setCustomLayout(
session.mediaNotificationControllerInfo!!,
ImmutableList.of(customLayoutCommandButtons[0])
)
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
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_REPEAT_MODE_OFF,
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ALL,
CUSTOM_COMMAND_TOGGLE_REPEAT_MODE_ONE -> {
val nextMode = when (session.player.repeatMode) {
Player.REPEAT_MODE_ONE -> Player.REPEAT_MODE_ALL
Player.REPEAT_MODE_OFF -> Player.REPEAT_MODE_ONE
else -> Player.REPEAT_MODE_OFF
}
session.player.repeatMode = nextMode
}
else -> return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
}
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_ERROR_NOT_SUPPORTED))
session.setCustomLayout(
session.mediaNotificationControllerInfo!!,
buildCustomLayout(session.player)
)
return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
}
override fun onGetLibraryRoot(
@ -158,5 +192,11 @@ open class MediaLibrarySessionCallback(
"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"
}
}

View file

@ -33,6 +33,7 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
private lateinit var player: ExoPlayer
private lateinit var castPlayer: CastPlayer
private lateinit var mediaLibrarySession: MediaLibrarySession
private lateinit var librarySessionCallback: MediaLibrarySessionCallback
override fun onCreate() {
super.onCreate()
@ -79,6 +80,9 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
.setWakeMode(C.WAKE_MODE_NETWORK)
.setLoadControl(initializeLoadControl())
.build()
player.shuffleModeEnabled = Preferences.isShuffleModeEnabled()
player.repeatMode = Preferences.getRepeatMode()
}
private fun initializeCastPlayer() {
@ -97,13 +101,14 @@ class MediaService : MediaLibraryService(), SessionAvailabilityListener {
getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)
}
librarySessionCallback = createLibrarySessionCallback()
mediaLibrarySession =
MediaLibrarySession.Builder(this, player, createLibrarySessionCallback())
MediaLibrarySession.Builder(this, player, librarySessionCallback)
.setSessionActivity(sessionActivityPendingIntent)
.build()
}
private fun createLibrarySessionCallback(): MediaLibrarySession.Callback {
private fun createLibrarySessionCallback(): MediaLibrarySessionCallback {
return MediaLibrarySessionCallback(this, automotiveRepository)
}
@ -166,6 +171,20 @@ 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)
)
}
})
}