Merge pull request #4054 from element-hq/feature/bma/testDefaultMediaPlayer
Add test on DefaultMediaPlayer.
This commit is contained in:
commit
a52ec1bfdc
3 changed files with 449 additions and 9 deletions
|
|
@ -15,7 +15,6 @@ import io.element.android.libraries.di.RoomScope
|
||||||
import io.element.android.libraries.di.SingleIn
|
import io.element.android.libraries.di.SingleIn
|
||||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.FlowPreview
|
import kotlinx.coroutines.FlowPreview
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
@ -36,6 +35,7 @@ import kotlin.time.Duration.Companion.seconds
|
||||||
@SingleIn(RoomScope::class)
|
@SingleIn(RoomScope::class)
|
||||||
class DefaultMediaPlayer @Inject constructor(
|
class DefaultMediaPlayer @Inject constructor(
|
||||||
private val player: SimplePlayer,
|
private val player: SimplePlayer,
|
||||||
|
private val coroutineScope: CoroutineScope,
|
||||||
) : MediaPlayer {
|
) : MediaPlayer {
|
||||||
private val listener = object : SimplePlayer.Listener {
|
private val listener = object : SimplePlayer.Listener {
|
||||||
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
override fun onIsPlayingChanged(isPlaying: Boolean) {
|
||||||
|
|
@ -47,7 +47,7 @@ class DefaultMediaPlayer @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
job = scope.launch { updateCurrentPosition() }
|
job = coroutineScope.launch { updateCurrentPosition() }
|
||||||
} else {
|
} else {
|
||||||
job?.cancel()
|
job?.cancel()
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +79,6 @@ class DefaultMediaPlayer @Inject constructor(
|
||||||
player.addListener(listener)
|
player.addListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val scope = CoroutineScope(Job() + Dispatchers.Main)
|
|
||||||
private var job: Job? = null
|
private var job: Job? = null
|
||||||
|
|
||||||
private val _state = MutableStateFlow(
|
private val _state = MutableStateFlow(
|
||||||
|
|
@ -102,7 +101,8 @@ class DefaultMediaPlayer @Inject constructor(
|
||||||
mimeType: String,
|
mimeType: String,
|
||||||
startPositionMs: Long,
|
startPositionMs: Long,
|
||||||
): MediaPlayer.State {
|
): MediaPlayer.State {
|
||||||
player.pause() // Must pause here otherwise if the player was playing it would keep on playing the new media item.
|
// Must pause here otherwise if the player was playing it would keep on playing the new media item.
|
||||||
|
player.pause()
|
||||||
player.clearMediaItems()
|
player.clearMediaItems()
|
||||||
player.setMediaItem(
|
player.setMediaItem(
|
||||||
MediaItem.Builder()
|
MediaItem.Builder()
|
||||||
|
|
@ -129,11 +129,9 @@ class DefaultMediaPlayer @Inject constructor(
|
||||||
player.getCurrentMediaItem()?.let {
|
player.getCurrentMediaItem()?.let {
|
||||||
player.setMediaItem(it, 0)
|
player.setMediaItem(it, 0)
|
||||||
player.prepare()
|
player.prepare()
|
||||||
player.play()
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
player.play()
|
|
||||||
}
|
}
|
||||||
|
player.play()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun pause() {
|
override fun pause() {
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,396 @@
|
||||||
|
|
||||||
package io.element.android.libraries.mediaplayer.impl
|
package io.element.android.libraries.mediaplayer.impl
|
||||||
|
|
||||||
|
import androidx.media3.common.MediaItem
|
||||||
|
import androidx.media3.common.Player
|
||||||
|
import app.cash.turbine.test
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
|
import io.element.android.tests.testutils.lambda.value
|
||||||
|
import kotlinx.coroutines.TimeoutCancellationException
|
||||||
|
import kotlinx.coroutines.test.TestScope
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Assert.assertThrows
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class DefaultMediaPlayerTest {
|
class DefaultMediaPlayerTest {
|
||||||
|
private val aMediaId = "mediaId"
|
||||||
|
private val aMediaItem = MediaItem.Builder().setMediaId(aMediaId).build()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `default test`() = runTest {
|
fun `initial state`() = runTest {
|
||||||
// TODO
|
val sut = createDefaultMediaPlayer()
|
||||||
|
sut.state.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
assertThat(initialState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `start player will update the current position and pause it will stop`() = runTest {
|
||||||
|
val playLambda = lambdaRecorder<Unit> { }
|
||||||
|
val pauseLambda = lambdaRecorder<Unit> { }
|
||||||
|
val player = FakeSimplePlayer(
|
||||||
|
playLambda = playLambda,
|
||||||
|
pauseLambda = pauseLambda,
|
||||||
|
)
|
||||||
|
val sut = createDefaultMediaPlayer(
|
||||||
|
simplePlayer = player,
|
||||||
|
)
|
||||||
|
sut.state.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
assertThat(initialState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
sut.play()
|
||||||
|
playLambda.assertions().isCalledOnce()
|
||||||
|
player.durationResult = 123L
|
||||||
|
player.simulateIsPlayingChanged(true)
|
||||||
|
val playingState = awaitItem()
|
||||||
|
assertThat(playingState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = true,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = 123,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
player.currentPositionResult = 1L
|
||||||
|
assertThat(awaitItem()).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = true,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 1,
|
||||||
|
duration = 123,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
player.currentPositionResult = 2L
|
||||||
|
assertThat(awaitItem()).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = true,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 2,
|
||||||
|
duration = 123,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
player.pause()
|
||||||
|
pauseLambda.assertions().isCalledOnce()
|
||||||
|
player.simulateIsPlayingChanged(false)
|
||||||
|
assertThat(awaitItem()).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 2,
|
||||||
|
duration = 123,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `start player on ended playback will not invoke more methods if current media item is null`() = runTest {
|
||||||
|
val playLambda = lambdaRecorder<Unit> { }
|
||||||
|
val getCurrentMediaItemLambda = lambdaRecorder<MediaItem?> { null }
|
||||||
|
val player = FakeSimplePlayer(
|
||||||
|
playLambda = playLambda,
|
||||||
|
getCurrentMediaItemLambda = getCurrentMediaItemLambda,
|
||||||
|
)
|
||||||
|
val sut = createDefaultMediaPlayer(
|
||||||
|
simplePlayer = player,
|
||||||
|
)
|
||||||
|
sut.state.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
assertThat(initialState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
player.playbackStateResult = Player.STATE_ENDED
|
||||||
|
sut.play()
|
||||||
|
playLambda.assertions().isCalledOnce()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `start player on ended playback will invoke more methods if current media item is not null`() = runTest {
|
||||||
|
val playLambda = lambdaRecorder<Unit> { }
|
||||||
|
val prepareLambda = lambdaRecorder<Unit> { }
|
||||||
|
val getCurrentMediaItemLambda = lambdaRecorder<MediaItem?> { aMediaItem }
|
||||||
|
val setMediaItemLambda = lambdaRecorder<MediaItem, Long, Unit> { _, _ -> }
|
||||||
|
val player = FakeSimplePlayer(
|
||||||
|
playLambda = playLambda,
|
||||||
|
prepareLambda = prepareLambda,
|
||||||
|
setMediaItemLambda = setMediaItemLambda,
|
||||||
|
getCurrentMediaItemLambda = getCurrentMediaItemLambda,
|
||||||
|
)
|
||||||
|
val sut = createDefaultMediaPlayer(
|
||||||
|
simplePlayer = player,
|
||||||
|
)
|
||||||
|
sut.state.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
assertThat(initialState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
player.playbackStateResult = Player.STATE_ENDED
|
||||||
|
sut.play()
|
||||||
|
setMediaItemLambda.assertions().isCalledOnce().with(
|
||||||
|
value(aMediaItem),
|
||||||
|
value(0L),
|
||||||
|
)
|
||||||
|
prepareLambda.assertions().isCalledOnce()
|
||||||
|
playLambda.assertions().isCalledOnce()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `pause player invokes pause on the embedded player`() = runTest {
|
||||||
|
val pauseLambda = lambdaRecorder<Unit> { }
|
||||||
|
val player = FakeSimplePlayer(
|
||||||
|
pauseLambda = pauseLambda,
|
||||||
|
)
|
||||||
|
val sut = createDefaultMediaPlayer(
|
||||||
|
simplePlayer = player,
|
||||||
|
)
|
||||||
|
sut.pause()
|
||||||
|
pauseLambda.assertions().isCalledOnce()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `close player invokes release on the embedded player`() = runTest {
|
||||||
|
val releaseLambda = lambdaRecorder<Unit> { }
|
||||||
|
val player = FakeSimplePlayer(
|
||||||
|
releaseLambda = releaseLambda,
|
||||||
|
)
|
||||||
|
val sut = createDefaultMediaPlayer(
|
||||||
|
simplePlayer = player,
|
||||||
|
)
|
||||||
|
sut.close()
|
||||||
|
releaseLambda.assertions().isCalledOnce()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `seekTo invokes release on the embedded player`() = runTest {
|
||||||
|
val seekToLambda = lambdaRecorder<Long, Unit> { }
|
||||||
|
val player = FakeSimplePlayer(
|
||||||
|
seekToLambda = seekToLambda,
|
||||||
|
)
|
||||||
|
val sut = createDefaultMediaPlayer(
|
||||||
|
simplePlayer = player,
|
||||||
|
)
|
||||||
|
sut.state.test {
|
||||||
|
awaitItem()
|
||||||
|
player.currentPositionResult = 33L
|
||||||
|
sut.seekTo(33L)
|
||||||
|
seekToLambda.assertions().isCalledOnce().with(value(33L))
|
||||||
|
val finalState = awaitItem()
|
||||||
|
assertThat(finalState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 33L,
|
||||||
|
duration = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `onPlaybackStateChanged update the state`() = runTest {
|
||||||
|
val player = FakeSimplePlayer()
|
||||||
|
val sut = createDefaultMediaPlayer(
|
||||||
|
simplePlayer = player,
|
||||||
|
)
|
||||||
|
sut.state.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
assertThat(initialState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
player.currentPositionResult = 44
|
||||||
|
player.durationResult = 123L
|
||||||
|
player.simulatePlaybackStateChanged(Player.STATE_READY)
|
||||||
|
val readyState = awaitItem()
|
||||||
|
assertThat(readyState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = true,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 44,
|
||||||
|
duration = 123,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
player.simulatePlaybackStateChanged(Player.STATE_ENDED)
|
||||||
|
val endedState = awaitItem()
|
||||||
|
assertThat(endedState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = true,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 44,
|
||||||
|
duration = 123,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `setMedia with timeout error`() = runTest {
|
||||||
|
val pauseLambda = lambdaRecorder<Unit> { }
|
||||||
|
val clearMediaItemsLambda = lambdaRecorder<Unit> { }
|
||||||
|
val setMediaItemLambda = lambdaRecorder<MediaItem, Long, Unit> { _, _ -> }
|
||||||
|
val prepareLambda = lambdaRecorder<Unit> { }
|
||||||
|
val player = FakeSimplePlayer(
|
||||||
|
pauseLambda = pauseLambda,
|
||||||
|
clearMediaItemsLambda = clearMediaItemsLambda,
|
||||||
|
setMediaItemLambda = setMediaItemLambda,
|
||||||
|
prepareLambda = prepareLambda,
|
||||||
|
)
|
||||||
|
val sut = createDefaultMediaPlayer(
|
||||||
|
simplePlayer = player,
|
||||||
|
)
|
||||||
|
sut.state.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
assertThat(initialState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val result = runCatching {
|
||||||
|
sut.setMedia("uri", "mediaId", "mimeType", 12)
|
||||||
|
}
|
||||||
|
pauseLambda.assertions().isCalledOnce()
|
||||||
|
clearMediaItemsLambda.assertions().isCalledOnce()
|
||||||
|
setMediaItemLambda.assertions().isCalledOnce().with(
|
||||||
|
value(MediaItem.Builder().setUri("uri").setMediaId("mediaId").setMimeType("mimeType").build()),
|
||||||
|
value(12L),
|
||||||
|
)
|
||||||
|
prepareLambda.assertions().isCalledOnce()
|
||||||
|
assertThat(result.isFailure).isTrue()
|
||||||
|
assertThrows(TimeoutCancellationException::class.java) {
|
||||||
|
result.getOrThrow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `setMedia success`() = runTest {
|
||||||
|
var player: FakeSimplePlayer? = null
|
||||||
|
val pauseLambda = lambdaRecorder<Unit> { }
|
||||||
|
val clearMediaItemsLambda = lambdaRecorder<Unit> { }
|
||||||
|
val setMediaItemLambda = lambdaRecorder<MediaItem, Long, Unit> { _, _ -> }
|
||||||
|
val prepareLambda = lambdaRecorder<Unit> {
|
||||||
|
player?.simulatePlaybackStateChanged(Player.STATE_READY)
|
||||||
|
player?.simulateMediaItemTransition(aMediaItem)
|
||||||
|
}
|
||||||
|
player = FakeSimplePlayer(
|
||||||
|
pauseLambda = pauseLambda,
|
||||||
|
clearMediaItemsLambda = clearMediaItemsLambda,
|
||||||
|
setMediaItemLambda = setMediaItemLambda,
|
||||||
|
prepareLambda = prepareLambda,
|
||||||
|
)
|
||||||
|
val sut = createDefaultMediaPlayer(
|
||||||
|
simplePlayer = player,
|
||||||
|
)
|
||||||
|
sut.state.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
assertThat(initialState).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = false,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = null,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val state = sut.setMedia("uri", "mediaId", "mimeType", 12)
|
||||||
|
pauseLambda.assertions().isCalledOnce()
|
||||||
|
clearMediaItemsLambda.assertions().isCalledOnce()
|
||||||
|
setMediaItemLambda.assertions().isCalledOnce().with(
|
||||||
|
value(MediaItem.Builder().setUri("uri").setMediaId("mediaId").setMimeType("mimeType").build()),
|
||||||
|
value(12L),
|
||||||
|
)
|
||||||
|
prepareLambda.assertions().isCalledOnce()
|
||||||
|
|
||||||
|
val finalState = MediaPlayer.State(
|
||||||
|
isReady = true,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = "mediaId",
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = 0,
|
||||||
|
)
|
||||||
|
assertThat(awaitItem()).isEqualTo(
|
||||||
|
MediaPlayer.State(
|
||||||
|
isReady = true,
|
||||||
|
isPlaying = false,
|
||||||
|
isEnded = false,
|
||||||
|
mediaId = null,
|
||||||
|
currentPosition = 0,
|
||||||
|
duration = 0,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assertThat(awaitItem()).isEqualTo(finalState)
|
||||||
|
assertThat(state).isEqualTo(finalState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TestScope.createDefaultMediaPlayer(
|
||||||
|
simplePlayer: SimplePlayer = FakeSimplePlayer(),
|
||||||
|
): DefaultMediaPlayer = DefaultMediaPlayer(
|
||||||
|
simplePlayer,
|
||||||
|
backgroundScope,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 New Vector Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
* Please see LICENSE in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.libraries.mediaplayer.impl
|
||||||
|
|
||||||
|
import androidx.media3.common.MediaItem
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaError
|
||||||
|
|
||||||
|
class FakeSimplePlayer(
|
||||||
|
private val clearMediaItemsLambda: () -> Unit = { lambdaError() },
|
||||||
|
private val setMediaItemLambda: (MediaItem, Long) -> Unit = { _, _ -> lambdaError() },
|
||||||
|
private val getCurrentMediaItemLambda: () -> MediaItem? = { lambdaError() },
|
||||||
|
private val prepareLambda: () -> Unit = { lambdaError() },
|
||||||
|
private val playLambda: () -> Unit = { lambdaError() },
|
||||||
|
private val pauseLambda: () -> Unit = { lambdaError() },
|
||||||
|
private val seekToLambda: (Long) -> Unit = { lambdaError() },
|
||||||
|
private val releaseLambda: () -> Unit = { lambdaError() },
|
||||||
|
) : SimplePlayer {
|
||||||
|
private val listeners = mutableListOf<SimplePlayer.Listener>()
|
||||||
|
override fun addListener(listener: SimplePlayer.Listener) {
|
||||||
|
listeners.add(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentPositionResult: Long = 0
|
||||||
|
override val currentPosition: Long get() = currentPositionResult
|
||||||
|
var playbackStateResult: Int = 0
|
||||||
|
override val playbackState: Int get() = playbackStateResult
|
||||||
|
var durationResult: Long = 0
|
||||||
|
override val duration: Long get() = durationResult
|
||||||
|
|
||||||
|
override fun clearMediaItems() = clearMediaItemsLambda()
|
||||||
|
override fun setMediaItem(mediaItem: MediaItem, startPositionMs: Long) {
|
||||||
|
setMediaItemLambda(mediaItem, startPositionMs)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCurrentMediaItem(): MediaItem? = getCurrentMediaItemLambda()
|
||||||
|
override fun prepare() = prepareLambda()
|
||||||
|
override fun play() = playLambda()
|
||||||
|
override fun pause() = pauseLambda()
|
||||||
|
override fun seekTo(positionMs: Long) = seekToLambda(positionMs)
|
||||||
|
override fun release() = releaseLambda()
|
||||||
|
|
||||||
|
fun simulateIsPlayingChanged(isPlaying: Boolean) {
|
||||||
|
listeners.forEach { it.onIsPlayingChanged(isPlaying) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun simulateMediaItemTransition(mediaItem: MediaItem?) {
|
||||||
|
listeners.forEach { it.onMediaItemTransition(mediaItem) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun simulatePlaybackStateChanged(playbackState: Int) {
|
||||||
|
listeners.forEach { it.onPlaybackStateChanged(playbackState) }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue