Merge lp:~phablet-team/media-hub/bg-playlist-fixes into lp:media-hub/stable
- bg-playlist-fixes
- Merge into stable
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 |
Related bugs: |
|
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).
- 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.
- 167. By Alfonso Sanchez-Beato
-
Address review comments
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : | # |
Branch refreshed after addressing comments.
Jim Hodapp (jhodapp) wrote : | # |
Looks good, one minor change still needed.
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : | # |
Branch refreshed after addressing comment.
- 168. By Alfonso Sanchez-Beato
-
Address review comment
- 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
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : | # |
lp:~morphis/media-hub/previous-to-same-after-four-secs merged + fix for it
- 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
Jim Hodapp (jhodapp) wrote : | # |
A few comments below about the latest changes.
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
Jim Hodapp (jhodapp) wrote : | # |
Several comments inline below.
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote : | # |
See comments below. I will address the remaining issues asap.
- 176. By Alfonso Sanchez-Beato
-
Address review comments
Jim Hodapp (jhodapp) wrote : | # |
A couple of comments below.
Preview Diff
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; |
A few comments inline.