Fixed ChromeCast crashes

This commit is contained in:
Prathamesh More 2022-06-10 22:58:26 +05:30
parent 9966ddad9d
commit ed6ca486d6
4 changed files with 21 additions and 73 deletions

View file

@ -10,8 +10,7 @@ import com.google.android.gms.cast.MediaStatus
import com.google.android.gms.cast.framework.CastSession import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.media.RemoteMediaClient import com.google.android.gms.cast.framework.media.RemoteMediaClient
class CastPlayer(castSession: CastSession) : Playback, class CastPlayer(castSession: CastSession) : Playback, RemoteMediaClient.Callback() {
RemoteMediaClient.Callback() {
override val isInitialized: Boolean = true override val isInitialized: Boolean = true

View file

@ -203,8 +203,7 @@ class MusicService : MediaBrowserServiceCompat(),
} }
} }
} }
private var queueSaveHandler: QueueSaveHandler? = null
private var queueSaveHandlerThread: HandlerThread? = null
private var queuesRestored = false private var queuesRestored = false
var repeatMode = 0 var repeatMode = 0
@ -277,12 +276,6 @@ class MusicService : MediaBrowserServiceCompat(),
playbackManager.setCallbacks(this) playbackManager.setCallbacks(this)
setupMediaSession() setupMediaSession()
// queue saving needs to run on a separate thread so that it doesn't block the playback handler
// events
queueSaveHandlerThread =
HandlerThread("QueueSaveHandler", Process.THREAD_PRIORITY_BACKGROUND)
queueSaveHandlerThread?.start()
queueSaveHandler = QueueSaveHandler(this, queueSaveHandlerThread!!.looper)
uiThreadHandler = Handler(Looper.getMainLooper()) uiThreadHandler = Handler(Looper.getMainLooper())
registerReceiver(widgetIntentReceiver, IntentFilter(APP_WIDGET_UPDATE)) registerReceiver(widgetIntentReceiver, IntentFilter(APP_WIDGET_UPDATE))
registerReceiver(updateFavoriteReceiver, IntentFilter(FAVORITE_STATE_CHANGED)) registerReceiver(updateFavoriteReceiver, IntentFilter(FAVORITE_STATE_CHANGED))
@ -291,7 +284,7 @@ class MusicService : MediaBrowserServiceCompat(),
notificationManager = getSystemService() notificationManager = getSystemService()
initNotification() initNotification()
mediaStoreObserver = MediaStoreObserver(this, playerHandler!!) mediaStoreObserver = MediaStoreObserver(this, playerHandler!!)
throttledSeekHandler = ThrottledSeekHandler(this, playerHandler!!) throttledSeekHandler = ThrottledSeekHandler(this, Handler(mainLooper))
contentResolver.registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, contentResolver.registerContentObserver(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
true, true,
mediaStoreObserver) mediaStoreObserver)
@ -798,7 +791,7 @@ class MusicService : MediaBrowserServiceCompat(),
// Every chromecast method needs to run on main thread or you are greeted with IllegalStateException // Every chromecast method needs to run on main thread or you are greeted with IllegalStateException
// So it will use Main dispatcher // So it will use Main dispatcher
// And by using Default dispatcher for local playback we are reduce the burden of main thread // And by using Default dispatcher for local playback we are reduce the burden of main thread
serviceScope.launch(if(playbackManager.isLocalPlayback) Default else Main) { serviceScope.launch(if (playbackManager.isLocalPlayback) Default else Main) {
openTrackAndPrepareNextAt(position) { success -> openTrackAndPrepareNextAt(position) { success ->
if (success) { if (success) {
play() play()
@ -953,17 +946,6 @@ class MusicService : MediaBrowserServiceCompat(),
} }
} }
fun saveQueuesImpl() {
MusicPlaybackQueueStore.getInstance(this).saveQueues(playingQueue, originalPlayingQueue)
}
fun saveState() {
saveQueues()
savePosition()
savePositionInTrack()
storage.saveSong(currentSong)
}
@Synchronized @Synchronized
fun seek(millis: Int): Int { fun seek(millis: Int): Int {
return try { return try {
@ -1105,8 +1087,10 @@ class MusicService : MediaBrowserServiceCompat(),
// if we are loading it or it won't be updated in the notification // if we are loading it or it won't be updated in the notification
updateMediaSessionMetaData(::updateMediaSessionPlaybackState) updateMediaSessionMetaData(::updateMediaSessionPlaybackState)
serviceScope.launch(IO) { serviceScope.launch(IO) {
savePosition() withContext(Main) {
savePositionInTrack() savePosition()
savePositionInTrack()
}
val currentSong = currentSong val currentSong = currentSong
HistoryStore.getInstance(this@MusicService).addSongId(currentSong.id) HistoryStore.getInstance(this@MusicService).addSongId(currentSong.id)
if (songPlayCountHelper.shouldBumpPlayCount()) { if (songPlayCountHelper.shouldBumpPlayCount()) {
@ -1114,13 +1098,14 @@ class MusicService : MediaBrowserServiceCompat(),
.bumpPlayCount(songPlayCountHelper.song.id) .bumpPlayCount(songPlayCountHelper.song.id)
} }
songPlayCountHelper.notifySongChanged(currentSong) songPlayCountHelper.notifySongChanged(currentSong)
storage.saveSong(currentSong)
} }
} }
QUEUE_CHANGED -> { QUEUE_CHANGED -> {
mediaSession?.setQueueTitle(getString(R.string.now_playing_queue)) mediaSession?.setQueueTitle(getString(R.string.now_playing_queue))
mediaSession?.setQueue(playingQueue.toMediaSessionQueue()) mediaSession?.setQueue(playingQueue.toMediaSessionQueue())
updateMediaSessionMetaData(::updateMediaSessionPlaybackState) // because playing queue size might have changed updateMediaSessionMetaData(::updateMediaSessionPlaybackState) // because playing queue size might have changed
saveState() saveQueues()
if (playingQueue.size > 0) { if (playingQueue.size > 0) {
prepareNext() prepareNext()
} else { } else {
@ -1198,6 +1183,8 @@ class MusicService : MediaBrowserServiceCompat(),
seek(progress) seek(progress)
if (wasPlaying) { if (wasPlaying) {
play() play()
} else {
pause()
} }
} }
} }
@ -1247,8 +1234,6 @@ class MusicService : MediaBrowserServiceCompat(),
private fun releaseResources() { private fun releaseResources() {
playerHandler?.removeCallbacksAndMessages(null) playerHandler?.removeCallbacksAndMessages(null)
musicPlayerHandlerThread?.quitSafely() musicPlayerHandlerThread?.quitSafely()
queueSaveHandler?.removeCallbacksAndMessages(null)
queueSaveHandlerThread?.quitSafely()
playbackManager.release() playbackManager.release()
mediaSession?.release() mediaSession?.release()
} }
@ -1275,8 +1260,10 @@ class MusicService : MediaBrowserServiceCompat(),
} }
private fun saveQueues() { private fun saveQueues() {
queueSaveHandler?.removeMessages(SAVE_QUEUES) serviceScope.launch(IO) {
queueSaveHandler?.sendEmptyMessage(SAVE_QUEUES) MusicPlaybackQueueStore.getInstance(this@MusicService)
.saveQueues(playingQueue, originalPlayingQueue)
}
} }
private fun sendChangeInternal(what: String) { private fun sendChangeInternal(what: String) {

View file

@ -16,7 +16,7 @@ class PlaybackManager(val context: Context) {
var playback: Playback? = null var playback: Playback? = null
private var playbackLocation = PlaybackLocation.LOCAL private var playbackLocation = PlaybackLocation.LOCAL
val isLocalPlayback get() = playbackLocation== PlaybackLocation.LOCAL val isLocalPlayback get() = playbackLocation == PlaybackLocation.LOCAL
val audioSessionId: Int val audioSessionId: Int
get() = if (playback != null) { get() = if (playback != null) {
@ -168,14 +168,11 @@ class PlaybackManager(val context: Context) {
playback: Playback, playback: Playback,
onChange: (wasPlaying: Boolean, progress: Int) -> Unit, onChange: (wasPlaying: Boolean, progress: Int) -> Unit,
) { ) {
val oldPlayback = playback val oldPlayback = this.playback
val wasPlaying: Boolean = oldPlayback.isPlaying val wasPlaying: Boolean = oldPlayback?.isPlaying == true
val progress: Int = oldPlayback.position() val progress: Int = oldPlayback?.position() ?: 0
this.playback = playback this.playback = playback
oldPlayback?.stop()
oldPlayback.stop()
onChange(wasPlaying, progress) onChange(wasPlaying, progress)
} }

View file

@ -1,35 +0,0 @@
/*
* Copyright (c) 2019 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic.service
import android.os.Handler
import android.os.Looper
import android.os.Message
import code.name.monkey.retromusic.service.MusicService.Companion.SAVE_QUEUES
import java.lang.ref.WeakReference
internal class QueueSaveHandler(
musicService: MusicService,
looper: Looper
) : Handler(looper) {
private val service: WeakReference<MusicService> = WeakReference(musicService)
override fun handleMessage(msg: Message) {
val service: MusicService? = service.get()
if (msg.what == SAVE_QUEUES) {
service?.saveQueuesImpl()
}
}
}