Merge lp:~phablet-team/media-hub/bg-playlist-fixes into lp:media-hub/stable

Proposed by Alfonso Sanchez-Beato
Status: Merged
Approved by: Jim Hodapp
Approved revision: 168
Merged at revision: 163
Proposed branch: lp:~phablet-team/media-hub/bg-playlist-fixes
Merge into: lp:media-hub/stable
Prerequisite: lp:~morphis/media-hub/previous-to-same-after-four-secs
Diff against target: 703 lines (+237/-42)
11 files modified
include/core/media/track_list.h (+8/-0)
src/core/media/mpris/service.h (+12/-0)
src/core/media/mpris/track_list.h (+17/-0)
src/core/media/player_implementation.cpp (+12/-0)
src/core/media/service_skeleton.cpp (+22/-6)
src/core/media/track_list.cpp (+5/-0)
src/core/media/track_list_implementation.cpp (+25/-18)
src/core/media/track_list_skeleton.cpp (+102/-16)
src/core/media/track_list_skeleton.h (+4/-0)
src/core/media/track_list_stub.cpp (+29/-2)
src/core/media/track_list_stub.h (+1/-0)
To merge this branch: bzr merge lp:~phablet-team/media-hub/bg-playlist-fixes
Reviewer Review Type Date Requested Status
Jim Hodapp (community) code Approve
Review via email: mp+276094@code.launchpad.net

Commit message

Make sure our iterator for the current track points to the right place when (un)shuffling (LP #1510219). Fix crash when client tries to set the player for a non-existing key. Do not add empty URIs to the list (LP: #1511029).

Description of the change

Make sure our iterator for the current track points to the right place when (un)shuffling (LP #1510219). Fix crash when client tries to set the player for a non-existing key. Do not add empty URIs to the list (LP: #1511029).

To post a comment you must log in.
165. By Alfonso Sanchez-Beato

Do not add empty URIs to the list (LP: #1511029)

166. By Alfonso Sanchez-Beato

Send TrackChanged signals only when the TrackAdded signal for the
corresponding track has already been sent.

Revision history for this message
Jim Hodapp (jhodapp) wrote :

A few comments inline.

review: Needs Fixing (code)
167. By Alfonso Sanchez-Beato

Address review comments

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Branch refreshed after addressing comments.

Revision history for this message
Jim Hodapp (jhodapp) wrote :

Looks good, one minor change still needed.

review: Needs Fixing
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Branch refreshed after addressing comment.

168. By Alfonso Sanchez-Beato

Address review comment

Revision history for this message
Jim Hodapp (jhodapp) wrote :

LGTM

review: Approve (code)
169. By Alfonso Sanchez-Beato

Repeat current track when already played more than five seconds

170. By Alfonso Sanchez-Beato

Fix for the repeat track feature

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :
171. By Alfonso Sanchez-Beato

Add TrackListReset signal, which is emitted when the Reset DBus method is
called.

172. By Alfonso Sanchez-Beato

Update properly playlist iterator when adding or removing tracks
(LP: #1511073).

173. By Alfonso Sanchez-Beato

Use get/set_current track when shuffling

174. By Alfonso Sanchez-Beato

Force index update when changing the track list

Revision history for this message
Jim Hodapp (jhodapp) wrote :

A few comments below about the latest changes.

review: Needs Fixing
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Some comments answered. I will update the branch later as I will modify qtubuntu-media too.

175. By Alfonso Sanchez-Beato

Address review comments

Revision history for this message
Jim Hodapp (jhodapp) wrote :

Several comments inline below.

review: Needs Fixing (code)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

See comments below. I will address the remaining issues asap.

176. By Alfonso Sanchez-Beato

Address review comments

Revision history for this message
Jim Hodapp (jhodapp) wrote :

A couple of comments below.

Revision history for this message
Jim Hodapp (jhodapp) wrote :

LGTM

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/core/media/track_list.h'
2--- include/core/media/track_list.h 2015-10-23 14:39:34 +0000
3+++ include/core/media/track_list.h 2015-11-13 15:27:09 +0000
4@@ -54,6 +54,11 @@
5 {
6 InsufficientPermissionsToAddTrack();
7 };
8+
9+ struct TrackNotFound : public std::runtime_error
10+ {
11+ TrackNotFound();
12+ };
13 };
14
15 static const Track::Id& after_empty_track();
16@@ -123,6 +128,9 @@
17 /** Indicates that a track has been removed from the track list. */
18 virtual const core::Signal<Track::Id>& on_track_removed() const = 0;
19
20+ /** Indicates that the track list has been reset and there are no tracks now */
21+ virtual const core::Signal<void>& on_track_list_reset() const = 0;
22+
23 /** Indicates that the track list advanced from one track to another. */
24 virtual const core::Signal<Track::Id>& on_track_changed() const = 0;
25
26
27=== modified file 'src/core/media/mpris/service.h'
28--- src/core/media/mpris/service.h 2015-09-08 20:03:56 +0000
29+++ src/core/media/mpris/service.h 2015-11-13 15:27:09 +0000
30@@ -107,6 +107,18 @@
31 return s;
32 }
33 };
34+
35+ struct PlayerKeyNotFound
36+ {
37+ static const std::string& name()
38+ {
39+ static const std::string s
40+ {
41+ "core.ubuntu.media.Service.Error.PlayerKeyNotFound"
42+ };
43+ return s;
44+ }
45+ };
46 };
47
48 DBUS_CPP_METHOD_WITH_TIMEOUT_DEF(CreateSession, Service, 1000)
49
50=== modified file 'src/core/media/mpris/track_list.h'
51--- src/core/media/mpris/track_list.h 2015-10-23 14:39:34 +0000
52+++ src/core/media/mpris/track_list.h 2015-11-13 15:27:09 +0000
53@@ -57,6 +57,14 @@
54 "mpris.TrackList.Error.InsufficientPermissionsToAddTrack"
55 };
56 };
57+
58+ struct TrackNotFound
59+ {
60+ static constexpr const char* name
61+ {
62+ "mpris.TrackList.Error.TrackNotFound"
63+ };
64+ };
65 };
66
67 DBUS_CPP_METHOD_DEF(GetTracksMetadata, TrackList)
68@@ -108,6 +116,13 @@
69
70 DBUS_CPP_SIGNAL_DEF
71 (
72+ TrackListReset,
73+ TrackList,
74+ void
75+ )
76+
77+ DBUS_CPP_SIGNAL_DEF
78+ (
79 TrackMetadataChanged,
80 TrackList,
81 BOOST_IDENTITY_TYPE((std::tuple<std::map<std::string, dbus::types::Variant>, dbus::types::ObjectPath>))
82@@ -156,6 +171,7 @@
83 configuration.object->template get_signal<Signals::TracksAdded>(),
84 configuration.object->template get_signal<Signals::TrackRemoved>(),
85 configuration.object->template get_signal<Signals::TrackChanged>(),
86+ configuration.object->template get_signal<Signals::TrackListReset>(),
87 configuration.object->template get_signal<Signals::TrackMetadataChanged>(),
88 configuration.object->template get_signal<core::dbus::interfaces::Properties::Signals::PropertiesChanged>()
89 }
90@@ -201,6 +217,7 @@
91 core::dbus::Signal<Signals::TracksAdded, Signals::TracksAdded::ArgumentType>::Ptr tracks_added;
92 core::dbus::Signal<Signals::TrackRemoved, Signals::TrackRemoved::ArgumentType>::Ptr track_removed;
93 core::dbus::Signal<Signals::TrackChanged, Signals::TrackChanged::ArgumentType>::Ptr track_changed;
94+ core::dbus::Signal<Signals::TrackListReset, Signals::TrackListReset::ArgumentType>::Ptr track_list_reset;
95 core::dbus::Signal<Signals::TrackMetadataChanged, Signals::TrackMetadataChanged::ArgumentType>::Ptr track_metadata_changed;
96
97 dbus::Signal <core::dbus::interfaces::Properties::Signals::PropertiesChanged,
98
99=== modified file 'src/core/media/player_implementation.cpp'
100--- src/core/media/player_implementation.cpp 2015-11-13 15:27:09 +0000
101+++ src/core/media/player_implementation.cpp 2015-11-13 15:27:09 +0000
102@@ -569,6 +569,11 @@
103 d->update_mpris_properties();
104 });
105
106+ d->track_list->on_track_list_reset().connect([this](void)
107+ {
108+ d->update_mpris_properties();
109+ });
110+
111 d->track_list->on_track_changed().connect([this](const media::Track::Id&)
112 {
113 d->update_mpris_properties();
114@@ -681,6 +686,13 @@
115 bool media::PlayerImplementation<Parent>::open_uri(const Track::UriType& uri)
116 {
117 d->track_list->reset();
118+
119+ // If empty uri, give the same meaning as QMediaPlayer::setMedia("")
120+ if (uri.empty()) {
121+ cout << __PRETTY_FUNCTION__ << ": resetting current media" << endl;
122+ return true;
123+ }
124+
125 const bool ret = d->engine->open_resource_for_uri(uri, false);
126 // Don't set new track as the current track to play since we're calling open_resource_for_uri above
127 static const bool make_current = false;
128
129=== modified file 'src/core/media/service_skeleton.cpp'
130--- src/core/media/service_skeleton.cpp 2015-10-14 20:54:19 +0000
131+++ src/core/media/service_skeleton.cpp 2015-11-13 15:27:09 +0000
132@@ -46,6 +46,8 @@
133 namespace dbus = core::dbus;
134 namespace media = core::ubuntu::media;
135
136+using namespace std;
137+
138 namespace
139 {
140 core::Signal<void> the_empty_signal;
141@@ -132,7 +134,9 @@
142 impl->access_service()->add_object_for_path(op)
143 };
144
145- std::cout << "Session created by request of: " << msg->sender() << ", uuid: " << uuid << ", path:" << op << std::endl;
146+ cout << "Session created by request of: " << msg->sender()
147+ << ", key: " << key << ", uuid: " << uuid
148+ << ", path:" << op << std::endl;
149
150 try
151 {
152@@ -205,9 +209,11 @@
153 std::string uuid;
154 msg->reader() >> uuid;
155
156- if (uuid_player_map.count(uuid) != 0) {
157+ if (uuid_player_map.count(uuid) != 0)
158+ {
159 auto key = uuid_player_map.at(uuid);
160- if (not configuration.player_store->has_player_for_key(key)) {
161+ if (not configuration.player_store->has_player_for_key(key))
162+ {
163 auto reply = dbus::Message::make_error(
164 msg,
165 mpris::Service::Errors::ReattachingSession::name(),
166@@ -442,9 +448,19 @@
167 {
168 Player::PlayerKey key;
169 msg->reader() >> key;
170- impl->set_current_player(key);
171-
172- auto reply = dbus::Message::make_method_return(msg);
173+
174+ core::dbus::Message::Ptr reply;
175+ if (not configuration.player_store->has_player_for_key(key)) {
176+ cerr << __PRETTY_FUNCTION__ << " player key not found - " << key << endl;
177+ reply = dbus::Message::make_error(
178+ msg,
179+ mpris::Service::Errors::PlayerKeyNotFound::name(),
180+ "Player key not found");
181+ } else {
182+ impl->set_current_player(key);
183+ reply = dbus::Message::make_method_return(msg);
184+ }
185+
186 impl->access_bus()->send(reply);
187 }
188
189
190=== modified file 'src/core/media/track_list.cpp'
191--- src/core/media/track_list.cpp 2015-10-23 14:39:34 +0000
192+++ src/core/media/track_list.cpp 2015-11-13 15:27:09 +0000
193@@ -25,6 +25,11 @@
194 {
195 }
196
197+media::TrackList::Errors::TrackNotFound::TrackNotFound()
198+ : std::runtime_error{"Track not found in TrackList"}
199+{
200+}
201+
202 const media::Track::Id& media::TrackList::after_empty_track()
203 {
204 static const media::Track::Id id{"/org/mpris/MediaPlayer2/TrackList/NoTrack"};
205
206=== modified file 'src/core/media/track_list_implementation.cpp'
207--- src/core/media/track_list_implementation.cpp 2015-10-23 14:39:34 +0000
208+++ src/core/media/track_list_implementation.cpp 2015-11-13 15:27:09 +0000
209@@ -118,6 +118,8 @@
210 std::cout << "Adding Track::Id: " << id << std::endl;
211 std::cout << "\tURI: " << uri << std::endl;
212
213+ const auto current = get_current_track();
214+
215 auto result = tracks().update([this, id, position, make_current](TrackList::Container& container)
216 {
217 auto it = std::find(container.begin(), container.end(), position);
218@@ -133,20 +135,24 @@
219
220 if (make_current)
221 {
222+ set_current_track(id);
223 // Don't automatically call stop() and play() in player_implementation.cpp on_go_to_track()
224 // since this breaks video playback when using open_uri() (stop() and play() are unwanted in
225 // this scenario since the qtubuntu-media will handle this automatically)
226 const bool toggle_player_state = false;
227 go_to(id, toggle_player_state);
228+ } else {
229+ set_current_track(current);
230 }
231
232- // Signal to the client that the current track has changed for the first track added to the TrackList
233- if (tracks().get().size() == 1)
234- on_track_changed()(id);
235-
236 std::cout << "Signaling that we just added track id: " << id << std::endl;
237 // Signal to the client that a track was added to the TrackList
238 on_track_added()(id);
239+
240+ // Signal to the client that the current track has changed for the first
241+ // track added to the TrackList
242+ if (tracks().get().size() == 1)
243+ on_track_changed()(id);
244 }
245 }
246
247@@ -154,6 +160,9 @@
248 {
249 std::cout << __PRETTY_FUNCTION__ << std::endl;
250
251+ const auto current = get_current_track();
252+
253+ Track::Id current_id;
254 ContainerURI tmp;
255 for (const auto uri : uris)
256 {
257@@ -185,12 +194,17 @@
258
259 // Signal to the client that the current track has changed for the first track added to the TrackList
260 if (tracks().get().size() == 1)
261- on_track_changed()(id);
262+ current_id = id;
263 }
264 }
265
266+ set_current_track(current);
267+
268 std::cout << "Signaling that we just added " << tmp.size() << " tracks to the TrackList" << std::endl;
269 on_tracks_added()(tmp);
270+
271+ if (!current_id.empty())
272+ on_track_changed()(current_id);
273 }
274
275 void media::TrackListImplementation::remove_track(const media::Track::Id& id)
276@@ -209,7 +223,6 @@
277
278 on_track_removed()(id);
279 }
280-
281 }
282
283 void media::TrackListImplementation::go_to(const media::Track::Id& track, bool toggle_player_state)
284@@ -266,26 +279,20 @@
285
286 void media::TrackListImplementation::reset()
287 {
288+ std::cout << __PRETTY_FUNCTION__ << std::endl;
289+
290 // Make sure playback stops
291 on_end_of_tracklist()();
292 // And make sure there is no "current" track
293 media::TrackListSkeleton::reset();
294
295- auto result = tracks().update([this](TrackList::Container& container)
296+ tracks().update([this](TrackList::Container& container)
297 {
298- TrackList::Container ids = container;
299-
300- for (auto it = container.begin(); it != container.end(); ) {
301- auto id = *it;
302- it = container.erase(it);
303- on_track_removed()(id);
304- }
305-
306- container.resize(0);
307+ container.clear();
308+ on_track_list_reset()();
309+
310 d->track_counter = 0;
311
312 return true;
313 });
314-
315- (void) result;
316 }
317
318=== modified file 'src/core/media/track_list_skeleton.cpp'
319--- src/core/media/track_list_skeleton.cpp 2015-11-13 15:27:09 +0000
320+++ src/core/media/track_list_skeleton.cpp 2015-11-13 15:27:09 +0000
321@@ -38,10 +38,14 @@
322
323 #include <iostream>
324 #include <limits>
325+#include <sstream>
326+#include <cstdint>
327
328 namespace dbus = core::dbus;
329 namespace media = core::ubuntu::media;
330
331+using namespace std;
332+
333 struct media::TrackListSkeleton::Private
334 {
335 Private(media::TrackListSkeleton* impl, const dbus::Bus::Ptr& bus, const dbus::Object::Ptr& object,
336@@ -63,6 +67,7 @@
337 skeleton.signals.tracks_added,
338 skeleton.signals.track_removed,
339 skeleton.signals.track_changed,
340+ skeleton.signals.track_list_reset,
341 skeleton.signals.tracklist_replaced
342 }
343 {
344@@ -176,8 +181,53 @@
345 media::Track::Id track;
346 msg->reader() >> track;
347
348+ auto id_it = find(impl->tracks().get().begin(), impl->tracks().get().end(), track);
349+ if (id_it == impl->tracks().get().end()) {
350+ ostringstream err_str;
351+ err_str << "Track " << track << " not found in track list";
352+ cout << __PRETTY_FUNCTION__ << " WARNING " << err_str.str() << endl;
353+ auto reply = dbus::Message::make_error(
354+ msg,
355+ mpris::TrackList::Error::TrackNotFound::name,
356+ err_str.str());
357+ bus->send(reply);
358+ return;
359+ }
360+
361+ media::Track::Id next;
362+ bool deleting_current = false;
363+
364+ if (id_it == impl->current_iterator()) {
365+ cout << "Removing current track" << endl;
366+ deleting_current = true;
367+
368+ if (current_track != empty_iterator) {
369+ ++current_track;
370+
371+ if (current_track == impl->tracks().get().end()
372+ && loop_status == media::Player::LoopStatus::playlist)
373+ current_track = impl->tracks().get().begin();
374+
375+ if (current_track == impl->tracks().get().end())
376+ current_track = empty_iterator;
377+ else
378+ next = *current_track;
379+ }
380+ } else if (current_track != empty_iterator) {
381+ next = *current_track;
382+ }
383+
384 impl->remove_track(track);
385
386+ if (not next.empty()) {
387+ current_track = find(impl->tracks().get().begin(), impl->tracks().get().end(), next);
388+
389+ if (deleting_current) {
390+ const bool toggle_player_state = true;
391+ impl->go_to(next, toggle_player_state);
392+ }
393+ }
394+
395 auto reply = dbus::Message::make_method_return(msg);
396 bus->send(reply);
397 }
398@@ -221,12 +271,17 @@
399 typedef core::dbus::Signal<mpris::TrackList::Signals::TracksAdded, mpris::TrackList::Signals::TracksAdded::ArgumentType> DBusTracksAddedSignal;
400 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackRemoved, mpris::TrackList::Signals::TrackRemoved::ArgumentType> DBusTrackRemovedSignal;
401 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackChanged, mpris::TrackList::Signals::TrackChanged::ArgumentType> DBusTrackChangedSignal;
402+ typedef core::dbus::Signal<
403+ mpris::TrackList::Signals::TrackListReset,
404+ mpris::TrackList::Signals::TrackListReset::ArgumentType>
405+ DBusTrackListResetSignal;
406 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackListReplaced, mpris::TrackList::Signals::TrackListReplaced::ArgumentType> DBusTrackListReplacedSignal;
407
408 Signals(const std::shared_ptr<DBusTrackAddedSignal>& remote_track_added,
409 const std::shared_ptr<DBusTracksAddedSignal>& remote_tracks_added,
410 const std::shared_ptr<DBusTrackRemovedSignal>& remote_track_removed,
411 const std::shared_ptr<DBusTrackChangedSignal>& remote_track_changed,
412+ const std::shared_ptr<DBusTrackListResetSignal>& remote_track_list_reset,
413 const std::shared_ptr<DBusTrackListReplacedSignal>& remote_track_list_replaced)
414 {
415 // Connect all of the MPRIS interface signals to be emitted over dbus
416@@ -245,6 +300,11 @@
417 remote_track_removed->emit(id);
418 });
419
420+ on_track_list_reset.connect([remote_track_list_reset]()
421+ {
422+ remote_track_list_reset->emit();
423+ });
424+
425 on_track_changed.connect([remote_track_changed](const media::Track::Id &id)
426 {
427 remote_track_changed->emit(id);
428@@ -259,6 +319,7 @@
429 core::Signal<Track::Id> on_track_added;
430 core::Signal<TrackList::ContainerURI> on_tracks_added;
431 core::Signal<Track::Id> on_track_removed;
432+ core::Signal<void> on_track_list_reset;
433 core::Signal<Track::Id> on_track_changed;
434 core::Signal<TrackList::ContainerTrackIdTuple> on_track_list_replaced;
435 core::Signal<std::pair<Track::Id, bool>> on_go_to_track;
436@@ -401,6 +462,7 @@
437
438 if (do_go_to_next_track)
439 {
440+ cout << "next track id is " << *(current_iterator()) << endl;
441 on_track_changed()(*(current_iterator()));
442 // Don't automatically call stop() and play() in player_implementation.cpp on_go_to_track()
443 // since this breaks video playback when using open_uri() (stop() and play() are unwanted in
444@@ -425,15 +487,15 @@
445 }
446
447 bool do_go_to_previous_track = false;
448- bool repeat_current_track = false;
449- const uint64_t max_position = 4 * 1000;
450+ // Position is measured in nanoseconds
451+ const uint64_t max_position = 5 * UINT64_C(1000000000);
452
453- // If we're playing the current already for some time we will
454+ // If we're playing the current track for > max_position time then
455 // repeat it from the beginning
456 if (d->current_position > max_position)
457 {
458 std::cout << "Repeating current track..." << std::endl;
459- repeat_current_track = true;
460+ do_go_to_previous_track = true;
461 }
462 // Loop on the current track forever
463 else if (d->loop_status == media::Player::LoopStatus::track)
464@@ -465,7 +527,7 @@
465 }
466 }
467
468- if (do_go_to_previous_track && !repeat_current_track)
469+ if (do_go_to_previous_track)
470 {
471 on_track_changed()(*(current_iterator()));
472 // Don't automatically call stop() and play() in player_implementation.cpp on_go_to_track()
473@@ -510,6 +572,21 @@
474 d->current_track = d->empty_iterator;
475 }
476
477+media::Track::Id media::TrackListSkeleton::get_current_track(void)
478+{
479+ if (d->current_track == d->empty_iterator || tracks().get().empty())
480+ return media::Track::Id{};
481+
482+ return *(current_iterator());
483+}
484+
485+void media::TrackListSkeleton::set_current_track(const media::Track::Id& id)
486+{
487+ const auto id_it = find(tracks().get().begin(), tracks().get().end(), id);
488+ if (id_it != tracks().get().end())
489+ d->current_track = id_it;
490+}
491+
492 const core::Property<bool>& media::TrackListSkeleton::can_edit_tracks() const
493 {
494 return *d->skeleton.properties.can_edit_tracks;
495@@ -527,7 +604,6 @@
496
497 void media::TrackListSkeleton::on_position_changed(uint64_t position)
498 {
499- std::cout << "TrackListSkeleton::on_position_changed: position = " << position << std::endl;
500 d->current_position = position;
501 }
502
503@@ -543,21 +619,21 @@
504
505 void media::TrackListSkeleton::on_shuffle_changed(bool shuffle)
506 {
507+ if (tracks().get().empty())
508+ return;
509+
510+ const auto current_id = get_current_track();
511+
512+ cout << __PRETTY_FUNCTION__ << " " << shuffle
513+ << " current track: " << current_id << endl;
514+
515 if (shuffle)
516 shuffle_tracks();
517 else
518- {
519- // Save the current Track::Id of what's currently playing to restore after unshuffle
520- const media::Track::Id current_id = *(current_iterator());
521-
522 unshuffle_tracks();
523
524- // Since we use assign() in unshuffle_tracks, which invalidates existing iterators, we need
525- // to make sure that current is pointing to the right place
526- auto it = std::find(tracks().get().begin(), tracks().get().end(), current_id);
527- if (it != tracks().get().end())
528- d->current_track = it;
529- }
530+ // Shuffling and unshuffling invalidates iterators, so we re-create current_track
531+ set_current_track(current_id);
532 }
533
534 const core::Property<media::TrackList::Container>& media::TrackListSkeleton::tracks() const
535@@ -587,6 +663,11 @@
536 return d->signals.on_track_removed;
537 }
538
539+const core::Signal<void>& media::TrackListSkeleton::on_track_list_reset() const
540+{
541+ return d->signals.on_track_list_reset;
542+}
543+
544 const core::Signal<media::Track::Id>& media::TrackListSkeleton::on_track_changed() const
545 {
546 return d->signals.on_track_changed;
547@@ -622,6 +703,11 @@
548 return d->signals.on_track_removed;
549 }
550
551+core::Signal<void>& media::TrackListSkeleton::on_track_list_reset()
552+{
553+ return d->signals.on_track_list_reset;
554+}
555+
556 core::Signal<media::Track::Id>& media::TrackListSkeleton::on_track_changed()
557 {
558 return d->signals.on_track_changed;
559
560=== modified file 'src/core/media/track_list_skeleton.h'
561--- src/core/media/track_list_skeleton.h 2015-11-13 15:27:09 +0000
562+++ src/core/media/track_list_skeleton.h 2015-11-13 15:27:09 +0000
563@@ -57,6 +57,7 @@
564 const core::Signal<ContainerURI>& on_tracks_added() const;
565 core::Signal<ContainerURI>& on_tracks_added();
566 const core::Signal<Track::Id>& on_track_removed() const;
567+ const core::Signal<void>& on_track_list_reset() const;
568 const core::Signal<Track::Id>& on_track_changed() const;
569 core::Signal<Track::Id>& on_track_changed();
570 const core::Signal<std::pair<Track::Id, bool>>& on_go_to_track() const;
571@@ -64,6 +65,7 @@
572 const core::Signal<void>& on_end_of_tracklist() const;
573 core::Signal<void>& on_end_of_tracklist();
574 core::Signal<Track::Id>& on_track_removed();
575+ core::Signal<void>& on_track_list_reset();
576
577 core::Property<Container>& tracks();
578 void on_loop_status_changed(const core::ubuntu::media::Player::LoopStatus& loop_status);
579@@ -80,6 +82,8 @@
580 inline bool is_last_track(const ConstIterator &it);
581 inline const TrackList::ConstIterator& current_iterator();
582 void reset_current_iterator_if_needed();
583+ media::Track::Id get_current_track(void);
584+ void set_current_track(const media::Track::Id& id);
585
586 core::Property<bool>& can_edit_tracks();
587
588
589=== modified file 'src/core/media/track_list_stub.cpp'
590--- src/core/media/track_list_stub.cpp 2015-10-23 14:39:34 +0000
591+++ src/core/media/track_list_stub.cpp 2015-11-13 15:27:09 +0000
592@@ -54,6 +54,7 @@
593 object->get_signal<mpris::TrackList::Signals::TrackAdded>(),
594 object->get_signal<mpris::TrackList::Signals::TracksAdded>(),
595 object->get_signal<mpris::TrackList::Signals::TrackRemoved>(),
596+ object->get_signal<mpris::TrackList::Signals::TrackListReset>(),
597 object->get_signal<mpris::TrackList::Signals::TrackListReplaced>(),
598 object->get_signal<mpris::TrackList::Signals::TrackChanged>()
599 }
600@@ -73,17 +74,23 @@
601 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackAdded, mpris::TrackList::Signals::TrackAdded::ArgumentType> DBusTrackAddedSignal;
602 typedef core::dbus::Signal<mpris::TrackList::Signals::TracksAdded, mpris::TrackList::Signals::TracksAdded::ArgumentType> DBusTracksAddedSignal;
603 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackRemoved, mpris::TrackList::Signals::TrackRemoved::ArgumentType> DBusTrackRemovedSignal;
604+ typedef core::dbus::Signal<
605+ mpris::TrackList::Signals::TrackListReset,
606+ mpris::TrackList::Signals::TrackListReset::ArgumentType>
607+ DBusTrackListResetSignal;
608 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackListReplaced, mpris::TrackList::Signals::TrackListReplaced::ArgumentType> DBusTrackListReplacedSignal;
609 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackChanged, mpris::TrackList::Signals::TrackChanged::ArgumentType> DBusTrackChangedSignal;
610
611 Signals(const std::shared_ptr<DBusTrackAddedSignal>& track_added,
612 const std::shared_ptr<DBusTracksAddedSignal>& tracks_added,
613 const std::shared_ptr<DBusTrackRemovedSignal>& track_removed,
614+ const std::shared_ptr<DBusTrackListResetSignal>& track_list_reset,
615 const std::shared_ptr<DBusTrackListReplacedSignal>& track_list_replaced,
616 const std::shared_ptr<DBusTrackChangedSignal>& track_changed)
617 : on_track_added(),
618 on_tracks_added(),
619 on_track_removed(),
620+ on_track_list_reset(),
621 on_track_list_replaced(),
622 on_track_changed(),
623 dbus
624@@ -91,6 +98,7 @@
625 track_added,
626 tracks_added,
627 track_removed,
628+ track_list_reset,
629 track_list_replaced,
630 track_changed,
631 }
632@@ -113,9 +121,15 @@
633 on_track_removed(id);
634 });
635
636+ dbus.on_track_list_reset->connect([this](void)
637+ {
638+ std::cout << "OnTrackListReset signal arrived via the bus." << std::endl;
639+ on_track_list_reset();
640+ });
641+
642 dbus.on_track_list_replaced->connect([this](const media::TrackList::ContainerTrackIdTuple& list)
643 {
644- std::cout << "OnTrackListRemoved signal arrived via the bus." << std::endl;
645+ std::cout << "OnTrackListReplaced signal arrived via the bus." << std::endl;
646 on_track_list_replaced(list);
647 });
648
649@@ -129,6 +143,7 @@
650 core::Signal<Track::Id> on_track_added;
651 core::Signal<media::TrackList::ContainerURI> on_tracks_added;
652 core::Signal<Track::Id> on_track_removed;
653+ core::Signal<void> on_track_list_reset;
654 core::Signal<media::TrackList::ContainerTrackIdTuple> on_track_list_replaced;
655 core::Signal<Track::Id> on_track_changed;
656 core::Signal<std::pair<Track::Id, bool>> on_go_to_track;
657@@ -139,6 +154,7 @@
658 std::shared_ptr<DBusTrackAddedSignal> on_track_added;
659 std::shared_ptr<DBusTracksAddedSignal> on_tracks_added;
660 std::shared_ptr<DBusTrackRemovedSignal> on_track_removed;
661+ std::shared_ptr<DBusTrackListResetSignal> on_track_list_reset;
662 std::shared_ptr<DBusTrackListReplacedSignal> on_track_list_replaced;
663 std::shared_ptr<DBusTrackChangedSignal> on_track_changed;
664 } dbus;
665@@ -237,7 +253,13 @@
666 track);
667
668 if (op.is_error())
669- throw std::runtime_error("Problem removing track: " + op.error());
670+ {
671+ if (op.error().name() ==
672+ mpris::TrackList::Error::TrackNotFound::name)
673+ throw media::TrackList::Errors::TrackNotFound{};
674+ else
675+ throw std::runtime_error{"Problem removing track: " + op.error().print()};
676+ }
677 }
678
679 void media::TrackListStub::go_to(const media::Track::Id& track, bool toggle_player_state)
680@@ -300,6 +322,11 @@
681 return d->signals.on_track_removed;
682 }
683
684+const core::Signal<void>& media::TrackListStub::on_track_list_reset() const
685+{
686+ return d->signals.on_track_list_reset;
687+}
688+
689 const core::Signal<media::Track::Id>& media::TrackListStub::on_track_changed() const
690 {
691 return d->signals.on_track_changed;
692
693=== modified file 'src/core/media/track_list_stub.h'
694--- src/core/media/track_list_stub.h 2015-10-21 19:40:20 +0000
695+++ src/core/media/track_list_stub.h 2015-11-13 15:27:09 +0000
696@@ -65,6 +65,7 @@
697 const core::Signal<Track::Id>& on_track_added() const;
698 const core::Signal<ContainerURI>& on_tracks_added() const;
699 const core::Signal<Track::Id>& on_track_removed() const;
700+ const core::Signal<void>& on_track_list_reset() const;
701 const core::Signal<Track::Id>& on_track_changed() const;
702 const core::Signal<std::pair<Track::Id, bool>>& on_go_to_track() const;
703 const core::Signal<void>& on_end_of_tracklist() const;

Subscribers

People subscribed via source and target branches

to all changes: