Music Hub  ..
A session-wide music playback service
player_skeleton.cpp
Go to the documentation of this file.
1 /*
2  * Copyright © 2013-2015 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by: Thomas Voß <thomas.voss@canonical.com>
17  * Jim Hodapp <jim.hodapp@canonical.com>
18  */
19 
20 #include "codec.h"
21 #include "engine.h"
22 #include "external_services.h"
23 #include "player_skeleton.h"
24 #include "player_traits.h"
25 #include "property_stub.h"
26 #include "the_session_bus.h"
27 #include "xesam.h"
28 
29 #include "apparmor/ubuntu.h"
30 #include "mpris/media_player2.h"
31 #include "mpris/metadata.h"
32 #include "mpris/player.h"
33 #include "mpris/playlists.h"
34 #include "util/uri_check.h"
35 
36 #include <core/dbus/object.h>
37 #include <core/dbus/property.h>
38 #include <core/dbus/stub.h>
39 
40 #include <core/dbus/asio/executor.h>
41 #include <core/dbus/interfaces/properties.h>
42 
43 namespace dbus = core::dbus;
44 namespace media = core::ubuntu::media;
45 
47 {
49  const std::shared_ptr<core::dbus::Bus>& bus,
50  const std::shared_ptr<core::dbus::Object>& session,
51  const apparmor::ubuntu::RequestContextResolver::Ptr& request_context_resolver,
52  const apparmor::ubuntu::RequestAuthenticator::Ptr& request_authenticator)
53  : impl(player),
54  bus(bus),
55  object(session),
56  request_context_resolver{request_context_resolver},
58  uri_check(std::make_shared<UriCheck>()),
60  signals
61  {
68  }
69  {
70  }
71 
72  void handle_next(const core::dbus::Message::Ptr& msg)
73  {
74  impl->next();
75  auto reply = dbus::Message::make_method_return(msg);
76  bus->send(reply);
77  }
78 
79  void handle_previous(const core::dbus::Message::Ptr& msg)
80  {
81  impl->previous();
82  auto reply = dbus::Message::make_method_return(msg);
83  bus->send(reply);
84  }
85 
86  void handle_pause(const core::dbus::Message::Ptr& msg)
87  {
88  impl->pause();
89  auto reply = dbus::Message::make_method_return(msg);
90  bus->send(reply);
91  }
92 
93  void handle_stop(const core::dbus::Message::Ptr& msg)
94  {
95  impl->stop();
96  auto reply = dbus::Message::make_method_return(msg);
97  bus->send(reply);
98  }
99 
100  void handle_play(const core::dbus::Message::Ptr& msg)
101  {
102  impl->play();
103  auto reply = dbus::Message::make_method_return(msg);
104  bus->send(reply);
105  }
106 
107  void handle_play_pause(const core::dbus::Message::Ptr& msg)
108  {
109  switch(impl->playback_status().get())
110  {
111  case core::ubuntu::media::Player::PlaybackStatus::ready:
112  case core::ubuntu::media::Player::PlaybackStatus::paused:
113  case core::ubuntu::media::Player::PlaybackStatus::stopped:
114  impl->play();
115  break;
116  case core::ubuntu::media::Player::PlaybackStatus::playing:
117  impl->pause();
118  break;
119  default:
120  break;
121  }
122 
123  bus->send(dbus::Message::make_method_return(msg));
124  }
125 
126  void handle_seek(const core::dbus::Message::Ptr& in)
127  {
128  uint64_t ticks;
129  in->reader() >> ticks;
130  impl->seek_to(std::chrono::microseconds(ticks));
131 
132  auto reply = dbus::Message::make_method_return(in);
133  bus->send(reply);
134  }
135 
136  void handle_set_position(const core::dbus::Message::Ptr&)
137  {
138  }
139 
140  void handle_create_video_sink(const core::dbus::Message::Ptr& in)
141  {
142  uint32_t texture_id;
143  in->reader() >> texture_id;
144 
145  core::dbus::Message::Ptr reply;
146 
147  try
148  {
149  impl->create_gl_texture_video_sink(texture_id);
150  reply = dbus::Message::make_method_return(in);
151  }
152  catch (const media::Player::Errors::OutOfProcessBufferStreamingNotSupported& e)
153  {
154  reply = dbus::Message::make_error(
155  in,
157  e.what());
158  }
159  catch (...)
160  {
161  reply = dbus::Message::make_error(
162  in,
164  std::string{});
165  }
166 
167  bus->send(reply);
168  }
169 
170  void handle_key(const core::dbus::Message::Ptr& in)
171  {
172  auto reply = dbus::Message::make_method_return(in);
173  reply->writer() << impl->key();
174  bus->send(reply);
175  }
176 
177  void handle_open_uri(const core::dbus::Message::Ptr& in)
178  {
179  request_context_resolver->resolve_context_for_dbus_name_async(in->sender(), [this, in](const media::apparmor::ubuntu::Context& context)
180  {
181  Track::UriType uri;
182  in->reader() >> uri;
183 
184  auto reply = dbus::Message::make_method_return(in);
185  uri_check->set(uri);
186  const bool valid_uri = !uri_check->is_local_file() or
187  (uri_check->is_local_file() and uri_check->file_exists());
188  if (!valid_uri)
189  {
190  const std::string err_str = {"Warning: Failed to open uri " + uri +
191  " because it can't be found."};
192  std::cerr << err_str << std::endl;
193  reply = dbus::Message::make_error(
194  in,
196  err_str);
197  }
198  else
199  {
200  // Make sure the client has adequate apparmor permissions to open the URI
201  const auto result = request_authenticator->authenticate_open_uri_request(context, uri);
202  if (std::get<0>(result))
203  {
204  reply->writer() << (std::get<0>(result) ? impl->open_uri(uri) : false);
205  }
206  else
207  {
208  const std::string err_str = {"Warning: Failed to authenticate necessary "
209  "apparmor permissions to open uri: " + std::get<1>(result)};
210  std::cerr << err_str << std::endl;
211  reply = dbus::Message::make_error(
212  in,
214  err_str);
215  }
216  }
217 
218  bus->send(reply);
219  });
220  }
221 
222  void handle_open_uri_extended(const core::dbus::Message::Ptr& in)
223  {
224  request_context_resolver->resolve_context_for_dbus_name_async(in->sender(), [this, in](const media::apparmor::ubuntu::Context& context)
225  {
226  Track::UriType uri;
227  Player::HeadersType headers;
228 
229  in->reader() >> uri >> headers;
230 
231  auto reply = dbus::Message::make_method_return(in);
232  uri_check->set(uri);
233  const bool valid_uri = !uri_check->is_local_file() or
234  (uri_check->is_local_file() and uri_check->file_exists());
235  if (!valid_uri)
236  {
237  const std::string err_str = {"Warning: Failed to open uri " + uri +
238  " because it can't be found."};
239  std::cerr << err_str << std::endl;
240  reply = dbus::Message::make_error(
241  in,
243  err_str);
244  }
245  else
246  {
247  // Make sure the client has adequate apparmor permissions to open the URI
248  const auto result = request_authenticator->authenticate_open_uri_request(context, uri);
249  if (std::get<0>(result))
250  {
251  reply->writer() << (std::get<0>(result) ? impl->open_uri(uri, headers) : false);
252  }
253  else
254  {
255  const std::string err_str = {"Warning: Failed to authenticate necessary "
256  "apparmor permissions to open uri: " + std::get<1>(result)};
257  std::cerr << err_str << std::endl;
258  reply = dbus::Message::make_error(
259  in,
261  err_str);
262  }
263  }
264 
265  bus->send(reply);
266  });
267  }
268 
269  template<typename Property>
271  const typename Property::ValueType& value,
272  const dbus::Signal
273  <
274  core::dbus::interfaces::Properties::Signals::PropertiesChanged,
275  core::dbus::interfaces::Properties::Signals::PropertiesChanged::ArgumentType
276  >::Ptr& signal)
277  {
278  typedef std::map<std::string, dbus::types::Variant> Dictionary;
279 
280  static const std::vector<std::string> the_empty_list_of_invalidated_properties;
281 
282  Dictionary dict; dict[Property::name()] = dbus::types::Variant::encode(value);
283 
284  signal->emit(std::make_tuple(
285  dbus::traits::Service<typename Property::Interface>::interface_name(),
286  dict,
287  the_empty_list_of_invalidated_properties));
288  }
289 
291  dbus::Bus::Ptr bus;
292  dbus::Object::Ptr object;
293  media::apparmor::ubuntu::RequestContextResolver::Ptr request_context_resolver;
294  media::apparmor::ubuntu::RequestAuthenticator::Ptr request_authenticator;
296 
298 
299  struct Signals
300  {
301  typedef core::dbus::Signal<mpris::Player::Signals::Seeked, mpris::Player::Signals::Seeked::ArgumentType> DBusSeekedToSignal;
302  typedef core::dbus::Signal<mpris::Player::Signals::EndOfStream, mpris::Player::Signals::EndOfStream::ArgumentType> DBusEndOfStreamSignal;
303  typedef core::dbus::Signal<mpris::Player::Signals::AboutToFinish, mpris::Player::Signals::AboutToFinish::ArgumentType> DBusAboutToFinishSignal;
304  typedef core::dbus::Signal<mpris::Player::Signals::PlaybackStatusChanged, mpris::Player::Signals::PlaybackStatusChanged::ArgumentType> DBusPlaybackStatusChangedSignal;
305  typedef core::dbus::Signal<mpris::Player::Signals::VideoDimensionChanged, mpris::Player::Signals::VideoDimensionChanged::ArgumentType> DBusVideoDimensionChangedSignal;
306  typedef core::dbus::Signal<mpris::Player::Signals::Error, mpris::Player::Signals::Error::ArgumentType> DBusErrorSignal;
307 
308  Signals(const std::shared_ptr<DBusSeekedToSignal>& remote_seeked,
309  const std::shared_ptr<DBusAboutToFinishSignal>& remote_atf,
310  const std::shared_ptr<DBusEndOfStreamSignal>& remote_eos,
311  const std::shared_ptr<DBusPlaybackStatusChangedSignal>& remote_playback_status_changed,
312  const std::shared_ptr<DBusVideoDimensionChangedSignal>& remote_video_dimension_changed,
313  const std::shared_ptr<DBusErrorSignal>& remote_error)
314  {
315  seeked_to.connect([remote_seeked](std::uint64_t value)
316  {
317  remote_seeked->emit(value);
318  });
319 
320  about_to_finish.connect([remote_atf]()
321  {
322  remote_atf->emit();
323  });
324 
325  end_of_stream.connect([remote_eos]()
326  {
327  remote_eos->emit();
328  });
329 
330  playback_status_changed.connect([remote_playback_status_changed](const media::Player::PlaybackStatus& status)
331  {
332  remote_playback_status_changed->emit(status);
333  });
334 
335  video_dimension_changed.connect([remote_video_dimension_changed](const media::video::Dimensions& dimensions)
336  {
337  remote_video_dimension_changed->emit(dimensions);
338  });
339 
340  error.connect([remote_error](const media::Player::Error& e)
341  {
342  remote_error->emit(e);
343  });
344  }
345 
346  core::Signal<int64_t> seeked_to;
347  core::Signal<void> about_to_finish;
348  core::Signal<void> end_of_stream;
349  core::Signal<media::Player::PlaybackStatus> playback_status_changed;
350  core::Signal<media::video::Dimensions> video_dimension_changed;
351  core::Signal<media::Player::Error> error;
352  } signals;
353 
354 };
355 
356 media::PlayerSkeleton::PlayerSkeleton(const media::PlayerSkeleton::Configuration& config)
357  : d(new Private{this, config.bus, config.session, config.request_context_resolver, config.request_authenticator})
358 {
359  // Setup method handlers for mpris::Player methods.
360  auto next = std::bind(&Private::handle_next, d, std::placeholders::_1);
361  d->object->install_method_handler<mpris::Player::Next>(next);
362 
363  auto previous = std::bind(&Private::handle_previous, d, std::placeholders::_1);
364  d->object->install_method_handler<mpris::Player::Previous>(previous);
365 
366  auto pause = std::bind(&Private::handle_pause, d, std::placeholders::_1);
367  d->object->install_method_handler<mpris::Player::Pause>(pause);
368 
369  auto stop = std::bind(&Private::handle_stop, d, std::placeholders::_1);
370  d->object->install_method_handler<mpris::Player::Stop>(stop);
371 
372  auto play = std::bind(&Private::handle_play, d, std::placeholders::_1);
373  d->object->install_method_handler<mpris::Player::Play>(play);
374 
375  auto play_pause = std::bind(&Private::handle_play_pause, d, std::placeholders::_1);
376  d->object->install_method_handler<mpris::Player::PlayPause>(play_pause);
377 
378  auto seek = std::bind(&Private::handle_seek, d, std::placeholders::_1);
379  d->object->install_method_handler<mpris::Player::Seek>(seek);
380 
381  auto set_position = std::bind(&Private::handle_set_position, d, std::placeholders::_1);
382  d->object->install_method_handler<mpris::Player::SetPosition>(set_position);
383 
384  auto open_uri = std::bind(&Private::handle_open_uri, d, std::placeholders::_1);
385  d->object->install_method_handler<mpris::Player::OpenUri>(open_uri);
386 
387  // All the method handlers that exceed the mpris spec go here.
388  d->object->install_method_handler<mpris::Player::CreateVideoSink>(
390  d,
391  std::placeholders::_1));
392 
393  d->object->install_method_handler<mpris::Player::Key>(
394  std::bind(&Private::handle_key,
395  d,
396  std::placeholders::_1));
397 
398  d->object->install_method_handler<mpris::Player::OpenUriExtended>(
400  d,
401  std::placeholders::_1));
402 }
403 
405 {
406  // The session object may outlive the private instance
407  // so uninstall all method handlers.
408  d->object->uninstall_method_handler<mpris::Player::Next>();
409  d->object->uninstall_method_handler<mpris::Player::Previous>();
410  d->object->uninstall_method_handler<mpris::Player::Pause>();
411  d->object->uninstall_method_handler<mpris::Player::Stop>();
412  d->object->uninstall_method_handler<mpris::Player::Play>();
413  d->object->uninstall_method_handler<mpris::Player::PlayPause>();
414  d->object->uninstall_method_handler<mpris::Player::Seek>();
415  d->object->uninstall_method_handler<mpris::Player::SetPosition>();
416  d->object->uninstall_method_handler<mpris::Player::OpenUri>();
417  d->object->uninstall_method_handler<mpris::Player::CreateVideoSink>();
418  d->object->uninstall_method_handler<mpris::Player::Key>();
419  d->object->uninstall_method_handler<mpris::Player::OpenUriExtended>();
420 }
421 
422 const core::Property<bool>& media::PlayerSkeleton::can_play() const
423 {
424  return *d->skeleton.properties.can_play;
425 }
426 
427 const core::Property<bool>& media::PlayerSkeleton::can_pause() const
428 {
429  return *d->skeleton.properties.can_pause;
430 }
431 
432 const core::Property<bool>& media::PlayerSkeleton::can_seek() const
433 {
434  return *d->skeleton.properties.can_seek;
435 }
436 
437 const core::Property<bool>& media::PlayerSkeleton::can_go_previous() const
438 {
439  return *d->skeleton.properties.can_go_previous;
440 }
441 
442 const core::Property<bool>& media::PlayerSkeleton::can_go_next() const
443 {
444  return *d->skeleton.properties.can_go_next;
445 }
446 
447 const core::Property<bool>& media::PlayerSkeleton::is_video_source() const
448 {
449  return *d->skeleton.properties.is_video_source;
450 }
451 
452 const core::Property<bool>& media::PlayerSkeleton::is_audio_source() const
453 {
454  return *d->skeleton.properties.is_audio_source;
455 }
456 
457 const core::Property<media::Player::PlaybackStatus>& media::PlayerSkeleton::playback_status() const
458 {
459  return *d->skeleton.properties.typed_playback_status;
460 }
461 
462 const core::Property<media::Player::LoopStatus>& media::PlayerSkeleton::loop_status() const
463 {
464  return *d->skeleton.properties.typed_loop_status;
465 }
466 
467 const core::Property<media::Player::PlaybackRate>& media::PlayerSkeleton::playback_rate() const
468 {
469  return *d->skeleton.properties.playback_rate;
470 }
471 
472 const core::Property<bool>& media::PlayerSkeleton::shuffle() const
473 {
474  return *d->skeleton.properties.shuffle;
475 }
476 
477 const core::Property<media::Track::MetaData>& media::PlayerSkeleton::meta_data_for_current_track() const
478 {
479  return *d->skeleton.properties.typed_meta_data_for_current_track;
480 }
481 
482 const core::Property<media::Player::Volume>& media::PlayerSkeleton::volume() const
483 {
484  return *d->skeleton.properties.volume;
485 }
486 
487 const core::Property<int64_t>& media::PlayerSkeleton::position() const
488 {
489  return *d->skeleton.properties.position;
490 }
491 
492 const core::Property<int64_t>& media::PlayerSkeleton::duration() const
493 {
494  return *d->skeleton.properties.duration;
495 }
496 
497 const core::Property<media::Player::AudioStreamRole>& media::PlayerSkeleton::audio_stream_role() const
498 {
499  return *d->skeleton.properties.audio_stream_role;
500 }
501 
502 const core::Property<media::Player::Orientation>& media::PlayerSkeleton::orientation() const
503 {
504  return *d->skeleton.properties.orientation;
505 }
506 
507 const core::Property<media::Player::Lifetime>& media::PlayerSkeleton::lifetime() const
508 {
509  return *d->skeleton.properties.lifetime;
510 }
511 
512 const core::Property<media::Player::PlaybackRate>& media::PlayerSkeleton::minimum_playback_rate() const
513 {
514  return *d->skeleton.properties.minimum_playback_rate;
515 }
516 
517 const core::Property<media::Player::PlaybackRate>& media::PlayerSkeleton::maximum_playback_rate() const
518 {
519  return *d->skeleton.properties.maximum_playback_rate;
520 }
521 
522 core::Property<media::Player::LoopStatus>& media::PlayerSkeleton::loop_status()
523 {
524  return *d->skeleton.properties.typed_loop_status;
525 }
526 
527 core::Property<media::Player::PlaybackRate>& media::PlayerSkeleton::playback_rate()
528 {
529  return *d->skeleton.properties.playback_rate;
530 }
531 
532 core::Property<bool>& media::PlayerSkeleton::shuffle()
533 {
534  return *d->skeleton.properties.shuffle;
535 }
536 
537 core::Property<media::Player::Volume>& media::PlayerSkeleton::volume()
538 {
539  return *d->skeleton.properties.volume;
540 }
541 
542 core::Property<int64_t>& media::PlayerSkeleton::position()
543 {
544  return *d->skeleton.properties.position;
545 }
546 
547 core::Property<int64_t>& media::PlayerSkeleton::duration()
548 {
549  return *d->skeleton.properties.duration;
550 }
551 
552 core::Property<media::Player::AudioStreamRole>& media::PlayerSkeleton::audio_stream_role()
553 {
554  return *d->skeleton.properties.audio_stream_role;
555 }
556 
557 core::Property<media::Player::Orientation>& media::PlayerSkeleton::orientation()
558 {
559  return *d->skeleton.properties.orientation;
560 }
561 
562 core::Property<media::Player::Lifetime>& media::PlayerSkeleton::lifetime()
563 {
564  return *d->skeleton.properties.lifetime;
565 }
566 
567 core::Property<media::Player::PlaybackStatus>& media::PlayerSkeleton::playback_status()
568 {
569  return *d->skeleton.properties.typed_playback_status;
570 }
571 
572 core::Property<bool>& media::PlayerSkeleton::can_play()
573 {
574  return *d->skeleton.properties.can_play;
575 }
576 
577 core::Property<bool>& media::PlayerSkeleton::can_pause()
578 {
579  return *d->skeleton.properties.can_pause;
580 }
581 
582 core::Property<bool>& media::PlayerSkeleton::can_seek()
583 {
584  return *d->skeleton.properties.can_seek;
585 }
586 
587 core::Property<bool>& media::PlayerSkeleton::can_go_previous()
588 {
589  return *d->skeleton.properties.can_go_previous;
590 }
591 
592 core::Property<bool>& media::PlayerSkeleton::can_go_next()
593 {
594  return *d->skeleton.properties.can_go_next;
595 }
596 
597 core::Property<bool>& media::PlayerSkeleton::is_video_source()
598 {
599  return *d->skeleton.properties.is_video_source;
600 }
601 
602 core::Property<bool>& media::PlayerSkeleton::is_audio_source()
603 {
604  return *d->skeleton.properties.is_audio_source;
605 }
606 
607 core::Property<media::Track::MetaData>& media::PlayerSkeleton::meta_data_for_current_track()
608 {
609  return *d->skeleton.properties.typed_meta_data_for_current_track;
610 }
611 
612 core::Property<media::Player::PlaybackRate>& media::PlayerSkeleton::minimum_playback_rate()
613 {
614  return *d->skeleton.properties.minimum_playback_rate;
615 }
616 
617 core::Property<media::Player::PlaybackRate>& media::PlayerSkeleton::maximum_playback_rate()
618 {
619  return *d->skeleton.properties.maximum_playback_rate;
620 }
621 
622 const core::Signal<int64_t>& media::PlayerSkeleton::seeked_to() const
623 {
624  return d->signals.seeked_to;
625 }
626 
627 core::Signal<int64_t>& media::PlayerSkeleton::seeked_to()
628 {
629  return d->signals.seeked_to;
630 }
631 
632 const core::Signal<void>& media::PlayerSkeleton::about_to_finish() const
633 {
634  return d->signals.about_to_finish;
635 }
636 
637 core::Signal<void>& media::PlayerSkeleton::about_to_finish()
638 {
639  return d->signals.about_to_finish;
640 }
641 
642 const core::Signal<void>& media::PlayerSkeleton::end_of_stream() const
643 {
644  return d->signals.end_of_stream;
645 }
646 
647 core::Signal<void>& media::PlayerSkeleton::end_of_stream()
648 {
649  return d->signals.end_of_stream;
650 }
651 
652 core::Signal<media::Player::PlaybackStatus>& media::PlayerSkeleton::playback_status_changed()
653 {
654  return d->signals.playback_status_changed;
655 }
656 
657 const core::Signal<media::video::Dimensions>& media::PlayerSkeleton::video_dimension_changed() const
658 {
659  return d->signals.video_dimension_changed;
660 }
661 
662 core::Signal<media::video::Dimensions>& media::PlayerSkeleton::video_dimension_changed()
663 {
664  return d->signals.video_dimension_changed;
665 }
666 
667 core::Signal<media::Player::Error>& media::PlayerSkeleton::error()
668 {
669  return d->signals.error;
670 }
671 
672 const core::Signal<media::Player::Error>& media::PlayerSkeleton::error() const
673 {
674  return d->signals.error;
675 }
void handle_previous(const core::dbus::Message::Ptr &msg)
struct mpris::Player::Skeleton::@16 signals
virtual const core::Signal< Error > & error() const
mpris::Player::Skeleton skeleton
void handle_play(const core::dbus::Message::Ptr &msg)
virtual const core::Property< PlaybackStatus > & playback_status() const
std::tuple< Height, Width > Dimensions
Height and Width of a video.
Definition: dimensions.h:139
virtual const core::Property< bool > & is_video_source() const
virtual const core::Signal< void > & end_of_stream() const
virtual const core::Property< int64_t > & duration() const
virtual const core::Property< bool > & can_seek() const
virtual const core::Property< PlaybackRate > & maximum_playback_rate() const
virtual const core::Property< bool > & can_go_next() const
virtual const core::Property< int64_t > & position() const
virtual const core::Property< bool > & can_go_previous() const
virtual void previous()=0
void handle_set_position(const core::dbus::Message::Ptr &)
void handle_open_uri_extended(const core::dbus::Message::Ptr &in)
virtual const core::Property< bool > & can_play() const
core::dbus::Signal< Signals::VideoDimensionChanged, Signals::VideoDimensionChanged::ArgumentType >::Ptr video_dimension_changed
Definition: player.h:422
virtual const core::Signal< void > & about_to_finish() const
std::map< std::string, std::string > HeadersType
Definition: player.h:49
void handle_play_pause(const core::dbus::Message::Ptr &msg)
virtual const core::Property< Track::MetaData > & meta_data_for_current_track() const
virtual const core::Property< bool > & can_pause() const
virtual const core::Property< LoopStatus > & loop_status() const
void handle_stop(const core::dbus::Message::Ptr &msg)
virtual bool open_uri(const Track::UriType &uri)=0
virtual const core::Signal< int64_t > & seeked_to() const
virtual const core::Property< PlaybackRate > & playback_rate() const
PlayerSkeleton(const Configuration &configuration)
static constexpr const char * name
Definition: player.h:131
Private(media::PlayerSkeleton *player, const std::shared_ptr< core::dbus::Bus > &bus, const std::shared_ptr< core::dbus::Object > &session, const apparmor::ubuntu::RequestContextResolver::Ptr &request_context_resolver, const apparmor::ubuntu::RequestAuthenticator::Ptr &request_authenticator)
virtual const core::Property< AudioStreamRole > & audio_stream_role() const
std::shared_ptr< UriCheck > Ptr
Definition: uri_check.h:37
core::dbus::Signal< mpris::Player::Signals::EndOfStream, mpris::Player::Signals::EndOfStream::ArgumentType > DBusEndOfStreamSignal
media::apparmor::ubuntu::RequestContextResolver::Ptr request_context_resolver
media::PlayerSkeleton * impl
core::dbus::Signal< Signals::AboutToFinish, Signals::AboutToFinish::ArgumentType >::Ptr about_to_finish
Definition: player.h:419
core::dbus::Signal< mpris::Player::Signals::VideoDimensionChanged, mpris::Player::Signals::VideoDimensionChanged::ArgumentType > DBusVideoDimensionChangedSignal
void handle_pause(const core::dbus::Message::Ptr &msg)
core::dbus::Signal< mpris::Player::Signals::PlaybackStatusChanged, mpris::Player::Signals::PlaybackStatusChanged::ArgumentType > DBusPlaybackStatusChangedSignal
virtual const core::Property< PlaybackRate > & minimum_playback_rate() const
struct media::PlayerSkeleton::Private::Signals signals
core::Signal< media::Player::Error > error
void handle_seek(const core::dbus::Message::Ptr &in)
virtual const core::Property< Orientation > & orientation() const
void handle_open_uri(const core::dbus::Message::Ptr &in)
core::dbus::Signal< Signals::Seeked, Signals::Seeked::ArgumentType >::Ptr seeked_to
Definition: player.h:418
virtual const core::Property< Volume > & volume() const
virtual const core::Signal< video::Dimensions > & video_dimension_changed() const
std::string UriType
Definition: track.h:40
Signals(const std::shared_ptr< DBusSeekedToSignal > &remote_seeked, const std::shared_ptr< DBusAboutToFinishSignal > &remote_atf, const std::shared_ptr< DBusEndOfStreamSignal > &remote_eos, const std::shared_ptr< DBusPlaybackStatusChangedSignal > &remote_playback_status_changed, const std::shared_ptr< DBusVideoDimensionChangedSignal > &remote_video_dimension_changed, const std::shared_ptr< DBusErrorSignal > &remote_error)
void handle_next(const core::dbus::Message::Ptr &msg)
virtual core::Signal< PlaybackStatus > & playback_status_changed()
void on_property_value_changed(const typename Property::ValueType &value, const dbus::Signal< core::dbus::interfaces::Properties::Signals::PropertiesChanged, core::dbus::interfaces::Properties::Signals::PropertiesChanged::ArgumentType >::Ptr &signal)
virtual const core::Property< bool > & shuffle() const
virtual const core::Property< bool > & is_audio_source() const
media::apparmor::ubuntu::RequestAuthenticator::Ptr request_authenticator
core::Signal< media::video::Dimensions > video_dimension_changed
core::dbus::Signal< mpris::Player::Signals::Seeked, mpris::Player::Signals::Seeked::ArgumentType > DBusSeekedToSignal
core::dbus::Signal< Signals::EndOfStream, Signals::EndOfStream::ArgumentType >::Ptr end_of_stream
Definition: player.h:420
core::dbus::Signal< mpris::Player::Signals::AboutToFinish, mpris::Player::Signals::AboutToFinish::ArgumentType > DBusAboutToFinishSignal
core::dbus::Signal< mpris::Player::Signals::Error, mpris::Player::Signals::Error::ArgumentType > DBusErrorSignal
core::Signal< media::Player::PlaybackStatus > playback_status_changed
virtual const core::Property< Lifetime > & lifetime() const
core::dbus::Signal< Signals::PlaybackStatusChanged, Signals::PlaybackStatusChanged::ArgumentType >::Ptr playback_status_changed
Definition: player.h:421
void handle_create_video_sink(const core::dbus::Message::Ptr &in)
core::dbus::Signal< Signals::Error, Signals::Error::ArgumentType >::Ptr error
Definition: player.h:423
void handle_key(const core::dbus::Message::Ptr &in)