diff --git a/domain/src/main/java/org/oppia/android/domain/audio/AudioPlayerController.kt b/domain/src/main/java/org/oppia/android/domain/audio/AudioPlayerController.kt index d9ac8e2691d..4e9827a6ff2 100644 --- a/domain/src/main/java/org/oppia/android/domain/audio/AudioPlayerController.kt +++ b/domain/src/main/java/org/oppia/android/domain/audio/AudioPlayerController.kt @@ -78,6 +78,7 @@ class AudioPlayerController @Inject constructor( private var nextUpdateJob: Job? = null private val audioLock = ReentrantLock() + private var isInitalized = false private var prepared = false private var observerActive = false private var mediaPlayerActive = false @@ -95,6 +96,7 @@ class AudioPlayerController @Inject constructor( */ fun initializeMediaPlayer(): LiveData> { audioLock.withLock { + isInitalized = true mediaPlayerActive = true if (isReleased) { // Recreation is necessary since media player's resources have been released @@ -125,24 +127,33 @@ class AudioPlayerController @Inject constructor( private fun setMediaPlayerListeners() { mediaPlayer.setOnCompletionListener { - completed = true - stopUpdatingSeekBar() - playProgress?.value = - AsyncResult.Success(PlayProgress(PlayStatus.COMPLETED, 0, duration)) + audioLock.withLock { + completed = true + stopUpdatingSeekBar() + playProgress?.value = + AsyncResult.Success(PlayProgress(PlayStatus.COMPLETED, 0, duration)) + } } mediaPlayer.setOnPreparedListener { - prepared = true - duration = it.duration - playProgress?.value = - AsyncResult.Success(PlayProgress(PlayStatus.PREPARED, 0, duration)) + audioLock.withLock { + prepared = true + duration = it.duration + playProgress?.value = + AsyncResult.Success(PlayProgress(PlayStatus.PREPARED, 0, duration)) + } } mediaPlayer.setOnErrorListener { _, what, extra -> - playProgress?.value = - AsyncResult.Failure( - AudioPlayerException("Audio Player put in error state with what: $what and extra: $extra") - ) - releaseMediaPlayer() - initializeMediaPlayer() + audioLock.withLock { + playProgress?.value = + AsyncResult.Failure( + AudioPlayerException( + "Audio Player put in error state with what: $what " + + "and extra: $extra" + ) + ) + releaseMediaPlayer() + initializeMediaPlayer() + } // Indicates that error was handled and to not invoke completion listener. return@setOnErrorListener true } @@ -251,11 +262,13 @@ class AudioPlayerController @Inject constructor( */ fun releaseMediaPlayer() { audioLock.withLock { - check(mediaPlayerActive) { "Media player has not been previously initialized" } + check(isInitalized) { "Media player has not been previously initialized" } + if (mediaPlayerActive) { + mediaPlayer.release() + } mediaPlayerActive = false isReleased = true prepared = false - mediaPlayer.release() stopUpdatingSeekBar() playProgress = null }