diff --git a/mopidy/core/actor.py b/mopidy/core/actor.py index 52c3dfb3..56fe6e74 100644 --- a/mopidy/core/actor.py +++ b/mopidy/core/actor.py @@ -146,7 +146,7 @@ class Core( coverage = [] if self._config and 'restore_state' in self._config['core']: if self._config['core']['restore_state']: - coverage = ['tracklist', 'mode', 'play-last', 'volume', + coverage = ['tracklist', 'mode', 'play-last', 'mixer', 'history'] if len(coverage): self._load_state(coverage) @@ -198,7 +198,7 @@ class Core( - 'tracklist' fill the tracklist - 'mode' set tracklist properties (consume, random, repeat, single) - 'autoplay' start playing ('tracklist' also required) - - 'volume' set mixer volume + - 'mixer' set mixer volume and mute state - 'history' restore history :param coverage: amount of data to restore diff --git a/mopidy/core/mixer.py b/mopidy/core/mixer.py index cceb0ebe..3d9b7003 100644 --- a/mopidy/core/mixer.py +++ b/mopidy/core/mixer.py @@ -103,11 +103,13 @@ class MixerController(object): def _export_state(self): """Internal method for :class:`mopidy.Core`.""" - return MixerState(volume=self.get_volume()) + return MixerState(volume=self.get_volume(), + mute=self.get_mute()) def _restore_state(self, state, coverage): """Internal method for :class:`mopidy.Core`.""" if state: - if 'volume' in coverage: + if 'mixer' in coverage: if state.volume: self.set_volume(state.volume) + self.set_mute(state.mute) diff --git a/mopidy/internal/models.py b/mopidy/internal/models.py index 690b1802..b66e0504 100644 --- a/mopidy/internal/models.py +++ b/mopidy/internal/models.py @@ -7,7 +7,7 @@ from mopidy.models.immutable import ValidatedImmutableObject class HistoryTrack(ValidatedImmutableObject): """ - A history track. Wraps a :class:`Ref` and it's timestamp. + A history track. Wraps a :class:`Ref` and its timestamp. :param timestamp: the timestamp :type timestamp: int @@ -42,11 +42,16 @@ class MixerState(ValidatedImmutableObject): :param volume: the volume :type volume: int + :param mute: the volume + :type mute: int """ # The volume. Read-only. volume = fields.Integer(min=0, max=100) + # The mute state. Read-only. + mute = fields.Boolean(default=False) + class PlaybackState(ValidatedImmutableObject): """ @@ -85,9 +90,9 @@ class TracklistState(ValidatedImmutableObject): :type random: bool :param single: the single mode :type single: bool - :param next_tlid: the single mode - :type next_tlid: bool - :param tl_tracks: the single mode + :param next_tlid: the id of the next track to play + :type next_tlid: int + :param tl_tracks: the list of tracks :type tl_tracks: list of :class:`TlTrack` """ @@ -103,7 +108,7 @@ class TracklistState(ValidatedImmutableObject): # The single mode. Read-only. single = fields.Boolean() - # The repeat mode. Read-only. + # The id of the track to play. Read-only. next_tlid = fields.Integer(min=0) # The list of tracks. Read-only. diff --git a/tests/core/test_mixer.py b/tests/core/test_mixer.py index 0b7b789b..17ecdfb5 100644 --- a/tests/core/test_mixer.py +++ b/tests/core/test_mixer.py @@ -163,10 +163,21 @@ class CoreMixerExportRestoreTest(unittest.TestCase): self.mixer = dummy_mixer.create_proxy() self.core = core.Core(mixer=self.mixer, backends=[]) - def test_export(self): + def test_export_mute(self): volume = 32 - target = MixerState(volume=volume) + mute = False + target = MixerState(volume=volume, mute=mute) self.core.mixer.set_volume(volume) + self.core.mixer.set_mute(mute) + value = self.core.mixer._export_state() + self.assertEqual(target, value) + + def test_export_unmute(self): + volume = 33 + mute = True + target = MixerState(volume=volume, mute=mute) + self.core.mixer.set_volume(volume) + self.core.mixer.set_mute(mute) value = self.core.mixer._export_state() self.assertEqual(target, value) @@ -174,16 +185,34 @@ class CoreMixerExportRestoreTest(unittest.TestCase): self.core.mixer.set_volume(11) volume = 45 target = MixerState(volume=volume) - coverage = ['volume'] + coverage = ['mixer'] self.core.mixer._restore_state(target, coverage) self.assertEqual(volume, self.core.mixer.get_volume()) def test_import_not_covered(self): self.core.mixer.set_volume(21) - target = MixerState(volume=56) + self.core.mixer.set_mute(True) + target = MixerState(volume=56, mute=False) coverage = ['other'] self.core.mixer._restore_state(target, coverage) self.assertEqual(21, self.core.mixer.get_volume()) + self.assertEqual(True, self.core.mixer.get_mute()) + + def test_import_mute_on(self): + self.core.mixer.set_mute(False) + self.assertEqual(False, self.core.mixer.get_mute()) + target = MixerState(mute=True) + coverage = ['mixer'] + self.core.mixer._restore_state(target, coverage) + self.assertEqual(True, self.core.mixer.get_mute()) + + def test_import_mute_off(self): + self.core.mixer.set_mute(True) + self.assertEqual(True, self.core.mixer.get_mute()) + target = MixerState(mute=False) + coverage = ['mixer'] + self.core.mixer._restore_state(target, coverage) + self.assertEqual(False, self.core.mixer.get_mute()) def test_import_invalid_type(self): with self.assertRaises(TypeError):