Music service: Expose supported actions

This commit is contained in:
MM20 2023-02-13 14:45:50 +01:00
parent 5c690f7bc8
commit 2a25db9433
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
2 changed files with 49 additions and 5 deletions

View File

@ -10,12 +10,12 @@ import android.media.AudioManager
import android.media.MediaMetadata import android.media.MediaMetadata
import android.media.session.MediaController import android.media.session.MediaController
import android.media.session.MediaSession import android.media.session.MediaSession
import android.media.session.PlaybackState.CustomAction
import android.net.Uri import android.net.Uri
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.os.SystemClock import android.os.SystemClock
import android.service.notification.StatusBarNotification import android.service.notification.StatusBarNotification
import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.content.edit import androidx.core.content.edit
@ -57,6 +57,8 @@ interface MusicService {
val position: Flow<Long?> val position: Flow<Long?>
val duration: Flow<Long?> val duration: Flow<Long?>
val supportedActions: Flow<SupportedActions>
val lastPlayerPackage: String? val lastPlayerPackage: String?
fun next() fun next()
@ -203,7 +205,12 @@ internal class MusicServiceImpl(
send(lastPosition) send(lastPosition)
return@collectLatest 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 offset = SystemClock.elapsedRealtime() - state.lastPositionUpdateTime
val position = state.position + offset val position = state.position + offset
lastPosition = position lastPosition = position
@ -356,7 +363,7 @@ internal class MusicServiceImpl(
private var lastDuration: Long? = null private var lastDuration: Long? = null
get() { get() {
if (field == null) { 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 return field
} }
@ -373,12 +380,21 @@ internal class MusicServiceImpl(
send(lastDuration) send(lastDuration)
return@collectLatest return@collectLatest
} }
val duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION) val duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION).takeIf { it > 0 }
lastDuration = duration lastDuration = duration
send(duration.takeIf { it > 0 }) send(duration)
} }
}.shareIn(scope, SharingStarted.WhileSubscribed(), 1) }.shareIn(scope, SharingStarted.WhileSubscribed(), 1)
override val supportedActions: Flow<SupportedActions> = 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? { private suspend fun loadBitmapFromUri(uri: Uri, size: Int): Bitmap? {
try { try {

View File

@ -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<CustomAction> = emptyList()
) {
constructor(actions: Long?, customActions: List<CustomAction>?) : 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(),
)
}