More potential fixes for the MediaSession issue. Ugh. Wish there were

reliable repro steps.
This commit is contained in:
casey langen 2019-02-17 13:05:45 -08:00
parent 9085ee3020
commit d28a85dc4f
3 changed files with 98 additions and 84 deletions

View File

@ -122,7 +122,7 @@ class SystemService : Service() {
if (wakeLock == null) {
wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "StreamingPlaybackService:")
PowerManager.PARTIAL_WAKE_LOCK, "$SESSION_TAG:")
wakeLock?.let {
it.setReferenceCounted(false)
@ -159,19 +159,24 @@ class SystemService : Service() {
}
private fun checkInitMediaSession() {
val receiver = ComponentName(packageName, MediaButtonReceiver::class.java.name)
if (mediaSession == null || mediaSession?.isActive != true) {
deinitMediaSession()
mediaSession = MediaSessionCompat(this, "musikdroid.SystemService", receiver, null)
val receiver = ComponentName(
packageName, MediaButtonReceiver::class.java.name)
mediaSession?.setFlags(
mediaSession = MediaSessionCompat(
this, SESSION_TAG, receiver, null)
.apply {
this.setFlags(
MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS)
mediaSession?.setCallback(mediaSessionCallback)
this.setCallback(mediaSessionCallback)
this.isActive = true
}
updateMediaSessionPlaybackState()
mediaSession?.isActive = true
}
}
private fun deinitMediaSession() {
@ -184,14 +189,13 @@ class SystemService : Service() {
registerReceiver(headsetUnpluggedReceiver, filter)
}
private fun unregisterReceivers() {
private fun unregisterReceivers() =
try {
unregisterReceiver(headsetUnpluggedReceiver)
}
catch (ex: Exception) {
Log.e(TAG, "unable to unregister headset (un)plugged BroadcastReceiver")
}
}
private fun updateMediaSessionPlaybackState() {
var mediaSessionState = PlaybackStateCompat.STATE_STOPPED
@ -199,31 +203,33 @@ class SystemService : Service() {
var duration = 0
var playing: ITrack? = null
if (playback != null) {
when (playback?.state) {
playback?.let {
when (it.state) {
PlaybackState.Playing -> mediaSessionState = PlaybackStateCompat.STATE_PLAYING
PlaybackState.Buffering -> mediaSessionState = PlaybackStateCompat.STATE_BUFFERING
PlaybackState.Paused -> mediaSessionState = PlaybackStateCompat.STATE_PAUSED
else -> { }
}
playing = playback!!.playingTrack
duration = ((playback?.duration ?: 0.0) * 1000).toInt()
playing = it.playingTrack
duration = (it.duration * 1000).toInt()
}
mediaSession?.let {
updateMediaSession(playing, duration)
updateNotification(playing, mediaSessionState)
mediaSession?.setPlaybackState(PlaybackStateCompat.Builder()
it.setPlaybackState(PlaybackStateCompat.Builder()
.setState(mediaSessionState, 0, 0f)
.setActions(MEDIA_SESSION_ACTIONS)
.build())
}
}
private fun downloadAlbumArtIfNecessary(track: ITrack, duration: Int) {
if (!albumArt.same(track) || (albumArt.request == null && albumArt.bitmap == null)) {
if (track.artist.isNotBlank() && track.album.isNotBlank()) {
Log.d(TAG, "download")
Log.d(TAG, "downloading album art")
val url = getAlbumArtUrl(track, Size.Mega)
@ -321,13 +327,11 @@ class SystemService : Service() {
if (state == PlaybackStateCompat.STATE_PAUSED) {
notification.addAction(action(
android.R.drawable.ic_media_play,
getString(R.string.button_play),
ACTION_NOTIFICATION_PLAY))
getString(R.string.button_play), ACTION_NOTIFICATION_PLAY))
notification.addAction(action(
android.R.drawable.ic_menu_close_clear_cancel,
getString(R.string.button_close),
ACTION_NOTIFICATION_STOP))
getString(R.string.button_close), ACTION_NOTIFICATION_STOP))
notification.setStyle(MediaStyle()
.setShowActionsInCompactView(0, 1)
@ -336,18 +340,15 @@ class SystemService : Service() {
else {
notification.addAction(action(
android.R.drawable.ic_media_previous,
getString(R.string.button_prev),
ACTION_NOTIFICATION_PREV))
getString(R.string.button_prev), ACTION_NOTIFICATION_PREV))
notification.addAction(action(
android.R.drawable.ic_media_pause,
getString(R.string.button_pause),
ACTION_NOTIFICATION_PAUSE))
getString(R.string.button_pause), ACTION_NOTIFICATION_PAUSE))
notification.addAction(action(
android.R.drawable.ic_media_next,
getString(R.string.button_next),
ACTION_NOTIFICATION_NEXT))
getString(R.string.button_next), ACTION_NOTIFICATION_NEXT))
notification.setStyle(MediaStyle()
.setShowActionsInCompactView(0, 1, 2)
@ -366,44 +367,49 @@ class SystemService : Service() {
}
private fun handlePlaybackAction(action: String?): Boolean {
if (this.playback != null && Strings.notEmpty(action)) {
this.playback?.let {
if (Strings.notEmpty(action)) {
when (action) {
ACTION_NOTIFICATION_NEXT -> {
this.playback?.next()
it.next()
return true
}
ACTION_NOTIFICATION_PAUSE -> {
this.playback?.pause()
it.pause()
return true
}
ACTION_NOTIFICATION_PLAY -> {
this.playback?.resume()
it.resume()
return true
}
ACTION_NOTIFICATION_PREV -> {
this.playback?.prev()
it.prev()
return true
}
ACTION_NOTIFICATION_STOP -> {
this.playback?.stop()
it.stop()
shutdown()
return true
}
}
}
}
return false
}
private val headsetHookDebouncer = object : Debouncer<Void>(HEADSET_HOOK_DEBOUNCE_MS) {
override fun onDebounced(last: Void?) {
playback?.let {
when (headsetHookPressCount) {
1 -> playback?.pauseOrResume()
2 -> playback?.next()
3 -> playback?.prev()
1 -> it.pauseOrResume()
2 -> it.next()
3 -> it.prev()
}
}
headsetHookPressCount = 0
}
@ -455,11 +461,11 @@ class SystemService : Service() {
}
override fun onPlay() {
if (playback?.queueCount == 0) {
playback?.playAll()
playback?.let {
when (it.queueCount == 0) {
true -> it.playAll()
false -> it.resume()
}
else {
playback?.resume()
}
}
@ -547,6 +553,7 @@ class SystemService : Service() {
companion object {
private const val TAG = "SystemService"
private const val SESSION_TAG = "musikdroid.SystemService"
private const val NOTIFICATION_ID = 0xdeadbeef.toInt()
private const val NOTIFICATION_CHANNEL = "musikdroid"
private const val HEADSET_HOOK_DEBOUNCE_MS = 500L

View File

@ -245,7 +245,11 @@ class MainMetadataView : FrameLayout {
.load(albumArtUrl)
.apply(BITMAP_OPTIONS)
.listener(object: RequestListener<Drawable> {
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
override fun onResourceReady(resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean): Boolean {
if (!paused) {
preloadNextImage()
}
@ -254,7 +258,10 @@ class MainMetadataView : FrameLayout {
return false
}
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
override fun onLoadFailed(e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean): Boolean {
setMetadataDisplayMode(DisplayMode.NoArtwork)
loadedAlbumArtUrl = null
return false