core: Make sure current_tl_track changes on stream change

- Adds stream changed handler to core
- Moves playback started trigger to stream changed
- Made about to finish store next track in _pending_tl_track
- Set the pending track as current in stream changed
- Adds tests for all of this and fixes existing tests
This commit is contained in:
Thomas Adamcik 2015-01-23 00:14:30 +01:00
parent 49f16704d8
commit b0aebaf993
4 changed files with 89 additions and 8 deletions

View File

@ -75,6 +75,9 @@ class Core(
def reached_end_of_stream(self):
self.playback.on_end_of_stream()
def stream_changed(self, uri):
self.playback.on_stream_changed(uri)
def state_changed(self, old_state, new_state, target_state):
# XXX: This is a temporary fix for issue #232 while we wait for a more
# permanent solution with the implementation of issue #234. When the

View File

@ -24,6 +24,7 @@ class PlaybackController(object):
self._state = PlaybackState.STOPPED
self._volume = None
self._mute = False
self._pending_tl_track = None
if self._audio:
self._audio.set_about_to_finish_callback(self.on_about_to_finish)
@ -133,22 +134,26 @@ class PlaybackController(object):
def on_end_of_stream(self):
self.state = PlaybackState.STOPPED
self.current_tl_track = None
# TODO: self._trigger_track_playback_ended?
def on_stream_changed(self, uri):
self.current_tl_track = self._pending_tl_track
self._pending_tl_track = None
self._trigger_track_playback_started()
# TODO: self._trigger_track_playback_ended?
def on_about_to_finish(self):
# TODO: check that we always have a current track
original_tl_track = self.current_tl_track
next_tl_track = self.core.tracklist.eot_track(original_tl_track)
next_tl_track = self.core.tracklist.eot_track(self.current_tl_track)
# TODO: this should be self.pending_tl_track and stream changed should
# make it current.
self.current_tl_track = next_tl_track
self._pending_tl_track = next_tl_track
backend = self._get_backend(next_tl_track)
if backend:
backend.playback.change_track(next_tl_track.track).get()
# TODO: this _really_ needs to be stream changed...
self._trigger_track_playback_started()
self.core.tracklist.mark_played(original_tl_track)

View File

@ -4,10 +4,82 @@ import unittest
import mock
from mopidy import backend, core
import pykka
from mopidy import audio, backend, core
from mopidy.models import Track
class TestBackend(pykka.ThreadingActor, backend.Backend):
uri_schemes = ['dummy']
def __init__(self, config, audio):
super(TestBackend, self).__init__()
self.playback = backend.PlaybackProvider(audio=audio, backend=self)
class TestCurrentAndPendingTlTrack(unittest.TestCase):
def setUp(self): # noqa: N802
self.audio = audio.DummyAudio.start().proxy()
self.backend = TestBackend.start(config={}, audio=self.audio).proxy()
self.core = core.Core(audio=self.audio, backends=[self.backend])
self.playback = self.core.playback
self.tracks = [Track(uri='dummy:a', length=1234),
Track(uri='dummy:b', length=1234)]
self.core.tracklist.add(self.tracks)
def tearDown(self): # noqa: N802
pykka.ActorRegistry.stop_all()
def trigger_about_to_finish(self):
self.audio.prepare_change()
# TODO: trigger via dummy audio?
self.playback.on_about_to_finish()
def trigger_stream_changed(self):
# TODO: trigger via dummy audio?
self.playback.on_stream_changed(None)
def trigger_end_of_stream(self):
# TODO: trigger via dummy audio?
self.playback.on_end_of_stream()
def test_pending_tl_track_is_none(self):
self.core.playback.play()
self.assertEqual(self.playback._pending_tl_track, None)
def test_pending_tl_track_after_about_to_finish(self):
self.core.playback.play()
self.trigger_about_to_finish()
self.assertEqual(self.playback._pending_tl_track.track.uri, 'dummy:b')
def test_pending_tl_track_after_stream_changed(self):
self.trigger_about_to_finish()
self.trigger_stream_changed()
self.assertEqual(self.playback._pending_tl_track, None)
def test_current_tl_track_after_about_to_finish(self):
self.core.playback.play()
self.trigger_about_to_finish()
self.assertEqual(self.playback.current_tl_track.track.uri, 'dummy:a')
def test_current_tl_track_after_stream_changed(self):
self.core.playback.play()
self.trigger_about_to_finish()
self.trigger_stream_changed()
self.assertEqual(self.playback.current_tl_track.track.uri, 'dummy:b')
def test_current_tl_track_after_end_of_stream(self):
self.core.playback.play()
self.trigger_about_to_finish()
self.trigger_stream_changed()
self.trigger_about_to_finish()
self.trigger_end_of_stream()
self.assertEqual(self.playback.current_tl_track, None)
class CorePlaybackTest(unittest.TestCase):
def setUp(self): # noqa: N802
self.backend1 = mock.Mock()

View File

@ -42,6 +42,7 @@ class LocalPlaybackProviderTest(unittest.TestCase):
def trigger_about_to_finish(self):
self.audio.prepare_change().get()
self.playback.on_about_to_finish()
self.playback.on_stream_changed(None)
def trigger_end_of_stream(self):
self.playback.on_end_of_stream()