32 #include <core/dbus/object.h>
33 #include <core/dbus/property.h>
34 #include <core/dbus/types/object_path.h>
35 #include <core/dbus/types/variant.h>
36 #include <core/dbus/types/stl/map.h>
37 #include <core/dbus/types/stl/vector.h>
53 request_context_resolver(request_context_resolver),
54 request_authenticator(request_authenticator),
72 msg->reader() >> track;
74 const auto meta_data =
impl->query_meta_data_for_track(track);
76 const auto reply = dbus::Message::make_method_return(msg);
77 reply->writer() << *meta_data;
84 msg->reader() >> track;
86 const auto uri =
impl->query_uri_for_track(track);
88 const auto reply = dbus::Message::make_method_return(msg);
89 reply->writer() << uri;
95 std::cout <<
"*** " << __PRETTY_FUNCTION__ << std::endl;
96 request_context_resolver->resolve_context_for_dbus_name_async(msg->sender(), [
this, msg](
const media::apparmor::ubuntu::Context& context)
99 msg->reader() >> uri >> after >> make_current;
104 auto reply = dbus::Message::make_method_return(msg);
106 if (std::get<0>(result))
107 impl->add_track_with_uri_at(uri, after, make_current);
109 std::cerr <<
"Warning: Not adding track " << uri <<
110 " to TrackList because of inadequate client apparmor permissions." << std::endl;
119 msg->reader() >> track;
121 impl->remove_track(track);
123 auto reply = dbus::Message::make_method_return(msg);
130 msg->reader() >> track;
133 const bool toggle_player_state =
true;
134 impl->go_to(track, toggle_player_state);
136 auto reply = dbus::Message::make_method_return(msg);
144 auto reply = dbus::Message::make_method_return(msg);
161 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackAdded, mpris::TrackList::Signals::TrackAdded::ArgumentType>
DBusTrackAddedSignal;
162 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackRemoved, mpris::TrackList::Signals::TrackRemoved::ArgumentType>
DBusTrackRemovedSignal;
163 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackChanged, mpris::TrackList::Signals::TrackChanged::ArgumentType>
DBusTrackChangedSignal;
164 typedef core::dbus::Signal<mpris::TrackList::Signals::TrackListReplaced, mpris::TrackList::Signals::TrackListReplaced::ArgumentType>
DBusTrackListReplacedSignal;
166 Signals(
const std::shared_ptr<DBusTrackAddedSignal>& remote_track_added,
167 const std::shared_ptr<DBusTrackRemovedSignal>& remote_track_removed,
168 const std::shared_ptr<DBusTrackChangedSignal>& remote_track_changed,
169 const std::shared_ptr<DBusTrackListReplacedSignal>& remote_track_list_replaced)
174 remote_track_added->emit(
id);
179 remote_track_removed->emit(
id);
184 remote_track_changed->emit(
id);
189 remote_track_list_replaced->emit(tltuple);
203 const media::apparmor::ubuntu::RequestContextResolver::Ptr& request_context_resolver,
204 const media::apparmor::ubuntu::RequestAuthenticator::Ptr& request_authenticator)
205 : d(new
Private(this, bus, object, request_context_resolver, request_authenticator))
207 d->object->install_method_handler<mpris::TrackList::GetTracksMetadata>(
210 std::placeholders::_1));
212 d->object->install_method_handler<mpris::TrackList::GetTracksUri>(
215 std::placeholders::_1));
217 d->object->install_method_handler<mpris::TrackList::AddTrack>(
220 std::placeholders::_1));
222 d->object->install_method_handler<mpris::TrackList::RemoveTrack>(
225 std::placeholders::_1));
227 d->object->install_method_handler<mpris::TrackList::GoTo>(
230 std::placeholders::_1));
232 d->object->install_method_handler<mpris::TrackList::Reset>(
235 std::placeholders::_1));
244 if (
tracks().
get().empty())
253 if (
tracks().
get().empty())
257 if (d->loop_status == media::Player::LoopStatus::playlist)
260 return d->current_track != std::begin(
tracks().
get());
265 return it == std::begin(
tracks().
get());
270 return it == std::end(
tracks().
get());
275 std::cout << __PRETTY_FUNCTION__ << std::endl;
276 if (
tracks().
get().empty())
277 return *(d->empty_iterator);
280 bool do_go_to_next_track =
false;
283 if (d->loop_status == media::Player::LoopStatus::track)
285 std::cout <<
"Looping on the current track since LoopStatus is set to track" << std::endl;
286 do_go_to_next_track =
true;
289 else if (d->loop_status == media::Player::LoopStatus::playlist && not
has_next())
291 std::cout <<
"Looping on the tracklist since LoopStatus is set to playlist" << std::endl;
292 d->current_track =
tracks().get().begin();
293 do_go_to_next_track =
true;
300 std::cout <<
"Advancing to next track: " << *(next_track) << std::endl;
301 d->current_track = next_track;
302 do_go_to_next_track =
true;
307 std::cout <<
"End of tracklist reached, not advancing to next since LoopStatus is set to none" << std::endl;
312 if (do_go_to_next_track)
318 const bool toggle_player_state =
false;
320 const std::pair<const media::Track::Id, bool> p = std::make_pair(
id, toggle_player_state);
330 std::cout << __PRETTY_FUNCTION__ << std::endl;
331 if (
tracks().
get().empty())
332 return *(d->empty_iterator);
334 bool do_go_to_previous_track =
false;
337 if (d->loop_status == media::Player::LoopStatus::track)
339 std::cout <<
"Looping on the current track..." << std::endl;
340 do_go_to_previous_track =
true;
345 std::cout <<
"Looping on the entire TrackList..." << std::endl;
346 d->current_track = std::prev(
tracks().
get().end());
347 do_go_to_previous_track =
true;
356 do_go_to_previous_track =
true;
361 std::cout <<
"Beginning of tracklist reached, not advancing to previous since LoopStatus is set to none" << std::endl;
366 if (do_go_to_previous_track)
372 const bool toggle_player_state =
false;
374 const std::pair<const media::Track::Id, bool> p = std::make_pair(
id, toggle_player_state);
390 if (
tracks().
get().size() && (d->current_track == d->empty_iterator))
392 std::cout <<
"Wrapping d->current_track back to begin()" << std::endl;
393 d->current_track = d->skeleton.properties.tracks->get().begin();
395 else if (
tracks().
get().empty())
397 std::cerr <<
"TrackList is empty therefore there is no valid current track" << std::endl;
400 return d->current_track;
407 if (
tracks().
get().empty())
408 d->current_track = d->empty_iterator;
413 return *d->skeleton.properties.can_edit_tracks;
418 return *d->skeleton.properties.can_edit_tracks;
423 return *d->skeleton.properties.tracks;
433 return d->loop_status;
449 auto it = std::find(
tracks().
get().begin(),
tracks().
get().end(), current_id);
450 if (it !=
tracks().
get().end())
451 d->current_track = it;
457 return *d->skeleton.properties.tracks;
463 std::cout << *
this << std::endl;
464 return d->signals.on_track_list_replaced;
469 return d->signals.on_track_added;
474 return d->signals.on_track_removed;
479 return d->signals.on_track_changed;
484 return d->signals.on_go_to_track;
489 return d->signals.on_end_of_tracklist;
494 return d->signals.on_track_list_replaced;
499 return d->signals.on_track_added;
504 return d->signals.on_track_removed;
509 return d->signals.on_track_changed;
514 return d->signals.on_go_to_track;
519 return d->signals.on_end_of_tracklist;
524 std::cout << __PRETTY_FUNCTION__ << std::endl;
525 d->current_track = d->empty_iterator;
532 out <<
"TrackList\n---------------" << std::endl;
537 out <<
"Track Id: " <<
id << std::endl;
541 out <<
"---------------\nEnd TrackList" << std::endl;
struct mpris::TrackList::Skeleton::@20 signals
std::shared_ptr< core::dbus::Property< Properties::Tracks > > tracks
core::dbus::Signal< Signals::TrackListReplaced, Signals::TrackListReplaced::ArgumentType >::Ptr tracklist_replaced
core::dbus::Signal< Signals::TrackAdded, Signals::TrackAdded::ArgumentType >::Ptr track_added
core::dbus::Signal< Signals::TrackRemoved, Signals::TrackRemoved::ArgumentType >::Ptr track_removed
struct mpris::TrackList::Skeleton::@19 properties
core::dbus::Signal< Signals::TrackChanged, Signals::TrackChanged::ArgumentType >::Ptr track_changed