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

117 lines
3.9 KiB
Kotlin

package audio.funkwhale.ffa.playback
import android.app.Notification
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
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.FFA
import audio.funkwhale.ffa.R
import audio.funkwhale.ffa.activities.MainActivity
import audio.funkwhale.ffa.utils.AppContext
import audio.funkwhale.ffa.utils.Track
import audio.funkwhale.ffa.utils.maybeNormalizeUrl
import com.squareup.picasso.Picasso
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.Default
import kotlinx.coroutines.launch
class MediaControlsManager(val context: Service, private val scope: CoroutineScope, private val mediaSession: MediaSessionCompat) {
companion object {
const val NOTIFICATION_ACTION_OPEN_QUEUE = 0
}
private var notification: Notification? = null
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) {
val openIntent = Intent(context, MainActivity::class.java).apply { action = NOTIFICATION_ACTION_OPEN_QUEUE.toString() }
val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, 0)
val coverUrl = maybeNormalizeUrl(track.album?.cover())
notification = NotificationCompat.Builder(
context,
AppContext.NOTIFICATION_CHANNEL_MEDIA_CONTROL
)
.setShowWhen(false)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setStyle(
MediaStyle()
.setMediaSession(mediaSession.sessionToken)
.setShowActionsInCompactView(0, 1, 2)
)
.setSmallIcon(R.drawable.funkwhaleshape)
.run {
coverUrl?.let {
try {
setLargeIcon(Picasso.get().load(coverUrl).get())
} catch (_: Exception) {
}
return@run this
}
this
}
.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
)
)
.addAction(
action(
stateIcon, context.getString(R.string.control_toggle),
PlaybackStateCompat.ACTION_PLAY_PAUSE
)
)
.addAction(
action(
R.drawable.next, context.getString(R.string.control_next),
PlaybackStateCompat.ACTION_SKIP_TO_NEXT
)
)
.build()
notification?.let {
if (playing) {
context.startForeground(AppContext.NOTIFICATION_MEDIA_CONTROL, it)
} else {
NotificationManagerCompat.from(context).notify(AppContext.NOTIFICATION_MEDIA_CONTROL, it)
}
}
audio.funkwhale.ffa.FFA.get().mediaSession.connector.invalidateMediaSessionMetadata()
}
}
}
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()
}
}
}