funkwhale-app-android/app/src/main/java/audio/funkwhale/ffa/playback/MediaControlsManager.kt

128 lines
4.0 KiB
Kotlin
Raw Normal View History

package audio.funkwhale.ffa.playback
2019-08-19 16:50:33 +02:00
import android.app.Notification
import android.app.PendingIntent
2022-12-06 09:37:20 +01:00
import android.app.PendingIntent.FLAG_IMMUTABLE
2019-08-19 16:50:33 +02:00
import android.app.Service
import android.content.Intent
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
2019-08-19 16:50:33 +02:00
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.media.app.NotificationCompat.MediaStyle
import androidx.media.session.MediaButtonReceiver
import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.activities.MainActivity
import audio.funkwhale.ffa.model.Track
2021-09-09 09:56:15 +02:00
import audio.funkwhale.ffa.utils.AppContext
import audio.funkwhale.ffa.utils.CoverArt
import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.Default
2019-08-19 16:50:33 +02:00
import kotlinx.coroutines.launch
import org.koin.java.KoinJavaComponent.inject
2019-08-19 16:50:33 +02:00
2022-12-06 09:37:20 +01:00
class MediaControlsManager(
val context: Service,
private val scope: CoroutineScope,
private val mediaSession: MediaSessionCompat
) {
2019-08-19 16:50:33 +02:00
companion object {
const val NOTIFICATION_ACTION_OPEN_QUEUE = 0
}
private val ffaMediaSession: MediaSession by inject(MediaSession::class.java)
2019-10-21 11:51:32 +02:00
private var notification: Notification? = null
2019-08-19 16:50:33 +02:00
fun updateNotification(track: Track?, playing: Boolean) {
if (notification == null && !playing) return
track?.let {
val stateIcon = when (playing) {
true -> R.drawable.pause
false -> R.drawable.play
}
scope.launch(Default) {
2022-12-06 09:37:20 +01:00
val openIntent = Intent(context, MainActivity::class.java).apply {
action = NOTIFICATION_ACTION_OPEN_QUEUE.toString()
}
val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, FLAG_IMMUTABLE)
2019-08-19 16:50:33 +02:00
2020-08-08 14:51:39 +02:00
val coverUrl = maybeNormalizeUrl(track.album?.cover())
2019-08-19 16:50:33 +02:00
notification = NotificationCompat.Builder(
context,
AppContext.NOTIFICATION_CHANNEL_MEDIA_CONTROL
)
.setShowWhen(false)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
2019-08-19 16:50:33 +02:00
.setStyle(
MediaStyle()
.setMediaSession(mediaSession.sessionToken)
.setShowActionsInCompactView(0, 1, 2)
)
.setSmallIcon(R.drawable.funkwhaleshape)
2019-10-22 21:56:33 +02:00
.run {
coverUrl?.let {
try {
setLargeIcon(CoverArt.requestCreator(coverUrl).get())
} catch (_: Exception) {
}
return@run this
}
this
2019-10-22 21:56:33 +02:00
}
2019-08-19 16:50:33 +02:00
.setContentTitle(track.title)
.setContentText(track.artist.name)
.setContentIntent(openPendingIntent)
.setChannelId(AppContext.NOTIFICATION_CHANNEL_MEDIA_CONTROL)
.addAction(
action(
R.drawable.previous, context.getString(R.string.control_previous),
PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
2019-08-19 16:50:33 +02:00
)
)
.addAction(
action(
stateIcon, context.getString(R.string.control_toggle),
PlaybackStateCompat.ACTION_PLAY_PAUSE
2019-08-19 16:50:33 +02:00
)
)
.addAction(
action(
R.drawable.next, context.getString(R.string.control_next),
PlaybackStateCompat.ACTION_SKIP_TO_NEXT
2019-08-19 16:50:33 +02:00
)
)
.build()
notification?.let {
if (playing) {
context.startForeground(AppContext.NOTIFICATION_MEDIA_CONTROL, it)
} else {
2022-12-06 09:37:20 +01:00
NotificationManagerCompat.from(context)
.notify(AppContext.NOTIFICATION_MEDIA_CONTROL, it)
}
2019-08-19 16:50:33 +02:00
}
ffaMediaSession.connector.invalidateMediaSessionMetadata()
2019-08-19 16:50:33 +02:00
}
}
}
fun remove() {
NotificationManagerCompat.from(context).cancel(AppContext.NOTIFICATION_MEDIA_CONTROL)
}
private fun action(icon: Int, title: String, id: Long): NotificationCompat.Action {
return MediaButtonReceiver.buildMediaButtonPendingIntent(context, id).run {
NotificationCompat.Action.Builder(icon, title, this).build()
2019-08-19 16:50:33 +02:00
}
}
}