From 2a25db943342e45b8c1e63a17eecc83db37336c3 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:45:50 +0100 Subject: [PATCH] Music service: Expose supported actions --- .../de/mm20/launcher2/music/MusicService.kt | 26 +++++++++++++---- .../mm20/launcher2/music/SupportedActions.kt | 28 +++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 services/music/src/main/java/de/mm20/launcher2/music/SupportedActions.kt diff --git a/services/music/src/main/java/de/mm20/launcher2/music/MusicService.kt b/services/music/src/main/java/de/mm20/launcher2/music/MusicService.kt index 0fb80bfe..d575184a 100644 --- a/services/music/src/main/java/de/mm20/launcher2/music/MusicService.kt +++ b/services/music/src/main/java/de/mm20/launcher2/music/MusicService.kt @@ -10,12 +10,12 @@ import android.media.AudioManager import android.media.MediaMetadata import android.media.session.MediaController import android.media.session.MediaSession +import android.media.session.PlaybackState.CustomAction import android.net.Uri import android.os.Handler import android.os.Looper import android.os.SystemClock import android.service.notification.StatusBarNotification -import android.util.Log import android.view.KeyEvent import androidx.core.app.NotificationCompat import androidx.core.content.edit @@ -57,6 +57,8 @@ interface MusicService { val position: Flow val duration: Flow + val supportedActions: Flow + val lastPlayerPackage: String? fun next() @@ -203,7 +205,12 @@ internal class MusicServiceImpl( send(lastPosition) return@collectLatest } - while(isActive) { + if (state.position < 0 || state.lastPositionUpdateTime == 0L) { + send(null) + lastPosition = null + return@collectLatest + } + while (isActive) { val offset = SystemClock.elapsedRealtime() - state.lastPositionUpdateTime val position = state.position + offset lastPosition = position @@ -356,7 +363,7 @@ internal class MusicServiceImpl( private var lastDuration: Long? = null get() { if (field == null) { - field = preferences.getLong(PREFS_KEY_DURATION, -1).takeIf { it >= 0 } + field = preferences.getLong(PREFS_KEY_DURATION, -1).takeIf { it > 0 } } return field } @@ -373,12 +380,21 @@ internal class MusicServiceImpl( send(lastDuration) return@collectLatest } - val duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION) + val duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION).takeIf { it > 0 } lastDuration = duration - send(duration.takeIf { it > 0 }) + send(duration) } }.shareIn(scope, SharingStarted.WhileSubscribed(), 1) + override val supportedActions: Flow = channelFlow { + currentState.collectLatest { state -> + if (state == null) { + send(SupportedActions()) + return@collectLatest + } + send(SupportedActions(state.actions, state.customActions)) + } + }.shareIn(scope, SharingStarted.WhileSubscribed(), 1) private suspend fun loadBitmapFromUri(uri: Uri, size: Int): Bitmap? { try { diff --git a/services/music/src/main/java/de/mm20/launcher2/music/SupportedActions.kt b/services/music/src/main/java/de/mm20/launcher2/music/SupportedActions.kt new file mode 100644 index 00000000..e32f785a --- /dev/null +++ b/services/music/src/main/java/de/mm20/launcher2/music/SupportedActions.kt @@ -0,0 +1,28 @@ +package de.mm20.launcher2.music + +import android.media.session.PlaybackState +import android.media.session.PlaybackState.CustomAction + +data class SupportedActions( + val stop: Boolean = false, + val skipToNext: Boolean = true, + val skipToPrevious: Boolean = true, + val fastForward: Boolean = false, + val rewind: Boolean = false, + val seekTo: Boolean = false, + val setPlaybackSpeed: Boolean = false, + val setRating: Boolean = false, + val customActions: List = emptyList() +) { + constructor(actions: Long?, customActions: List?) : this( + stop = actions?.and(PlaybackState.ACTION_STOP) == PlaybackState.ACTION_STOP, + skipToNext = actions?.and(PlaybackState.ACTION_SKIP_TO_NEXT) == PlaybackState.ACTION_SKIP_TO_NEXT, + skipToPrevious = actions?.and(PlaybackState.ACTION_SKIP_TO_PREVIOUS) == PlaybackState.ACTION_SKIP_TO_PREVIOUS, + fastForward = actions?.and(PlaybackState.ACTION_FAST_FORWARD) == PlaybackState.ACTION_FAST_FORWARD, + rewind = actions?.and(PlaybackState.ACTION_REWIND) == PlaybackState.ACTION_REWIND, + seekTo = actions?.and(PlaybackState.ACTION_SEEK_TO) == PlaybackState.ACTION_SEEK_TO, + setPlaybackSpeed = actions?.and(PlaybackState.ACTION_SET_PLAYBACK_SPEED) == PlaybackState.ACTION_SET_PLAYBACK_SPEED, + setRating = actions?.and(PlaybackState.ACTION_SET_RATING) == PlaybackState.ACTION_SET_RATING, + customActions = customActions ?: emptyList(), + ) +} \ No newline at end of file